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

Comparing deliantra/server/common/los.C (file contents):
Revision 1.51 by root, Wed Dec 24 01:37:23 2008 UTC vs.
Revision 1.54 by root, Sat Dec 27 07:50:05 2008 UTC

101// still is basically the same algorithm. 101// still is basically the same algorithm.
102static void 102static void
103calculate_los (player *pl) 103calculate_los (player *pl)
104{ 104{
105 { 105 {
106 memset (los, 0, sizeof (los));
107
106 // we keep one line for ourselves, for the border flag 108 // we keep one line for ourselves, for the border flag
107 // so the client area is actually MAP_CLIENT_(X|Y) - 2 109 // so the client area is actually MAP_CLIENT_(X|Y) - 2
108 int half_x = min (LOS_X0 - 1, pl->ns->mapx / 2); 110 int half_x = min (LOS_X0 - 1, pl->ns->mapx / 2);
109 int half_y = min (LOS_Y0 - 1, pl->ns->mapy / 2); 111 int half_y = min (LOS_Y0 - 1, pl->ns->mapy / 2);
110 112
118 los [LOS_X0 + (half_x + 1)][dy + LOS_Y0].flags = FLG_QUEUED; 120 los [LOS_X0 + (half_x + 1)][dy + LOS_Y0].flags = FLG_QUEUED;
119 121
120 // now reset the los area and also add blocked flags 122 // now reset the los area and also add blocked flags
121 // which supposedly is faster than doing it inside the 123 // which supposedly is faster than doing it inside the
122 // spiral path algorithm below, except when very little 124 // spiral path algorithm below, except when very little
123 // area is visible, in which case it is slower, evening 125 // area is visible, in which case it is slower. which evens
124 // out los calculation times between large and small los maps. 126 // out los calculation times between large and small los maps.
125 // apply_lights also iterates over this area, maybe these 127 // apply_lights also iterates over this area, maybe these
126 // two passes could be combined somehow. 128 // two passes could be combined somehow.
127 rectangular_mapspace_iterate_begin (pl->observe, -half_x, half_x, -half_y, half_y) 129 unordered_mapwalk (pl->observe, -half_x, -half_y, half_x, half_y)
130 {
128 los_info &l = los [LOS_X0 + dx][LOS_Y0 + dy]; 131 los_info &l = los [LOS_X0 + dx][LOS_Y0 + dy];
129 l.flags = m && m->at (nx, ny).flags () & P_BLOCKSVIEW ? FLG_BLOCKED : 0; 132 l.flags = m->at (nx, ny).flags () & P_BLOCKSVIEW ? FLG_BLOCKED : 0;
130 rectangular_mapspace_iterate_end 133 }
131 } 134 }
132 135
133 q1 = 0; q2 = 0; // initialise queue, not strictly required 136 q1 = 0; q2 = 0; // initialise queue, not strictly required
134 enqueue (0, 0); // enqueue center 137 enqueue (0, 0); // enqueue center
135 138
361 int half_x = pl->ns->mapx / 2; 364 int half_x = pl->ns->mapx / 2;
362 int half_y = pl->ns->mapy / 2; 365 int half_y = pl->ns->mapy / 2;
363 366
364 int pass2 = 0; // negative lights have an extra pass 367 int pass2 = 0; // negative lights have an extra pass
365 368
369 maprect *rects = pl->observe->map->split_to_tiles (
370 pl->observe->x - half_x - MAX_LIGHT_RADIUS,
371 pl->observe->y - half_y - MAX_LIGHT_RADIUS,
372 pl->observe->x + half_x + MAX_LIGHT_RADIUS + 1,
373 pl->observe->y + half_y + MAX_LIGHT_RADIUS + 1
374 );
375
366 if (!darklevel) 376 if (!darklevel)
367 pass2 = 1; 377 pass2 = 1;
368 else 378 else
369 { 379 {
370 /* first, make everything totally dark */ 380 /* first, make everything totally dark */
376 * Only process the area of interest. 386 * Only process the area of interest.
377 * the basex, basey values represent the position in the op->contr->los 387 * the basex, basey values represent the position in the op->contr->los
378 * array. Its easier to just increment them here (and start with the right 388 * array. Its easier to just increment them here (and start with the right
379 * value) than to recalculate them down below. 389 * value) than to recalculate them down below.
380 */ 390 */
381 rectangular_mapspace_iterate_begin (pl->observe, -half_x - MAX_LIGHT_RADIUS, half_x + MAX_LIGHT_RADIUS, -half_y - MAX_LIGHT_RADIUS, half_y + MAX_LIGHT_RADIUS) 391 for (maprect *r = rects; r->m; ++r)
382 if (m) 392 rect_mapwalk (r, 0, 0)
383 { 393 {
384 mapspace &ms = m->at (nx, ny); 394 mapspace &ms = m->at (nx, ny);
385 ms.update (); 395 ms.update ();
386 sint8 light = ms.light; 396 sint8 light = ms.light;
387 397
388 if (expect_false (light)) 398 if (expect_false (light))
389 if (light < 0) 399 if (light < 0)
390 pass2 = 1; 400 pass2 = 1;
391 else 401 else
392 apply_light<los_brighten> (pl, dx, dy, light, light_atten [light + MAX_LIGHT_RADIUS]); 402 apply_light<los_brighten> (pl, dx - pl->observe->x, dy - pl->observe->y, light, light_atten [light + MAX_LIGHT_RADIUS]);
393 } 403 }
394 rectangular_mapspace_iterate_end
395 404
396 /* grant some vision to the player, based on the darklevel */ 405 /* grant some vision to the player, based on the darklevel */
397 { 406 {
398 int light = clamp (MAX_DARKNESS - darklevel, 0, MAX_DARKNESS); 407 int light = clamp (MAX_DARKNESS - darklevel, 0, MAX_DARKNESS);
399 408
407 416
408 // possibly do 2nd pass for rare negative glow radii 417 // possibly do 2nd pass for rare negative glow radii
409 // for effect, those are always considered to be stronger than anything else 418 // for effect, those are always considered to be stronger than anything else
410 // but they can't darken a place completely 419 // but they can't darken a place completely
411 if (pass2) 420 if (pass2)
412 rectangular_mapspace_iterate_begin (pl->observe, -half_x - MAX_LIGHT_RADIUS, half_x + MAX_LIGHT_RADIUS, -half_y - MAX_LIGHT_RADIUS, half_y + MAX_LIGHT_RADIUS) 421 for (maprect *r = rects; r->m; ++r)
413 if (m) 422 rect_mapwalk (r, 0, 0)
414 { 423 {
415 mapspace &ms = m->at (nx, ny); 424 mapspace &ms = m->at (nx, ny);
416 ms.update (); 425 ms.update ();
417 sint8 light = ms.light; 426 sint8 light = ms.light;
418 427
419 if (expect_false (light < 0)) 428 if (expect_false (light < 0))
420 apply_light<los_darken> (pl, dx, dy, -light, light_atten [light + MAX_LIGHT_RADIUS]); 429 apply_light<los_darken> (pl, dx - pl->observe->x, dy - pl->observe->y, -light, light_atten [light + MAX_LIGHT_RADIUS]);
421 } 430 }
422 rectangular_mapspace_iterate_end
423} 431}
424 432
425/* blinded_sight() - sets all viewable squares to blocked except 433/* blinded_sight() - sets all viewable squares to blocked except
426 * for the one the central one that the player occupies. A little 434 * for the one the central one that the player occupies. A little
427 * odd that you can see yourself (and what your standing on), but 435 * odd that you can see yourself (and what your standing on), but
494 * map is the map that changed, x and y are the coordinates. 502 * map is the map that changed, x and y are the coordinates.
495 */ 503 */
496void 504void
497update_all_los (const maptile *map, int x, int y) 505update_all_los (const maptile *map, int x, int y)
498{ 506{
507 // no need to do anything if we don't have darkness
508 if (map->darklevel () <= 0)
509 return;
510
499 map->at (x, y).invalidate (); 511 map->at (x, y).invalidate ();
500 512
501 for_all_players (pl) 513 for_all_players (pl)
502 { 514 {
503 /* Player should not have a null map, but do this 515 /* Player should not have a null map, but do this
514 * player can't be on another map that may be closer, 526 * player can't be on another map that may be closer,
515 * so by setting it up this way, we trim processing 527 * so by setting it up this way, we trim processing
516 * some. 528 * some.
517 */ 529 */
518 if (pl->ob->map == map) 530 if (pl->ob->map == map)
519 {
520 if ((abs (pl->ob->x - x) <= pl->ns->mapx / 2) && (abs (pl->ob->y - y) <= pl->ns->mapy / 2)) 531 if ((abs (pl->ob->x - x) <= pl->ns->mapx / 2) && (abs (pl->ob->y - y) <= pl->ns->mapy / 2))
521 pl->do_los = 1; 532 pl->do_los = 1;
522 }
523 533
524 /* Now we check to see if player is on adjacent 534 /* Now we check to see if player is on adjacent
525 * maps to the one that changed and also within 535 * maps to the one that changed and also within
526 * view. The tile_maps[] could be null, but in that 536 * view. The tile_maps[] could be null, but in that
527 * case it should never match the pl->ob->map, so 537 * case it should never match the pl->ob->map, so
636 if (pl->ob->map == op->map && 646 if (pl->ob->map == op->map &&
637 pl->ob->y - pl->ns->mapy / 2 <= op->y && 647 pl->ob->y - pl->ns->mapy / 2 <= op->y &&
638 pl->ob->y + pl->ns->mapy / 2 >= op->y && pl->ob->x - pl->ns->mapx / 2 <= op->x && pl->ob->x + pl->ns->mapx / 2 >= op->x) 648 pl->ob->y + pl->ns->mapy / 2 >= op->y && pl->ob->x - pl->ns->mapx / 2 <= op->x && pl->ob->x + pl->ns->mapx / 2 >= op->x)
639 pl->do_los = 1; 649 pl->do_los = 1;
640} 650}
651

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines