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.16 by root, Sat Jul 3 11:52:11 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)
809 break; 814 break;
810 } 815 }
811 816
812 border (); 817 border ();
813 isolation_remover (); 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);
814} 840}
815 841
816static void 842static void
817gen_mixed_ (layout &maze, random_map_params *RP, int dir) 843gen_mixed_ (layout &maze, random_map_params *RP, int dir)
818{ 844{
922 if (rmg_rndm (2)) 948 if (rmg_rndm (2))
923 doorify (); 949 doorify ();
924 950
925 break; 951 break;
926 952
953 case LAYOUT_CASTLE:
954 gen_castle ();
955
956 if (rmg_rndm (2))
957 doorify ();
958
959 break;
960
927 case LAYOUT_MULTIPLE: 961 case LAYOUT_MULTIPLE:
928 gen_mixed (*this, RP); 962 gen_mixed (*this, RP);
929 break; 963 break;
930 964
931 default: 965 default:
943 rmg_rndm.seed (time (0)); 977 rmg_rndm.seed (time (0));
944 978
945 for(int i=1;i<100;i++) 979 for(int i=1;i<100;i++)
946 { 980 {
947 layout maze (40, 25); 981 layout maze (40, 25);
948 maze.fill_rand (85); 982 maze.gen_castle ();
949 maze.border (); 983 maze.doorify ();
950 maze.isolation_remover ();
951 maze.print (); 984 maze.print ();
985 exit(0);
952 } 986 }
953 987
954 exit (1); 988 exit (1);
955 } 989 }
956} demo; 990} demo;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines