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.41 by root, Fri Dec 19 22:47:29 2008 UTC vs.
Revision 1.46 by root, Tue Dec 23 00:39:48 2008 UTC

33 LOS_YI = 0x02, 33 LOS_YI = 0x02,
34}; 34};
35 35
36struct los_info 36struct los_info
37{ 37{
38 sint8 xo, yo; // obscure angle 38 sint8 xo, yo; // obscure angle
39 sint8 xe, ye; // angle deviation 39 sint8 xe, ye; // angle deviation
40 uint8 culled; 40 uint8 culled; // culled from "tree"
41 uint8 queued; 41 uint8 queued; // already queued
42 uint8 visible; 42 uint8 visible;
43 uint8 flags; 43 uint8 flags; // LOS_XI/YI
44}; 44};
45 45
46// temporary storage for the los algorithm, 46// temporary storage for the los algorithm,
47// one los_info for each lightable map space 47// one los_info for each lightable map space
48static los_info los[MAP_CLIENT_X][MAP_CLIENT_Y]; 48static los_info los[MAP_CLIENT_X][MAP_CLIENT_Y];
62/* 62/*
63 * Clears/initialises the los-array associated to the player 63 * Clears/initialises the los-array associated to the player
64 * controlling the object. 64 * controlling the object.
65 */ 65 */
66void 66void
67clear_los (player *pl) 67player::clear_los (sint8 value)
68{ 68{
69 memset (pl->los, LOS_BLOCKED, sizeof (pl->los)); 69 memset (los, value, sizeof (los));
70} 70}
71 71
72// enqueue a single mapspace, but only if it hasn't 72// enqueue a single mapspace, but only if it hasn't
73// been enqueued yet. 73// been enqueued yet.
74static void 74static void
267 267
268 return 0; 268 return 0;
269} 269}
270 270
271/* radius, distance => lightness adjust */ 271/* radius, distance => lightness adjust */
272static sint8 darkness[MAX_LIGHT_RADIUS * 2 + 1][MAX_LIGHT_RADIUS * 3 / 2 + 1]; 272static sint8 light_atten[MAX_LIGHT_RADIUS * 2 + 1][MAX_LIGHT_RADIUS * 3 / 2 + 1];
273static sint8 vision_atten[MAX_DARKNESS + 1][MAX_DARKNESS * 3 / 2 + 1];
273 274
274static struct darkness_init 275static struct los_init
275{ 276{
276 darkness_init () 277 los_init ()
277 { 278 {
279 /* for lights */
278 for (int radius = -MAX_LIGHT_RADIUS; radius <= MAX_LIGHT_RADIUS; ++radius) 280 for (int radius = -MAX_LIGHT_RADIUS; radius <= MAX_LIGHT_RADIUS; ++radius)
279 for (int distance = 0; distance <= MAX_LIGHT_RADIUS * 3 / 2; ++distance) 281 for (int distance = 0; distance <= MAX_LIGHT_RADIUS * 3 / 2; ++distance)
280 { 282 {
281 // max intensity 283 // max intensity
282 int intensity = min (LOS_MAX, abs (radius) + 1); 284 int intensity = min (LOS_MAX, abs (radius) + 1);
283 285
284 // actual intensity 286 // actual intensity
285 intensity = max (0, lerp_rd (distance, 0, abs (radius) + 1, intensity, 0)); 287 intensity = max (0, lerp_rd (distance, 0, abs (radius) + 1, intensity, 0));
286 288
287 darkness [radius + MAX_LIGHT_RADIUS][distance] = radius < 0 289 light_atten [radius + MAX_LIGHT_RADIUS][distance] = radius < 0
288 ? min (3, intensity) 290 ? min (3, intensity)
289 : LOS_MAX - intensity; 291 : LOS_MAX - intensity;
290 } 292 }
293
294 /* for general vision */
295 for (int radius = 0; radius <= MAX_DARKNESS; ++radius)
296 for (int distance = 0; distance <= MAX_DARKNESS * 3 / 2; ++distance)
297 {
298 vision_atten [radius][distance] = distance <= radius ? 3 : 4;
299 }
291 } 300 }
292} darkness_init; 301} los_init;
293 302
294sint8 303sint8
295los_brighten (sint8 b, sint8 l) 304los_brighten (sint8 b, sint8 l)
296{ 305{
297 return b == LOS_BLOCKED ? b : min (b, l); 306 return b == LOS_BLOCKED ? b : min (b, l);
303 return max (b, l); 312 return max (b, l);
304} 313}
305 314
306template<sint8 change_it (sint8, sint8)> 315template<sint8 change_it (sint8, sint8)>
307static void 316static void
308apply_light (object *op, int dx, int dy, int light, const sint8 *darkness_table) 317apply_light (object *op, int dx, int dy, int light, const sint8 *atten_table)
309{ 318{
310 // min or max the circular area around basex, basey 319 // min or max the circular area around basex, basey
311 player *pl = op->contr; 320 player *pl = op->contr;
312 321
313 dx += LOS_X0; 322 dx += LOS_X0;
322 int ay1 = min (dy + light, LOS_Y0 + hy); 331 int ay1 = min (dy + light, LOS_Y0 + hy);
323 332
324 for (int ax = ax0; ax <= ax1; ax++) 333 for (int ax = ax0; ax <= ax1; ax++)
325 for (int ay = ay0; ay <= ay1; ay++) 334 for (int ay = ay0; ay <= ay1; ay++)
326 pl->los[ax][ay] = 335 pl->los[ax][ay] =
327 change_it (pl->los[ax][ay], darkness_table [idistance (ax - dx, ay - dy)]); 336 change_it (pl->los[ax][ay], atten_table [idistance (ax - dx, ay - dy)]);
328} 337}
329 338
330/* add light, by finding all (non-null) nearby light sources, then 339/* add light, by finding all (non-null) nearby light sources, then
331 * mark those squares specially. 340 * mark those squares specially.
332 */ 341 */
394 403
395 if (expect_false (light)) 404 if (expect_false (light))
396 if (light < 0) 405 if (light < 0)
397 pass2 = 1; 406 pass2 = 1;
398 else 407 else
399 apply_light<los_brighten> (op, x - op->x, y - op->y, light, darkness [light + MAX_LIGHT_RADIUS]); 408 apply_light<los_brighten> (op, x - op->x, y - op->y, light, light_atten [light + MAX_LIGHT_RADIUS]);
400 } 409 }
401 410
402 /* grant some vision to the player, based on the darklevel */ 411 /* grant some vision to the player, based on the darklevel */
403 /* for outdoor maps, ensure some mininum visibility radius */
404 { 412 {
405 int light = clamp (MAX_DARKNESS - darklevel, op->map->outdoor ? 2 : 0, MAX_LIGHT_RADIUS); 413 int light = clamp (MAX_DARKNESS - darklevel, 0, MAX_DARKNESS);
406 414
407 apply_light<los_brighten> (op, 0, 0, light, darkness [light + MAX_LIGHT_RADIUS]); 415 apply_light<los_brighten> (op, 0, 0, light, vision_atten [light]);
408 } 416 }
409 } 417 }
410 418
411 // possibly do 2nd pass for rare negative glow radii 419 // possibly do 2nd pass for rare negative glow radii
412 // for effect, those are always considered to be stronger than anything else 420 // for effect, those are always considered to be stronger than anything else
425 mapspace &ms = m->at (nx, ny); 433 mapspace &ms = m->at (nx, ny);
426 ms.update (); 434 ms.update ();
427 sint8 light = ms.light; 435 sint8 light = ms.light;
428 436
429 if (expect_false (light < 0)) 437 if (expect_false (light < 0))
430 apply_light<los_darken> (op, x - op->x, y - op->y, -light, darkness [light + MAX_LIGHT_RADIUS]); 438 apply_light<los_darken> (op, x - op->x, y - op->y, -light, light_atten [light + MAX_LIGHT_RADIUS]);
431 } 439 }
432} 440}
433 441
434/* blinded_sight() - sets all viewable squares to blocked except 442/* blinded_sight() - sets all viewable squares to blocked except
435 * for the one the central one that the player occupies. A little 443 * for the one the central one that the player occupies. A little
437 * really need for any reasonable game play. 445 * really need for any reasonable game play.
438 */ 446 */
439static void 447static void
440blinded_sight (object *op) 448blinded_sight (object *op)
441{ 449{
442 op->contr->los[LOS_X0][LOS_Y0] = 3; 450 op->contr->los[LOS_X0][LOS_Y0] = 1;
443} 451}
444 452
445/* 453/*
446 * update_los() recalculates the array which specifies what is 454 * update_los() recalculates the array which specifies what is
447 * visible for the given player-object. 455 * visible for the given player-object.
450update_los (object *op) 458update_los (object *op)
451{ 459{
452 if (QUERY_FLAG (op, FLAG_REMOVED)) 460 if (QUERY_FLAG (op, FLAG_REMOVED))
453 return; 461 return;
454 462
455 clear_los (op->contr); 463 op->contr->clear_los ();
456 464
457 if (QUERY_FLAG (op, FLAG_WIZ) /* ||XRAYS(op) */ ) 465 if (QUERY_FLAG (op, FLAG_WIZ) /* ||XRAYS(op) */ )
458 memset (op->contr->los, 0, sizeof (op->contr->los)); 466 memset (op->contr->los, 0, sizeof (op->contr->los));
459 else if (QUERY_FLAG (op, FLAG_BLIND)) /* player is blind */ 467 else if (QUERY_FLAG (op, FLAG_BLIND)) /* player is blind */
460 blinded_sight (op); 468 blinded_sight (op);
482 * change_map_light function 490 * change_map_light function
483 */ 491 */
484void 492void
485update_all_map_los (maptile *map) 493update_all_map_los (maptile *map)
486{ 494{
487 for_all_players (pl) 495 for_all_players_on_map (pl, map)
488 if (pl->ob && pl->ob->map == map)
489 pl->do_los = 1; 496 pl->do_los = 1;
490} 497}
491 498
492/* 499/*
493 * This function makes sure that update_los() will be called for all 500 * This function makes sure that update_los() will be called for all
494 * players on the given map within the next frame. 501 * players on the given map within the next frame.
502 * map is the map that changed, x and y are the coordinates. 509 * map is the map that changed, x and y are the coordinates.
503 */ 510 */
504void 511void
505update_all_los (const maptile *map, int x, int y) 512update_all_los (const maptile *map, int x, int y)
506{ 513{
514 map->at (x, y).invalidate ();
515
507 for_all_players (pl) 516 for_all_players (pl)
508 { 517 {
509 /* Player should not have a null map, but do this 518 /* Player should not have a null map, but do this
510 * check as a safety 519 * check as a safety
511 */ 520 */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines