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.3 by root, Sun Sep 10 16:06:37 2006 UTC vs.
Revision 1.30 by root, Sun Jul 1 05:00:19 2007 UTC

1
2/* 1/*
3 * static char *rcsid_random_map_c = 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
4 * "$Id: random_map.C,v 1.3 2006/09/10 16:06:37 root Exp $"; 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your 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 GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
5 */ 22 */
6
7/*
8 CrossFire, A Multiplayer game for X-windows
9
10 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27 The authors can be reached via e-mail at crossfire-devel@real-time.com
28*/
29 23
30#include <time.h> 24#include <time.h>
31#include <stdio.h> 25#include <stdio.h>
32#include <global.h> 26#include <global.h>
33#include <maze_gen.h> 27#include <maze_gen.h>
34#include <room_gen.h> 28#include <room_gen.h>
35#include <random_map.h> 29#include <random_map.h>
36#include <rproto.h> 30#include <rproto.h>
37#include <sproto.h> 31#include <sproto.h>
38 32
33#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__);
34
39void 35void
40dump_layout (char **layout, RMParms * RP) 36dump_layout (char **layout, random_map_params *RP)
41{ 37{
42 { 38 {
43 int i, j; 39 int i, j;
44 40
45 for (i = 0; i < RP->Xsize; i++) 41 for (i = 0; i < RP->Xsize; i++)
55 printf ("\n"); 51 printf ("\n");
56 } 52 }
57 } 53 }
58 printf ("\n"); 54 printf ("\n");
59} 55}
60EXTERN FILE *logfile; 56
61mapstruct * 57bool
62generate_random_map (const char *OutFileName, RMParms * RP) 58maptile::generate_random_map (random_map_params *RP)
63{ 59{
64 char **layout, buf[HUGE_BUF]; 60 char **layout, buf[16384];
65 mapstruct *theMap;
66 int i; 61 int i;
67 62
63 RP->Xsize = RP->xsize;
64 RP->Ysize = RP->ysize;
65
68 /* pick a random seed, or use the one from the input file */ 66 /* pick a random seed, or use the one from the input file */
69 if (RP->random_seed == 0) 67 RP->random_seed = RP->random_seed
70 RP->random_seed = time (0); 68 ? RP->random_seed + RP->dungeon_level
71 69 : time (0);
72 SRANDOM (RP->random_seed); 70 CEDE;
73 71
74 write_map_parameters_to_string (buf, RP); 72 write_map_parameters_to_string (buf, RP);
75 73
76 if (RP->difficulty == 0) 74 if (RP->difficulty == 0)
77 { 75 {
78 RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */ 76 RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
77
79 if (RP->difficulty_increase > 0.001) 78 if (RP->difficulty_increase > 0.001)
80 {
81 RP->difficulty = (int) ((float) RP->dungeon_level * RP->difficulty_increase); 79 RP->difficulty = (int) ((float) RP->dungeon_level * RP->difficulty_increase);
80
82 if (RP->difficulty < 1) 81 if (RP->difficulty < 1)
83 RP->difficulty = 1; 82 RP->difficulty = 1;
84 }
85 } 83 }
86 else 84 else
87 RP->difficulty_given = 1; 85 RP->difficulty_given = 1;
88 86
89 if (RP->Xsize < MIN_RANDOM_MAP_SIZE) 87 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
90 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 88 RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
89
91 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 90 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
92 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 91 RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
92
93 if (RP->symmetry == SYMMETRY_RANDOM)
94 RP->symmetry_used = rndm (SYMMETRY_XY) + 1;
95 else
96 RP->symmetry_used = RP->symmetry;
97
98 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
99 RP->Ysize = RP->Ysize / 2 + 1;
100
101 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
102 RP->Xsize = RP->Xsize / 2 + 1;
93 103
94 if (RP->expand2x > 0) 104 if (RP->expand2x > 0)
95 { 105 {
96 RP->Xsize /= 2; 106 RP->Xsize /= 2;
97 RP->Ysize /= 2; 107 RP->Ysize /= 2;
98 } 108 }
99 109
100 layout = layoutgen (RP);
101
102#ifdef RMAP_DEBUG
103 dump_layout (layout, RP);
104#endif
105
106 /* increment these for the current map */
107 RP->dungeon_level += 1;
108 /* allow constant-difficulty maps. */
109 /* difficulty+=1; */
110
111 /* rotate the layout randomly */
112 layout = rotate_layout (layout, RANDOM () % 4, RP);
113#ifdef RMAP_DEBUG
114 dump_layout (layout, RP);
115#endif
116
117 /* allocate the map and set the floor */
118 theMap = make_map_floor (layout, RP->floorstyle, RP);
119
120 /* set the name of the map. */
121 strcpy (theMap->path, OutFileName);
122
123 /* set region */
124 theMap->region = RP->region;
125
126 /* create walls unless the wallstyle is "none" */
127 if (strcmp (RP->wallstyle, "none"))
128 {
129 make_map_walls (theMap, layout, RP->wallstyle, RP);
130
131 /* place doors unless doorstyle or wallstyle is "none" */
132 if (strcmp (RP->doorstyle, "none"))
133 put_doors (theMap, layout, RP->doorstyle, RP);
134
135 }
136
137 /* create exits unless the exitstyle is "none" */
138 if (strcmp (RP->exitstyle, "none"))
139 place_exits (theMap, layout, RP->exitstyle, RP->orientation, RP);
140
141 place_specials_in_map (theMap, layout, RP);
142
143 /* create monsters unless the monsterstyle is "none" */
144 if (strcmp (RP->monsterstyle, "none"))
145 place_monsters (theMap, RP->monsterstyle, RP->difficulty, RP);
146
147 /* treasures needs to have a proper difficulty set for the map. */
148 theMap->difficulty = calculate_difficulty (theMap);
149
150 /* create treasure unless the treasurestyle is "none" */
151 if (strcmp (RP->treasurestyle, "none"))
152 place_treasure (theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
153
154 /* create decor unless the decorstyle is "none" */
155 if (strcmp (RP->decorstyle, "none"))
156 put_decor (theMap, layout, RP->decorstyle, RP->decoroptions, RP);
157
158 /* generate treasures, etc. */
159 fix_auto_apply (theMap);
160
161 unblock_exits (theMap, layout, RP);
162
163 /* free the layout */
164 for (i = 0; i < RP->Xsize; i++)
165 free (layout[i]);
166 free (layout);
167
168 theMap->msg = strdup_local (buf);
169
170 return theMap;
171}
172
173
174/* function selects the layout function and gives it whatever
175 arguments it needs. */
176char **
177layoutgen (RMParms * RP)
178{
179 char **maze = 0;
180 int oxsize = RP->Xsize, oysize = RP->Ysize;
181
182 if (RP->symmetry == RANDOM_SYM)
183 RP->symmetry_used = (RANDOM () % (XY_SYM)) + 1;
184 else
185 RP->symmetry_used = RP->symmetry;
186
187 if (RP->symmetry_used == Y_SYM || RP->symmetry_used == XY_SYM)
188 RP->Ysize = RP->Ysize / 2 + 1;
189 if (RP->symmetry_used == X_SYM || RP->symmetry_used == XY_SYM)
190 RP->Xsize = RP->Xsize / 2 + 1;
191
192 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
193 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
194 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
195 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
196 RP->map_layout_style = 0; 110 RP->map_layout_style = LAYOUT_NONE;
197 111
198 /* Redo this - there was a lot of redundant code of checking for preset 112 /* Redo this - there was a lot of redundant code of checking for preset
199 * layout style and then random layout style. Instead, figure out 113 * layout style and then random layout style. Instead, figure out
200 * the numeric layoutstyle, so there is only one area that actually 114 * the numeric layoutstyle, so there is only one area that actually
201 * calls the code to make the maps. 115 * calls the code to make the maps.
202 */ 116 */
203 if (strstr (RP->layoutstyle, "onion")) 117 if (strstr (RP->layoutstyle, "onion"))
204 {
205 RP->map_layout_style = ONION_LAYOUT; 118 RP->map_layout_style = LAYOUT_ONION;
206 }
207 119
208 if (strstr (RP->layoutstyle, "maze")) 120 if (strstr (RP->layoutstyle, "maze"))
209 {
210 RP->map_layout_style = MAZE_LAYOUT; 121 RP->map_layout_style = LAYOUT_MAZE;
211 }
212 122
213 if (strstr (RP->layoutstyle, "spiral")) 123 if (strstr (RP->layoutstyle, "spiral"))
214 {
215 RP->map_layout_style = SPIRAL_LAYOUT; 124 RP->map_layout_style = LAYOUT_SPIRAL;
216 }
217 125
218 if (strstr (RP->layoutstyle, "rogue")) 126 if (strstr (RP->layoutstyle, "rogue"))
219 {
220 RP->map_layout_style = ROGUELIKE_LAYOUT; 127 RP->map_layout_style = LAYOUT_ROGUELIKE;
221 }
222 128
223 if (strstr (RP->layoutstyle, "snake")) 129 if (strstr (RP->layoutstyle, "snake"))
224 {
225 RP->map_layout_style = SNAKE_LAYOUT; 130 RP->map_layout_style = LAYOUT_SNAKE;
226 }
227 131
228 if (strstr (RP->layoutstyle, "squarespiral")) 132 if (strstr (RP->layoutstyle, "squarespiral"))
229 {
230 RP->map_layout_style = SQUARE_SPIRAL_LAYOUT; 133 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
231 } 134
232 /* No style found - choose one ranomdly */ 135 /* No style found - choose one randomly */
233 if (RP->map_layout_style == 0) 136 if (RP->map_layout_style == LAYOUT_NONE)
234 {
235 RP->map_layout_style = (RANDOM () % NROFLAYOUTS) + 1; 137 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1;
138
139 layout = layoutgen (RP);
140
141#ifdef RMAP_DEBUG
142 dump_layout (layout, RP);
143#endif
144
145 /* increment these for the current map */
146 RP->dungeon_level += 1;
147 /* allow constant-difficulty maps. */
148 /* difficulty+=1; */
149
150 /* rotate the layout randomly */
151 layout = rotate_layout (layout, rndm (4), RP);
152#ifdef RMAP_DEBUG
153 dump_layout (layout, RP);
154#endif
155
156 /* allocate the map and set the floor */
157 make_map_floor (layout, RP->floorstyle, RP);
158
159 /* set region */
160 default_region = RP->region;
161
162 CEDE;
163
164 /* create walls unless the wallstyle is "none" */
165 if (strcmp (RP->wallstyle, "none"))
236 } 166 {
167 make_map_walls (this, layout, RP->wallstyle, RP);
168
169 /* place doors unless doorstyle or wallstyle is "none" */
170 if (strcmp (RP->doorstyle, "none"))
171 put_doors (this, layout, RP->doorstyle, RP);
172 }
173
174 CEDE;
175
176 /* create exits unless the exitstyle is "none" */
177 if (strcmp (RP->exitstyle, "none"))
178 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
179
180 CEDE;
181
182 place_specials_in_map (this, layout, RP);
183
184 CEDE;
185
186 /* create monsters unless the monsterstyle is "none" */
187 if (strcmp (RP->monsterstyle, "none"))
188 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
189
190 CEDE;
191
192 /* treasures needs to have a proper difficulty set for the map. */
193 difficulty = estimate_difficulty ();
194
195 CEDE;
196
197 /* create treasure unless the treasurestyle is "none" */
198 if (strcmp (RP->treasurestyle, "none"))
199 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
200
201 CEDE;
202
203 /* create decor unless the decorstyle is "none" */
204 if (strcmp (RP->decorstyle, "none"))
205 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
206
207 CEDE;
208
209 /* generate treasures, etc. */
210 fix_auto_apply ();
211
212 CEDE;
213
214 unblock_exits (this, layout, RP);
215
216 /* free the layout */
217 for (i = 0; i < RP->Xsize; i++)
218 free (layout[i]);
219
220 free (layout);
221
222 msg = strdup (buf);
223 in_memory = MAP_IN_MEMORY;
224
225 CEDE;
226
227 return 1;
228}
229
230/* function selects the layout function and gives it whatever
231 arguments it needs. */
232char **
233layoutgen (random_map_params *RP)
234{
235 char **maze = 0;
236 int oxsize = RP->Xsize, oysize = RP->Ysize;
237 237
238 switch (RP->map_layout_style) 238 switch (RP->map_layout_style)
239 { 239 {
240 240 case LAYOUT_ONION:
241 case ONION_LAYOUT:
242 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 241 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
243 if (!(RANDOM () % 3) && !(RP->layoutoptions1 & OPT_WALLS_ONLY)) 242 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
244 roomify_layout (maze, RP); 243 roomify_layout (maze, RP);
245 break; 244 break;
246 245
247 case MAZE_LAYOUT: 246 case LAYOUT_MAZE:
248 maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2); 247 maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2));
249 if (!(RANDOM () % 2)) 248 if (!(rndm (2)))
250 doorify_layout (maze, RP); 249 doorify_layout (maze, RP);
251 break; 250 break;
252 251
253 case SPIRAL_LAYOUT: 252 case LAYOUT_SPIRAL:
254 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 253 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1);
255 if (!(RANDOM () % 2)) 254 if (!(rndm (2)))
256 doorify_layout (maze, RP); 255 doorify_layout (maze, RP);
257 break; 256 break;
258 257
259 case ROGUELIKE_LAYOUT: 258 case LAYOUT_ROGUELIKE:
260 /* Don't put symmetry in rogue maps. There isn't much reason to 259 /* Don't put symmetry in rogue maps. There isn't much reason to
261 * do so in the first place (doesn't make it any more interesting), 260 * do so in the first place (doesn't make it any more interesting),
262 * but more importantly, the symmetry code presumes we are symmetrizing 261 * but more importantly, the symmetry code presumes we are symmetrizing
263 * spirals, or maps with lots of passages - making a symmetric rogue 262 * spirals, or maps with lots of passages - making a symmetric rogue
264 * map fails because its likely that the passages the symmetry process 263 * map fails because its likely that the passages the symmetry process
265 * creates may not connect the rooms. 264 * creates may not connect the rooms.
266 */ 265 */
267 RP->symmetry_used = NO_SYM; 266 RP->symmetry_used = SYMMETRY_NONE;
268 RP->Ysize = oysize; 267 RP->Ysize = oysize;
269 RP->Xsize = oxsize; 268 RP->Xsize = oxsize;
270 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1); 269 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1);
271 /* no doorifying... done already */ 270 /* no doorifying... done already */
272 break; 271 break;
273 272
274 case SNAKE_LAYOUT: 273 case LAYOUT_SNAKE:
275 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 274 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
276 if (RANDOM () % 2) 275 if (rndm (2))
277 roomify_layout (maze, RP); 276 roomify_layout (maze, RP);
278 break; 277 break;
279 278
280 case SQUARE_SPIRAL_LAYOUT: 279 case LAYOUT_SQUARE_SPIRAL:
281 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 280 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
282 if (RANDOM () % 2) 281 if (rndm (2))
283 roomify_layout (maze, RP); 282 roomify_layout (maze, RP);
284 break; 283 break;
285 } 284 }
286 285
287 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 286 maze = symmetrize_layout (maze, RP->symmetry_used, RP);
287
288#ifdef RMAP_DEBUG 288#ifdef RMAP_DEBUG
289 dump_layout (maze, RP); 289 dump_layout (maze, RP);
290#endif 290#endif
291
291 if (RP->expand2x) 292 if (RP->expand2x)
292 { 293 {
293 maze = expand2x (maze, RP->Xsize, RP->Ysize); 294 maze = expand2x (maze, RP->Xsize, RP->Ysize);
294 RP->Xsize = RP->Xsize * 2 - 1; 295 RP->Xsize = RP->Xsize * 2 - 1;
295 RP->Ysize = RP->Ysize * 2 - 1; 296 RP->Ysize = RP->Ysize * 2 - 1;
296 } 297 }
298
297 return maze; 299 return maze;
298} 300}
299
300 301
301/* takes a map and makes it symmetric: adjusts Xsize and 302/* takes a map and makes it symmetric: adjusts Xsize and
302Ysize to produce a symmetric map. */ 303Ysize to produce a symmetric map. */
303
304char ** 304char **
305symmetrize_layout (char **maze, int sym, RMParms * RP) 305symmetrize_layout (char **maze, int sym, random_map_params *RP)
306{ 306{
307 int i, j; 307 int i, j;
308 char **sym_maze; 308 char **sym_maze;
309 int Xsize_orig, Ysize_orig; 309 int Xsize_orig, Ysize_orig;
310 310
311 Xsize_orig = RP->Xsize; 311 Xsize_orig = RP->Xsize;
312 Ysize_orig = RP->Ysize; 312 Ysize_orig = RP->Ysize;
313 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */ 313 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */
314 if (sym == NO_SYM) 314 if (sym == SYMMETRY_NONE)
315 { 315 {
316 RP->Xsize = Xsize_orig; 316 RP->Xsize = Xsize_orig;
317 RP->Ysize = Ysize_orig; 317 RP->Ysize = Ysize_orig;
318 return maze; 318 return maze;
319 } 319 }
320 /* pick new sizes */ 320 /* pick new sizes */
321 RP->Xsize = ((sym == X_SYM || sym == XY_SYM) ? RP->Xsize * 2 - 3 : RP->Xsize); 321 RP->Xsize = ((sym == SYMMETRY_X || sym == SYMMETRY_XY) ? RP->Xsize * 2 - 3 : RP->Xsize);
322 RP->Ysize = ((sym == Y_SYM || sym == XY_SYM) ? RP->Ysize * 2 - 3 : RP->Ysize); 322 RP->Ysize = ((sym == SYMMETRY_Y || sym == SYMMETRY_XY) ? RP->Ysize * 2 - 3 : RP->Ysize);
323 323
324 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize); 324 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize);
325 for (i = 0; i < RP->Xsize; i++) 325 for (i = 0; i < RP->Xsize; i++)
326 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize); 326 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize);
327 327
328 if (sym == X_SYM) 328 if (sym == SYMMETRY_X)
329 for (i = 0; i < RP->Xsize / 2 + 1; i++) 329 for (i = 0; i < RP->Xsize / 2 + 1; i++)
330 for (j = 0; j < RP->Ysize; j++) 330 for (j = 0; j < RP->Ysize; j++)
331 { 331 {
332 sym_maze[i][j] = maze[i][j]; 332 sym_maze[i][j] = maze[i][j];
333 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 333 sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
334 }; 334 };
335 if (sym == Y_SYM) 335 if (sym == SYMMETRY_Y)
336 for (i = 0; i < RP->Xsize; i++) 336 for (i = 0; i < RP->Xsize; i++)
337 for (j = 0; j < RP->Ysize / 2 + 1; j++) 337 for (j = 0; j < RP->Ysize / 2 + 1; j++)
338 { 338 {
339 sym_maze[i][j] = maze[i][j]; 339 sym_maze[i][j] = maze[i][j];
340 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 340 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
341 } 341 }
342 if (sym == XY_SYM) 342 if (sym == SYMMETRY_XY)
343 for (i = 0; i < RP->Xsize / 2 + 1; i++) 343 for (i = 0; i < RP->Xsize / 2 + 1; i++)
344 for (j = 0; j < RP->Ysize / 2 + 1; j++) 344 for (j = 0; j < RP->Ysize / 2 + 1; j++)
345 { 345 {
346 sym_maze[i][j] = maze[i][j]; 346 sym_maze[i][j] = maze[i][j];
347 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 347 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
351 /* delete the old maze */ 351 /* delete the old maze */
352 for (i = 0; i < Xsize_orig; i++) 352 for (i = 0; i < Xsize_orig; i++)
353 free (maze[i]); 353 free (maze[i]);
354 free (maze); 354 free (maze);
355 /* reconnect disjointed spirals */ 355 /* reconnect disjointed spirals */
356 if (RP->map_layout_style == SPIRAL_LAYOUT) 356 if (RP->map_layout_style == LAYOUT_SPIRAL)
357 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 357 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
358 /* reconnect disjointed nethackmazes: the routine for 358 /* reconnect disjointed nethackmazes: the routine for
359 spirals will do the trick? */ 359 spirals will do the trick? */
360 if (RP->map_layout_style == ROGUELIKE_LAYOUT) 360 if (RP->map_layout_style == LAYOUT_ROGUELIKE)
361 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 361 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
362 362
363 return sym_maze; 363 return sym_maze;
364} 364}
365 365
368 onion layouts, making them possibly centered on any wall. 368 onion layouts, making them possibly centered on any wall.
369 It'll modify Xsize and Ysize if they're swapped. 369 It'll modify Xsize and Ysize if they're swapped.
370*/ 370*/
371 371
372char ** 372char **
373rotate_layout (char **maze, int rotation, RMParms * RP) 373rotate_layout (char **maze, int rotation, random_map_params *RP)
374{ 374{
375 char **new_maze; 375 char **new_maze;
376 int i, j; 376 int i, j;
377 377
378 switch (rotation) 378 switch (rotation)
379 { 379 {
380 case 0: 380 case 0:
381 return maze;
382 break;
383 case 2: /* a reflection */
384 {
385 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize);
386
387 for (i = 0; i < RP->Xsize; i++)
388 { /* make a copy */
389 for (j = 0; j < RP->Ysize; j++)
390 {
391 newmaze[i * RP->Ysize + j] = maze[i][j];
392 }
393 }
394 for (i = 0; i < RP->Xsize; i++)
395 { /* copy a reflection back */
396 for (j = 0; j < RP->Ysize; j++)
397 {
398 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
399 }
400 }
401 free (newmaze);
381 return maze; 402 return maze;
382 break; 403 break;
383 case 2: /* a reflection */ 404 }
405 case 1:
406 case 3:
407 {
408 int swap;
409 new_maze = (char **) calloc (sizeof (char *), RP->Ysize);
410 for (i = 0; i < RP->Ysize; i++)
384 { 411 {
385 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize); 412 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
386 413 }
414 if (rotation == 1) /* swap x and y */
387 for (i = 0; i < RP->Xsize; i++) 415 for (i = 0; i < RP->Xsize; i++)
388 { /* make a copy */
389 for (j = 0; j < RP->Ysize; j++) 416 for (j = 0; j < RP->Ysize; j++)
390 {
391 newmaze[i * RP->Ysize + j] = maze[i][j]; 417 new_maze[j][i] = maze[i][j];
392 } 418
393 } 419 if (rotation == 3)
394 for (i = 0; i < RP->Xsize; i++) 420 { /* swap x and y */
395 { /* copy a reflection back */
396 for (j = 0; j < RP->Ysize; j++)
397 {
398 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
399 }
400 }
401 free (newmaze);
402 return maze;
403 break;
404 }
405 case 1:
406 case 3:
407 {
408 int swap;
409 new_maze = (char **) calloc (sizeof (char *), RP->Ysize);
410 for (i = 0; i < RP->Ysize; i++)
411 {
412 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
413 }
414 if (rotation == 1) /* swap x and y */
415 for (i = 0; i < RP->Xsize; i++) 421 for (i = 0; i < RP->Xsize; i++)
416 for (j = 0; j < RP->Ysize; j++) 422 for (j = 0; j < RP->Ysize; j++)
417 new_maze[j][i] = maze[i][j];
418
419 if (rotation == 3)
420 { /* swap x and y */
421 for (i = 0; i < RP->Xsize; i++)
422 for (j = 0; j < RP->Ysize; j++)
423 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1]; 423 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1];
424 } 424 }
425 425
426 /* delete the old layout */ 426 /* delete the old layout */
427 for (i = 0; i < RP->Xsize; i++) 427 for (i = 0; i < RP->Xsize; i++)
428 free (maze[i]); 428 free (maze[i]);
429 free (maze); 429 free (maze);
430 430
431 swap = RP->Ysize; 431 swap = RP->Ysize;
432 RP->Ysize = RP->Xsize; 432 RP->Ysize = RP->Xsize;
433 RP->Xsize = swap; 433 RP->Xsize = swap;
434 return new_maze; 434 return new_maze;
435 break; 435 break;
436 } 436 }
437 } 437 }
438 return NULL; 438 return NULL;
439} 439}
440 440
441/* take a layout and make some rooms in it. 441/* take a layout and make some rooms in it.
442 --works best on onions.*/ 442 --works best on onions.*/
443void 443void
444roomify_layout (char **maze, RMParms * RP) 444roomify_layout (char **maze, random_map_params *RP)
445{ 445{
446 int tries = RP->Xsize * RP->Ysize / 30; 446 int tries = RP->Xsize * RP->Ysize / 30;
447 int ti; 447 int ti;
448 448
449 for (ti = 0; ti < tries; ti++) 449 for (ti = 0; ti < tries; ti++)
450 { 450 {
451 int dx, dy; /* starting location for looking at creating a door */ 451 int dx, dy; /* starting location for looking at creating a door */
452 int cx, cy; /* results of checking on creating walls. */ 452 int cx, cy; /* results of checking on creating walls. */
453 453
454 dx = RANDOM () % RP->Xsize; 454 dx = rndm (RP->Xsize);
455 dy = RANDOM () % RP->Ysize; 455 dy = rndm (RP->Ysize);
456
456 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ 457 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
457 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ 458 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
458 if (cx == -1) 459 if (cx == -1)
459 { 460 {
460 if (cy != -1) 461 if (cy != -1)
461 make_wall (maze, dx, dy, 1); 462 make_wall (maze, dx, dy, 1);
463
462 continue; 464 continue;
463 } 465 }
466
464 if (cy == -1) 467 if (cy == -1)
465 { 468 {
466 make_wall (maze, dx, dy, 0); 469 make_wall (maze, dx, dy, 0);
467 continue; 470 continue;
468 } 471 }
472
469 if (cx < cy) 473 if (cx < cy)
470 make_wall (maze, dx, dy, 0); 474 make_wall (maze, dx, dy, 0);
471 else 475 else
472 make_wall (maze, dx, dy, 1); 476 make_wall (maze, dx, dy, 1);
473 } 477 }
476/* checks the layout to see if I can stick a horizontal(dir = 0) wall 480/* checks the layout to see if I can stick a horizontal(dir = 0) wall
477 (or vertical, dir == 1) 481 (or vertical, dir == 1)
478 here which ends up on other walls sensibly. */ 482 here which ends up on other walls sensibly. */
479 483
480int 484int
481can_make_wall (char **maze, int dx, int dy, int dir, RMParms * RP) 485can_make_wall (char **maze, int dx, int dy, int dir, random_map_params *RP)
482{ 486{
483 int i1; 487 int i1;
484 int length = 0; 488 int length = 0;
485 489
486 /* dont make walls if we're on the edge. */ 490 /* dont make walls if we're on the edge. */
561make_wall (char **maze, int x, int y, int dir) 565make_wall (char **maze, int x, int y, int dir)
562{ 566{
563 maze[x][y] = 'D'; /* mark a door */ 567 maze[x][y] = 'D'; /* mark a door */
564 switch (dir) 568 switch (dir)
565 { 569 {
566 case 0: /* horizontal */ 570 case 0: /* horizontal */
567 { 571 {
568 int i1; 572 int i1;
569 573
570 for (i1 = x - 1; maze[i1][y] == 0; i1--) 574 for (i1 = x - 1; maze[i1][y] == 0; i1--)
571 maze[i1][y] = '#'; 575 maze[i1][y] = '#';
572 for (i1 = x + 1; maze[i1][y] == 0; i1++) 576 for (i1 = x + 1; maze[i1][y] == 0; i1++)
573 maze[i1][y] = '#'; 577 maze[i1][y] = '#';
574 break; 578 break;
575 } 579 }
576 case 1: /* vertical */ 580 case 1: /* vertical */
577 { 581 {
578 int i1; 582 int i1;
579 583
580 for (i1 = y - 1; maze[x][i1] == 0; i1--) 584 for (i1 = y - 1; maze[x][i1] == 0; i1--)
581 maze[x][i1] = '#'; 585 maze[x][i1] = '#';
582 for (i1 = y + 1; maze[x][i1] == 0; i1++) 586 for (i1 = y + 1; maze[x][i1] == 0; i1++)
583 maze[x][i1] = '#'; 587 maze[x][i1] = '#';
584 break; 588 break;
585 } 589 }
586 } 590 }
587 591
588 return 0; 592 return 0;
589} 593}
590 594
591/* puts doors at appropriate locations in a layout. */ 595/* puts doors at appropriate locations in a layout. */
592
593void 596void
594doorify_layout (char **maze, RMParms * RP) 597doorify_layout (char **maze, random_map_params *RP)
595{ 598{
596 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */ 599 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
597 char *doorlist_x; 600 char *doorlist_x;
598 char *doorlist_y; 601 char *doorlist_y;
599 int doorlocs = 0; /* # of available doorlocations */ 602 int doorlocs = 0; /* # of available doorlocations */
614 doorlist_x[doorlocs] = i; 617 doorlist_x[doorlocs] = i;
615 doorlist_y[doorlocs] = j; 618 doorlist_y[doorlocs] = j;
616 doorlocs++; 619 doorlocs++;
617 } 620 }
618 } 621 }
622
619 while (ndoors > 0 && doorlocs > 0) 623 while (ndoors > 0 && doorlocs > 0)
620 { 624 {
621 int di; 625 int di;
622 int sindex; 626 int sindex;
623 627
624 di = RANDOM () % doorlocs; 628 di = rndm (doorlocs);
625 i = doorlist_x[di]; 629 i = doorlist_x[di];
626 j = doorlist_y[di]; 630 j = doorlist_y[di];
627 sindex = surround_flag (maze, i, j, RP); 631 sindex = surround_flag (maze, i, j, RP);
632
628 if (sindex == 3 || sindex == 12) /* these are possible door sindex */ 633 if (sindex == 3 || sindex == 12) /* these are possible door sindex */
629 { 634 {
630 maze[i][j] = 'D'; 635 maze[i][j] = 'D';
631 ndoors--; 636 ndoors--;
632 } 637 }
638
633 /* reduce the size of the list */ 639 /* reduce the size of the list */
634 doorlocs--; 640 doorlocs--;
635 doorlist_x[di] = doorlist_x[doorlocs]; 641 doorlist_x[di] = doorlist_x[doorlocs];
636 doorlist_y[di] = doorlist_y[doorlocs]; 642 doorlist_y[di] = doorlist_y[doorlocs];
637 } 643 }
644
638 free (doorlist_x); 645 free (doorlist_x);
639 free (doorlist_y); 646 free (doorlist_y);
640} 647}
641 648
642
643void 649void
644write_map_parameters_to_string (char *buf, RMParms * RP) 650write_map_parameters_to_string (char *buf, random_map_params *RP)
645{ 651{
646
647 char small_buf[256]; 652 char small_buf[16384];
648 653
649 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); 654 sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize);
650 655
651 if (RP->wallstyle[0]) 656 if (RP->wallstyle[0])
652 { 657 {
653 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle); 658 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle);
654 strcat (buf, small_buf); 659 strcat (buf, small_buf);
694 { 699 {
695 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle); 700 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle);
696 strcat (buf, small_buf); 701 strcat (buf, small_buf);
697 } 702 }
698 703
699 if (RP->final_map[0]) 704 if (RP->final_map.length ())
700 { 705 {
701 sprintf (small_buf, "final_map %s\n", RP->final_map); 706 sprintf (small_buf, "final_map %s\n", &RP->final_map);
702 strcat (buf, small_buf); 707 strcat (buf, small_buf);
703 } 708 }
704 709
705 if (RP->exit_on_final_map[0]) 710 if (RP->exit_on_final_map[0])
706 { 711 {
707 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map); 712 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
708 strcat (buf, small_buf); 713 strcat (buf, small_buf);
709 } 714 }
710 715
711 if (RP->this_map[0]) 716 if (RP->this_map.length ())
712 { 717 {
713 sprintf (small_buf, "origin_map %s\n", RP->this_map); 718 sprintf (small_buf, "origin_map %s\n", &RP->this_map);
714 strcat (buf, small_buf); 719 strcat (buf, small_buf);
715 } 720 }
716 721
717 if (RP->expand2x) 722 if (RP->expand2x)
718 { 723 {
724 { 729 {
725 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1); 730 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1);
726 strcat (buf, small_buf); 731 strcat (buf, small_buf);
727 } 732 }
728 733
729
730 if (RP->layoutoptions2) 734 if (RP->layoutoptions2)
731 { 735 {
732 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2); 736 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2);
733 strcat (buf, small_buf); 737 strcat (buf, small_buf);
734 } 738 }
735 739
736
737 if (RP->layoutoptions3) 740 if (RP->layoutoptions3)
738 { 741 {
739 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3); 742 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3);
740 strcat (buf, small_buf); 743 strcat (buf, small_buf);
741 } 744 }
743 if (RP->symmetry) 746 if (RP->symmetry)
744 { 747 {
745 sprintf (small_buf, "symmetry %d\n", RP->symmetry); 748 sprintf (small_buf, "symmetry %d\n", RP->symmetry);
746 strcat (buf, small_buf); 749 strcat (buf, small_buf);
747 } 750 }
748
749 751
750 if (RP->difficulty && RP->difficulty_given) 752 if (RP->difficulty && RP->difficulty_given)
751 { 753 {
752 sprintf (small_buf, "difficulty %d\n", RP->difficulty); 754 sprintf (small_buf, "difficulty %d\n", RP->difficulty);
753 strcat (buf, small_buf); 755 strcat (buf, small_buf);
789 if (RP->origin_y) 791 if (RP->origin_y)
790 { 792 {
791 sprintf (small_buf, "origin_y %d\n", RP->origin_y); 793 sprintf (small_buf, "origin_y %d\n", RP->origin_y);
792 strcat (buf, small_buf); 794 strcat (buf, small_buf);
793 } 795 }
796
797 if (RP->treasureoptions)
798 {
799 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
800 strcat (buf, small_buf);
801 }
802
794 if (RP->random_seed) 803 if (RP->random_seed)
795 { 804 {
796 /* Add one so that the next map is a bit different */
797 sprintf (small_buf, "random_seed %d\n", RP->random_seed + 1); 805 sprintf (small_buf, "random_seed %u\n", RP->random_seed);
798 strcat (buf, small_buf); 806 strcat (buf, small_buf);
799 }
800
801 if (RP->treasureoptions)
802 { 807 }
803 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions); 808
804 strcat (buf, small_buf); 809 if (RP->custom)
805 } 810 {
806 811 sprintf (small_buf, "custom %s\n", RP->custom);
807 812 strcat (buf, small_buf);
813 }
808} 814}
809 815
810void 816void
811write_parameters_to_string (char *buf, 817write_parameters_to_string (char *buf,
812 int xsize_n, 818 int xsize_n,
813 int ysize_n, 819 int ysize_n,
814 char *wallstyle_n, 820 const char *wallstyle_n,
815 char *floorstyle_n, 821 const char *floorstyle_n,
816 char *monsterstyle_n, 822 const char *monsterstyle_n,
817 char *treasurestyle_n, 823 const char *treasurestyle_n,
818 char *layoutstyle_n, 824 const char *layoutstyle_n,
819 char *decorstyle_n, 825 const char *decorstyle_n,
820 char *doorstyle_n, 826 const char *doorstyle_n,
821 char *exitstyle_n, 827 const char *exitstyle_n,
822 char *final_map_n, 828 const char *final_map_n,
823 char *exit_on_final_map_n, 829 const char *exit_on_final_map_n,
824 char *this_map_n, 830 const char *this_map_n,
825 int layoutoptions1_n, 831 int layoutoptions1_n,
826 int layoutoptions2_n, 832 int layoutoptions2_n,
827 int layoutoptions3_n, 833 int layoutoptions3_n,
828 int symmetry_n, 834 int symmetry_n,
829 int dungeon_depth_n, 835 int dungeon_depth_n,
830 int dungeon_level_n, 836 int dungeon_level_n,
831 int difficulty_n, 837 int difficulty_n,
832 int difficulty_given_n, 838 int difficulty_given_n,
833 int decoroptions_n, 839 int decoroptions_n,
834 int orientation_n, 840 int orientation_n,
835 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) 841 int origin_x_n,
842 int origin_y_n,
843 uint32_t random_seed_n,
844 int treasureoptions_n,
845 float difficulty_increase)
836{ 846{
837
838 char small_buf[256]; 847 char small_buf[16384];
839 848
840 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); 849 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
841 850
842 if (wallstyle_n && wallstyle_n[0]) 851 if (wallstyle_n && wallstyle_n[0])
843 { 852 {
908 if (layoutoptions1_n) 917 if (layoutoptions1_n)
909 { 918 {
910 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n); 919 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n);
911 strcat (buf, small_buf); 920 strcat (buf, small_buf);
912 } 921 }
913
914 922
915 if (layoutoptions2_n) 923 if (layoutoptions2_n)
916 { 924 {
917 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n); 925 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n);
918 strcat (buf, small_buf); 926 strcat (buf, small_buf);
974 if (origin_y_n) 982 if (origin_y_n)
975 { 983 {
976 sprintf (small_buf, "origin_y %d\n", origin_y_n); 984 sprintf (small_buf, "origin_y %d\n", origin_y_n);
977 strcat (buf, small_buf); 985 strcat (buf, small_buf);
978 } 986 }
987
979 if (random_seed_n) 988 if (random_seed_n)
980 { 989 {
981 /* Add one so that the next map is a bit different */ 990 /* Add one so that the next map is a bit different */
982 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1); 991 sprintf (small_buf, "random_seed %u\n", random_seed_n + 1);
983 strcat (buf, small_buf); 992 strcat (buf, small_buf);
984 } 993 }
985 994
986 if (treasureoptions_n) 995 if (treasureoptions_n)
987 { 996 {
988 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n); 997 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n);
989 strcat (buf, small_buf); 998 strcat (buf, small_buf);
990 } 999 }
991
992
993} 1000}
994 1001
995/* copy an object with an inventory... i.e., duplicate the inv too. */ 1002/* copy an object with an inventory... i.e., duplicate the inv too. */
996void 1003void
997copy_object_with_inv (object *src_ob, object *dest_ob) 1004copy_object_with_inv (object *src_ob, object *dest_ob)
998{ 1005{
999 object *walk, *tmp; 1006 object *walk, *tmp;
1000 1007
1001 copy_object (src_ob, dest_ob); 1008 src_ob->copy_to (dest_ob);
1002 1009
1003 for (walk = src_ob->inv; walk != NULL; walk = walk->below) 1010 for (walk = src_ob->inv; walk; walk = walk->below)
1004 { 1011 {
1005 tmp = get_object (); 1012 tmp = object::create ();
1006 copy_object (walk, tmp); 1013
1014 walk->copy_to (tmp);
1007 insert_ob_in_ob (tmp, dest_ob); 1015 insert_ob_in_ob (tmp, dest_ob);
1008 } 1016 }
1009} 1017}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines