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.44 by root, Sun Dec 21 21:20:35 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];
273 273
274static struct darkness_init 274static struct los_init
275{ 275{
276 darkness_init () 276 los_init ()
277 { 277 {
278 for (int radius = -MAX_LIGHT_RADIUS; radius <= MAX_LIGHT_RADIUS; ++radius) 278 for (int radius = -MAX_LIGHT_RADIUS; radius <= MAX_LIGHT_RADIUS; ++radius)
279 for (int distance = 0; distance <= MAX_LIGHT_RADIUS * 3 / 2; ++distance) 279 for (int distance = 0; distance <= MAX_LIGHT_RADIUS * 3 / 2; ++distance)
280 { 280 {
281 // max intensity 281 // max intensity
282 int intensity = min (LOS_MAX, abs (radius) + 1); 282 int intensity = min (LOS_MAX, abs (radius) + 1);
283 283
284 // actual intensity 284 // actual intensity
285 intensity = max (0, lerp_rd (distance, 0, abs (radius) + 1, intensity, 0)); 285 intensity = max (0, lerp_rd (distance, 0, abs (radius) + 1, intensity, 0));
286 286
287 darkness [radius + MAX_LIGHT_RADIUS][distance] = radius < 0 287 light_atten [radius + MAX_LIGHT_RADIUS][distance] = radius < 0
288 ? min (3, intensity) 288 ? min (3, intensity)
289 : LOS_MAX - intensity; 289 : LOS_MAX - intensity;
290 } 290 }
291 } 291 }
292} darkness_init; 292} los_init;
293 293
294sint8 294sint8
295los_brighten (sint8 b, sint8 l) 295los_brighten (sint8 b, sint8 l)
296{ 296{
297 return b == LOS_BLOCKED ? b : min (b, l); 297 return b == LOS_BLOCKED ? b : min (b, l);
303 return max (b, l); 303 return max (b, l);
304} 304}
305 305
306template<sint8 change_it (sint8, sint8)> 306template<sint8 change_it (sint8, sint8)>
307static void 307static void
308apply_light (object *op, int dx, int dy, int light, const sint8 *darkness_table) 308apply_light (object *op, int dx, int dy, int light, const sint8 *atten_table)
309{ 309{
310 // min or max the circular area around basex, basey 310 // min or max the circular area around basex, basey
311 player *pl = op->contr; 311 player *pl = op->contr;
312 312
313 dx += LOS_X0; 313 dx += LOS_X0;
322 int ay1 = min (dy + light, LOS_Y0 + hy); 322 int ay1 = min (dy + light, LOS_Y0 + hy);
323 323
324 for (int ax = ax0; ax <= ax1; ax++) 324 for (int ax = ax0; ax <= ax1; ax++)
325 for (int ay = ay0; ay <= ay1; ay++) 325 for (int ay = ay0; ay <= ay1; ay++)
326 pl->los[ax][ay] = 326 pl->los[ax][ay] =
327 change_it (pl->los[ax][ay], darkness_table [idistance (ax - dx, ay - dy)]); 327 change_it (pl->los[ax][ay], atten_table [idistance (ax - dx, ay - dy)]);
328} 328}
329 329
330/* add light, by finding all (non-null) nearby light sources, then 330/* add light, by finding all (non-null) nearby light sources, then
331 * mark those squares specially. 331 * mark those squares specially.
332 */ 332 */
394 394
395 if (expect_false (light)) 395 if (expect_false (light))
396 if (light < 0) 396 if (light < 0)
397 pass2 = 1; 397 pass2 = 1;
398 else 398 else
399 apply_light<los_brighten> (op, x - op->x, y - op->y, light, darkness [light + MAX_LIGHT_RADIUS]); 399 apply_light<los_brighten> (op, x - op->x, y - op->y, light, light_atten [light + MAX_LIGHT_RADIUS]);
400 } 400 }
401 401
402 /* grant some vision to the player, based on the darklevel */ 402 /* grant some vision to the player, based on the darklevel */
403 /* for outdoor maps, ensure some mininum visibility radius */
404 { 403 {
405 int light = clamp (MAX_DARKNESS - darklevel, op->map->outdoor ? 2 : 0, MAX_LIGHT_RADIUS); 404 int light = clamp (MAX_DARKNESS - darklevel, 0, MAX_LIGHT_RADIUS);
406 405
407 apply_light<los_brighten> (op, 0, 0, light, darkness [light + MAX_LIGHT_RADIUS]); 406 apply_light<los_brighten> (op, 0, 0, light, light_atten [light + MAX_LIGHT_RADIUS]);
408 } 407 }
409 } 408 }
410 409
411 // possibly do 2nd pass for rare negative glow radii 410 // possibly do 2nd pass for rare negative glow radii
412 // for effect, those are always considered to be stronger than anything else 411 // for effect, those are always considered to be stronger than anything else
425 mapspace &ms = m->at (nx, ny); 424 mapspace &ms = m->at (nx, ny);
426 ms.update (); 425 ms.update ();
427 sint8 light = ms.light; 426 sint8 light = ms.light;
428 427
429 if (expect_false (light < 0)) 428 if (expect_false (light < 0))
430 apply_light<los_darken> (op, x - op->x, y - op->y, -light, darkness [light + MAX_LIGHT_RADIUS]); 429 apply_light<los_darken> (op, x - op->x, y - op->y, -light, light_atten [light + MAX_LIGHT_RADIUS]);
431 } 430 }
432} 431}
433 432
434/* blinded_sight() - sets all viewable squares to blocked except 433/* blinded_sight() - sets all viewable squares to blocked except
435 * 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
450update_los (object *op) 449update_los (object *op)
451{ 450{
452 if (QUERY_FLAG (op, FLAG_REMOVED)) 451 if (QUERY_FLAG (op, FLAG_REMOVED))
453 return; 452 return;
454 453
455 clear_los (op->contr); 454 op->contr->clear_los ();
456 455
457 if (QUERY_FLAG (op, FLAG_WIZ) /* ||XRAYS(op) */ ) 456 if (QUERY_FLAG (op, FLAG_WIZ) /* ||XRAYS(op) */ )
458 memset (op->contr->los, 0, sizeof (op->contr->los)); 457 memset (op->contr->los, 0, sizeof (op->contr->los));
459 else if (QUERY_FLAG (op, FLAG_BLIND)) /* player is blind */ 458 else if (QUERY_FLAG (op, FLAG_BLIND)) /* player is blind */
460 blinded_sight (op); 459 blinded_sight (op);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines