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.18 by root, Sat Jul 3 13:39:04 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
811 else 776 else
812 make_wall (*this, dx, dy, 1); 777 make_wall (*this, dx, dy, 1);
813 } 778 }
814} 779}
815 780
781//-GPL
782
816///////////////////////////////////////////////////////////////////////////// 783/////////////////////////////////////////////////////////////////////////////
784
785// inspired mostly by http://www.jimrandomh.org/misc/caves.txt
786void
787layout::gen_cave (int subtype)
788{
789 switch (subtype)
790 {
791 // a rough cave
792 case 0:
793 fill_rand (rmg_rndm (85, 97));
794 break;
795
796 // corridors
797 case 1:
798 fill_rand (rmg_rndm (5, 40));
799 erode_1_2 (5, 2, 10);
800 erode_1_2 (5, -1, 10);
801 erode_1_2 (5, 2, 1);
802 break;
803
804 // somewhat open, roundish
805 case 2:
806 fill_rand (45);
807 erode_1_2 (5, 0, 5);
808 erode_1_2 (5, 1, 1);
809 break;
810
811 // wide open, some room-like structures
812 case 3:
813 fill_rand (45);
814 erode_1_2 (5, 2, 4);
815 erode_1_2 (5, -1, 3);
816 break;
817 }
818
819 border ();
820 isolation_remover ();
821}
822
823void
824layout::gen_castle ()
825{
826 fill ('#');
827
828 for (int n = w * h / 30 + 1; n--; )
829 {
830 int rw = rmg_rndm (6, 10);
831 int rh = rmg_rndm (6, 10);
832
833 int rx = rmg_rndm (0, w - rw);
834 int ry = rmg_rndm (0, h - rh);
835
836 rect (rx, ry, rx + rw, ry + rh, '#');
837 fill_rect (rx + 1, ry + 1, rx + rw - 1, ry + rh - 1, 0);
838 }
839
840 border ();
841 isolation_remover (0);
842}
817 843
818static void 844static void
819gen_mixed_ (layout &maze, random_map_params *RP, int dir) 845gen_mixed_ (layout &maze, random_map_params *RP, int dir)
820{ 846{
821 if (maze.w < 20 && maze.h < 20 && !rmg_rndm (3)) 847 if (maze.w < 20 && maze.h < 20 && !rmg_rndm (3))
844 870
845 maze.generate (RP); 871 maze.generate (RP);
846 } 872 }
847} 873}
848 874
875// recursive subdivision with random sublayouts
849static void 876static void
850gen_mixed (layout &maze, random_map_params *RP) 877gen_mixed (layout &maze, random_map_params *RP)
851{ 878{
852 random_map_params &rp = *new random_map_params (RP); 879 random_map_params &rp = *new random_map_params (RP);
853 gen_mixed_ (maze, &rp, rmg_rndm (2)); 880 gen_mixed_ (maze, &rp, rmg_rndm (2));
854 delete &rp; 881 delete &rp;
855 882
856 maze.border (); 883 maze.border ();
857 maze.isolation_remover (); 884 maze.isolation_remover ();
858} 885}
886
887//+GPL
859 888
860/* function selects the maze function and gives it whatever 889/* function selects the maze function and gives it whatever
861 arguments it needs. */ 890 arguments it needs. */
862void 891void
863layout::generate (random_map_params *RP) 892layout::generate (random_map_params *RP)
923 if (rmg_rndm (2)) 952 if (rmg_rndm (2))
924 doorify (); 953 doorify ();
925 954
926 break; 955 break;
927 956
957 case LAYOUT_CASTLE:
958 gen_castle ();
959
960 if (rmg_rndm (2))
961 doorify ();
962
963 break;
964
928 case LAYOUT_MULTIPLE: 965 case LAYOUT_MULTIPLE:
929 gen_mixed (*this, RP); 966 gen_mixed (*this, RP);
930 break; 967 break;
931 968
932 default: 969 default:
944 rmg_rndm.seed (time (0)); 981 rmg_rndm.seed (time (0));
945 982
946 for(int i=1;i<100;i++) 983 for(int i=1;i<100;i++)
947 { 984 {
948 layout maze (40, 25); 985 layout maze (40, 25);
949 maze.fill_rand (85); 986 maze.gen_castle ();
950 maze.border (); 987 maze.doorify ();
951 maze.isolation_remover ();
952 maze.print (); 988 maze.print ();
989 exit(0);
953 } 990 }
954 991
955 exit (1); 992 exit (1);
956 } 993 }
957} demo; 994} demo;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines