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.11 by root, Sat Dec 30 18:45:28 2006 UTC vs.
Revision 1.32 by root, Fri Apr 11 21:09:53 2008 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 *
20 21 * The authors can be reached via e-mail to <support@deliantra.net>
21 The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 22 */
23 23
24#include <time.h> 24#include <time.h>
25#include <stdio.h> 25#include <stdio.h>
26#include <global.h> 26#include <global.h>
27#include <maze_gen.h>
28#include <room_gen.h>
29#include <random_map.h> 27#include <random_map.h>
30#include <rproto.h> 28#include <rproto.h>
31#include <sproto.h> 29#include <sproto.h>
32 30
31#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__);
32
33void 33void
34dump_layout (char **layout, random_map_params * RP) 34dump_layout (char **layout, random_map_params *RP)
35{ 35{
36 { 36 {
37 int i, j; 37 int i, j;
38 38
39 for (i = 0; i < RP->Xsize; i++) 39 for (i = 0; i < RP->Xsize; i++)
50 } 50 }
51 } 51 }
52 printf ("\n"); 52 printf ("\n");
53} 53}
54 54
55extern FILE *logfile; 55bool
56 56maptile::generate_random_map (random_map_params *RP)
57maptile *
58generate_random_map (const char *OutFileName, random_map_params * RP)
59{ 57{
60 char **layout, buf[HUGE_BUF]; 58 char buf[16384];
61 maptile *theMap;
62 int i; 59 int i;
63 60
61 RP->Xsize = RP->xsize;
62 RP->Ysize = RP->ysize;
63
64 /* pick a random seed, or use the one from the input file */ 64 /* pick a random seed, or use the one from the input file */
65 if (RP->random_seed == 0) 65 RP->random_seed = RP->random_seed
66 RP->random_seed = time (0); 66 ? RP->random_seed + RP->dungeon_level
67 67 : time (0);
68 SRANDOM (RP->random_seed); 68 CEDE;
69 69
70 write_map_parameters_to_string (buf, RP); 70 write_map_parameters_to_string (buf, RP);
71 71
72 if (RP->difficulty == 0) 72 if (RP->difficulty == 0)
73 { 73 {
81 } 81 }
82 else 82 else
83 RP->difficulty_given = 1; 83 RP->difficulty_given = 1;
84 84
85 if (RP->Xsize < MIN_RANDOM_MAP_SIZE) 85 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
86 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 86 RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
87 87
88 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 88 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
89 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 89 RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
90
91 if (RP->symmetry == SYMMETRY_RANDOM)
92 RP->symmetry_used = rndm (SYMMETRY_XY) + 1;
93 else
94 RP->symmetry_used = RP->symmetry;
95
96 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
97 RP->Ysize = RP->Ysize / 2 + 1;
98
99 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
100 RP->Xsize = RP->Xsize / 2 + 1;
90 101
91 if (RP->expand2x > 0) 102 if (RP->expand2x > 0)
92 { 103 {
93 RP->Xsize /= 2; 104 RP->Xsize /= 2;
94 RP->Ysize /= 2; 105 RP->Ysize /= 2;
95 } 106 }
96 107
97 layout = layoutgen (RP);
98
99#ifdef RMAP_DEBUG
100 dump_layout (layout, RP);
101#endif
102
103 /* increment these for the current map */
104 RP->dungeon_level += 1;
105 /* allow constant-difficulty maps. */
106 /* difficulty+=1; */
107
108 /* rotate the layout randomly */
109 layout = rotate_layout (layout, RANDOM () % 4, RP);
110#ifdef RMAP_DEBUG
111 dump_layout (layout, RP);
112#endif
113
114 /* allocate the map and set the floor */
115 theMap = make_map_floor (layout, RP->floorstyle, RP);
116
117 /* set the name of the map. */
118 theMap->path = OutFileName;
119
120 /* set region */
121 theMap->region = RP->region;
122
123 /* create walls unless the wallstyle is "none" */
124 if (strcmp (RP->wallstyle, "none"))
125 {
126 make_map_walls (theMap, layout, RP->wallstyle, RP);
127
128 /* place doors unless doorstyle or wallstyle is "none" */
129 if (strcmp (RP->doorstyle, "none"))
130 put_doors (theMap, layout, RP->doorstyle, RP);
131
132 }
133
134 /* create exits unless the exitstyle is "none" */
135 if (strcmp (RP->exitstyle, "none"))
136 place_exits (theMap, layout, RP->exitstyle, RP->orientation, RP);
137
138 place_specials_in_map (theMap, layout, RP);
139
140 /* create monsters unless the monsterstyle is "none" */
141 if (strcmp (RP->monsterstyle, "none"))
142 place_monsters (theMap, RP->monsterstyle, RP->difficulty, RP);
143
144 /* treasures needs to have a proper difficulty set for the map. */
145 theMap->difficulty = theMap->estimate_difficulty ();
146
147 /* create treasure unless the treasurestyle is "none" */
148 if (strcmp (RP->treasurestyle, "none"))
149 place_treasure (theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
150
151 /* create decor unless the decorstyle is "none" */
152 if (strcmp (RP->decorstyle, "none"))
153 put_decor (theMap, layout, RP->decorstyle, RP->decoroptions, RP);
154
155 /* generate treasures, etc. */
156 theMap->fix_auto_apply ();
157
158 unblock_exits (theMap, layout, RP);
159
160 /* free the layout */
161 for (i = 0; i < RP->Xsize; i++)
162 free (layout[i]);
163 free (layout);
164
165 theMap->msg = strdup (buf);
166
167 return theMap;
168}
169
170/* function selects the layout function and gives it whatever
171 arguments it needs. */
172char **
173layoutgen (random_map_params * RP)
174{
175 char **maze = 0;
176 int oxsize = RP->Xsize, oysize = RP->Ysize;
177
178 if (RP->symmetry == SYMMETRY_RANDOM)
179 RP->symmetry_used = (RANDOM () % (SYMMETRY_XY)) + 1;
180 else
181 RP->symmetry_used = RP->symmetry;
182
183 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
184 RP->Ysize = RP->Ysize / 2 + 1;
185 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
186 RP->Xsize = RP->Xsize / 2 + 1;
187
188 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
189 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
190 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
191 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
192 RP->map_layout_style = 0; 108 RP->map_layout_style = LAYOUT_NONE;
193 109
194 /* Redo this - there was a lot of redundant code of checking for preset 110 /* Redo this - there was a lot of redundant code of checking for preset
195 * layout style and then random layout style. Instead, figure out 111 * layout style and then random layout style. Instead, figure out
196 * the numeric layoutstyle, so there is only one area that actually 112 * the numeric layoutstyle, so there is only one area that actually
197 * calls the code to make the maps. 113 * calls the code to make the maps.
212 RP->map_layout_style = LAYOUT_SNAKE; 128 RP->map_layout_style = LAYOUT_SNAKE;
213 129
214 if (strstr (RP->layoutstyle, "squarespiral")) 130 if (strstr (RP->layoutstyle, "squarespiral"))
215 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; 131 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
216 132
217 /* No style found - choose one ranomdly */ 133 /* No style found - choose one randomly */
218 if (RP->map_layout_style == LAYOUT_NONE) 134 if (RP->map_layout_style == LAYOUT_NONE)
219 RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1; 135 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1;
136
137 Maze layout = layoutgen (RP);
138
139#ifdef RMAP_DEBUG
140 dump_layout (layout, RP);
141#endif
142
143 /* increment these for the current map */
144 RP->dungeon_level += 1;
145 /* allow constant-difficulty maps. */
146 /* difficulty+=1; */
147
148 /* rotate the layout randomly */
149 layout = rotate_layout (layout, rndm (4), RP);
150#ifdef RMAP_DEBUG
151 dump_layout (layout, RP);
152#endif
153
154 /* allocate the map and set the floor */
155 make_map_floor (layout, RP->floorstyle, RP);
156
157 /* set region */
158 default_region = RP->region;
159
160 CEDE;
161
162 /* create walls unless the wallstyle is "none" */
163 if (strcmp (RP->wallstyle, "none"))
164 {
165 make_map_walls (this, layout, RP->wallstyle, RP);
166
167 /* place doors unless doorstyle or wallstyle is "none" */
168 if (strcmp (RP->doorstyle, "none"))
169 put_doors (this, layout, RP->doorstyle, RP);
170 }
171
172 CEDE;
173
174 /* create exits unless the exitstyle is "none" */
175 if (strcmp (RP->exitstyle, "none"))
176 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
177
178 CEDE;
179
180 place_specials_in_map (this, layout, RP);
181
182 CEDE;
183
184 /* create monsters unless the monsterstyle is "none" */
185 if (strcmp (RP->monsterstyle, "none"))
186 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
187
188 CEDE;
189
190 /* treasures needs to have a proper difficulty set for the map. */
191 difficulty = estimate_difficulty ();
192
193 CEDE;
194
195 /* create treasure unless the treasurestyle is "none" */
196 if (strcmp (RP->treasurestyle, "none"))
197 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
198
199 CEDE;
200
201 /* create decor unless the decorstyle is "none" */
202 if (strcmp (RP->decorstyle, "none"))
203 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
204
205 CEDE;
206
207 /* generate treasures, etc. */
208 fix_auto_apply ();
209
210 CEDE;
211
212 unblock_exits (this, layout, RP);
213
214 layout.free ();
215
216 msg = strdup (buf);
217 in_memory = MAP_IN_MEMORY;
218
219 CEDE;
220
221 return 1;
222}
223
224/* function selects the layout function and gives it whatever
225 arguments it needs. */
226Maze
227layoutgen (random_map_params *RP)
228{
229 Maze maze;
230
231 int oxsize = RP->Xsize, oysize = RP->Ysize;
220 232
221 switch (RP->map_layout_style) 233 switch (RP->map_layout_style)
222 { 234 {
223 case LAYOUT_ONION: 235 case LAYOUT_ONION:
224 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 236 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
237
225 if (!(RANDOM () % 3) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) 238 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
226 roomify_layout (maze, RP); 239 roomify_layout (maze, RP);
240
227 break; 241 break;
228 242
229 case LAYOUT_MAZE: 243 case LAYOUT_MAZE:
230 maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2); 244 maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2));
231 if (!(RANDOM () % 2)) 245
246 if (!(rndm (2)))
232 doorify_layout (maze, RP); 247 doorify_layout (maze, RP);
248
233 break; 249 break;
234 250
235 case LAYOUT_SPIRAL: 251 case LAYOUT_SPIRAL:
236 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 252 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1);
237 if (!(RANDOM () % 2)) 253
254 if (!(rndm (2)))
238 doorify_layout (maze, RP); 255 doorify_layout (maze, RP);
256
239 break; 257 break;
240 258
241 case LAYOUT_ROGUELIKE: 259 case LAYOUT_ROGUELIKE:
242 /* Don't put symmetry in rogue maps. There isn't much reason to 260 /* Don't put symmetry in rogue maps. There isn't much reason to
243 * do so in the first place (doesn't make it any more interesting), 261 * do so in the first place (doesn't make it any more interesting),
253 /* no doorifying... done already */ 271 /* no doorifying... done already */
254 break; 272 break;
255 273
256 case LAYOUT_SNAKE: 274 case LAYOUT_SNAKE:
257 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 275 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
258 if (RANDOM () % 2) 276
277 if (rndm (2))
259 roomify_layout (maze, RP); 278 roomify_layout (maze, RP);
279
260 break; 280 break;
261 281
262 case LAYOUT_SQUARE_SPIRAL: 282 case LAYOUT_SQUARE_SPIRAL:
263 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 283 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
264 if (RANDOM () % 2) 284
285 if (rndm (2))
265 roomify_layout (maze, RP); 286 roomify_layout (maze, RP);
287
266 break; 288 break;
289
290 default:
291 abort ();
267 } 292 }
268 293
269 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 294 maze = symmetrize_layout (maze, RP->symmetry_used, RP);
270 295
271#ifdef RMAP_DEBUG 296#ifdef RMAP_DEBUG
282 return maze; 307 return maze;
283} 308}
284 309
285/* takes a map and makes it symmetric: adjusts Xsize and 310/* takes a map and makes it symmetric: adjusts Xsize and
286Ysize to produce a symmetric map. */ 311Ysize to produce a symmetric map. */
287char ** 312Maze
288symmetrize_layout (char **maze, int sym, random_map_params * RP) 313symmetrize_layout (Maze maze, int sym, random_map_params *RP)
289{ 314{
290 int i, j; 315 int i, j;
291 char **sym_maze;
292 int Xsize_orig, Ysize_orig; 316 int Xsize_orig, Ysize_orig;
293 317
294 Xsize_orig = RP->Xsize; 318 Xsize_orig = RP->Xsize;
295 Ysize_orig = RP->Ysize; 319 Ysize_orig = RP->Ysize;
320
296 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */ 321 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */
322
297 if (sym == SYMMETRY_NONE) 323 if (sym == SYMMETRY_NONE)
298 { 324 {
299 RP->Xsize = Xsize_orig; 325 RP->Xsize = Xsize_orig;
300 RP->Ysize = Ysize_orig; 326 RP->Ysize = Ysize_orig;
327
301 return maze; 328 return maze;
302 } 329 }
330
303 /* pick new sizes */ 331 /* pick new sizes */
304 RP->Xsize = ((sym == SYMMETRY_X || sym == SYMMETRY_XY) ? RP->Xsize * 2 - 3 : RP->Xsize); 332 RP->Xsize = ((sym == SYMMETRY_X || sym == SYMMETRY_XY) ? RP->Xsize * 2 - 3 : RP->Xsize);
305 RP->Ysize = ((sym == SYMMETRY_Y || sym == SYMMETRY_XY) ? RP->Ysize * 2 - 3 : RP->Ysize); 333 RP->Ysize = ((sym == SYMMETRY_Y || sym == SYMMETRY_XY) ? RP->Ysize * 2 - 3 : RP->Ysize);
306 334
307 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize); 335 Maze sym_maze (RP);
308 for (i = 0; i < RP->Xsize; i++)
309 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize);
310 336
311 if (sym == SYMMETRY_X) 337 if (sym == SYMMETRY_X)
312 for (i = 0; i < RP->Xsize / 2 + 1; i++) 338 for (i = 0; i < RP->Xsize / 2 + 1; i++)
313 for (j = 0; j < RP->Ysize; j++) 339 for (j = 0; j < RP->Ysize; j++)
314 { 340 {
315 sym_maze[i][j] = maze[i][j]; 341 sym_maze[i][j] = maze[i][j];
316 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 342 sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
317 }; 343 }
344
318 if (sym == SYMMETRY_Y) 345 if (sym == SYMMETRY_Y)
319 for (i = 0; i < RP->Xsize; i++) 346 for (i = 0; i < RP->Xsize; i++)
320 for (j = 0; j < RP->Ysize / 2 + 1; j++) 347 for (j = 0; j < RP->Ysize / 2 + 1; j++)
321 { 348 {
322 sym_maze[i][j] = maze[i][j]; 349 sym_maze[i][j] = maze[i][j];
323 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 350 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
324 } 351 }
352
325 if (sym == SYMMETRY_XY) 353 if (sym == SYMMETRY_XY)
326 for (i = 0; i < RP->Xsize / 2 + 1; i++) 354 for (i = 0; i < RP->Xsize / 2 + 1; i++)
327 for (j = 0; j < RP->Ysize / 2 + 1; j++) 355 for (j = 0; j < RP->Ysize / 2 + 1; j++)
328 { 356 {
329 sym_maze[i][j] = maze[i][j]; 357 sym_maze[i][j] = maze[i][j];
330 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 358 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
331 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 359 sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
332 sym_maze[RP->Xsize - i - 1][RP->Ysize - j - 1] = maze[i][j]; 360 sym_maze[RP->Xsize - i - 1][RP->Ysize - j - 1] = maze[i][j];
333 } 361 }
334 /* delete the old maze */ 362
335 for (i = 0; i < Xsize_orig; i++) 363 maze.free ();
336 free (maze[i]); 364
337 free (maze);
338 /* reconnect disjointed spirals */ 365 /* reconnect disjointed spirals */
339 if (RP->map_layout_style == LAYOUT_SPIRAL) 366 if (RP->map_layout_style == LAYOUT_SPIRAL)
340 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 367 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
368
341 /* reconnect disjointed nethackmazes: the routine for 369 /* reconnect disjointed nethackmazes: the routine for
342 spirals will do the trick? */ 370 spirals will do the trick? */
343 if (RP->map_layout_style == LAYOUT_ROGUELIKE) 371 if (RP->map_layout_style == LAYOUT_ROGUELIKE)
344 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 372 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
345 373
346 return sym_maze; 374 return sym_maze;
347} 375}
348 376
349
350/* takes a map and rotates it. This completes the 377/* takes a map and rotates it. This completes the
351 onion layouts, making them possibly centered on any wall. 378 onion layouts, making them possibly centered on any wall.
352 It'll modify Xsize and Ysize if they're swapped. 379 It'll modify Xsize and Ysize if they're swapped.
353*/ 380*/
354 381Maze
355char **
356rotate_layout (char **maze, int rotation, random_map_params * RP) 382rotate_layout (Maze maze, int rotation, random_map_params *RP)
357{ 383{
358 char **new_maze;
359 int i, j;
360
361 switch (rotation) 384 switch (rotation)
362 { 385 {
363 case 0:
364 return maze;
365 break;
366 case 2: /* a reflection */ 386 case 2: /* a reflection */
367 { 387 {
368 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize); 388 Maze new_maze (RP);
369 389
370 for (i = 0; i < RP->Xsize; i++) 390 for (int i = 0; i < RP->Xsize; i++) /* copy a reflection back */
371 { /* make a copy */
372 for (j = 0; j < RP->Ysize; j++) 391 for (int j = 0; j < RP->Ysize; j++)
373 { 392 new_maze[i][j] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1];
374 newmaze[i * RP->Ysize + j] = maze[i][j]; 393
375 } 394 maze.free ();
395 maze = new_maze;
376 } 396 }
377 for (i = 0; i < RP->Xsize; i++) 397
378 { /* copy a reflection back */
379 for (j = 0; j < RP->Ysize; j++)
380 {
381 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
382 }
383 }
384 free (newmaze);
385 return maze;
386 break;
387 }
388 case 1: 398 case 1:
389 case 3: 399 case 3:
390 { 400 {
391 int swap; 401 Maze new_maze (RP->Ysize, RP->Xsize);
392 new_maze = (char **) calloc (sizeof (char *), RP->Ysize); 402
393 for (i = 0; i < RP->Ysize; i++)
394 {
395 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
396 }
397 if (rotation == 1) /* swap x and y */ 403 if (rotation == 1) /* swap x and y */
398 for (i = 0; i < RP->Xsize; i++) 404 for (int i = 0; i < RP->Xsize; i++)
399 for (j = 0; j < RP->Ysize; j++) 405 for (int j = 0; j < RP->Ysize; j++)
400 new_maze[j][i] = maze[i][j]; 406 new_maze[j][i] = maze[i][j];
401 407
402 if (rotation == 3) 408 if (rotation == 3) /* swap x and y */
403 { /* swap x and y */
404 for (i = 0; i < RP->Xsize; i++) 409 for (int i = 0; i < RP->Xsize; i++)
405 for (j = 0; j < RP->Ysize; j++) 410 for (int j = 0; j < RP->Ysize; j++)
406 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1]; 411 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1];
412
413 maze.free ();
414 maze = new_maze;
415 swap (RP->Xsize, RP->Ysize);
407 } 416 }
408
409 /* delete the old layout */
410 for (i = 0; i < RP->Xsize; i++)
411 free (maze[i]);
412 free (maze);
413
414 swap = RP->Ysize;
415 RP->Ysize = RP->Xsize;
416 RP->Xsize = swap;
417 return new_maze;
418 break;
419 }
420 } 417 }
421 return NULL; 418
419 return maze;
422} 420}
423 421
424/* take a layout and make some rooms in it. 422/* take a layout and make some rooms in it.
425 --works best on onions.*/ 423 --works best on onions.*/
426void 424void
427roomify_layout (char **maze, random_map_params * RP) 425roomify_layout (char **maze, random_map_params *RP)
428{ 426{
429 int tries = RP->Xsize * RP->Ysize / 30; 427 int tries = RP->Xsize * RP->Ysize / 30;
430 int ti; 428 int ti;
431 429
432 for (ti = 0; ti < tries; ti++) 430 for (ti = 0; ti < tries; ti++)
433 { 431 {
434 int dx, dy; /* starting location for looking at creating a door */ 432 int dx, dy; /* starting location for looking at creating a door */
435 int cx, cy; /* results of checking on creating walls. */ 433 int cx, cy; /* results of checking on creating walls. */
436 434
437 dx = RANDOM () % RP->Xsize; 435 dx = rndm (RP->Xsize);
438 dy = RANDOM () % RP->Ysize; 436 dy = rndm (RP->Ysize);
437
439 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ 438 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
440 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ 439 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
441 if (cx == -1) 440 if (cx == -1)
442 { 441 {
443 if (cy != -1) 442 if (cy != -1)
444 make_wall (maze, dx, dy, 1); 443 make_wall (maze, dx, dy, 1);
444
445 continue; 445 continue;
446 } 446 }
447
447 if (cy == -1) 448 if (cy == -1)
448 { 449 {
449 make_wall (maze, dx, dy, 0); 450 make_wall (maze, dx, dy, 0);
450 continue; 451 continue;
451 } 452 }
453
452 if (cx < cy) 454 if (cx < cy)
453 make_wall (maze, dx, dy, 0); 455 make_wall (maze, dx, dy, 0);
454 else 456 else
455 make_wall (maze, dx, dy, 1); 457 make_wall (maze, dx, dy, 1);
456 } 458 }
459/* checks the layout to see if I can stick a horizontal(dir = 0) wall 461/* checks the layout to see if I can stick a horizontal(dir = 0) wall
460 (or vertical, dir == 1) 462 (or vertical, dir == 1)
461 here which ends up on other walls sensibly. */ 463 here which ends up on other walls sensibly. */
462 464
463int 465int
464can_make_wall (char **maze, int dx, int dy, int dir, random_map_params * RP) 466can_make_wall (char **maze, int dx, int dy, int dir, random_map_params *RP)
465{ 467{
466 int i1; 468 int i1;
467 int length = 0; 469 int length = 0;
468 470
469 /* dont make walls if we're on the edge. */ 471 /* dont make walls if we're on the edge. */
544make_wall (char **maze, int x, int y, int dir) 546make_wall (char **maze, int x, int y, int dir)
545{ 547{
546 maze[x][y] = 'D'; /* mark a door */ 548 maze[x][y] = 'D'; /* mark a door */
547 switch (dir) 549 switch (dir)
548 { 550 {
549 case 0: /* horizontal */ 551 case 0: /* horizontal */
550 { 552 {
551 int i1; 553 int i1;
552 554
553 for (i1 = x - 1; maze[i1][y] == 0; i1--) 555 for (i1 = x - 1; maze[i1][y] == 0; i1--)
554 maze[i1][y] = '#'; 556 maze[i1][y] = '#';
555 for (i1 = x + 1; maze[i1][y] == 0; i1++) 557 for (i1 = x + 1; maze[i1][y] == 0; i1++)
556 maze[i1][y] = '#'; 558 maze[i1][y] = '#';
557 break; 559 break;
558 } 560 }
559 case 1: /* vertical */ 561 case 1: /* vertical */
560 { 562 {
561 int i1; 563 int i1;
562 564
563 for (i1 = y - 1; maze[x][i1] == 0; i1--) 565 for (i1 = y - 1; maze[x][i1] == 0; i1--)
564 maze[x][i1] = '#'; 566 maze[x][i1] = '#';
565 for (i1 = y + 1; maze[x][i1] == 0; i1++) 567 for (i1 = y + 1; maze[x][i1] == 0; i1++)
566 maze[x][i1] = '#'; 568 maze[x][i1] = '#';
567 break; 569 break;
568 } 570 }
569 } 571 }
570 572
571 return 0; 573 return 0;
572} 574}
573 575
574/* puts doors at appropriate locations in a layout. */ 576/* puts doors at appropriate locations in a layout. */
575
576void 577void
577doorify_layout (char **maze, random_map_params * RP) 578doorify_layout (char **maze, random_map_params *RP)
578{ 579{
579 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */ 580 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
580 char *doorlist_x;
581 char *doorlist_y;
582 int doorlocs = 0; /* # of available doorlocations */ 581 int doorlocs = 0; /* # of available doorlocations */
583 int i, j; 582 int i, j;
584 583
585 doorlist_x = (char *) malloc (sizeof (int) * RP->Xsize * RP->Ysize); 584 char *doorlist_x = salloc<char> (RP->Xsize * RP->Ysize);
586 doorlist_y = (char *) malloc (sizeof (int) * RP->Xsize * RP->Ysize); 585 char *doorlist_y = salloc<char> (RP->Xsize * RP->Ysize);
587
588 586
589 /* make a list of possible door locations */ 587 /* make a list of possible door locations */
590 for (i = 1; i < RP->Xsize - 1; i++) 588 for (i = 1; i < RP->Xsize - 1; i++)
591 for (j = 1; j < RP->Ysize - 1; j++) 589 for (j = 1; j < RP->Ysize - 1; j++)
592 { 590 {
597 doorlist_x[doorlocs] = i; 595 doorlist_x[doorlocs] = i;
598 doorlist_y[doorlocs] = j; 596 doorlist_y[doorlocs] = j;
599 doorlocs++; 597 doorlocs++;
600 } 598 }
601 } 599 }
600
602 while (ndoors > 0 && doorlocs > 0) 601 while (ndoors > 0 && doorlocs > 0)
603 { 602 {
604 int di; 603 int di;
605 int sindex; 604 int sindex;
606 605
607 di = RANDOM () % doorlocs; 606 di = rndm (doorlocs);
608 i = doorlist_x[di]; 607 i = doorlist_x[di];
609 j = doorlist_y[di]; 608 j = doorlist_y[di];
610 sindex = surround_flag (maze, i, j, RP); 609 sindex = surround_flag (maze, i, j, RP);
610
611 if (sindex == 3 || sindex == 12) /* these are possible door sindex */ 611 if (sindex == 3 || sindex == 12) /* these are possible door sindex */
612 { 612 {
613 maze[i][j] = 'D'; 613 maze[i][j] = 'D';
614 ndoors--; 614 ndoors--;
615 } 615 }
616
616 /* reduce the size of the list */ 617 /* reduce the size of the list */
617 doorlocs--; 618 doorlocs--;
618 doorlist_x[di] = doorlist_x[doorlocs]; 619 doorlist_x[di] = doorlist_x[doorlocs];
619 doorlist_y[di] = doorlist_y[doorlocs]; 620 doorlist_y[di] = doorlist_y[doorlocs];
620 } 621 }
621 free (doorlist_x);
622 free (doorlist_y);
623}
624 622
623 sfree (doorlist_x, RP->Xsize * RP->Ysize);
624 sfree (doorlist_y, RP->Xsize * RP->Ysize);
625}
625 626
626void 627void
627write_map_parameters_to_string (char *buf, random_map_params * RP) 628write_map_parameters_to_string (char *buf, random_map_params *RP)
628{ 629{
629 char small_buf[256]; 630 char small_buf[16384];
630 631
631 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); 632 sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize);
632 633
633 if (RP->wallstyle[0]) 634 if (RP->wallstyle[0])
634 { 635 {
635 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle); 636 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle);
636 strcat (buf, small_buf); 637 strcat (buf, small_buf);
676 { 677 {
677 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle); 678 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle);
678 strcat (buf, small_buf); 679 strcat (buf, small_buf);
679 } 680 }
680 681
681 if (RP->final_map[0]) 682 if (RP->final_map.length ())
682 { 683 {
683 sprintf (small_buf, "final_map %s\n", RP->final_map); 684 sprintf (small_buf, "final_map %s\n", &RP->final_map);
684 strcat (buf, small_buf); 685 strcat (buf, small_buf);
685 } 686 }
686 687
687 if (RP->exit_on_final_map[0]) 688 if (RP->exit_on_final_map[0])
688 { 689 {
689 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map); 690 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
690 strcat (buf, small_buf); 691 strcat (buf, small_buf);
691 } 692 }
692 693
693 if (RP->this_map[0]) 694 if (RP->this_map.length ())
694 { 695 {
695 sprintf (small_buf, "origin_map %s\n", RP->this_map); 696 sprintf (small_buf, "origin_map %s\n", &RP->this_map);
696 strcat (buf, small_buf); 697 strcat (buf, small_buf);
697 } 698 }
698 699
699 if (RP->expand2x) 700 if (RP->expand2x)
700 { 701 {
706 { 707 {
707 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1); 708 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1);
708 strcat (buf, small_buf); 709 strcat (buf, small_buf);
709 } 710 }
710 711
711
712 if (RP->layoutoptions2) 712 if (RP->layoutoptions2)
713 { 713 {
714 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2); 714 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2);
715 strcat (buf, small_buf); 715 strcat (buf, small_buf);
716 } 716 }
717 717
718
719 if (RP->layoutoptions3) 718 if (RP->layoutoptions3)
720 { 719 {
721 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3); 720 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3);
722 strcat (buf, small_buf); 721 strcat (buf, small_buf);
723 } 722 }
725 if (RP->symmetry) 724 if (RP->symmetry)
726 { 725 {
727 sprintf (small_buf, "symmetry %d\n", RP->symmetry); 726 sprintf (small_buf, "symmetry %d\n", RP->symmetry);
728 strcat (buf, small_buf); 727 strcat (buf, small_buf);
729 } 728 }
730
731 729
732 if (RP->difficulty && RP->difficulty_given) 730 if (RP->difficulty && RP->difficulty_given)
733 { 731 {
734 sprintf (small_buf, "difficulty %d\n", RP->difficulty); 732 sprintf (small_buf, "difficulty %d\n", RP->difficulty);
735 strcat (buf, small_buf); 733 strcat (buf, small_buf);
772 { 770 {
773 sprintf (small_buf, "origin_y %d\n", RP->origin_y); 771 sprintf (small_buf, "origin_y %d\n", RP->origin_y);
774 strcat (buf, small_buf); 772 strcat (buf, small_buf);
775 } 773 }
776 774
775 if (RP->treasureoptions)
776 {
777 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
778 strcat (buf, small_buf);
779 }
780
777 if (RP->random_seed) 781 if (RP->random_seed)
778 { 782 {
779 /* Add one so that the next map is a bit different */
780 sprintf (small_buf, "random_seed %d\n", RP->random_seed + 1); 783 sprintf (small_buf, "random_seed %u\n", RP->random_seed);
781 strcat (buf, small_buf); 784 strcat (buf, small_buf);
782 }
783
784 if (RP->treasureoptions)
785 { 785 }
786 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions); 786
787 if (RP->custom)
788 {
789 sprintf (small_buf, "custom %s\n", RP->custom);
787 strcat (buf, small_buf); 790 strcat (buf, small_buf);
788 } 791 }
789} 792}
790 793
791void 794void
792write_parameters_to_string (char *buf, 795write_parameters_to_string (char *buf,
793 int xsize_n, 796 int xsize_n,
794 int ysize_n, 797 int ysize_n,
795 char *wallstyle_n, 798 const char *wallstyle_n,
796 char *floorstyle_n, 799 const char *floorstyle_n,
797 char *monsterstyle_n, 800 const char *monsterstyle_n,
798 char *treasurestyle_n, 801 const char *treasurestyle_n,
799 char *layoutstyle_n, 802 const char *layoutstyle_n,
800 char *decorstyle_n, 803 const char *decorstyle_n,
801 char *doorstyle_n, 804 const char *doorstyle_n,
802 char *exitstyle_n, 805 const char *exitstyle_n,
803 char *final_map_n, 806 const char *final_map_n,
804 char *exit_on_final_map_n, 807 const char *exit_on_final_map_n,
805 char *this_map_n, 808 const char *this_map_n,
806 int layoutoptions1_n, 809 int layoutoptions1_n,
807 int layoutoptions2_n, 810 int layoutoptions2_n,
808 int layoutoptions3_n, 811 int layoutoptions3_n,
809 int symmetry_n, 812 int symmetry_n,
810 int dungeon_depth_n, 813 int dungeon_depth_n,
811 int dungeon_level_n, 814 int dungeon_level_n,
812 int difficulty_n, 815 int difficulty_n,
813 int difficulty_given_n, 816 int difficulty_given_n,
814 int decoroptions_n, 817 int decoroptions_n,
815 int orientation_n, 818 int orientation_n,
816 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) 819 int origin_x_n,
820 int origin_y_n,
821 uint32_t random_seed_n,
822 int treasureoptions_n,
823 float difficulty_increase)
817{ 824{
818
819 char small_buf[256]; 825 char small_buf[16384];
820 826
821 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); 827 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
822 828
823 if (wallstyle_n && wallstyle_n[0]) 829 if (wallstyle_n && wallstyle_n[0])
824 { 830 {
889 if (layoutoptions1_n) 895 if (layoutoptions1_n)
890 { 896 {
891 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n); 897 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n);
892 strcat (buf, small_buf); 898 strcat (buf, small_buf);
893 } 899 }
894
895 900
896 if (layoutoptions2_n) 901 if (layoutoptions2_n)
897 { 902 {
898 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n); 903 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n);
899 strcat (buf, small_buf); 904 strcat (buf, small_buf);
959 } 964 }
960 965
961 if (random_seed_n) 966 if (random_seed_n)
962 { 967 {
963 /* Add one so that the next map is a bit different */ 968 /* Add one so that the next map is a bit different */
964 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1); 969 sprintf (small_buf, "random_seed %u\n", random_seed_n + 1);
965 strcat (buf, small_buf); 970 strcat (buf, small_buf);
966 } 971 }
967 972
968 if (treasureoptions_n) 973 if (treasureoptions_n)
969 { 974 {
970 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n); 975 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n);
971 strcat (buf, small_buf); 976 strcat (buf, small_buf);
972 } 977 }
973
974
975} 978}
976 979
977/* copy an object with an inventory... i.e., duplicate the inv too. */ 980/* copy an object with an inventory... i.e., duplicate the inv too. */
978void 981void
979copy_object_with_inv (object *src_ob, object *dest_ob) 982copy_object_with_inv (object *src_ob, object *dest_ob)
980{ 983{
981 object *walk, *tmp; 984 object *walk, *tmp;
982 985
983 src_ob->copy_to (dest_ob); 986 src_ob->copy_to (dest_ob);
984 987
985 for (walk = src_ob->inv; walk != NULL; walk = walk->below) 988 for (walk = src_ob->inv; walk; walk = walk->below)
986 { 989 {
987 tmp = object::create (); 990 tmp = object::create ();
991
988 walk->copy_to (tmp); 992 walk->copy_to (tmp);
989 insert_ob_in_ob (tmp, dest_ob); 993 insert_ob_in_ob (tmp, dest_ob);
990 } 994 }
991} 995}
996
997MazeData::MazeData (int xsize, int ysize)
998{
999 int size = xsize * ysize
1000 + sizeof (char *) * xsize
1001 + sizeof (char *);
1002
1003 col = (char **)salloc0<char> (size);
1004 *col++ = (char *)size;
1005
1006 char *data = (char *)(col + xsize);
1007
1008 for (int x = xsize; x--; )
1009 col [x] = data + x * ysize;
1010}
1011
1012MazeData::~MazeData ()
1013{
1014 int size = (long)*--col;
1015 sfree ((char *)col, size);
1016}
1017

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines