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.37 by root, Thu Dec 18 02:49:22 2008 UTC vs.
Revision 1.40 by root, Fri Dec 19 17:52:50 2008 UTC

274 if (op->contr->blocked_los[dx][dy] > 0) /* for any square blocked */ 274 if (op->contr->blocked_los[dx][dy] > 0) /* for any square blocked */
275 op->contr->blocked_los[dx][dy] = -1; 275 op->contr->blocked_los[dx][dy] = -1;
276 } 276 }
277 } 277 }
278 278
279 if (op->map->darkness > 0) /* player is on a dark map */
280 expand_lighted_sight (op); 279 expand_lighted_sight (op);
281 280
282 /* clear mark squares */ 281 /* clear mark squares */
283 for (int x = 0; x < op->contr->ns->mapx; x++) 282 for (int x = 0; x < op->contr->ns->mapx; x++)
284 for (int y = 0; y < op->contr->ns->mapy; y++) 283 for (int y = 0; y < op->contr->ns->mapy; y++)
285 if (op->contr->blocked_los[x][y] < 0) 284 if (op->contr->blocked_los[x][y] < 0)
322 : LOS_MAX - intensity; 321 : LOS_MAX - intensity;
323 } 322 }
324 } 323 }
325} darkness_init; 324} darkness_init;
326 325
326sint8
327los_brighten (sint8 b, sint8 l)
328{
329 return b == LOS_BLOCKED ? b : min (b, l);
330}
331
332sint8
333los_darken (sint8 b, sint8 l)
334{
335 return max (b, l);
336}
337
338template<sint8 change_it (sint8, sint8)>
339static void
340apply_light (object *op, int basex, int basey, int light, const sint8 *darkness_table)
341{
342 // min or max the ciruclar area around basex, basey
343 player *pl = op->contr;
344
345 int ax0 = max (0, basex - light);
346 int ay0 = max (0, basey - light);
347 int ax1 = min (basex + light, pl->ns->mapx - 1);
348 int ay1 = min (basey + light, pl->ns->mapy - 1);
349
350 for (int ax = ax0; ax <= ax1; ax++)
351 for (int ay = ay0; ay <= ay1; ay++)
352 pl->blocked_los[ax][ay] =
353 change_it (pl->blocked_los[ax][ay], darkness_table [idistance (ax - basex, ay - basey)]);
354}
355
356/* add light, by finding all (non-null) nearby light sources, then
357 * mark those squares specially.
358 */
327static void 359static void
328expand_lighted_sight (object *op) 360expand_lighted_sight (object *op)
329{ 361{
330 int x, y, darklevel, basex, basey, mflags, light, x1, y1; 362 int darklevel, mflags, light, x1, y1;
331 maptile *m = op->map; 363 maptile *m = op->map;
332 sint16 nx, ny; 364 sint16 nx, ny;
333 365
334 darklevel = m->darkness; 366 darklevel = m->darkness;
335 367
336 /* If the player can see in the dark, lower the darklevel for him */ 368 /* If the player can see in the dark, lower the darklevel for him */
337 if (QUERY_FLAG (op, FLAG_SEE_IN_DARK)) 369 if (QUERY_FLAG (op, FLAG_SEE_IN_DARK))
338 darklevel -= LOS_MAX / 2; 370 darklevel -= LOS_MAX / 2;
339
340 /* add light, by finding all (non-null) nearby light sources, then
341 * mark those squares specially. If the darklevel<1, there is no
342 * reason to do this, so we skip this function
343 */
344
345 if (darklevel < 1)
346 return;
347 371
348 /* Do a sanity check. If not valid, some code below may do odd 372 /* Do a sanity check. If not valid, some code below may do odd
349 * things. 373 * things.
350 */ 374 */
351 if (darklevel > MAX_DARKNESS) 375 if (darklevel > MAX_DARKNESS)
352 { 376 {
353 LOG (llevError, "Map darkness for %s on %s is too high (%d)\n", &op->name, &op->map->path, darklevel); 377 LOG (llevError, "Map darkness for %s on %s is too high (%d)\n", &op->name, &op->map->path, darklevel);
354 darklevel = MAX_DARKNESS; 378 darklevel = MAX_DARKNESS;
355 } 379 }
356 380
357 /* first, make everything totally dark */
358 for (x = 0; x < op->contr->ns->mapx; x++)
359 for (y = 0; y < op->contr->ns->mapy; y++)
360 if (op->contr->blocked_los[x][y] != LOS_BLOCKED)
361 op->contr->blocked_los[x][y] = LOS_MAX;
362
363 int half_x = op->contr->ns->mapx / 2; 381 int half_x = op->contr->ns->mapx / 2;
364 int half_y = op->contr->ns->mapy / 2; 382 int half_y = op->contr->ns->mapy / 2;
365 383
366 int min_x = op->x - half_x - MAX_LIGHT_RADIUS; 384 int min_x = op->x - half_x - MAX_LIGHT_RADIUS;
367 int min_y = op->y - half_y - MAX_LIGHT_RADIUS; 385 int min_y = op->y - half_y - MAX_LIGHT_RADIUS;
368 int max_x = op->x + half_x + MAX_LIGHT_RADIUS; 386 int max_x = op->x + half_x + MAX_LIGHT_RADIUS;
369 int max_y = op->y + half_y + MAX_LIGHT_RADIUS; 387 int max_y = op->y + half_y + MAX_LIGHT_RADIUS;
370 388
371 int pass2 = 0; // negative lights have an extra pass 389 int pass2 = 0; // negative lights have an extra pass
372 390
373 /* 391 if (darklevel < 1)
392 pass2 = 1;
393 else
394 {
395 /* first, make everything totally dark */
396 for (int x = 0; x < op->contr->ns->mapx; x++)
397 for (int y = 0; y < op->contr->ns->mapy; y++)
398 if (op->contr->blocked_los[x][y] != LOS_BLOCKED)
399 op->contr->blocked_los[x][y] = LOS_MAX;
400
401 /*
374 * Only process the area of interest. 402 * Only process the area of interest.
375 * the basex, basey values represent the position in the op->contr->blocked_los 403 * the basex, basey values represent the position in the op->contr->blocked_los
376 * array. Its easier to just increment them here (and start with the right 404 * array. Its easier to just increment them here (and start with the right
377 * value) than to recalculate them down below. 405 * value) than to recalculate them down below.
378 */ 406 */
379 for (int x = min_x, basex = -MAX_LIGHT_RADIUS; x <= max_x; x++, basex++) 407 for (int x = min_x, basex = -MAX_LIGHT_RADIUS; x <= max_x; x++, basex++)
380 for (int y = min_y, basey = -MAX_LIGHT_RADIUS; y <= max_y; y++, basey++) 408 for (int y = min_y, basey = -MAX_LIGHT_RADIUS; y <= max_y; y++, basey++)
409 {
410 maptile *m = op->map;
411 sint16 nx = x;
412 sint16 ny = y;
413
414 if (!xy_normalise (m, nx, ny))
415 continue;
416
417 mapspace &ms = m->at (nx, ny);
418 ms.update ();
419 sint8 light = ms.light;
420
421 if (expect_false (light))
422 if (light < 0)
423 pass2 = 1;
424 else
425 apply_light<los_brighten> (op, basex, basey, light, darkness [light + MAX_LIGHT_RADIUS]);
426 }
427
428 /* grant some vision to the player, based on the darklevel */
429 /* for outdoor maps, ensure some mininum visibility radius */
381 { 430 {
382 maptile *m = op->map; 431 int light = clamp (MAX_DARKNESS - darklevel, op->map->outdoor ? 2 : 0, MAX_LIGHT_RADIUS);
383 sint16 nx = x;
384 sint16 ny = y;
385 432
386 if (!xy_normalise (m, nx, ny)) 433 apply_light<los_brighten> (op, half_x, half_y, light, darkness [light + MAX_LIGHT_RADIUS]);
387 continue;
388
389 mapspace &ms = m->at (nx, ny);
390 ms.update ();
391 sint8 light = ms.light;
392
393 if (expect_false (light))
394 if (light < 0)
395 pass2 = 1;
396 else
397 {
398 /* This space is providing light, so we need to brighten up the
399 * spaces around here.
400 */
401 const sint8 *darkness_table = darkness [light + MAX_LIGHT_RADIUS];
402
403 for (int ax = max (0, basex - light); ax <= min (basex + light, op->contr->ns->mapx - 1); ax++)
404 for (int ay = max (0, basey - light); ay <= min (basey + light, op->contr->ns->mapy - 1); ay++)
405 if (op->contr->blocked_los[ax][ay] != LOS_BLOCKED)
406 min_it (op->contr->blocked_los[ax][ay], darkness_table [idistance (ax - basex, ay - basey)]);
407 }
408 } 434 }
435 }
409 436
410 // psosibly do 2nd pass for rare negative glow radii 437 // possibly do 2nd pass for rare negative glow radii
411 if (expect_false (pass2)) 438 // for effect, those are always considered to be stronger than anything else
439 // but they can't darken a place completely
440 if (pass2)
412 for (x = min_x, basex = -MAX_LIGHT_RADIUS; x <= max_x; x++, basex++) 441 for (int x = min_x, basex = -MAX_LIGHT_RADIUS; x <= max_x; x++, basex++)
413 for (y = min_y, basey = -MAX_LIGHT_RADIUS; y <= max_y; y++, basey++) 442 for (int y = min_y, basey = -MAX_LIGHT_RADIUS; y <= max_y; y++, basey++)
414 { 443 {
415 maptile *m = op->map; 444 maptile *m = op->map;
416 sint16 nx = x; 445 sint16 nx = x;
417 sint16 ny = y; 446 sint16 ny = y;
418 447
422 mapspace &ms = m->at (nx, ny); 451 mapspace &ms = m->at (nx, ny);
423 ms.update (); 452 ms.update ();
424 sint8 light = ms.light; 453 sint8 light = ms.light;
425 454
426 if (expect_false (light < 0)) 455 if (expect_false (light < 0))
427 { 456 apply_light<los_darken> (op, basex, basey, -light, darkness [light + MAX_LIGHT_RADIUS]);
428 const sint8 *darkness_table = darkness [light + MAX_LIGHT_RADIUS];
429
430 for (int ax = max (0, basex + light); ax <= min (basex - light, op->contr->ns->mapx - 1); ax++)
431 for (int ay = max (0, basey + light); ay <= min (basey - light, op->contr->ns->mapy - 1); ay++)
432 if (op->contr->blocked_los[ax][ay] != LOS_BLOCKED)
433 max_it (op->contr->blocked_los[ax][ay], darkness_table [idistance (ax - basex, ay - basey)]);
434 } 457 }
435 }
436
437 /* Outdoor should never really be completely pitch black dark like
438 * a dungeon, so let the player at least see a little around themselves
439 */
440 if (op->map->outdoor && darklevel > MAX_DARKNESS - 3)
441 {
442 if (op->contr->blocked_los[op->contr->ns->mapx / 2][op->contr->ns->mapy / 2] > (LOS_MAX - 3))
443 op->contr->blocked_los[op->contr->ns->mapx / 2][op->contr->ns->mapy / 2] = LOS_MAX - 3;
444
445 for (x = -1; x <= 1; x++)
446 for (y = -1; y <= 1; y++)
447 if (op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] > (LOS_MAX - 2))
448 op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] = LOS_MAX - 2;
449 }
450
451 /* grant some vision to the player, based on the darklevel */
452 for (x = darklevel - MAX_DARKNESS; x < MAX_DARKNESS + 1 - darklevel; x++)
453 for (y = darklevel - MAX_DARKNESS; y < MAX_DARKNESS + 1 - darklevel; y++)
454 if (!(op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] == LOS_BLOCKED))
455 op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] -=
456 max (0, 6 - darklevel - max (abs (x), abs (y)));
457} 458}
458 459
459/* blinded_sight() - sets all viewable squares to blocked except 460/* blinded_sight() - sets all viewable squares to blocked except
460 * for the one the central one that the player occupies. A little 461 * for the one the central one that the player occupies. A little
461 * odd that you can see yourself (and what your standing on), but 462 * odd that you can see yourself (and what your standing on), but

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines