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.10 by root, Sun May 4 14:12:37 2008 UTC vs.
Revision 1.24 by root, Sat Nov 17 23:40:02 2018 UTC

1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
6 * Copyright (©) 1994-2004 Crossfire Development Team (restored, original file without copyright notice)
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>
23 */
1 24
2/* generate a rogue/nethack-like layout */ 25/* generate a rogue/nethack-like maze */
3#include <global.h> 26#include <global.h>
4#include <random_map.h>
5#include <math.h> 27#include <rmg.h>
28#include <rproto.h>
6 29
7typedef struct 30typedef struct
8{ 31{
9 int x; 32 int x;
10 int y; /* coordinates of room centers */ 33 int y; /* coordinates of room centers */
16 int rtype; /* circle or rectangular */ 39 int rtype; /* circle or rectangular */
17} Room; 40} Room;
18 41
19static int roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms); 42static int roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms);
20static void roguelike_make_rooms (Room *rooms, char **maze, int options); 43static void roguelike_make_rooms (Room *rooms, char **maze, int options);
21static void roguelike_link_rooms (Room *rooms, char **maze, int xsize, int ysize); 44static void roguelike_link_rooms (Room *rooms, layout &maze);
22 45
23int 46int
24surround_check (char **layout, int i, int j, int Xsize, int Ysize) 47surround_check (layout &maze, int i, int j)
25{ 48{
26 /* 1 = wall to left, 49 /* 1 = wall to left,
27 2 = wall to right, 50 2 = wall to right,
28 4 = wall above 51 4 = wall above
29 8 = wall below */ 52 8 = wall below */
30 int surround_index = 0; 53 int surround_index = 0;
31 54
32 if ((i > 0) && (layout[i - 1][j] != 0 && layout[i - 1][j] != '.')) surround_index |= 1; 55 if ((i > 0) && (maze[i - 1][j] != 0 && maze[i - 1][j] != '.')) surround_index |= 1;
33 if ((i < Xsize - 1) && (layout[i + 1][j] != 0 && layout[i + 1][j] != '.')) surround_index |= 2; 56 if ((i < maze.w - 1) && (maze[i + 1][j] != 0 && maze[i + 1][j] != '.')) surround_index |= 2;
34 if ((j > 0) && (layout[i][j - 1] != 0 && layout[i][j - 1] != '.')) surround_index |= 4; 57 if ((j > 0) && (maze[i][j - 1] != 0 && maze[i][j - 1] != '.')) surround_index |= 4;
35 if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.')) surround_index |= 8; 58 if ((j < maze.h - 1) && (maze[i][j + 1] != 0 && maze[i][j + 1] != '.')) surround_index |= 8;
36 59
37 return surround_index; 60 return surround_index;
38} 61}
39 62
40/* actually make the layout: we work by a reduction process: 63/* actually make the maze: we work by a reduction process:
41 * first we make everything a wall, then we remove areas to make rooms 64 * first we make everything a wall, then we remove areas to make rooms
42 */ 65 */
43void 66void
44roguelike_layout_gen (Layout maze, int options) 67roguelike_layout_gen (layout &maze, int options)
45{ 68{
46 int i, j; 69 int i, j;
47 Room *walk; 70 Room *walk;
48 int nrooms = 0; 71 int nrooms = 0;
49 int tries = 0; 72 int tries = 0;
50 73
51 int xsize = maze->w; 74 int xsize = maze.w;
52 int ysize = maze->h; 75 int ysize = maze.h;
53 76
54 /* minimum room size is basically 5x5: if xsize/ysize is 77 /* minimum room size is basically 5x5: if xsize/ysize is
55 less than 3x that then hollow things out, stick in 78 less than 3x that then hollow things out, stick in
56 a stairsup and stairs down, and exit */ 79 a stairsup and stairs down, and exit */
57 if (xsize < 11 || ysize < 11) 80 if (xsize < 11 || ysize < 11)
58 { 81 {
59 maze->clear (); 82 maze.clear ();
60 maze->border (); 83 maze.border ();
61 84
62 maze[(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; 85 maze[(xsize - 1) / 2][(ysize - 1) / 2 ] = '>';
63 maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; 86 maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<';
64 87
65 return; 88 return;
66 } 89 }
67 90
68 maze->clear ('#'); 91 maze.fill ('#');
69 92
70 /* decide on the number of rooms */ 93 /* decide on the number of rooms */
71 nrooms = rmg_rndm (10) + 6; 94 nrooms = rmg_rndm (10) + 6;
72 Room *rooms = salloc0<Room> (nrooms + 1); 95 Room *rooms = salloc0<Room> (nrooms + 1);
73 96
82 i++; 105 i++;
83 } 106 }
84 107
85 if (i == 0) /* no can do! */ 108 if (i == 0) /* no can do! */
86 { 109 {
87 maze->clear (); 110 maze.clear ();
88 maze->border (); 111 maze.border ();
89 112
90 maze [(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; 113 maze [(xsize - 1) / 2][(ysize - 1) / 2 ] = '>';
91 maze [(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; 114 maze [(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<';
92 115
93 sfree (rooms, nrooms + 1); 116 sfree (rooms, nrooms + 1);
95 } 118 }
96 119
97 /* erase the areas occupied by the rooms */ 120 /* erase the areas occupied by the rooms */
98 roguelike_make_rooms (rooms, maze, options); 121 roguelike_make_rooms (rooms, maze, options);
99 122
100 roguelike_link_rooms (rooms, maze, xsize, ysize); 123 roguelike_link_rooms (rooms, maze);
101 124
102 /* put in the stairs */ 125 /* put in the stairs */
103 126
104 maze[rooms->x][rooms->y] = '<'; 127 maze[rooms->x][rooms->y] = '<';
105 128
132 if (maze[i][j] == '.') 155 if (maze[i][j] == '.')
133 maze[i][j] = 0; 156 maze[i][j] = 0;
134 157
135 if (maze[i][j] == 'D') 158 if (maze[i][j] == 'D')
136 { /* remove bad door. */ 159 { /* remove bad door. */
137 int si = surround_check (maze, i, j, xsize, ysize); 160 int si = surround_check (maze, i, j);
138 161
139 if (si != 3 && si != 12) 162 if (si != 3 && si != 12)
140 { 163 {
141 maze[i][j] = 0; 164 maze[i][j] = 0;
142 /* back up and recheck any nearby doors */ 165 /* back up and recheck any nearby doors */
168 ty = rmg_rndm (ysize); 191 ty = rmg_rndm (ysize);
169 192
170 /* generate a distribution of sizes centered about basesize */ 193 /* generate a distribution of sizes centered about basesize */
171 sx = rmg_rndm (x_basesize) + rmg_rndm (x_basesize) + rmg_rndm (x_basesize); 194 sx = rmg_rndm (x_basesize) + rmg_rndm (x_basesize) + rmg_rndm (x_basesize);
172 sy = rmg_rndm (y_basesize) + rmg_rndm (y_basesize) + rmg_rndm (y_basesize); 195 sy = rmg_rndm (y_basesize) + rmg_rndm (y_basesize) + rmg_rndm (y_basesize);
173 sy = (int) (sy * .5); /* renormalize */ 196 sy >>= 1; /* renormalize */
174 197
175 /* find the corners */ 198 /* find the corners */
176 ax = tx - sx / 2; 199 ax = tx - sx / 2;
177 zx = tx + sx / 2 + sx % 2; 200 zx = tx + sx / 2 + sx % 2;
178 201
198 } 221 }
199 222
200 /* if we've got here, presumably the room is OK. */ 223 /* if we've got here, presumably the room is OK. */
201 224
202 /* get a pointer to the first free room */ 225 /* get a pointer to the first free room */
203 for (walk = rooms; walk->x != 0; walk++) 226 for (walk = rooms; walk->x; walk++)
204 ; 227 ;
205 228
206 walk->x = tx; 229 walk->x = tx;
207 walk->y = ty; 230 walk->y = ty;
208 walk->sx = sx; 231 walk->sx = sx;
209 walk->sy = sy; 232 walk->sy = sy;
210 walk->ax = ax; 233 walk->ax = ax;
211 walk->ay = ay; 234 walk->ay = ay;
212 walk->zx = zx; 235 walk->zx = zx;
218/* write all the rooms into the maze */ 241/* write all the rooms into the maze */
219static void 242static void
220roguelike_make_rooms (Room *rooms, char **maze, int options) 243roguelike_make_rooms (Room *rooms, char **maze, int options)
221{ 244{
222 int making_circle = 0; 245 int making_circle = 0;
223 int i, j;
224 int R; 246 int R;
225 Room *walk; 247 Room *walk;
226 248
227 for (walk = rooms; walk->x != 0; walk++) 249 for (walk = rooms; walk->x; walk++)
228 { 250 {
229 /* first decide what shape to make */ 251 /* first decide what shape to make */
230 switch (options) 252 switch (options)
231 { 253 {
232 case 1: 254 case 1:
244 R = walk->sx / 2; 266 R = walk->sx / 2;
245 else 267 else
246 R = walk->sy / 2; 268 R = walk->sy / 2;
247 269
248 /* enscribe a rectangle */ 270 /* enscribe a rectangle */
249 for (i = walk->ax; i < walk->zx; i++) 271 for (int i = walk->ax; i < walk->zx; i++)
250 for (j = walk->ay; j < walk->zy; j++) 272 for (int j = walk->ay; j < walk->zy; j++)
251 if (!making_circle || ((int) (0.5 + hypot (walk->x - i, walk->y - j))) <= R) 273 if (!making_circle || ((int) (0.5 + hypot (walk->x - i, walk->y - j))) <= R)
252 maze[i][j] = '.'; 274 maze[i][j] = '.';
253 } 275 }
254} 276}
255 277
256static void 278static void
257roguelike_link_rooms (Room *rooms, char **maze, int xsize, int ysize) 279roguelike_link_rooms (Room *rooms, layout &maze)
258{ 280{
259 Room *walk; 281 Room *walk;
260 int i, j; 282 int i, j;
261 283
262 /* link each room to the previous room */ 284 /* link each room to the previous room */
301 maze[i - 1][j] = 'D'; 323 maze[i - 1][j] = 'D';
302 } 324 }
303 else if (maze[i][j] != 'D' && maze[i][j] != '.') 325 else if (maze[i][j] != 'D' && maze[i][j] != '.')
304 maze[i][j] = 0; 326 maze[i][j] = 0;
305 } 327 }
328
306 j = MIN (y1, y2); 329 j = min (y1, y2);
330
307 if (maze[i][j] == '.') 331 if (maze[i][j] == '.')
308 in_wall = 0; 332 in_wall = 0;
333
309 if (maze[i][j] == 0 || maze[i][j] == '#') 334 if (maze[i][j] == 0 || maze[i][j] == '#')
310 in_wall = 1; 335 in_wall = 1;
336
311 for ( /* j set already */ ; j < MAX (y1, y2); j++) 337 for ( /* j set already */ ; j < max (y1, y2); j++)
312 { 338 {
313 if (in_wall == 0 && maze[i][j] == '#') 339 if (in_wall == 0 && maze[i][j] == '#')
314 { 340 {
315 in_wall = 1; 341 in_wall = 1;
316 maze[i][j] = 'D'; 342 maze[i][j] = 'D';
354 } 380 }
355 else if (maze[i][j] != 'D' && maze[i][j] != '.') 381 else if (maze[i][j] != 'D' && maze[i][j] != '.')
356 maze[i][j] = 0; 382 maze[i][j] = 0;
357 } 383 }
358 384
359 i = MIN (x1, x2); 385 i = min (x1, x2);
386
360 if (maze[i][j] == '.') 387 if (maze[i][j] == '.')
361 in_wall = 0; 388 in_wall = 0;
389
362 if (maze[i][j] == 0 || maze[i][j] == '#') 390 if (maze[i][j] == 0 || maze[i][j] == '#')
363 in_wall = 1; 391 in_wall = 1;
392
364 for ( /* i set already */ ; i < MAX (x1, x2); i++) 393 for ( /* i set already */ ; i < max (x1, x2); i++)
365 { 394 {
366 if (in_wall == 0 && maze[i][j] == '#') 395 if (in_wall == 0 && maze[i][j] == '#')
367 { 396 {
368 in_wall = 1; 397 in_wall = 1;
369 maze[i][j] = 'D'; 398 maze[i][j] = 'D';

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines