ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/random_map.C
(Generate patch)

Comparing deliantra/server/random_maps/random_map.C (file contents):
Revision 1.1 by elmex, Sun Aug 13 17:16:03 2006 UTC vs.
Revision 1.49 by root, Tue Apr 13 02:39:53 2010 UTC

1/* 1/*
2 * static char *rcsid_random_map_c = 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * "$Id: random_map.C,v 1.1 2006/08/13 17:16:03 elmex Exp $"; 3 *
4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen
7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * 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 Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
21 *
22 * The authors can be reached via e-mail to <support@deliantra.net>
4 */ 23 */
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 24
29#include <time.h> 25#include <time.h>
30#include <stdio.h> 26#include <stdio.h>
31#include <global.h> 27#include <global.h>
32#include <maze_gen.h>
33#include <room_gen.h>
34#include <random_map.h> 28#include <random_map.h>
35#include <rproto.h> 29#include <rproto.h>
36#include <sproto.h> 30#include <sproto.h>
37 31
38void dump_layout(char **layout,RMParms *RP) { 32#define CEDE coroapi::cede_to_tick ()
39 { int i,j; 33
40 for(i=0;i<RP->Xsize;i++) { 34static void symmetrize_layout (Layout maze, random_map_params *RP);
41 for(j=0;j<RP->Ysize;j++) { 35static void rotate_layout (Layout maze, int rotation);
42 if(layout[i][j]==0) layout[i][j]=' '; 36
43 printf("%c",layout[i][j]); 37void
44 if(layout[i][j]==' ') layout[i][j]=0; 38dump_layout (Layout layout)
39{
40 for (int j = 0; j < layout->h; j++)
45 } 41 {
46 printf("\n"); 42 for (int i = 0; i < layout->w; i++)
43 putc (layout[i][j] ? layout[i][j] : ' ', stdout);
44
45 putc ('\n', stdout);
47 }} 46 }
48 printf("\n");
49}
50EXTERN FILE *logfile;
51mapstruct *generate_random_map(const char *OutFileName, RMParms *RP) {
52 char **layout, buf[HUGE_BUF];
53 mapstruct *theMap;
54 int i;
55 47
56 /* pick a random seed, or use the one from the input file */ 48 putc ('\n', stdout);
57 if(RP->random_seed == 0)
58 RP->random_seed=time(0);
59
60 SRANDOM(RP->random_seed);
61
62 write_map_parameters_to_string(buf, RP);
63
64 if(RP->difficulty==0) {
65 RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
66 if (RP->difficulty_increase > 0.001) {
67 RP->difficulty = (int)((float)RP->dungeon_level * RP->difficulty_increase);
68 if (RP->difficulty < 1) RP->difficulty=1;
69 }
70 }
71 else
72 RP->difficulty_given=1;
73
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;
76
77 if(RP->expand2x > 0) {
78 RP->Xsize /=2;
79 RP->Ysize /=2;
80 }
81
82 layout = layoutgen(RP);
83
84#ifdef RMAP_DEBUG
85 dump_layout(layout,RP);
86#endif
87
88 /* increment these for the current map */
89 RP->dungeon_level+=1;
90 /* allow constant-difficulty maps. */
91 /* difficulty+=1; */
92
93 /* rotate the layout randomly */
94 layout=rotate_layout(layout,RANDOM()%4,RP);
95#ifdef RMAP_DEBUG
96 dump_layout(layout,RP);
97#endif
98
99 /* allocate the map and set the floor */
100 theMap = make_map_floor(layout,RP->floorstyle,RP);
101
102 /* set the name of the map. */
103 strcpy(theMap->path,OutFileName);
104
105 /* set region */
106 theMap->region=RP->region;
107
108 /* create walls unless the wallstyle is "none" */
109 if (strcmp (RP->wallstyle, "none")) {
110 make_map_walls(theMap,layout,RP->wallstyle,RP);
111
112 /* place doors unless doorstyle or wallstyle is "none"*/
113 if (strcmp (RP->doorstyle, "none"))
114 put_doors(theMap,layout,RP->doorstyle,RP);
115
116 }
117
118 /* create exits unless the exitstyle is "none" */
119 if (strcmp (RP->exitstyle, "none"))
120 place_exits(theMap,layout,RP->exitstyle,RP->orientation,RP);
121
122 place_specials_in_map(theMap,layout,RP);
123
124 /* create monsters unless the monsterstyle is "none" */
125 if (strcmp (RP->monsterstyle, "none"))
126 place_monsters(theMap,RP->monsterstyle,RP->difficulty,RP);
127
128 /* treasures needs to have a proper difficulty set for the map. */
129 theMap->difficulty=calculate_difficulty(theMap);
130
131 /* create treasure unless the treasurestyle is "none" */
132 if (strcmp (RP->treasurestyle, "none"))
133 place_treasure(theMap,layout,RP->treasurestyle,RP->treasureoptions,RP);
134
135 /* create decor unless the decorstyle is "none" */
136 if (strcmp (RP->decorstyle, "none"))
137 put_decor(theMap,layout,RP->decorstyle,RP->decoroptions,RP);
138
139 /* generate treasures, etc. */
140 fix_auto_apply(theMap);
141
142 unblock_exits(theMap,layout,RP);
143
144 /* free the layout */
145 for(i=0;i<RP->Xsize;i++)
146 free(layout[i]);
147 free(layout);
148
149 theMap->msg = strdup_local(buf);
150
151 return theMap;
152} 49}
153 50
154
155/* function selects the layout function and gives it whatever
156 arguments it needs. */
157char **layoutgen(RMParms *RP) {
158 char **maze=0;
159 int oxsize= RP->Xsize, oysize=RP->Ysize;
160
161 if(RP->symmetry == RANDOM_SYM)
162 RP->symmetry_used = (RANDOM() % ( XY_SYM))+1;
163 else RP->symmetry_used = RP->symmetry;
164
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;
167
168 if(RP->Xsize<MIN_RANDOM_MAP_SIZE) RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM()%5;
169 if(RP->Ysize<MIN_RANDOM_MAP_SIZE) RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM()%5;
170 RP->map_layout_style = 0;
171
172 /* Redo this - there was a lot of redundant code of checking for preset
173 * layout style and then random layout style. Instead, figure out
174 * the numeric layoutstyle, so there is only one area that actually
175 * calls the code to make the maps.
176 */
177 if(strstr(RP->layoutstyle,"onion")) {
178 RP->map_layout_style = ONION_LAYOUT;
179 }
180
181 if(strstr(RP->layoutstyle,"maze")) {
182 RP->map_layout_style = MAZE_LAYOUT;
183 }
184
185 if(strstr(RP->layoutstyle,"spiral")) {
186 RP->map_layout_style = SPIRAL_LAYOUT;
187 }
188
189 if(strstr(RP->layoutstyle,"rogue")) {
190 RP->map_layout_style = ROGUELIKE_LAYOUT;
191 }
192
193 if(strstr(RP->layoutstyle,"snake")) {
194 RP->map_layout_style = SNAKE_LAYOUT;
195 }
196
197 if(strstr(RP->layoutstyle,"squarespiral")) {
198 RP->map_layout_style = SQUARE_SPIRAL_LAYOUT;
199 }
200 /* No style found - choose one ranomdly */
201 if (RP->map_layout_style == 0) {
202 RP->map_layout_style = (RANDOM() % NROFLAYOUTS) + 1;
203 }
204
205 switch(RP->map_layout_style) {
206
207 case ONION_LAYOUT:
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);
210 break;
211
212 case MAZE_LAYOUT:
213 maze = maze_gen(RP->Xsize,RP->Ysize,RANDOM()%2);
214 if(!(RANDOM()%2)) doorify_layout(maze,RP);
215 break;
216
217 case SPIRAL_LAYOUT:
218 maze = map_gen_spiral(RP->Xsize,RP->Ysize,RP->layoutoptions1);
219 if(!(RANDOM()%2)) doorify_layout(maze,RP);
220 break;
221
222 case ROGUELIKE_LAYOUT:
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),
225 * but more importantly, the symmetry code presumes we are symmetrizing
226 * spirals, or maps with lots of passages - making a symmetric rogue
227 * map fails because its likely that the passages the symmetry process
228 * creates may not connect the rooms.
229 */
230 RP->symmetry_used = NO_SYM;
231 RP->Ysize = oysize;
232 RP->Xsize = oxsize;
233 maze = roguelike_layout_gen(RP->Xsize,RP->Ysize,RP->layoutoptions1);
234 /* no doorifying... done already */
235 break;
236
237 case SNAKE_LAYOUT:
238 maze = make_snake_layout(RP->Xsize,RP->Ysize,RP->layoutoptions1);
239 if(RANDOM()%2) roomify_layout(maze,RP);
240 break;
241
242 case SQUARE_SPIRAL_LAYOUT:
243 maze = make_square_spiral_layout(RP->Xsize,RP->Ysize,RP->layoutoptions1);
244 if(RANDOM()%2) roomify_layout(maze,RP);
245 break;
246 }
247
248 maze = symmetrize_layout(maze, RP->symmetry_used,RP);
249#ifdef RMAP_DEBUG
250 dump_layout(maze,RP);
251#endif
252 if(RP->expand2x) {
253 maze = expand2x(maze,RP->Xsize,RP->Ysize);
254 RP->Xsize = RP->Xsize * 2 -1;
255 RP->Ysize = RP->Ysize * 2 -1;
256 }
257 return maze;
258}
259
260
261/* takes a map and makes it symmetric: adjusts Xsize and 51/* takes a map and makes it symmetric: adjusts Xsize and
262Ysize to produce a symmetric map. */ 52 * Ysize to produce a symmetric map.
263 53 */
264char **symmetrize_layout(char **maze, int sym,RMParms *RP) { 54static void
265 int i,j; 55symmetrize_layout (Layout layout, random_map_params *RP)
266 char **sym_maze; 56{
267 int Xsize_orig,Ysize_orig; 57 if (RP->symmetry_used == SYMMETRY_NONE)
268 Xsize_orig = RP->Xsize;
269 Ysize_orig = RP->Ysize;
270 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used.*/
271 if(sym == NO_SYM) {
272 RP->Xsize = Xsize_orig;
273 RP->Ysize = Ysize_orig;
274 return maze; 58 return;
275 }
276 /* pick new sizes */
277 RP->Xsize = ((sym==X_SYM||sym==XY_SYM)?RP->Xsize*2-3:RP->Xsize);
278 RP->Ysize = ((sym==Y_SYM||sym==XY_SYM)?RP->Ysize*2-3:RP->Ysize);
279 59
280 sym_maze = (char **)calloc(sizeof(char*),RP->Xsize); 60 Layout sym_layout (
281 for(i=0;i<RP->Xsize;i++) 61 RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? layout->w * 2 - 3 : layout->w,
282 sym_maze[i] = (char *)calloc(sizeof(char),RP->Ysize); 62 RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? layout->h * 2 - 3 : layout->h
63 );
283 64
284 if(sym==X_SYM) 65 if (RP->symmetry_used == SYMMETRY_X)
285 for(i=0;i<RP->Xsize/2+1;i++) 66 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
286 for(j=0;j<RP->Ysize;j++) { 67 for (int j = 0; j < sym_layout->h; j++)
287 sym_maze[i][j] = maze[i][j]; 68 {
288 sym_maze[RP->Xsize - i-1][j] = maze[i][j]; 69 sym_layout[i ][j] =
289 }; 70 sym_layout[sym_layout->w - i - 1][j] = layout[i][j];
290 if(sym==Y_SYM)
291 for(i=0;i<RP->Xsize;i++)
292 for(j=0;j<RP->Ysize/2+1;j++) {
293 sym_maze[i][j] = maze[i][j];
294 sym_maze[i][RP->Ysize-j-1] = maze[i][j];
295 } 71 }
296 if(sym==XY_SYM) 72
297 for(i=0;i<RP->Xsize/2+1;i++) 73 if (RP->symmetry_used == SYMMETRY_Y)
298 for(j=0;j<RP->Ysize/2+1;j++) { 74 for (int i = 0; i < sym_layout->w; i++)
299 sym_maze[i][j] = maze[i][j]; 75 for (int j = 0; j < sym_layout->h / 2 + 1; j++)
300 sym_maze[i][RP->Ysize-j-1] = maze[i][j]; 76 {
301 sym_maze[RP->Xsize - i-1][j] = maze[i][j]; 77 sym_layout[i][j ] =
302 sym_maze[RP->Xsize - i-1][RP->Ysize-j-1] = maze[i][j]; 78 sym_layout[i][sym_layout->h - j - 1] = layout[i][j];
303 } 79 }
304 /* delete the old maze */ 80
305 for(i=0;i<Xsize_orig;i++) 81 if (RP->symmetry_used == SYMMETRY_XY)
306 free(maze[i]); 82 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
307 free(maze); 83 for (int j = 0; j < sym_layout->h / 2 + 1; j++)
84 {
85 sym_layout[i ][j ] =
86 sym_layout[i ][sym_layout->h - j - 1] =
87 sym_layout[sym_layout->w - i - 1][j ] =
88 sym_layout[sym_layout->w - i - 1][sym_layout->h - j - 1] = layout[i][j];
89 }
90
91 layout.swap (sym_layout);
92 sym_layout.free ();
93
308 /* reconnect disjointed spirals */ 94 /* reconnect disjointed spirals */
309 if(RP->map_layout_style==SPIRAL_LAYOUT)
310 connect_spirals(RP->Xsize,RP->Ysize,sym,sym_maze);
311 /* reconnect disjointed nethackmazes: the routine for 95 /* reconnect disjointed nethacklayouts: the routine for
312 spirals will do the trick?*/ 96 spirals will do the trick? */
313 if(RP->map_layout_style==ROGUELIKE_LAYOUT) 97 if (RP->map_layout_style == LAYOUT_SPIRAL
314 connect_spirals(RP->Xsize,RP->Ysize,sym,sym_maze); 98 || RP->map_layout_style == LAYOUT_ROGUELIKE)
315 99 connect_spirals (layout->w, layout->h, RP->symmetry_used, layout);
316 return sym_maze;
317} 100}
318
319 101
320/* takes a map and rotates it. This completes the 102/* takes a map and rotates it. This completes the
321 onion layouts, making them possibly centered on any wall. 103 onion layouts, making them possibly centered on any wall.
322 It'll modify Xsize and Ysize if they're swapped. 104 It'll modify Xsize and Ysize if they're swapped.
323*/ 105*/
106static void
107rotate_layout (Layout layout, int rotation)
108{
109 int w = layout->w;
110 int h = layout->h;
324 111
325char ** rotate_layout(char **maze,int rotation,RMParms *RP) {
326 char **new_maze;
327 int i,j;
328
329 switch(rotation) { 112 switch (rotation)
330 case 0:
331 return maze;
332 break;
333 case 2: /* a reflection */
334 { 113 {
335 char *newmaze= (char *) malloc(sizeof(char) * RP->Xsize*RP->Ysize); 114 case 2: /* a reflection */
336 for(i=0;i<RP->Xsize;i++) { /* make a copy */
337 for(j=0;j<RP->Ysize;j++) {
338 newmaze[i * RP->Ysize + j] = maze[i][j];
339 } 115 {
116 Layout new_layout (w, h);
117
118 for (int i = 0; i < w; i++) /* copy a reflection back */
119 for (int j = 0; j < h; j++)
120 new_layout[i][j] = layout[w - i - 1][h - j - 1];
121
122 layout.swap (new_layout);
123 new_layout.free ();
340 } 124 }
341 for(i=0;i<RP->Xsize;i++) { /* copy a reflection back */
342 for(j=0;j<RP->Ysize;j++) {
343 maze[i][j]= newmaze[(RP->Xsize-i-1)*RP->Ysize + RP->Ysize-j-1];
344 }
345 }
346 free(newmaze);
347 return maze;
348 break; 125 break;
349 } 126
350 case 1: 127 case 1:
351 case 3: 128 case 3:
352 { int swap; 129 {
353 new_maze = (char **) calloc(sizeof(char *),RP->Ysize); 130 Layout new_layout (h, w);
354 for(i=0;i<RP->Ysize;i++) { 131
355 new_maze[i] = (char *) calloc(sizeof(char),RP->Xsize);
356 }
357 if(rotation == 1) /* swap x and y */ 132 if (rotation == 1) /* swap x and y */
358 for(i=0;i<RP->Xsize;i++) 133 for (int i = 0; i < w; i++)
359 for(j=0;j<RP->Ysize;j++) 134 for (int j = 0; j < h; j++)
360 new_maze[j][i] = maze[i][j]; 135 new_layout[j][i] = layout[i][j];
361 136
362 if(rotation == 3) { /* swap x and y */ 137 if (rotation == 3) /* swap x and y */
363 for(i=0;i<RP->Xsize;i++) 138 for (int i = 0; i < w; i++)
364 for(j=0;j<RP->Ysize;j++) 139 for (int j = 0; j < h; j++)
365 new_maze[j][i] = maze[RP->Xsize -i-1][RP->Ysize - j-1]; 140 new_layout[j][i] = layout[w - i - 1][h - j - 1];
366 }
367 141
368 /* delete the old layout */ 142 layout.swap (new_layout);
369 for(i=0;i<RP->Xsize;i++) 143 new_layout.free ();
370 free(maze[i]); 144 }
371 free(maze);
372
373 swap = RP->Ysize;
374 RP->Ysize = RP->Xsize;
375 RP->Xsize = swap;
376 return new_maze;
377 break; 145 break;
378 }
379 } 146 }
380 return NULL;
381}
382
383/* take a layout and make some rooms in it.
384 --works best on onions.*/
385void roomify_layout(char **maze,RMParms *RP) {
386 int tries = RP->Xsize*RP->Ysize/30;
387 int ti;
388
389 for(ti=0;ti<tries;ti++) {
390 int dx,dy; /* starting location for looking at creating a door */
391 int cx,cy; /* results of checking on creating walls. */
392 dx = RANDOM() % RP->Xsize;
393 dy = RANDOM() % RP->Ysize;
394 cx = can_make_wall(maze,dx,dy,0,RP); /* horizontal */
395 cy = can_make_wall(maze,dx,dy,1,RP); /* vertical */
396 if(cx == -1) {
397 if(cy != -1)
398 make_wall(maze,dx,dy,1);
399 continue;
400 }
401 if(cy == -1) {
402 make_wall(maze,dx,dy,0);
403 continue;
404 }
405 if(cx < cy) make_wall(maze,dx,dy,0);
406 else make_wall(maze,dx,dy,1);
407 }
408} 147}
409 148
410/* checks the layout to see if I can stick a horizontal(dir = 0) wall 149/* checks the layout to see if I can stick a horizontal(dir = 0) wall
411 (or vertical, dir == 1) 150 (or vertical, dir == 1)
412 here which ends up on other walls sensibly. */ 151 here which ends up on other walls sensibly. */
413 152static int
414int can_make_wall(char **maze,int dx,int dy,int dir,RMParms *RP) { 153can_make_wall (char **maze, int dx, int dy, int dir, random_map_params *RP)
154{
415 int i1; 155 int i1;
416 int length=0; 156 int length = 0;
417 157
418 /* dont make walls if we're on the edge. */ 158 /* dont make walls if we're on the edge. */
419 if(dx == 0 || dx == (RP->Xsize -1) || dy == 0 || dy == (RP->Ysize-1)) return -1; 159 if (dx == 0 || dx == (RP->Xsize - 1) || dy == 0 || dy == (RP->Ysize - 1))
160 return -1;
420 161
421 /* don't make walls if we're ON a wall. */ 162 /* don't make walls if we're ON a wall. */
422 if(maze[dx][dy]!=0) return -1; 163 if (maze[dx][dy] != 0)
164 return -1;
423 165
424 if(dir==0) /* horizontal */ 166 if (dir == 0) /* horizontal */
425 { 167 {
426 int y = dy; 168 int y = dy;
169
427 for(i1=dx-1;i1>0;i1--) { 170 for (i1 = dx - 1; i1 > 0; i1--)
171 {
428 int sindex=surround_flag2(maze,i1,y,RP); 172 int sindex = surround_flag2 (maze, i1, y, RP);
173
429 if(sindex == 1) break; 174 if (sindex == 1)
175 break;
176 if (sindex != 0)
430 if(sindex != 0) return -1; /* can't make horiz. wall here */ 177 return -1; /* can't make horiz. wall here */
178 if (maze[i1][y] != 0)
431 if(maze[i1][y]!=0) return -1; /* can't make horiz. wall here */ 179 return -1; /* can't make horiz. wall here */
432 length++; 180 length++;
181 }
182
183 for (i1 = dx + 1; i1 < RP->Xsize - 1; i1++)
184 {
185 int sindex = surround_flag2 (maze, i1, y, RP);
186
187 if (sindex == 2)
188 break;
189 if (sindex != 0)
190 return -1; /* can't make horiz. wall here */
191 if (maze[i1][y] != 0)
192 return -1; /* can't make horiz. wall here */
193 length++;
194 }
195 return length;
196 }
197 else
198 { /* vertical */
199 int x = dx;
200
201 for (i1 = dy - 1; i1 > 0; i1--)
202 {
203 int sindex = surround_flag2 (maze, x, i1, RP);
204
205 if (sindex == 4)
206 break;
207 if (sindex != 0)
208 return -1; /* can't make vert. wall here */
209 if (maze[x][i1] != 0)
210 return -1; /* can't make horiz. wall here */
211 length++;
212 }
213
214 for (i1 = dy + 1; i1 < RP->Ysize - 1; i1++)
215 {
216 int sindex = surround_flag2 (maze, x, i1, RP);
217
218 if (sindex == 8)
219 break;
220 if (sindex != 0)
221 return -1; /* can't make verti. wall here */
222 if (maze[x][i1] != 0)
223 return -1; /* can't make horiz. wall here */
224 length++;
225 }
226
227 return length;
228 }
229
230 return -1;
231}
232
233/* take a layout and make some rooms in it.
234 --works best on onions.*/
235static void
236roomify_layout (char **maze, random_map_params *RP)
237{
238 int tries = RP->Xsize * RP->Ysize / 30;
239 int ti;
240
241 for (ti = 0; ti < tries; ti++)
242 {
243 int dx, dy; /* starting location for looking at creating a door */
244 int cx, cy; /* results of checking on creating walls. */
245
246 dx = rmg_rndm (RP->Xsize);
247 dy = rmg_rndm (RP->Ysize);
248
249 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
250 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
251 if (cx == -1)
252 {
253 if (cy != -1)
254 make_wall (maze, dx, dy, 1);
255
256 continue;
257 }
258
259 if (cy == -1)
260 {
261 make_wall (maze, dx, dy, 0);
262 continue;
263 }
264
265 if (cx < cy)
266 make_wall (maze, dx, dy, 0);
267 else
268 make_wall (maze, dx, dy, 1);
269 }
270}
271
272int
273make_wall (char **maze, int x, int y, int dir)
274{
275 maze[x][y] = 'D'; /* mark a door */
276 switch (dir)
277 {
278 case 0: /* horizontal */
279 {
280 int i1;
281
282 for (i1 = x - 1; maze[i1][y] == 0; i1--)
283 maze[i1][y] = '#';
284 for (i1 = x + 1; maze[i1][y] == 0; i1++)
285 maze[i1][y] = '#';
286 break;
287 }
288 case 1: /* vertical */
289 {
290 int i1;
291
292 for (i1 = y - 1; maze[x][i1] == 0; i1--)
293 maze[x][i1] = '#';
294 for (i1 = y + 1; maze[x][i1] == 0; i1++)
295 maze[x][i1] = '#';
296 break;
297 }
298 }
299
300 return 0;
301}
302
303/* puts doors at appropriate locations in a layout. */
304static void
305doorify_layout (char **maze, random_map_params *RP)
306{
307 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
308 int doorlocs = 0; /* # of available doorlocations */
309
310 uint16 *doorlist_x = salloc<uint16> (RP->Xsize * RP->Ysize);
311 uint16 *doorlist_y = salloc<uint16> (RP->Xsize * RP->Ysize);
312
313 /* make a list of possible door locations */
314 for (int i = 1; i < RP->Xsize - 1; i++)
315 for (int j = 1; j < RP->Ysize - 1; j++)
316 {
317 int sindex = surround_flag (maze, i, j, RP);
318
319 if (sindex == 3 || sindex == 12) /* these are possible door sindex */
320 {
321 doorlist_x[doorlocs] = i;
322 doorlist_y[doorlocs] = j;
323 doorlocs++;
324 }
433 } 325 }
434 326
435 for(i1=dx+1;i1<RP->Xsize-1;i1++) { 327 while (ndoors > 0 && doorlocs > 0)
436 int sindex=surround_flag2(maze,i1,y,RP);
437 if(sindex == 2) break;
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 */
440 length++;
441 }
442 return length;
443 } 328 {
444 else { /* vertical */ 329 int di = rmg_rndm (doorlocs);
445 int x = dx; 330 int i = doorlist_x[di];
446 for(i1=dy-1;i1>0;i1--) { 331 int j = doorlist_y[di];
447 int sindex=surround_flag2(maze,x,i1,RP);
448 if(sindex == 4) break;
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 */
451 length++;
452 }
453
454 for(i1=dy+1;i1<RP->Ysize-1;i1++) {
455 int sindex=surround_flag2(maze,x,i1,RP);
456 if(sindex == 8) break;
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 */
459 length++;
460 }
461 return length;
462 }
463 return -1;
464}
465
466
467int make_wall(char **maze,int x, int y, int dir){
468 maze[x][y] = 'D'; /* mark a door */
469 switch(dir) {
470 case 0: /* horizontal */
471 {
472 int i1;
473 for(i1 = x-1;maze[i1][y]==0;i1--)
474 maze[i1][y]='#';
475 for(i1 = x+1;maze[i1][y]==0;i1++)
476 maze[i1][y]='#';
477 break;
478 }
479 case 1: /* vertical */
480 {
481 int i1;
482 for(i1 = y-1;maze[x][i1]==0;i1--)
483 maze[x][i1]='#';
484 for(i1 = y+1;maze[x][i1]==0;i1++)
485 maze[x][i1]='#';
486 break;
487 }
488 }
489
490 return 0;
491}
492
493/* puts doors at appropriate locations in a layout. */
494
495void doorify_layout(char **maze,RMParms *RP) {
496 int ndoors = RP->Xsize*RP->Ysize/60; /* reasonable number of doors. */
497 char *doorlist_x;
498 char *doorlist_y;
499 int doorlocs = 0; /* # of available doorlocations */
500 int i,j;
501
502 doorlist_x = (char *) malloc(sizeof(int) * RP->Xsize*RP->Ysize);
503 doorlist_y = (char *) malloc(sizeof(int) * RP->Xsize*RP->Ysize);
504
505
506 /* make a list of possible door locations */
507 for(i=1;i<RP->Xsize-1;i++)
508 for(j=1;j<RP->Ysize-1;j++) {
509 int sindex = surround_flag(maze,i,j,RP); 332 int sindex = surround_flag (maze, i, j, RP);
333
510 if(sindex == 3 || sindex == 12) /* these are possible door sindex*/ 334 if (sindex == 3 || sindex == 12) /* these are possible door sindex */
511 {
512 doorlist_x[doorlocs]=i;
513 doorlist_y[doorlocs]=j;
514 doorlocs++;
515 } 335 {
516 }
517 while(ndoors > 0 && doorlocs > 0) {
518 int di;
519 int sindex;
520 di = RANDOM() % doorlocs;
521 i=doorlist_x[di];
522 j=doorlist_y[di];
523 sindex= surround_flag(maze,i,j,RP);
524 if(sindex == 3 || sindex == 12) /* these are possible door sindex*/
525 {
526 maze[i][j] = 'D'; 336 maze[i][j] = 'D';
527 ndoors--; 337 ndoors--;
528 } 338 }
339
529 /* reduce the size of the list */ 340 /* reduce the size of the list */
530 doorlocs--; 341 doorlocs--;
531 doorlist_x[di]=doorlist_x[doorlocs]; 342 doorlist_x[di] = doorlist_x[doorlocs];
532 doorlist_y[di]=doorlist_y[doorlocs]; 343 doorlist_y[di] = doorlist_y[doorlocs];
533 } 344 }
534 free(doorlist_x);
535 free(doorlist_y);
536}
537 345
346 sfree (doorlist_x, RP->Xsize * RP->Ysize);
347 sfree (doorlist_y, RP->Xsize * RP->Ysize);
348}
538 349
350void
539void write_map_parameters_to_string(char *buf,RMParms *RP) { 351write_map_parameters_to_string (char *buf, random_map_params *RP)
540 352{
541 char small_buf[256]; 353 char small_buf[16384];
354
542 sprintf(buf,"xsize %d\nysize %d\n",RP->Xsize,RP->Ysize); 355 sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize);
543 356
544 if(RP->wallstyle[0]) { 357 if (RP->wallstyle[0])
358 {
545 sprintf(small_buf,"wallstyle %s\n",RP->wallstyle); 359 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle);
546 strcat(buf,small_buf); 360 strcat (buf, small_buf);
547 } 361 }
548 362
363 if (RP->miningstyle[0])
364 {
365 sprintf (small_buf, "miningstyle %s\n", RP->miningstyle);
366 strcat (buf, small_buf);
367 }
368
549 if(RP->floorstyle[0]) { 369 if (RP->floorstyle[0])
370 {
550 sprintf(small_buf,"floorstyle %s\n",RP->floorstyle); 371 sprintf (small_buf, "floorstyle %s\n", RP->floorstyle);
551 strcat(buf,small_buf); 372 strcat (buf, small_buf);
552 } 373 }
553 374
554 if(RP->monsterstyle[0]) { 375 if (RP->monsterstyle[0])
376 {
555 sprintf(small_buf,"monsterstyle %s\n",RP->monsterstyle); 377 sprintf (small_buf, "monsterstyle %s\n", RP->monsterstyle);
556 strcat(buf,small_buf); 378 strcat (buf, small_buf);
557 } 379 }
558 380
559 if(RP->treasurestyle[0]) { 381 if (RP->treasurestyle[0])
382 {
560 sprintf(small_buf,"treasurestyle %s\n",RP->treasurestyle); 383 sprintf (small_buf, "treasurestyle %s\n", RP->treasurestyle);
561 strcat(buf,small_buf); 384 strcat (buf, small_buf);
562 } 385 }
563 386
564 if(RP->layoutstyle[0]) { 387 if (RP->layoutstyle[0])
388 {
565 sprintf(small_buf,"layoutstyle %s\n",RP->layoutstyle); 389 sprintf (small_buf, "layoutstyle %s\n", RP->layoutstyle);
566 strcat(buf,small_buf); 390 strcat (buf, small_buf);
567 } 391 }
568 392
569 if(RP->decorstyle[0]) { 393 if (RP->decorstyle[0])
394 {
570 sprintf(small_buf,"decorstyle %s\n",RP->decorstyle); 395 sprintf (small_buf, "decorstyle %s\n", RP->decorstyle);
571 strcat(buf,small_buf); 396 strcat (buf, small_buf);
572 } 397 }
573 398
574 if(RP->doorstyle[0]) { 399 if (RP->doorstyle[0])
400 {
575 sprintf(small_buf,"doorstyle %s\n",RP->doorstyle); 401 sprintf (small_buf, "doorstyle %s\n", RP->doorstyle);
576 strcat(buf,small_buf); 402 strcat (buf, small_buf);
577 } 403 }
578 404
579 if(RP->exitstyle[0]) { 405 if (RP->exitstyle[0])
406 {
580 sprintf(small_buf,"exitstyle %s\n",RP->exitstyle); 407 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle);
581 strcat(buf,small_buf); 408 strcat (buf, small_buf);
582 } 409 }
583 410
584 if(RP->final_map[0]) { 411 if (RP->final_map.length ())
412 {
585 sprintf(small_buf,"final_map %s\n",RP->final_map); 413 sprintf (small_buf, "final_map %s\n", &RP->final_map);
586 strcat(buf,small_buf); 414 strcat (buf, small_buf);
587 } 415 }
588 416
589 if(RP->exit_on_final_map[0]) { 417 if (RP->exit_on_final_map[0])
418 {
590 sprintf(small_buf,"exit_on_final_map %s\n",RP->exit_on_final_map); 419 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
591 strcat(buf,small_buf); 420 strcat (buf, small_buf);
592 } 421 }
593 422
594 if(RP->this_map[0]) { 423 if (RP->this_map.length ())
424 {
595 sprintf(small_buf,"origin_map %s\n",RP->this_map); 425 sprintf (small_buf, "origin_map %s\n", &RP->this_map);
596 strcat(buf,small_buf); 426 strcat (buf, small_buf);
597 } 427 }
598 428
599 if(RP->expand2x) { 429 if (RP->expand2x)
430 {
600 sprintf(small_buf,"expand2x %d\n",RP->expand2x); 431 sprintf (small_buf, "expand2x %d\n", RP->expand2x);
601 strcat(buf,small_buf); 432 strcat (buf, small_buf);
602 } 433 }
603 434
604 if(RP->layoutoptions1) { 435 if (RP->layoutoptions1)
436 {
605 sprintf(small_buf,"layoutoptions1 %d\n",RP->layoutoptions1); 437 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1);
606 strcat(buf,small_buf); 438 strcat (buf, small_buf);
607 } 439 }
608 440
609
610 if(RP->layoutoptions2) { 441 if (RP->layoutoptions2)
442 {
611 sprintf(small_buf,"layoutoptions2 %d\n",RP->layoutoptions2); 443 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2);
612 strcat(buf,small_buf); 444 strcat (buf, small_buf);
613 } 445 }
614 446
615
616 if(RP->layoutoptions3) { 447 if (RP->layoutoptions3)
448 {
617 sprintf(small_buf,"layoutoptions3 %d\n",RP->layoutoptions3); 449 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3);
618 strcat(buf,small_buf); 450 strcat (buf, small_buf);
619 } 451 }
620 452
621 if(RP->symmetry) { 453 if (RP->symmetry)
454 {
622 sprintf(small_buf,"symmetry %d\n",RP->symmetry); 455 sprintf (small_buf, "symmetry %d\n", RP->symmetry);
623 strcat(buf,small_buf); 456 strcat (buf, small_buf);
624 } 457 }
625 458
626
627 if(RP->difficulty && RP->difficulty_given ) { 459 if (RP->difficulty && RP->difficulty_given)
460 {
628 sprintf(small_buf,"difficulty %d\n",RP->difficulty); 461 sprintf (small_buf, "difficulty %d\n", RP->difficulty);
629 strcat(buf,small_buf); 462 strcat (buf, small_buf);
630 } 463 }
631 464
632 if(RP->difficulty_increase != 1.0 ) { 465 if (fabs (RP->difficulty_increase - 1.f) >= (1.f / 1024.f))
466 {
633 sprintf(small_buf,"difficulty_increase %f\n",RP->difficulty_increase); 467 sprintf (small_buf, "difficulty_increase %f\n", RP->difficulty_increase);
634 strcat(buf,small_buf); 468 strcat (buf, small_buf);
635 } 469 }
636 470
637 sprintf(small_buf,"dungeon_level %d\n",RP->dungeon_level); 471 sprintf (small_buf, "dungeon_level %d\n", RP->dungeon_level);
638 strcat(buf,small_buf); 472 strcat (buf, small_buf);
639 473
640 if(RP->dungeon_depth) { 474 if (RP->dungeon_depth)
475 {
641 sprintf(small_buf,"dungeon_depth %d\n",RP->dungeon_depth); 476 sprintf (small_buf, "dungeon_depth %d\n", RP->dungeon_depth);
642 strcat(buf,small_buf); 477 strcat (buf, small_buf);
643 } 478 }
644 479
645 if(RP->decoroptions) { 480 if (RP->decoroptions)
481 {
646 sprintf(small_buf,"decoroptions %d\n",RP->decoroptions); 482 sprintf (small_buf, "decoroptions %d\n", RP->decoroptions);
647 strcat(buf,small_buf); 483 strcat (buf, small_buf);
648 } 484 }
649 485
650 if(RP->orientation) { 486 if (RP->orientation)
487 {
651 sprintf(small_buf,"orientation %d\n",RP->orientation); 488 sprintf (small_buf, "orientation %d\n", RP->orientation);
652 strcat(buf,small_buf); 489 strcat (buf, small_buf);
653 } 490 }
654 491
655 if(RP->origin_x) { 492 if (RP->origin_x)
493 {
656 sprintf(small_buf,"origin_x %d\n",RP->origin_x); 494 sprintf (small_buf, "origin_x %d\n", RP->origin_x);
657 strcat(buf,small_buf); 495 strcat (buf, small_buf);
658 } 496 }
659 497
660 if(RP->origin_y) { 498 if (RP->origin_y)
499 {
661 sprintf(small_buf,"origin_y %d\n",RP->origin_y); 500 sprintf (small_buf, "origin_y %d\n", RP->origin_y);
662 strcat(buf,small_buf); 501 strcat (buf, small_buf);
663 } 502 }
664 if(RP->random_seed) {
665 /* Add one so that the next map is a bit different */
666 sprintf(small_buf,"random_seed %d\n",RP->random_seed + 1);
667 strcat(buf,small_buf);
668 }
669 503
670 if(RP->treasureoptions) { 504 if (RP->treasureoptions)
505 {
671 sprintf(small_buf,"treasureoptions %d\n",RP->treasureoptions); 506 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
672 strcat(buf,small_buf); 507 strcat (buf, small_buf);
673 } 508 }
674 509
675 510 if (RP->random_seed)
676} 511 {
677 512 sprintf (small_buf, "random_seed %u\n", RP->random_seed);
678void write_parameters_to_string(char *buf,
679 int xsize_n,
680 int ysize_n,
681 char *wallstyle_n,
682 char *floorstyle_n,
683 char *monsterstyle_n,
684 char *treasurestyle_n,
685 char *layoutstyle_n,
686 char *decorstyle_n,
687 char *doorstyle_n,
688 char *exitstyle_n,
689 char *final_map_n,
690 char *exit_on_final_map_n,
691 char *this_map_n,
692 int layoutoptions1_n,
693 int layoutoptions2_n,
694 int layoutoptions3_n,
695 int symmetry_n,
696 int dungeon_depth_n,
697 int dungeon_level_n,
698 int difficulty_n,
699 int difficulty_given_n,
700 int decoroptions_n,
701 int orientation_n,
702 int origin_x_n,
703 int origin_y_n,
704 int random_seed_n,
705 int treasureoptions_n,
706 float difficulty_increase)
707{
708
709 char small_buf[256];
710 sprintf(buf,"xsize %d\nysize %d\n",xsize_n,ysize_n);
711
712 if(wallstyle_n && wallstyle_n[0]) {
713 sprintf(small_buf,"wallstyle %s\n",wallstyle_n);
714 strcat(buf,small_buf); 513 strcat (buf, small_buf);
715 } 514 }
716 515
717 if(floorstyle_n && floorstyle_n[0]) { 516 if (RP->custom)
718 sprintf(small_buf,"floorstyle %s\n",floorstyle_n); 517 {
518 sprintf (small_buf, "custom %s\n", RP->custom);
719 strcat(buf,small_buf); 519 strcat (buf, small_buf);
720 } 520 }
521}
721 522
722 if(monsterstyle_n && monsterstyle_n[0]) { 523/////////////////////////////////////////////////////////////////////////////
723 sprintf(small_buf,"monsterstyle %s\n",monsterstyle_n); 524
724 strcat(buf,small_buf); 525LayoutData::LayoutData (int w, int h)
526: w(w), h(h)
527{
528 int size = (sizeof (char *) + sizeof (char) * h) * w;
529
530 col = (char **)salloc<char> (size);
531
532 char *data = (char *)(col + w);
533
534 for (int x = w; x--; )
535 col [x] = data + x * h;
536}
537
538LayoutData::~LayoutData ()
539{
540 int size = (sizeof (char *) + sizeof (char) * h) * w;
541
542 sfree ((char *)col, size);
543}
544
545void LayoutData::clear (char fill)
546{
547 memset (col [0], fill, w * h);
548}
549
550void LayoutData::border (char fill)
551{
552 for (int i = 0; i < w; i++) col [i][0] = col [i][h - 1] = fill;
553 for (int j = 0; j < h; j++) col [0][j] = col [w - 1][j] = fill;
554}
555
556/* function selects the layout function and gives it whatever
557 arguments it needs. */
558static Layout
559layoutgen (random_map_params *RP)
560{
561 Layout layout (RP);
562
563 switch (RP->map_layout_style)
564 {
565 case LAYOUT_ONION:
566 map_gen_onion (layout, RP->layoutoptions1, RP->layoutoptions2);
567
568 if (!(rmg_rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
569 roomify_layout (layout, RP);
570
571 break;
572
573 case LAYOUT_MAZE:
574 maze_gen (layout, rmg_rndm (2));
575
576 if (!(rmg_rndm (2)))
577 doorify_layout (layout, RP);
578
579 break;
580
581 case LAYOUT_SPIRAL:
582 map_gen_spiral (layout, RP->layoutoptions1);
583
584 if (!(rmg_rndm (2)))
585 doorify_layout (layout, RP);
586
587 break;
588
589 case LAYOUT_ROGUELIKE:
590 /* Don't put symmetry in rogue maps. There isn't much reason to
591 * do so in the first place (doesn't make it any more interesting),
592 * but more importantly, the symmetry code presumes we are symmetrizing
593 * spirals, or maps with lots of passages - making a symmetric rogue
594 * map fails because its likely that the passages the symmetry process
595 * creates may not connect the rooms.
596 */
597 RP->symmetry_used = SYMMETRY_NONE;
598 roguelike_layout_gen (layout, RP->layoutoptions1);
599 /* no doorifying... done already */
600 break;
601
602 case LAYOUT_SNAKE:
603 make_snake_layout (layout, RP->layoutoptions1);
604
605 if (rmg_rndm (2))
606 roomify_layout (layout, RP);
607
608 break;
609
610 case LAYOUT_SQUARE_SPIRAL:
611 make_square_spiral_layout (layout, RP->layoutoptions1);
612
613 if (rmg_rndm (2))
614 roomify_layout (layout, RP);
615
616 break;
617
618 default:
619 abort ();
725 } 620 }
726 621
727 if(treasurestyle_n && treasurestyle_n[0]) { 622 /* rotate the layout randomly */
728 sprintf(small_buf,"treasurestyle %s\n",treasurestyle_n); 623 rotate_layout (layout, rmg_rndm (4));
729 strcat(buf,small_buf);
730 }
731 624
732 if(layoutstyle_n &&layoutstyle_n[0]) { 625 symmetrize_layout (layout, RP);
733 sprintf(small_buf,"layoutstyle %s\n",layoutstyle_n);
734 strcat(buf,small_buf);
735 }
736 626
737 if(decorstyle_n && decorstyle_n[0]) { 627#ifdef RMAP_DEBUG
738 sprintf(small_buf,"decorstyle %s\n",decorstyle_n); 628 dump_layout (layout);
739 strcat(buf,small_buf); 629#endif
740 }
741 630
742 if(doorstyle_n && doorstyle_n[0]) { 631 if (RP->expand2x)
743 sprintf(small_buf,"doorstyle %s\n",doorstyle_n); 632 expand2x (layout);
744 strcat(buf,small_buf);
745 }
746 633
747 if(exitstyle_n && exitstyle_n[0]) { 634 return layout;
748 sprintf(small_buf,"exitstyle %s\n",exitstyle_n); 635}
749 strcat(buf,small_buf);
750 }
751 636
752 if(final_map_n && final_map_n[0]) { 637bool
753 sprintf(small_buf,"final_map %s\n",final_map_n); 638maptile::generate_random_map (random_map_params *RP)
754 strcat(buf,small_buf); 639{
755 } 640 char buf[16384];
641 int i;
756 642
757 if(exit_on_final_map_n && exit_on_final_map_n[0]) { 643 RP->Xsize = RP->xsize;
758 sprintf(small_buf,"exit_on_final_map %s\n",exit_on_final_map_n); 644 RP->Ysize = RP->ysize;
759 strcat(buf,small_buf);
760 }
761
762 if(this_map_n && this_map_n[0]) {
763 sprintf(small_buf,"origin_map %s\n",this_map_n);
764 strcat(buf,small_buf);
765 }
766 645
767 if(layoutoptions1_n) { 646 /* pick a random seed, or use the one from the input file */
768 sprintf(small_buf,"layoutoptions1 %d\n",layoutoptions1_n); 647 RP->random_seed = RP->random_seed
769 strcat(buf,small_buf); 648 ? RP->random_seed + RP->dungeon_level
770 } 649 : time (0);
771 650
651 // we run "single-threaded"
652 rmg_rndm.seed (RP->random_seed);
772 653
773 if(layoutoptions2_n) { 654 write_map_parameters_to_string (buf, RP);
774 sprintf(small_buf,"layoutoptions2 %d\n",layoutoptions2_n);
775 strcat(buf,small_buf);
776 }
777 655
656 if (RP->difficulty == 0)
657 {
658 RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
778 659
779 if(layoutoptions3_n) {
780 sprintf(small_buf,"layoutoptions3 %d\n",layoutoptions3_n);
781 strcat(buf,small_buf);
782 }
783
784 if(symmetry_n) {
785 sprintf(small_buf,"symmetry %d\n",symmetry_n);
786 strcat(buf,small_buf);
787 }
788
789
790 if(difficulty_n && difficulty_given_n ) {
791 sprintf(small_buf,"difficulty %d\n",difficulty_n);
792 strcat(buf,small_buf);
793 }
794
795 if(difficulty_increase > 0.001 ) { 660 if (RP->difficulty_increase > 0.001)
796 sprintf(small_buf,"difficulty_increase %f\n",difficulty_increase); 661 RP->difficulty = (int) ((float) RP->dungeon_level * RP->difficulty_increase);
797 strcat(buf,small_buf); 662
663 if (RP->difficulty < 1)
664 RP->difficulty = 1;
798 } 665 }
666 else
667 RP->difficulty_given = 1;
799 668
800 sprintf(small_buf,"dungeon_level %d\n",dungeon_level_n); 669 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
801 strcat(buf,small_buf); 670 RP->Xsize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5;
802 671
803 if(dungeon_depth_n) { 672 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
804 sprintf(small_buf,"dungeon_depth %d\n",dungeon_depth_n); 673 RP->Ysize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5;
805 strcat(buf,small_buf); 674
675 if (RP->symmetry == SYMMETRY_RANDOM)
676 RP->symmetry_used = rmg_rndm (SYMMETRY_XY) + 1;
677 else
678 RP->symmetry_used = RP->symmetry;
679
680 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
681 RP->Ysize = RP->Ysize / 2 + 1;
682
683 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
684 RP->Xsize = RP->Xsize / 2 + 1;
685
686 if (RP->expand2x > 0)
687 {
688 RP->Xsize /= 2;
689 RP->Ysize /= 2;
806 } 690 }
807 691
808 if(decoroptions_n) { 692 RP->map_layout_style = LAYOUT_NONE;
809 sprintf(small_buf,"decoroptions %d\n",decoroptions_n); 693
810 strcat(buf,small_buf); 694 /* Redo this - there was a lot of redundant code of checking for preset
695 * layout style and then random layout style. Instead, figure out
696 * the numeric layoutstyle, so there is only one area that actually
697 * calls the code to make the maps.
698 */
699 if (strstr (RP->layoutstyle, "onion"))
700 RP->map_layout_style = LAYOUT_ONION;
701 else if (strstr (RP->layoutstyle, "maze"))
702 RP->map_layout_style = LAYOUT_MAZE;
703 else if (strstr (RP->layoutstyle, "spiral"))
704 RP->map_layout_style = LAYOUT_SPIRAL;
705 else if (strstr (RP->layoutstyle, "rogue"))
706 RP->map_layout_style = LAYOUT_ROGUELIKE;
707 else if (strstr (RP->layoutstyle, "snake"))
708 RP->map_layout_style = LAYOUT_SNAKE;
709 else if (strstr (RP->layoutstyle, "squarespiral"))
710 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
711 else if (RP->map_layout_style == LAYOUT_NONE)
712 RP->map_layout_style = rmg_rndm (NROFLAYOUTS - 1) + 1; /* No style found - choose one randomly */
713 else
714 abort ();
715
716 Layout layout = layoutgen (RP);
717
718#ifdef RMAP_DEBUG
719 dump_layout (layout);
720#endif
721
722 /* increment these for the current map */
723 ++RP->dungeon_level;
724
725 // need to patch RP becasue following code doesn't use the Layout object
726 RP->Xsize = layout->w;
727 RP->Ysize = layout->h;
728
729 /* allocate the map and set the floor */
730 make_map_floor (layout, RP->floorstyle, RP);
731
732 /* set region */
733 default_region = RP->region;
734
735 CEDE;
736
737 place_specials_in_map (this, layout, RP);
738
739 CEDE;
740
741 /* create walls unless the wallstyle is "none" */
742 if (strcmp (RP->wallstyle, "none"))
743 {
744 make_map_walls (this, layout, RP->wallstyle, RP->miningstyle, RP);
745
746 /* place doors unless doorstyle or wallstyle is "none" */
747 if (strcmp (RP->doorstyle, "none"))
748 put_doors (this, layout, RP->doorstyle, RP);
811 } 749 }
812 750
813 if(orientation_n) { 751 CEDE;
814 sprintf(small_buf,"orientation %d\n",orientation_n);
815 strcat(buf,small_buf);
816 }
817 752
818 if(origin_x_n) { 753 /* create exits unless the exitstyle is "none" */
819 sprintf(small_buf,"origin_x %d\n",origin_x_n); 754 if (strcmp (RP->exitstyle, "none"))
820 strcat(buf,small_buf); 755 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
821 }
822 756
823 if(origin_y_n) { 757 CEDE;
824 sprintf(small_buf,"origin_y %d\n",origin_y_n);
825 strcat(buf,small_buf);
826 }
827 if(random_seed_n) {
828 /* Add one so that the next map is a bit different */
829 sprintf(small_buf,"random_seed %d\n",random_seed_n + 1);
830 strcat(buf,small_buf);
831 }
832 758
833 if(treasureoptions_n) { 759 /* create monsters unless the monsterstyle is "none" */
834 sprintf(small_buf,"treasureoptions %d\n",treasureoptions_n); 760 if (strcmp (RP->monsterstyle, "none"))
835 strcat(buf,small_buf); 761 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
836 }
837 762
763 CEDE;
838 764
839} 765 /* treasures needs to have a proper difficulty set for the map. */
766 difficulty = estimate_difficulty ();
840 767
841/* copy an object with an inventory... i.e., duplicate the inv too. */ 768 CEDE;
842void copy_object_with_inv(object *src_ob, object *dest_ob) {
843 object *walk,*tmp;
844 769
845 copy_object(src_ob,dest_ob); 770 /* create treasure unless the treasurestyle is "none" */
771 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
846 772
847 for(walk=src_ob->inv;walk!=NULL;walk=walk->below) { 773 CEDE;
848 tmp=get_object(); 774
849 copy_object(walk,tmp); 775 /* create decor unless the decorstyle is "none" */
850 insert_ob_in_ob(tmp,dest_ob); 776 if (strcmp (RP->decorstyle, "none"))
851 } 777 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
778
779 CEDE;
780
781 /* generate treasures, etc. */
782 fix_auto_apply ();
783
784 CEDE;
785
786 unblock_exits (this, layout, RP);
787
788 msg = strdup (buf);
789 in_memory = MAP_ACTIVE;
790
791 CEDE;
792
793 return 1;
852} 794}
795

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines