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

Comparing deliantra/server/random_maps/layout.C (file contents):
Revision 1.15 by root, Sat Jul 3 03:09:27 2010 UTC vs.
Revision 1.17 by root, Sat Jul 3 13:14:35 2010 UTC

221 if (x < dist.w - 1 && !dist [x + 1][y]) push_flood_fill (dist, seeds, x + 1, y); 221 if (x < dist.w - 1 && !dist [x + 1][y]) push_flood_fill (dist, seeds, x + 1, y);
222 } 222 }
223} 223}
224 224
225static inline void 225static inline void
226make_tunnel (layout &dist, pointlist &seeds, int x, int y, U8 d) 226make_tunnel (layout &dist, pointlist &seeds, int x, int y, U8 d, int perturb)
227{ 227{
228 for (;;) 228 for (;;)
229 { 229 {
230 point neigh[4]; 230 point neigh[4];
231 int ncnt = 0; 231 int ncnt = 0;
232 232
233 d += perturb > 1;
234
233 if (x > 0 && U8 (dist [x - 1][y]) <= d && dist [x - 1][y] > 1) neigh [ncnt++] = point (x - 1, y); 235 if (x > 0 && U8 (dist [x - 1][y]) < d && dist [x - 1][y] > 1) neigh [ncnt++] = point (x - 1, y);
234 if (x < dist.w - 1 && U8 (dist [x + 1][y]) <= d && dist [x + 1][y] > 1) neigh [ncnt++] = point (x + 1, y); 236 if (x < dist.w - 1 && U8 (dist [x + 1][y]) < d && dist [x + 1][y] > 1) neigh [ncnt++] = point (x + 1, y);
235 if (y > 0 && U8 (dist [x][y - 1]) <= d && dist [x][y - 1] > 1) neigh [ncnt++] = point (x, y - 1); 237 if (y > 0 && U8 (dist [x][y - 1]) < d && dist [x][y - 1] > 1) neigh [ncnt++] = point (x, y - 1);
236 if (y < dist.h - 1 && U8 (dist [x][y + 1]) <= d && dist [x][y + 1] > 1) neigh [ncnt++] = point (x, y + 1); 238 if (y < dist.h - 1 && U8 (dist [x][y + 1]) < d && dist [x][y + 1] > 1) neigh [ncnt++] = point (x, y + 1);
237 239
238 if (!ncnt) 240 if (!ncnt)
239 return; 241 return;
240 242
241 point &p = neigh [rmg_rndm (ncnt)]; 243 point &p = neigh [perturb ? rmg_rndm (ncnt) : 0];
242 244
243 seeds.push (p); 245 seeds.push (p);
244 246
245 x = p.x; 247 x = p.x;
246 y = p.y; 248 y = p.y;
264} 266}
265 267
266// isolation remover, works on a "distance" map 268// isolation remover, works on a "distance" map
267// the map must be initialised with 0 == rooms, 255 = walls 269// the map must be initialised with 0 == rooms, 255 = walls
268static void noinline 270static void noinline
269isolation_remover (layout &dist) 271isolation_remover (layout &dist, unsigned int perturb = 2)
270{ 272{
271 // dist contains 273 // dist contains
272 // 0 == invisited rooms 274 // 0 == invisited rooms
273 // 1 == visited rooms 275 // 1 == visited rooms
274 // 2+ shortest distance to random near room 276 // 2+ shortest distance to random near room
275 277
278 max_it (perturb, 0);
279 min_it (perturb, 2);
280
276 // phase 1, find seed 281 // phase 1, find seed
277 int cnt = 0; 282 int cnt = 0;
278 int x, y; 283 int x, y;
279 284
280 for (int i = 0; i < dist.w; ++i) 285 for (int i = 0; i < dist.w; ++i)
311 316
312 if (!dist [x][y]) 317 if (!dist [x][y])
313 { 318 {
314 // found new isolated area, make tunnel 319 // found new isolated area, make tunnel
315 push_flood_fill (dist, seeds, x, y); 320 push_flood_fill (dist, seeds, x, y);
316 make_tunnel (dist, seeds, x, y, 255); 321 make_tunnel (dist, seeds, x, y, 254, perturb);
317 } 322 }
318 else 323 else
319 { 324 {
320 // nothing here, continue to expand 325 // nothing here, continue to expand
321 U8 d = U8 (dist [x][y]) + 1; 326 U8 d = U8 (dist [x][y]) + 1;
327 } 332 }
328 } 333 }
329} 334}
330 335
331void 336void
332layout::isolation_remover () 337layout::isolation_remover (int perturb)
333{ 338{
334 layout dist (w - 2, h - 2); // map without border 339 layout dist (w - 2, h - 2); // map without border
335 340
336 for (int x = 1; x < w - 1; ++x) 341 for (int x = 1; x < w - 1; ++x)
337 for (int y = 1; y < h - 1; ++y) 342 for (int y = 1; y < h - 1; ++y)
338 dist [x - 1][y - 1] = data [x][y] == '#' ? U8 (255) : 0; 343 dist [x - 1][y - 1] = data [x][y] == '#' ? U8 (255) : 0;
339 344
340 ::isolation_remover (dist); 345 ::isolation_remover (dist, perturb);
341 346
342 // now copy the tunnels over 347 // now copy the tunnels over
343 for (int x = 1; x < w - 1; ++x) 348 for (int x = 1; x < w - 1; ++x)
344 for (int y = 1; y < h - 1; ++y) 349 for (int y = 1; y < h - 1; ++y)
345 if (data [x][y] == '#' && dist [x - 1][y - 1] == 1) 350 if (data [x][y] == '#' && dist [x - 1][y - 1] == 1)
346 data [x][y] = 0; 351 data [x][y] = 0;
347}
348
349/////////////////////////////////////////////////////////////////////////////
350
351// inspired mostly by http://www.jimrandomh.org/misc/caves.txt
352void
353layout::gen_cave (int subtype)
354{
355 switch (subtype)
356 {
357 // a rough cave
358 case 0:
359 fill_rand (rmg_rndm (85, 97));
360 break;
361
362 // corridors
363 case 1:
364 fill_rand (rmg_rndm (5, 40));
365 erode_1_2 (5, 2, 10);
366 erode_1_2 (5, -1, 10);
367 erode_1_2 (5, 2, 1);
368 break;
369
370 // somewhat open, roundish
371 case 2:
372 fill_rand (45);
373 erode_1_2 (5, 0, 5);
374 erode_1_2 (5, 1, 1);
375 break;
376
377 // wide open, some room-like structures
378 case 3:
379 fill_rand (45);
380 erode_1_2 (5, 2, 4);
381 erode_1_2 (5, -1, 3);
382 break;
383 }
384
385 border ();
386 isolation_remover ();
387} 352}
388 353
389///////////////////////////////////////////////////////////////////////////// 354/////////////////////////////////////////////////////////////////////////////
390 355
391//+GPL 356//+GPL
813 } 778 }
814} 779}
815 780
816///////////////////////////////////////////////////////////////////////////// 781/////////////////////////////////////////////////////////////////////////////
817 782
783// inspired mostly by http://www.jimrandomh.org/misc/caves.txt
784void
785layout::gen_cave (int subtype)
786{
787 switch (subtype)
788 {
789 // a rough cave
790 case 0:
791 fill_rand (rmg_rndm (85, 97));
792 break;
793
794 // corridors
795 case 1:
796 fill_rand (rmg_rndm (5, 40));
797 erode_1_2 (5, 2, 10);
798 erode_1_2 (5, -1, 10);
799 erode_1_2 (5, 2, 1);
800 break;
801
802 // somewhat open, roundish
803 case 2:
804 fill_rand (45);
805 erode_1_2 (5, 0, 5);
806 erode_1_2 (5, 1, 1);
807 break;
808
809 // wide open, some room-like structures
810 case 3:
811 fill_rand (45);
812 erode_1_2 (5, 2, 4);
813 erode_1_2 (5, -1, 3);
814 break;
815 }
816
817 border ();
818 isolation_remover ();
819}
820
821void
822layout::gen_castle ()
823{
824 fill ('#');
825
826 for (int n = w * h / 30 + 1; n--; )
827 {
828 int rw = rmg_rndm (6, 10);
829 int rh = rmg_rndm (6, 10);
830
831 int rx = rmg_rndm (0, w - rw);
832 int ry = rmg_rndm (0, h - rh);
833
834 rect (rx, ry, rx + rw, ry + rh, '#');
835 fill_rect (rx + 1, ry + 1, rx + rw - 1, ry + rh - 1, 0);
836 }
837
838 border ();
839 isolation_remover (0);
840}
841
818static void 842static void
819gen_mixed_ (layout &maze, random_map_params *RP, int dir) 843gen_mixed_ (layout &maze, random_map_params *RP, int dir)
820{ 844{
821 if (maze.w < 20 && maze.h < 20 && !rmg_rndm (3)) 845 if (maze.w < 20 && maze.h < 20 && !rmg_rndm (3))
822 dir = 2; // stop recursion randomly 846 dir = 2; // stop recursion randomly
844 868
845 maze.generate (RP); 869 maze.generate (RP);
846 } 870 }
847} 871}
848 872
873// recursive subdivision with random sublayouts
849static void 874static void
850gen_mixed (layout &maze, random_map_params *RP) 875gen_mixed (layout &maze, random_map_params *RP)
851{ 876{
852 random_map_params &rp = *new random_map_params (RP); 877 random_map_params &rp = *new random_map_params (RP);
853 gen_mixed_ (maze, &rp, rmg_rndm (2)); 878 gen_mixed_ (maze, &rp, rmg_rndm (2));
923 if (rmg_rndm (2)) 948 if (rmg_rndm (2))
924 doorify (); 949 doorify ();
925 950
926 break; 951 break;
927 952
953 case LAYOUT_CASTLE:
954 gen_castle ();
955
956 if (rmg_rndm (2))
957 doorify ();
958
959 break;
960
928 case LAYOUT_MULTIPLE: 961 case LAYOUT_MULTIPLE:
929 gen_mixed (*this, RP); 962 gen_mixed (*this, RP);
930 break; 963 break;
931 964
932 default: 965 default:
944 rmg_rndm.seed (time (0)); 977 rmg_rndm.seed (time (0));
945 978
946 for(int i=1;i<100;i++) 979 for(int i=1;i<100;i++)
947 { 980 {
948 layout maze (40, 25); 981 layout maze (40, 25);
949 maze.fill_rand (85); 982 maze.gen_castle ();
950 maze.border (); 983 maze.doorify ();
951 maze.isolation_remover ();
952 maze.print (); 984 maze.print ();
985 exit(0);
953 } 986 }
954 987
955 exit (1); 988 exit (1);
956 } 989 }
957} demo; 990} demo;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines