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.2 by root, Tue Aug 29 08:01:36 2006 UTC vs.
Revision 1.58 by root, Wed Jun 30 23:15:56 2010 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines