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

Comparing deliantra/server/random_maps/rogue_layout.C (file contents):
Revision 1.7 by root, Fri Apr 11 21:09:53 2008 UTC vs.
Revision 1.13 by root, Wed Jun 30 20:51:02 2010 UTC

1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 *
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) Crossfire Development Team (restored, original file without copyright notice)
6 *
7 * Deliantra is free software: you can redistribute it and/or modify it under
8 * the terms of the Affero GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the Affero GNU General Public License
18 * and the GNU General Public License along with this program. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <support@deliantra.net>
22 */
1 23
2/* generate a rogue/nethack-like layout */ 24/* generate a rogue/nethack-like layout */
3#include <global.h> 25#include <global.h>
4#include <random_map.h> 26#include <random_map.h>
5#include <math.h> 27#include <rproto.h>
6 28
7typedef struct 29typedef struct
8{ 30{
9 int x; 31 int x;
10 int y; /* coordinates of room centers */ 32 int y; /* coordinates of room centers */
27 2 = wall to right, 49 2 = wall to right,
28 4 = wall above 50 4 = wall above
29 8 = wall below */ 51 8 = wall below */
30 int surround_index = 0; 52 int surround_index = 0;
31 53
32 if ((i > 0) && (layout[i - 1][j] != 0 && layout[i - 1][j] != '.')) 54 if ((i > 0) && (layout[i - 1][j] != 0 && layout[i - 1][j] != '.')) surround_index |= 1;
33 surround_index += 1;
34 if ((i < Xsize - 1) && (layout[i + 1][j] != 0 && layout[i + 1][j] != '.')) 55 if ((i < Xsize - 1) && (layout[i + 1][j] != 0 && layout[i + 1][j] != '.')) surround_index |= 2;
35 surround_index += 2;
36 if ((j > 0) && (layout[i][j - 1] != 0 && layout[i][j - 1] != '.')) 56 if ((j > 0) && (layout[i][j - 1] != 0 && layout[i][j - 1] != '.')) surround_index |= 4;
37 surround_index += 4;
38 if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.')) 57 if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.')) surround_index |= 8;
39 surround_index += 8; 58
40 return surround_index; 59 return surround_index;
41} 60}
42 61
43/* actually make the layout: we work by a reduction process: 62/* actually make the layout: we work by a reduction process:
44 * first we make everything a wall, then we remove areas to make rooms 63 * first we make everything a wall, then we remove areas to make rooms
45 */ 64 */
46Maze 65void
47roguelike_layout_gen (int xsize, int ysize, int options) 66roguelike_layout_gen (Layout maze, int options)
48{ 67{
49 int i, j; 68 int i, j;
50 Room *walk; 69 Room *walk;
51 int nrooms = 0; 70 int nrooms = 0;
52 int tries = 0; 71 int tries = 0;
53 72
54 Maze maze (xsize, ysize); 73 int xsize = maze->w;
55 74 int ysize = maze->h;
56 for (i = 0; i < xsize; i++)
57 for (j = 0; j < ysize; j++)
58 maze[i][j] = '#';
59 75
60 /* minimum room size is basically 5x5: if xsize/ysize is 76 /* minimum room size is basically 5x5: if xsize/ysize is
61 less than 3x that then hollow things out, stick in 77 less than 3x that then hollow things out, stick in
62 a stairsup and stairs down, and exit */ 78 a stairsup and stairs down, and exit */
63
64 if (xsize < 11 || ysize < 11) 79 if (xsize < 11 || ysize < 11)
65 { 80 {
66 for (i = 1; i < xsize - 1; i++) 81 maze->clear ();
67 for (j = 1; j < ysize - 1; j++) 82 maze->border ();
68 maze[i][j] = 0;
69 83
70 maze[(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; 84 maze[(xsize - 1) / 2][(ysize - 1) / 2 ] = '>';
71 maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; 85 maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<';
72 86
73 return maze; 87 return;
74 } 88 }
89
90 maze->fill ('#');
75 91
76 /* decide on the number of rooms */ 92 /* decide on the number of rooms */
77 nrooms = rndm (10) + 6; 93 nrooms = rmg_rndm (10) + 6;
78 Room *rooms = salloc0<Room> (nrooms + 1); 94 Room *rooms = salloc0<Room> (nrooms + 1);
79 95
80 /* actually place the rooms */ 96 /* actually place the rooms */
81 i = 0; 97 i = 0;
82 while (tries < 450 && i < nrooms) 98 while (tries < 450 && i < nrooms)
86 tries++; 102 tries++;
87 else 103 else
88 i++; 104 i++;
89 } 105 }
90 106
91 if (i == 0) 107 if (i == 0) /* no can do! */
92 { /* no can do! */ 108 {
93 for (i = 1; i < xsize - 1; i++) 109 maze->clear ();
94 for (j = 1; j < ysize - 1; j++) 110 maze->border ();
95 maze[i][j] = 0;
96 111
97 maze [(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; 112 maze [(xsize - 1) / 2][(ysize - 1) / 2 ] = '>';
98 maze [(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; 113 maze [(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<';
99 114
100 sfree (rooms, nrooms + 1); 115 sfree (rooms, nrooms + 1);
101 return maze; 116 return;
102 } 117 }
103
104 118
105 /* erase the areas occupied by the rooms */ 119 /* erase the areas occupied by the rooms */
106 roguelike_make_rooms (rooms, maze, options); 120 roguelike_make_rooms (rooms, maze, options);
107 121
108 roguelike_link_rooms (rooms, maze, xsize, ysize); 122 roguelike_link_rooms (rooms, maze, xsize, ysize);
153 } 167 }
154 } 168 }
155 } 169 }
156 170
157 sfree (rooms, nrooms + 1); 171 sfree (rooms, nrooms + 1);
158 return maze;
159} 172}
160 173
161static int 174static int
162roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms) 175roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms)
163{ 176{
171 184
172 /* decide on the base x and y sizes */ 185 /* decide on the base x and y sizes */
173 x_basesize = xsize / isqrt (nrooms); 186 x_basesize = xsize / isqrt (nrooms);
174 y_basesize = ysize / isqrt (nrooms); 187 y_basesize = ysize / isqrt (nrooms);
175 188
176 tx = rndm (xsize); 189 tx = rmg_rndm (xsize);
177 ty = rndm (ysize); 190 ty = rmg_rndm (ysize);
178 191
179 /* generate a distribution of sizes centered about basesize */ 192 /* generate a distribution of sizes centered about basesize */
180 sx = rndm (x_basesize) + rndm (x_basesize) + rndm (x_basesize); 193 sx = rmg_rndm (x_basesize) + rmg_rndm (x_basesize) + rmg_rndm (x_basesize);
181 sy = rndm (y_basesize) + rndm (y_basesize) + rndm (y_basesize); 194 sy = rmg_rndm (y_basesize) + rmg_rndm (y_basesize) + rmg_rndm (y_basesize);
182 sy = (int) (sy * .5); /* renormalize */ 195 sy = (int) (sy * .5); /* renormalize */
183 196
184 /* find the corners */ 197 /* find the corners */
185 ax = tx - sx / 2; 198 ax = tx - sx / 2;
186 zx = tx + sx / 2 + sx % 2; 199 zx = tx + sx / 2 + sx % 2;
243 break; 256 break;
244 case 2: 257 case 2:
245 making_circle = 1; 258 making_circle = 1;
246 break; 259 break;
247 default: 260 default:
248 making_circle = ((rndm (3) == 0) ? 1 : 0); 261 making_circle = ((rmg_rndm (3) == 0) ? 1 : 0);
249 break; 262 break;
250 } 263 }
251 264
252 if (walk->sx < walk->sy) 265 if (walk->sx < walk->sy)
253 R = walk->sx / 2; 266 R = walk->sx / 2;
278 int y1 = walk->y; 291 int y1 = walk->y;
279 int x2 = (walk - 1)->x; 292 int x2 = (walk - 1)->x;
280 int y2 = (walk - 1)->y; 293 int y2 = (walk - 1)->y;
281 int in_wall = 0; 294 int in_wall = 0;
282 295
283 if (rndm (2)) 296 if (rmg_rndm (2))
284 { /* connect in x direction first */ 297 { /* connect in x direction first */
285 /* horizontal connect */ 298 /* horizontal connect */
286 /* swap (x1,y1) (x2,y2) if necessary */ 299 /* swap (x1,y1) (x2,y2) if necessary */
287 300
288 if (x2 < x1) 301 if (x2 < x1)
310 maze[i - 1][j] = 'D'; 323 maze[i - 1][j] = 'D';
311 } 324 }
312 else if (maze[i][j] != 'D' && maze[i][j] != '.') 325 else if (maze[i][j] != 'D' && maze[i][j] != '.')
313 maze[i][j] = 0; 326 maze[i][j] = 0;
314 } 327 }
328
315 j = MIN (y1, y2); 329 j = min (y1, y2);
330
316 if (maze[i][j] == '.') 331 if (maze[i][j] == '.')
317 in_wall = 0; 332 in_wall = 0;
333
318 if (maze[i][j] == 0 || maze[i][j] == '#') 334 if (maze[i][j] == 0 || maze[i][j] == '#')
319 in_wall = 1; 335 in_wall = 1;
336
320 for ( /* j set already */ ; j < MAX (y1, y2); j++) 337 for ( /* j set already */ ; j < max (y1, y2); j++)
321 { 338 {
322 if (in_wall == 0 && maze[i][j] == '#') 339 if (in_wall == 0 && maze[i][j] == '#')
323 { 340 {
324 in_wall = 1; 341 in_wall = 1;
325 maze[i][j] = 'D'; 342 maze[i][j] = 'D';
363 } 380 }
364 else if (maze[i][j] != 'D' && maze[i][j] != '.') 381 else if (maze[i][j] != 'D' && maze[i][j] != '.')
365 maze[i][j] = 0; 382 maze[i][j] = 0;
366 } 383 }
367 384
368 i = MIN (x1, x2); 385 i = min (x1, x2);
386
369 if (maze[i][j] == '.') 387 if (maze[i][j] == '.')
370 in_wall = 0; 388 in_wall = 0;
389
371 if (maze[i][j] == 0 || maze[i][j] == '#') 390 if (maze[i][j] == 0 || maze[i][j] == '#')
372 in_wall = 1; 391 in_wall = 1;
392
373 for ( /* i set already */ ; i < MAX (x1, x2); i++) 393 for ( /* i set already */ ; i < max (x1, x2); i++)
374 { 394 {
375 if (in_wall == 0 && maze[i][j] == '#') 395 if (in_wall == 0 && maze[i][j] == '#')
376 { 396 {
377 in_wall = 1; 397 in_wall = 1;
378 maze[i][j] = 'D'; 398 maze[i][j] = 'D';

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines