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.10 by root, Sat Dec 30 10:16:11 2006 UTC vs.
Revision 1.22 by root, Fri Jan 19 15:29:52 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game for X-windows
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program 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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 23 */
23 24
24#include <time.h> 25#include <time.h>
25#include <stdio.h> 26#include <stdio.h>
26#include <global.h> 27#include <global.h>
27#include <maze_gen.h> 28#include <maze_gen.h>
28#include <room_gen.h> 29#include <room_gen.h>
29#include <random_map.h> 30#include <random_map.h>
30#include <rproto.h> 31#include <rproto.h>
31#include <sproto.h> 32#include <sproto.h>
32 33
34#define CEDE coroapi::cede (); rndm.seed (RP->random_seed + __LINE__);
35
33void 36void
34dump_layout (char **layout, RMParms * RP) 37dump_layout (char **layout, random_map_params *RP)
35{ 38{
36 { 39 {
37 int i, j; 40 int i, j;
38 41
39 for (i = 0; i < RP->Xsize; i++) 42 for (i = 0; i < RP->Xsize; i++)
50 } 53 }
51 } 54 }
52 printf ("\n"); 55 printf ("\n");
53} 56}
54 57
55extern FILE *logfile; 58bool
56 59maptile::generate_random_map (random_map_params *RP)
57maptile *
58generate_random_map (const char *OutFileName, RMParms * RP)
59{ 60{
60 char **layout, buf[HUGE_BUF]; 61 char **layout, buf[16384];
61 maptile *theMap;
62 int i; 62 int i;
63 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 = (RANDOM () % (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 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
99 RP->Xsize = RP->Xsize / 2 + 1;
90 100
91 if (RP->expand2x > 0) 101 if (RP->expand2x > 0)
92 { 102 {
93 RP->Xsize /= 2; 103 RP->Xsize /= 2;
94 RP->Ysize /= 2; 104 RP->Ysize /= 2;
95 } 105 }
96 106
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 fix_auto_apply (theMap);
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 (RMParms * RP)
174{
175 char **maze = 0;
176 int oxsize = RP->Xsize, oysize = RP->Ysize;
177
178 if (RP->symmetry == RANDOM_SYM)
179 RP->symmetry_used = (RANDOM () % (XY_SYM)) + 1;
180 else
181 RP->symmetry_used = RP->symmetry;
182
183 if (RP->symmetry_used == Y_SYM || RP->symmetry_used == XY_SYM)
184 RP->Ysize = RP->Ysize / 2 + 1;
185 if (RP->symmetry_used == X_SYM || RP->symmetry_used == XY_SYM)
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; 107 RP->map_layout_style = LAYOUT_NONE;
193 108
194 /* Redo this - there was a lot of redundant code of checking for preset 109 /* Redo this - there was a lot of redundant code of checking for preset
195 * layout style and then random layout style. Instead, figure out 110 * layout style and then random layout style. Instead, figure out
196 * the numeric layoutstyle, so there is only one area that actually 111 * the numeric layoutstyle, so there is only one area that actually
197 * calls the code to make the maps. 112 * calls the code to make the maps.
198 */ 113 */
199 if (strstr (RP->layoutstyle, "onion")) 114 if (strstr (RP->layoutstyle, "onion"))
200 {
201 RP->map_layout_style = ONION_LAYOUT; 115 RP->map_layout_style = LAYOUT_ONION;
202 }
203 116
204 if (strstr (RP->layoutstyle, "maze")) 117 if (strstr (RP->layoutstyle, "maze"))
205 {
206 RP->map_layout_style = MAZE_LAYOUT; 118 RP->map_layout_style = LAYOUT_MAZE;
207 }
208 119
209 if (strstr (RP->layoutstyle, "spiral")) 120 if (strstr (RP->layoutstyle, "spiral"))
210 {
211 RP->map_layout_style = SPIRAL_LAYOUT; 121 RP->map_layout_style = LAYOUT_SPIRAL;
212 }
213 122
214 if (strstr (RP->layoutstyle, "rogue")) 123 if (strstr (RP->layoutstyle, "rogue"))
215 {
216 RP->map_layout_style = ROGUELIKE_LAYOUT; 124 RP->map_layout_style = LAYOUT_ROGUELIKE;
217 }
218 125
219 if (strstr (RP->layoutstyle, "snake")) 126 if (strstr (RP->layoutstyle, "snake"))
220 {
221 RP->map_layout_style = SNAKE_LAYOUT; 127 RP->map_layout_style = LAYOUT_SNAKE;
222 }
223 128
224 if (strstr (RP->layoutstyle, "squarespiral")) 129 if (strstr (RP->layoutstyle, "squarespiral"))
225 {
226 RP->map_layout_style = SQUARE_SPIRAL_LAYOUT; 130 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
227 } 131
228 /* No style found - choose one ranomdly */ 132 /* No style found - choose one randomly */
229 if (RP->map_layout_style == 0) 133 if (RP->map_layout_style == LAYOUT_NONE)
230 {
231 RP->map_layout_style = (RANDOM () % NROFLAYOUTS) + 1; 134 RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1;
135
136 layout = layoutgen (RP);
137
138#ifdef RMAP_DEBUG
139 dump_layout (layout, RP);
140#endif
141
142 /* increment these for the current map */
143 RP->dungeon_level += 1;
144 /* allow constant-difficulty maps. */
145 /* difficulty+=1; */
146
147 /* rotate the layout randomly */
148 layout = rotate_layout (layout, rndm (4), RP);
149#ifdef RMAP_DEBUG
150 dump_layout (layout, RP);
151#endif
152
153 /* allocate the map and set the floor */
154 make_map_floor (layout, RP->floorstyle, RP);
155
156 /* set region */
157 region = RP->region;
158
159 CEDE;
160
161 /* create walls unless the wallstyle is "none" */
162 if (strcmp (RP->wallstyle, "none"))
232 } 163 {
164 make_map_walls (this, layout, RP->wallstyle, RP);
165
166 /* place doors unless doorstyle or wallstyle is "none" */
167 if (strcmp (RP->doorstyle, "none"))
168 put_doors (this, layout, RP->doorstyle, RP);
169
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 /* free the layout */
215 for (i = 0; i < RP->Xsize; i++)
216 free (layout[i]);
217
218 free (layout);
219
220 msg = strdup (buf);
221 in_memory = MAP_IN_MEMORY;
222
223 CEDE;
224
225 return 1;
226}
227
228/* function selects the layout function and gives it whatever
229 arguments it needs. */
230char **
231layoutgen (random_map_params *RP)
232{
233 char **maze = 0;
234 int oxsize = RP->Xsize, oysize = RP->Ysize;
233 235
234 switch (RP->map_layout_style) 236 switch (RP->map_layout_style)
235 { 237 {
236 238 case LAYOUT_ONION:
237 case ONION_LAYOUT:
238 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 239 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
239 if (!(RANDOM () % 3) && !(RP->layoutoptions1 & OPT_WALLS_ONLY)) 240 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
240 roomify_layout (maze, RP); 241 roomify_layout (maze, RP);
241 break; 242 break;
242 243
243 case MAZE_LAYOUT: 244 case LAYOUT_MAZE:
244 maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2); 245 maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2));
245 if (!(RANDOM () % 2)) 246 if (!(rndm (2)))
246 doorify_layout (maze, RP); 247 doorify_layout (maze, RP);
247 break; 248 break;
248 249
249 case SPIRAL_LAYOUT: 250 case LAYOUT_SPIRAL:
250 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 251 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1);
251 if (!(RANDOM () % 2)) 252 if (!(rndm (2)))
252 doorify_layout (maze, RP); 253 doorify_layout (maze, RP);
253 break; 254 break;
254 255
255 case ROGUELIKE_LAYOUT: 256 case LAYOUT_ROGUELIKE:
256 /* Don't put symmetry in rogue maps. There isn't much reason to 257 /* Don't put symmetry in rogue maps. There isn't much reason to
257 * do so in the first place (doesn't make it any more interesting), 258 * do so in the first place (doesn't make it any more interesting),
258 * but more importantly, the symmetry code presumes we are symmetrizing 259 * but more importantly, the symmetry code presumes we are symmetrizing
259 * spirals, or maps with lots of passages - making a symmetric rogue 260 * spirals, or maps with lots of passages - making a symmetric rogue
260 * map fails because its likely that the passages the symmetry process 261 * map fails because its likely that the passages the symmetry process
261 * creates may not connect the rooms. 262 * creates may not connect the rooms.
262 */ 263 */
263 RP->symmetry_used = NO_SYM; 264 RP->symmetry_used = SYMMETRY_NONE;
264 RP->Ysize = oysize; 265 RP->Ysize = oysize;
265 RP->Xsize = oxsize; 266 RP->Xsize = oxsize;
266 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1); 267 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1);
267 /* no doorifying... done already */ 268 /* no doorifying... done already */
268 break; 269 break;
269 270
270 case SNAKE_LAYOUT: 271 case LAYOUT_SNAKE:
271 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 272 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
272 if (RANDOM () % 2) 273 if (rndm (2))
273 roomify_layout (maze, RP); 274 roomify_layout (maze, RP);
274 break; 275 break;
275 276
276 case SQUARE_SPIRAL_LAYOUT: 277 case LAYOUT_SQUARE_SPIRAL:
277 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 278 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
278 if (RANDOM () % 2) 279 if (rndm (2))
279 roomify_layout (maze, RP); 280 roomify_layout (maze, RP);
280 break; 281 break;
281 } 282 }
282 283
283 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 284 maze = symmetrize_layout (maze, RP->symmetry_used, RP);
285
284#ifdef RMAP_DEBUG 286#ifdef RMAP_DEBUG
285 dump_layout (maze, RP); 287 dump_layout (maze, RP);
286#endif 288#endif
289
287 if (RP->expand2x) 290 if (RP->expand2x)
288 { 291 {
289 maze = expand2x (maze, RP->Xsize, RP->Ysize); 292 maze = expand2x (maze, RP->Xsize, RP->Ysize);
290 RP->Xsize = RP->Xsize * 2 - 1; 293 RP->Xsize = RP->Xsize * 2 - 1;
291 RP->Ysize = RP->Ysize * 2 - 1; 294 RP->Ysize = RP->Ysize * 2 - 1;
292 } 295 }
296
293 return maze; 297 return maze;
294} 298}
295
296 299
297/* takes a map and makes it symmetric: adjusts Xsize and 300/* takes a map and makes it symmetric: adjusts Xsize and
298Ysize to produce a symmetric map. */ 301Ysize to produce a symmetric map. */
299
300char ** 302char **
301symmetrize_layout (char **maze, int sym, RMParms * RP) 303symmetrize_layout (char **maze, int sym, random_map_params *RP)
302{ 304{
303 int i, j; 305 int i, j;
304 char **sym_maze; 306 char **sym_maze;
305 int Xsize_orig, Ysize_orig; 307 int Xsize_orig, Ysize_orig;
306 308
307 Xsize_orig = RP->Xsize; 309 Xsize_orig = RP->Xsize;
308 Ysize_orig = RP->Ysize; 310 Ysize_orig = RP->Ysize;
309 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */ 311 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */
310 if (sym == NO_SYM) 312 if (sym == SYMMETRY_NONE)
311 { 313 {
312 RP->Xsize = Xsize_orig; 314 RP->Xsize = Xsize_orig;
313 RP->Ysize = Ysize_orig; 315 RP->Ysize = Ysize_orig;
314 return maze; 316 return maze;
315 } 317 }
316 /* pick new sizes */ 318 /* pick new sizes */
317 RP->Xsize = ((sym == X_SYM || sym == XY_SYM) ? RP->Xsize * 2 - 3 : RP->Xsize); 319 RP->Xsize = ((sym == SYMMETRY_X || sym == SYMMETRY_XY) ? RP->Xsize * 2 - 3 : RP->Xsize);
318 RP->Ysize = ((sym == Y_SYM || sym == XY_SYM) ? RP->Ysize * 2 - 3 : RP->Ysize); 320 RP->Ysize = ((sym == SYMMETRY_Y || sym == SYMMETRY_XY) ? RP->Ysize * 2 - 3 : RP->Ysize);
319 321
320 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize); 322 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize);
321 for (i = 0; i < RP->Xsize; i++) 323 for (i = 0; i < RP->Xsize; i++)
322 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize); 324 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize);
323 325
324 if (sym == X_SYM) 326 if (sym == SYMMETRY_X)
325 for (i = 0; i < RP->Xsize / 2 + 1; i++) 327 for (i = 0; i < RP->Xsize / 2 + 1; i++)
326 for (j = 0; j < RP->Ysize; j++) 328 for (j = 0; j < RP->Ysize; j++)
327 { 329 {
328 sym_maze[i][j] = maze[i][j]; 330 sym_maze[i][j] = maze[i][j];
329 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 331 sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
330 }; 332 };
331 if (sym == Y_SYM) 333 if (sym == SYMMETRY_Y)
332 for (i = 0; i < RP->Xsize; i++) 334 for (i = 0; i < RP->Xsize; i++)
333 for (j = 0; j < RP->Ysize / 2 + 1; j++) 335 for (j = 0; j < RP->Ysize / 2 + 1; j++)
334 { 336 {
335 sym_maze[i][j] = maze[i][j]; 337 sym_maze[i][j] = maze[i][j];
336 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 338 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
337 } 339 }
338 if (sym == XY_SYM) 340 if (sym == SYMMETRY_XY)
339 for (i = 0; i < RP->Xsize / 2 + 1; i++) 341 for (i = 0; i < RP->Xsize / 2 + 1; i++)
340 for (j = 0; j < RP->Ysize / 2 + 1; j++) 342 for (j = 0; j < RP->Ysize / 2 + 1; j++)
341 { 343 {
342 sym_maze[i][j] = maze[i][j]; 344 sym_maze[i][j] = maze[i][j];
343 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 345 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
347 /* delete the old maze */ 349 /* delete the old maze */
348 for (i = 0; i < Xsize_orig; i++) 350 for (i = 0; i < Xsize_orig; i++)
349 free (maze[i]); 351 free (maze[i]);
350 free (maze); 352 free (maze);
351 /* reconnect disjointed spirals */ 353 /* reconnect disjointed spirals */
352 if (RP->map_layout_style == SPIRAL_LAYOUT) 354 if (RP->map_layout_style == LAYOUT_SPIRAL)
353 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 355 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
354 /* reconnect disjointed nethackmazes: the routine for 356 /* reconnect disjointed nethackmazes: the routine for
355 spirals will do the trick? */ 357 spirals will do the trick? */
356 if (RP->map_layout_style == ROGUELIKE_LAYOUT) 358 if (RP->map_layout_style == LAYOUT_ROGUELIKE)
357 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 359 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
358 360
359 return sym_maze; 361 return sym_maze;
360} 362}
361 363
364 onion layouts, making them possibly centered on any wall. 366 onion layouts, making them possibly centered on any wall.
365 It'll modify Xsize and Ysize if they're swapped. 367 It'll modify Xsize and Ysize if they're swapped.
366*/ 368*/
367 369
368char ** 370char **
369rotate_layout (char **maze, int rotation, RMParms * RP) 371rotate_layout (char **maze, int rotation, random_map_params *RP)
370{ 372{
371 char **new_maze; 373 char **new_maze;
372 int i, j; 374 int i, j;
373 375
374 switch (rotation) 376 switch (rotation)
375 { 377 {
376 case 0: 378 case 0:
379 return maze;
380 break;
381 case 2: /* a reflection */
382 {
383 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize);
384
385 for (i = 0; i < RP->Xsize; i++)
386 { /* make a copy */
387 for (j = 0; j < RP->Ysize; j++)
388 {
389 newmaze[i * RP->Ysize + j] = maze[i][j];
390 }
391 }
392 for (i = 0; i < RP->Xsize; i++)
393 { /* copy a reflection back */
394 for (j = 0; j < RP->Ysize; j++)
395 {
396 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
397 }
398 }
399 free (newmaze);
377 return maze; 400 return maze;
378 break; 401 break;
379 case 2: /* a reflection */ 402 }
403 case 1:
404 case 3:
405 {
406 int swap;
407 new_maze = (char **) calloc (sizeof (char *), RP->Ysize);
408 for (i = 0; i < RP->Ysize; i++)
380 { 409 {
381 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize); 410 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
382 411 }
412 if (rotation == 1) /* swap x and y */
383 for (i = 0; i < RP->Xsize; i++) 413 for (i = 0; i < RP->Xsize; i++)
384 { /* make a copy */
385 for (j = 0; j < RP->Ysize; j++) 414 for (j = 0; j < RP->Ysize; j++)
386 {
387 newmaze[i * RP->Ysize + j] = maze[i][j]; 415 new_maze[j][i] = maze[i][j];
388 } 416
389 } 417 if (rotation == 3)
390 for (i = 0; i < RP->Xsize; i++) 418 { /* swap x and y */
391 { /* copy a reflection back */
392 for (j = 0; j < RP->Ysize; j++)
393 {
394 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
395 }
396 }
397 free (newmaze);
398 return maze;
399 break;
400 }
401 case 1:
402 case 3:
403 {
404 int swap;
405 new_maze = (char **) calloc (sizeof (char *), RP->Ysize);
406 for (i = 0; i < RP->Ysize; i++)
407 {
408 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
409 }
410 if (rotation == 1) /* swap x and y */
411 for (i = 0; i < RP->Xsize; i++) 419 for (i = 0; i < RP->Xsize; i++)
412 for (j = 0; j < RP->Ysize; j++) 420 for (j = 0; j < RP->Ysize; j++)
413 new_maze[j][i] = maze[i][j];
414
415 if (rotation == 3)
416 { /* swap x and y */
417 for (i = 0; i < RP->Xsize; i++)
418 for (j = 0; j < RP->Ysize; j++)
419 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1]; 421 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1];
420 } 422 }
421 423
422 /* delete the old layout */ 424 /* delete the old layout */
423 for (i = 0; i < RP->Xsize; i++) 425 for (i = 0; i < RP->Xsize; i++)
424 free (maze[i]); 426 free (maze[i]);
425 free (maze); 427 free (maze);
426 428
427 swap = RP->Ysize; 429 swap = RP->Ysize;
428 RP->Ysize = RP->Xsize; 430 RP->Ysize = RP->Xsize;
429 RP->Xsize = swap; 431 RP->Xsize = swap;
430 return new_maze; 432 return new_maze;
431 break; 433 break;
432 } 434 }
433 } 435 }
434 return NULL; 436 return NULL;
435} 437}
436 438
437/* take a layout and make some rooms in it. 439/* take a layout and make some rooms in it.
438 --works best on onions.*/ 440 --works best on onions.*/
439void 441void
440roomify_layout (char **maze, RMParms * RP) 442roomify_layout (char **maze, random_map_params *RP)
441{ 443{
442 int tries = RP->Xsize * RP->Ysize / 30; 444 int tries = RP->Xsize * RP->Ysize / 30;
443 int ti; 445 int ti;
444 446
445 for (ti = 0; ti < tries; ti++) 447 for (ti = 0; ti < tries; ti++)
472/* checks the layout to see if I can stick a horizontal(dir = 0) wall 474/* checks the layout to see if I can stick a horizontal(dir = 0) wall
473 (or vertical, dir == 1) 475 (or vertical, dir == 1)
474 here which ends up on other walls sensibly. */ 476 here which ends up on other walls sensibly. */
475 477
476int 478int
477can_make_wall (char **maze, int dx, int dy, int dir, RMParms * RP) 479can_make_wall (char **maze, int dx, int dy, int dir, random_map_params *RP)
478{ 480{
479 int i1; 481 int i1;
480 int length = 0; 482 int length = 0;
481 483
482 /* dont make walls if we're on the edge. */ 484 /* dont make walls if we're on the edge. */
557make_wall (char **maze, int x, int y, int dir) 559make_wall (char **maze, int x, int y, int dir)
558{ 560{
559 maze[x][y] = 'D'; /* mark a door */ 561 maze[x][y] = 'D'; /* mark a door */
560 switch (dir) 562 switch (dir)
561 { 563 {
562 case 0: /* horizontal */ 564 case 0: /* horizontal */
563 { 565 {
564 int i1; 566 int i1;
565 567
566 for (i1 = x - 1; maze[i1][y] == 0; i1--) 568 for (i1 = x - 1; maze[i1][y] == 0; i1--)
567 maze[i1][y] = '#'; 569 maze[i1][y] = '#';
568 for (i1 = x + 1; maze[i1][y] == 0; i1++) 570 for (i1 = x + 1; maze[i1][y] == 0; i1++)
569 maze[i1][y] = '#'; 571 maze[i1][y] = '#';
570 break; 572 break;
571 } 573 }
572 case 1: /* vertical */ 574 case 1: /* vertical */
573 { 575 {
574 int i1; 576 int i1;
575 577
576 for (i1 = y - 1; maze[x][i1] == 0; i1--) 578 for (i1 = y - 1; maze[x][i1] == 0; i1--)
577 maze[x][i1] = '#'; 579 maze[x][i1] = '#';
578 for (i1 = y + 1; maze[x][i1] == 0; i1++) 580 for (i1 = y + 1; maze[x][i1] == 0; i1++)
579 maze[x][i1] = '#'; 581 maze[x][i1] = '#';
580 break; 582 break;
581 } 583 }
582 } 584 }
583 585
584 return 0; 586 return 0;
585} 587}
586 588
587/* puts doors at appropriate locations in a layout. */ 589/* puts doors at appropriate locations in a layout. */
588
589void 590void
590doorify_layout (char **maze, RMParms * RP) 591doorify_layout (char **maze, random_map_params *RP)
591{ 592{
592 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */ 593 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
593 char *doorlist_x; 594 char *doorlist_x;
594 char *doorlist_y; 595 char *doorlist_y;
595 int doorlocs = 0; /* # of available doorlocations */ 596 int doorlocs = 0; /* # of available doorlocations */
610 doorlist_x[doorlocs] = i; 611 doorlist_x[doorlocs] = i;
611 doorlist_y[doorlocs] = j; 612 doorlist_y[doorlocs] = j;
612 doorlocs++; 613 doorlocs++;
613 } 614 }
614 } 615 }
616
615 while (ndoors > 0 && doorlocs > 0) 617 while (ndoors > 0 && doorlocs > 0)
616 { 618 {
617 int di; 619 int di;
618 int sindex; 620 int sindex;
619 621
629 /* reduce the size of the list */ 631 /* reduce the size of the list */
630 doorlocs--; 632 doorlocs--;
631 doorlist_x[di] = doorlist_x[doorlocs]; 633 doorlist_x[di] = doorlist_x[doorlocs];
632 doorlist_y[di] = doorlist_y[doorlocs]; 634 doorlist_y[di] = doorlist_y[doorlocs];
633 } 635 }
636
634 free (doorlist_x); 637 free (doorlist_x);
635 free (doorlist_y); 638 free (doorlist_y);
636} 639}
637 640
638
639void 641void
640write_map_parameters_to_string (char *buf, RMParms * RP) 642write_map_parameters_to_string (char *buf, random_map_params *RP)
641{ 643{
642
643 char small_buf[256]; 644 char small_buf[16384];
644 645
645 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); 646 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize);
646 647
647 if (RP->wallstyle[0]) 648 if (RP->wallstyle[0])
648 { 649 {
690 { 691 {
691 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle); 692 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle);
692 strcat (buf, small_buf); 693 strcat (buf, small_buf);
693 } 694 }
694 695
695 if (RP->final_map[0]) 696 if (RP->final_map.length ())
696 { 697 {
697 sprintf (small_buf, "final_map %s\n", RP->final_map); 698 sprintf (small_buf, "final_map %s\n", &RP->final_map);
698 strcat (buf, small_buf); 699 strcat (buf, small_buf);
699 } 700 }
700 701
701 if (RP->exit_on_final_map[0]) 702 if (RP->exit_on_final_map[0])
702 { 703 {
703 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map); 704 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
704 strcat (buf, small_buf); 705 strcat (buf, small_buf);
705 } 706 }
706 707
707 if (RP->this_map[0]) 708 if (RP->this_map.length ())
708 { 709 {
709 sprintf (small_buf, "origin_map %s\n", RP->this_map); 710 sprintf (small_buf, "origin_map %s\n", &RP->this_map);
710 strcat (buf, small_buf); 711 strcat (buf, small_buf);
711 } 712 }
712 713
713 if (RP->expand2x) 714 if (RP->expand2x)
714 { 715 {
720 { 721 {
721 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1); 722 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1);
722 strcat (buf, small_buf); 723 strcat (buf, small_buf);
723 } 724 }
724 725
725
726 if (RP->layoutoptions2) 726 if (RP->layoutoptions2)
727 { 727 {
728 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2); 728 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2);
729 strcat (buf, small_buf); 729 strcat (buf, small_buf);
730 } 730 }
731 731
732
733 if (RP->layoutoptions3) 732 if (RP->layoutoptions3)
734 { 733 {
735 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3); 734 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3);
736 strcat (buf, small_buf); 735 strcat (buf, small_buf);
737 } 736 }
739 if (RP->symmetry) 738 if (RP->symmetry)
740 { 739 {
741 sprintf (small_buf, "symmetry %d\n", RP->symmetry); 740 sprintf (small_buf, "symmetry %d\n", RP->symmetry);
742 strcat (buf, small_buf); 741 strcat (buf, small_buf);
743 } 742 }
744
745 743
746 if (RP->difficulty && RP->difficulty_given) 744 if (RP->difficulty && RP->difficulty_given)
747 { 745 {
748 sprintf (small_buf, "difficulty %d\n", RP->difficulty); 746 sprintf (small_buf, "difficulty %d\n", RP->difficulty);
749 strcat (buf, small_buf); 747 strcat (buf, small_buf);
785 if (RP->origin_y) 783 if (RP->origin_y)
786 { 784 {
787 sprintf (small_buf, "origin_y %d\n", RP->origin_y); 785 sprintf (small_buf, "origin_y %d\n", RP->origin_y);
788 strcat (buf, small_buf); 786 strcat (buf, small_buf);
789 } 787 }
788
789 if (RP->treasureoptions)
790 {
791 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
792 strcat (buf, small_buf);
793 }
794
790 if (RP->random_seed) 795 if (RP->random_seed)
791 { 796 {
792 /* Add one so that the next map is a bit different */
793 sprintf (small_buf, "random_seed %d\n", RP->random_seed + 1); 797 sprintf (small_buf, "random_seed %d\n", RP->random_seed);
794 strcat (buf, small_buf); 798 strcat (buf, small_buf);
795 }
796
797 if (RP->treasureoptions)
798 { 799 }
799 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions); 800
800 strcat (buf, small_buf); 801 if (RP->custom)
801 } 802 {
802 803 sprintf (small_buf, "custom %s\n", RP->custom);
803 804 strcat (buf, small_buf);
805 }
804} 806}
805 807
806void 808void
807write_parameters_to_string (char *buf, 809write_parameters_to_string (char *buf,
808 int xsize_n, 810 int xsize_n,
828 int difficulty_given_n, 830 int difficulty_given_n,
829 int decoroptions_n, 831 int decoroptions_n,
830 int orientation_n, 832 int orientation_n,
831 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) 833 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase)
832{ 834{
833
834 char small_buf[256]; 835 char small_buf[16384];
835 836
836 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); 837 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
837 838
838 if (wallstyle_n && wallstyle_n[0]) 839 if (wallstyle_n && wallstyle_n[0])
839 { 840 {
904 if (layoutoptions1_n) 905 if (layoutoptions1_n)
905 { 906 {
906 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n); 907 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n);
907 strcat (buf, small_buf); 908 strcat (buf, small_buf);
908 } 909 }
909
910 910
911 if (layoutoptions2_n) 911 if (layoutoptions2_n)
912 { 912 {
913 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n); 913 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n);
914 strcat (buf, small_buf); 914 strcat (buf, small_buf);
970 if (origin_y_n) 970 if (origin_y_n)
971 { 971 {
972 sprintf (small_buf, "origin_y %d\n", origin_y_n); 972 sprintf (small_buf, "origin_y %d\n", origin_y_n);
973 strcat (buf, small_buf); 973 strcat (buf, small_buf);
974 } 974 }
975
975 if (random_seed_n) 976 if (random_seed_n)
976 { 977 {
977 /* Add one so that the next map is a bit different */ 978 /* Add one so that the next map is a bit different */
978 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1); 979 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1);
979 strcat (buf, small_buf); 980 strcat (buf, small_buf);
982 if (treasureoptions_n) 983 if (treasureoptions_n)
983 { 984 {
984 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n); 985 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n);
985 strcat (buf, small_buf); 986 strcat (buf, small_buf);
986 } 987 }
987
988
989} 988}
990 989
991/* copy an object with an inventory... i.e., duplicate the inv too. */ 990/* copy an object with an inventory... i.e., duplicate the inv too. */
992void 991void
993copy_object_with_inv (object *src_ob, object *dest_ob) 992copy_object_with_inv (object *src_ob, object *dest_ob)
994{ 993{
995 object *walk, *tmp; 994 object *walk, *tmp;
996 995
997 src_ob->copy_to (dest_ob); 996 src_ob->copy_to (dest_ob);
998 997
999 for (walk = src_ob->inv; walk != NULL; walk = walk->below) 998 for (walk = src_ob->inv; walk; walk = walk->below)
1000 { 999 {
1001 tmp = object::create (); 1000 tmp = object::create ();
1001
1002 walk->copy_to (tmp); 1002 walk->copy_to (tmp);
1003 insert_ob_in_ob (tmp, dest_ob); 1003 insert_ob_in_ob (tmp, dest_ob);
1004 } 1004 }
1005} 1005}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines