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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines