Crossfire Server, Trunk
los.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <math.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
32 #define SPACE_BLOCK 0.5
33 
37 #define XRAY_RADIUS 2
38 
43 #define SEE_IN_DARK_LEVELS 2
44 
48 #define LOS_BLOCKED 100
49 #define LOS_NO_DARKNESS 0
50 #define LOS_MARKED -1
51 
52 struct blocks {
53  int x[4], y[4];
54  int index;
55 };
56 
58 
59 static void expand_lighted_sight(object *op);
60 
79 static void set_block(int x, int y, int bx, int by) {
80  int index = block[x][y].index, i;
81 
82  /* Due to flipping, we may get duplicates - better safe than sorry.
83  */
84  for (i = 0; i < index; i++) {
85  if (block[x][y].x[i] == bx
86  && block[x][y].y[i] == by)
87  return;
88  }
89 
90  block[x][y].x[index] = bx;
91  block[x][y].y[index] = by;
92  block[x][y].index++;
93 #ifdef LOS_DEBUG
94  LOG(llevDebug, "setblock: added %d %d -> %d %d (%d)\n", x, y, bx, by, block[x][y].index);
95 #endif
96 }
97 
106 void init_block(void) {
107  int x, y, dx, dy, i;
108  static const int block_x[3] = {
109  -1, -1, 0
110  }, block_y[3] = {
111  -1, 0, -1
112  };
113 
114  for (x = 0; x < MAP_CLIENT_X; x++)
115  for (y = 0; y < MAP_CLIENT_Y; y++) {
116  block[x][y].index = 0;
117  }
118 
119  /* The table should be symmetric, so only do the upper left
120  * quadrant - makes the processing easier.
121  */
122  for (x = 1; x <= MAP_CLIENT_X/2; x++) {
123  for (y = 1; y <= MAP_CLIENT_Y/2; y++) {
124  /* center space never blocks */
125  if (x == MAP_CLIENT_X/2 && y == MAP_CLIENT_Y/2)
126  continue;
127 
128  for (i = 0; i < 3; i++) {
129  dx = x+block_x[i];
130  dy = y+block_y[i];
131 
132  /* If its a straight line, its blocked */
133  if ((dx == x && x == MAP_CLIENT_X/2)
134  || (dy == y && y == MAP_CLIENT_Y/2)) {
135  /* For simplicity, we mirror the coordinates to block the other
136  * quadrants.
137  */
138  set_block(x, y, dx, dy);
139  if (x == MAP_CLIENT_X/2) {
140  set_block(x, MAP_CLIENT_Y-y-1, dx, MAP_CLIENT_Y-dy-1);
141  } else if (y == MAP_CLIENT_Y/2) {
142  set_block(MAP_CLIENT_X-x-1, y, MAP_CLIENT_X-dx-1, dy);
143  }
144  } else {
145  float d1, s, l;
146 
147  /* We use the algorihm that found out how close the point
148  * (x,y) is to the line from dx,dy to the center of the viewable
149  * area. l is the distance from x,y to the line.
150  * r is more a curiosity - it lets us know what direction (left/right)
151  * the line is off
152  */
153 
154  d1 = (float)(pow(MAP_CLIENT_X/2-dx, 2)+pow(MAP_CLIENT_Y/2-dy, 2));
155  s = (float)((dy-y)*(MAP_CLIENT_X/2-dx)-(dx-x)*(MAP_CLIENT_Y/2-dy))/d1;
156  l = FABS(sqrt(d1)*s);
157 
158  if (l <= SPACE_BLOCK) {
159  /* For simplicity, we mirror the coordinates to block the other
160  * quadrants.
161  */
162  set_block(x, y, dx, dy);
163  set_block(MAP_CLIENT_X-x-1, y, MAP_CLIENT_X-dx-1, dy);
164  set_block(x, MAP_CLIENT_Y-y-1, dx, MAP_CLIENT_Y-dy-1);
166  }
167  }
168  }
169  }
170  }
171 }
172 
188 static void set_wall(player *pl, int x, int y) {
189  // Get this outside the loop -- now we can recycle x and y in the loop
190  // Trying less dereferencing for better efficiency
191  // Equivalent to &(block[x][y]), but faster.
192  const blocks * const at = block[x] + y;
193  /*
194  * Assume the mapsize will not change mid-drawing. This seemed to work in my testing
195  * Neila Hawkins 2019-12-03
196  */
197  const int map_sock_x = (MAP_CLIENT_X-pl->socket->mapx)>>1,
198  map_sock_y = (MAP_CLIENT_Y-pl->socket->mapy)>>1;
199  for (int i = 0; i < at->index; i++) {
200  int dx = at->x[i], dy = at->y[i];
201 
202  /* x, y are the values as adjusted to be in the
203  * socket look structure. Since the values are copied,
204  * we can safely store this in the x and y passed to the function,
205  * since they were only needed to find the element of the blocks array.
206  */
207  x = dx-map_sock_x;
208  y = dy-map_sock_y;
209 
210  if (x < 0 || x >= pl->socket->mapx
211  || y < 0 || y >= pl->socket->mapy
212  /* If already set to LOS_BLOCKED, we probably hit this space through recursion already. */
213  || pl->blocked_los[x][y] == LOS_BLOCKED)
214  continue;
215  /* we need to adjust to the fact that the socket
216  * code wants the los to start from the 0,0
217  * and not be relative to middle of los array.
218  */
219  pl->blocked_los[x][y] = LOS_BLOCKED;
220  set_wall(pl, dx, dy);
221  }
222 }
223 
235 static void check_wall(object *op, int x, int y) {
236  int ax, ay;
237 
238  if (!block[x][y].index)
239  return;
240 
241  /* ax, ay are coordinates as indexed into the look window */
242  ax = x-(MAP_CLIENT_X-op->contr->socket->mapx)/2;
243  ay = y-(MAP_CLIENT_Y-op->contr->socket->mapy)/2;
244 
245  /* If the converted coordinates are outside the viewable
246  * area for the client, return now.
247  */
248  if (ax < 0 || ay < 0 || ax >= op->contr->socket->mapx || ay >= op->contr->socket->mapy)
249  return;
250 
251  /* If this space is already blocked, prune the processing - presumably
252  * whatever has set this space to be blocked has done the work and already
253  * done the dependency chain.
254  */
255  if (op->contr->blocked_los[ax][ay] == LOS_BLOCKED)
256  return;
257 
258 
259  if (get_map_flags(op->map, NULL, op->x+x-MAP_CLIENT_X/2, op->y+y-MAP_CLIENT_Y/2, NULL, NULL)&(P_BLOCKSVIEW|P_OUT_OF_MAP))
260  set_wall(op->contr, x, y);
261 }
262 
271  /* This is safer than using the socket->mapx, mapy because
272  * we index the blocked_los as a 2 way array, so clearing
273  * the first z spaces may not not cover the spaces we are
274  * actually going to use
275  */
276  (void)memset((void *)pl->blocked_los, LOS_NO_DARKNESS,
278 }
279 
291 static void expand_sight(object *op) {
292  int i, x, y, dx, dy;
293 
294  for (x = 1; x < op->contr->socket->mapx-1; x++) { /* loop over inner squares */
295  for (y = 1; y < op->contr->socket->mapy-1; y++) {
296  if (op->contr->blocked_los[x][y] == LOS_NO_DARKNESS) {
297  /* If the space does not block view, process surrounding spaces */
298  if (!(get_map_flags(op->map, NULL,
299  op->x-op->contr->socket->mapx/2+x,
300  op->y-op->contr->socket->mapy/2+y,
301  NULL, NULL)&(P_BLOCKSVIEW|P_OUT_OF_MAP))) {
302  /* mark all directions around space */
303  for (i = 1; i <= 8; i += 1) {
304  dx = x+freearr_x[i];
305  dy = y+freearr_y[i];
306 
307  /* Mark any space that is blocked (or has a darkness value) */
308  if (op->contr->blocked_los[dx][dy] > LOS_NO_DARKNESS)
309  op->contr->blocked_los[dx][dy] = LOS_MARKED;
310  }
311  }
312  }
313  }
314  }
315 
316  if (MAP_DARKNESS(op->map) > 0) /* player is on a dark map */
318 
319 
320  /* clear mark squares, or fix up invalid spaces. The grant vision
321  * code in expand_lighted_sight() can result in negative numbers */
322  for (x = 0; x < op->contr->socket->mapx; x++) {
323  for (y = 0; y < op->contr->socket->mapy; y++) {
324  /* If space was marked above, or the space has an invalid
325  * darkness (too bright), then set the space to visible */
326  if (op->contr->blocked_los[x][y] <= LOS_MARKED) {
327  op->contr->blocked_los[x][y] = LOS_NO_DARKNESS;
328  }
329  }
330  }
331 }
332 
346 int has_carried_lights(const object *op) {
347  /* op may glow! */
348  if (op->glow_radius > 0)
349  return 1;
350 
351  return 0;
352 }
353 
360 static void expand_lighted_sight(object *op) {
361  int x, y, darklevel, ax, ay, basex, basey, mflags, light_radius, dark_change;
362  mapstruct *m = op->map;
363  int16_t nx, ny;
364 
365  darklevel = MAP_DARKNESS(m);
366 
367  /* If the player can see in the dark (infravision), lower the darklevel for the player */
369  darklevel -= SEE_IN_DARK_LEVELS;
370  }
371 
372  /* add light, by finding all (non-null) nearby light sources, then
373  * mark those squares specially. If the darklevel<1, there is no
374  * reason to do this, so we skip this function
375  */
376  if (darklevel < 1)
377  return;
378 
379  /* Do a sanity check. If not valid, some code below may do odd
380  * things.
381  */
382  if (darklevel > MAX_DARKNESS) {
383  LOG(llevError, "Map darkness for %s on %s is too high (%d)\n", op->name, op->map->path, darklevel);
384  darklevel = MAX_DARKNESS;
385  }
386 
387  /* First, limit player furthest (unlighted) vision */
388  for (x = 0; x < op->contr->socket->mapx; x++)
389  for (y = 0; y < op->contr->socket->mapy; y++)
390  if (op->contr->blocked_los[x][y] != LOS_BLOCKED)
391  op->contr->blocked_los[x][y] = MAX_LIGHT_RADII;
392 
393  /* the spaces[] darkness value contains the information we need.
394  * Only process the area of interest.
395  * the basex, basey values represent the position in the op->contr->blocked_los
396  * array. Its easier to just increment them here (and start with the right
397  * value) than to recalculate them down below.
398  */
399  for (x = (op->x-op->contr->socket->mapx/2-MAX_LIGHT_RADII), basex = -MAX_LIGHT_RADII;
400  x <= (op->x+op->contr->socket->mapx/2+MAX_LIGHT_RADII); x++, basex++) {
401  for (y = (op->y-op->contr->socket->mapy/2-MAX_LIGHT_RADII), basey = -MAX_LIGHT_RADII;
402  y <= (op->y+op->contr->socket->mapy/2+MAX_LIGHT_RADII); y++, basey++) {
403  m = op->map;
404  nx = x;
405  ny = y;
406 
407  mflags = get_map_flags(m, &m, nx, ny, &nx, &ny);
408 
409  if (mflags&P_OUT_OF_MAP)
410  continue;
411 
412  /* This space is providing light, so we need to brighten up the
413  * spaces around here.
414  */
415  light_radius = GET_MAP_LIGHT(m, nx, ny);
416 
417  if (light_radius == 0)
418  continue;
419 
420  for (ax = basex-light_radius; ax <= basex+light_radius; ax++) {
421  /* Check if space is within view */
422  if (ax < 0 || ax >= op->contr->socket->mapx)
423  continue;
424 
425  for (ay = basey-light_radius; ay <= basey+light_radius; ay++) {
426  /* Check if space is within view */
427  if (ay < 0 || ay >= op->contr->socket->mapy)
428  continue;
429 
430  /* If the space is fully blocked, do nothing. */
431  if (op->contr->blocked_los[ax][ay] == LOS_BLOCKED)
432  continue;
433 
434  /* Brighten the space. The further the light is away from the
435  * source (basex-x), the less effect it has. Though light used
436  * to dim in a square manner, it now dims in a circular manner
437  * using the the pythagorean theorem. glow_radius still
438  * represents the radius
439  */
440  int x1 = basex-ax;
441  int y1 = basey-ay;
442 
443  if (light_radius > 0)
444  op->contr->blocked_los[ax][ay] -= MAX((light_radius-ihypot(x1, y1)), 0);
445  if (light_radius < 0)
446  op->contr->blocked_los[ax][ay] -= MIN((light_radius+ihypot(x1, y1)), 0);
447  } /* for ay */
448  } /* for ax */
449  } /* for y */
450  } /* for x */
451 
452  /* Outdoor should never really be completely pitch black dark like
453  * a dungeon, so let the player at least see a little around themselves
454  */
455  if (op->map->outdoor && darklevel > (MAX_DARKNESS-3)) {
456 
457  /* Update player space */
458  if (op->contr->blocked_los[op->contr->socket->mapx/2][op->contr->socket->mapy/2] > (MAX_DARKNESS-3))
459  op->contr->blocked_los[op->contr->socket->mapx/2][op->contr->socket->mapy/2] = MAX_DARKNESS-3;
460 
461  /* Update spaces around player */
462  for (x = -1; x <= 1; x++) {
463  for (y = -1; y <= 1; y++) {
464  if (op->contr->blocked_los[x+op->contr->socket->mapx/2][y+op->contr->socket->mapy/2] > (MAX_DARKNESS-2))
465  op->contr->blocked_los[x+op->contr->socket->mapx/2][y+op->contr->socket->mapy/2] = MAX_DARKNESS-2;
466  }
467  }
468  }
469 
470  /* grant some vision to the player, based on the darklevel
471  * Note this might lighten spaces to be < 0, which is fixed up in expand_sight()
472  */
473  for (x = darklevel-MAX_DARKNESS; x < MAX_DARKNESS+1-darklevel; x++) {
474  for (y = darklevel-MAX_DARKNESS; y < MAX_DARKNESS+1-darklevel; y++) {
475  if (!(op->contr->blocked_los[x+op->contr->socket->mapx/2][y+op->contr->socket->mapy/2] == LOS_BLOCKED)) {
476  dark_change = MAX(0, (MAX_DARKNESS + 1) - darklevel - MAX(abs(x), abs(y)));
477  op->contr->blocked_los[x+op->contr->socket->mapx/2][y+op->contr->socket->mapy/2] -= dark_change;
478  }
479  }
480  }
481 }
482 
492 static void blinded_sight(player *pl) {
493  int x, y;
494 
495  for (x = 0; x < pl->socket->mapx; x++)
496  for (y = 0; y < pl->socket->mapy; y++)
497  pl->blocked_los[x][y] = LOS_BLOCKED;
498 
499  pl->blocked_los[pl->socket->mapx/2][pl->socket->mapy/2] = LOS_NO_DARKNESS;
500 }
501 
509 void update_los(object *op) {
510  int mapx, mapy, dx, dy, x, y;
511 
512  if (QUERY_FLAG(op, FLAG_REMOVED))
513  return;
514 
515  /* Set the LOS array to all visible */
516  clear_los(op->contr);
517  if (QUERY_FLAG(op, FLAG_WIZ) /* || XRAYS(op) */) {
518  return;
519  }
520 
521  /* Locally save mapx/mapy to save some dereferences */
522  mapx = op->contr->socket->mapx;
523  mapy = op->contr->socket->mapy;
524 
525  /* For larger maps, this is more efficient than the old way which
526  * used the chaining of the block array. Since many space views could
527  * be blocked by different spaces in front, this mean that a lot of spaces
528  * could be examined multiple times, as each path would be looked at.
529  */
530  for (x = (MAP_CLIENT_X-mapx)/2+1; x < (MAP_CLIENT_X+mapx)/2-1; x++)
531  for (y = (MAP_CLIENT_Y-mapy)/2+1; y < (MAP_CLIENT_Y+mapy)/2-1; y++)
532  check_wall(op, x, y);
533 
534  /* do the los of the player. 3 (potential) cases */
535  if (QUERY_FLAG(op, FLAG_BLIND)) { /* player is blind */
536  blinded_sight(op->contr);
537  }
538  else {
539  expand_sight(op);
540  }
541 
542  if (QUERY_FLAG(op, FLAG_XRAYS)) {
543  dx = mapx / 2;
544  dy = mapy / 2;
545 
546  for (x = -XRAY_RADIUS; x <= XRAY_RADIUS; x++)
547  for (y = -XRAY_RADIUS; y <= XRAY_RADIUS; y++)
548  op->contr->blocked_los[dx+x][dy+y] = LOS_NO_DARKNESS;
549  }
550 }
551 
568  player *pl;
569 
570  for (pl = first_player; pl != NULL; pl = pl->next) {
571  if (pl->ob->map == map)
572  pl->do_los = 1;
573  }
574 }
575 
595 void update_all_los(const mapstruct *map, int x, int y) {
596  player *pl;
597 
598  for (pl = first_player; pl != NULL; pl = pl->next) {
599  /* Player should not have a null map, but do this
600  * check as a safety
601  */
602  if (!pl->ob->map)
603  continue;
604 
605  /* Same map is simple case - see if pl is close enough.
606  * Note in all cases, we did the check for same map first,
607  * and then see if the player is close enough and update
608  * los if that is the case. If the player is on the
609  * corresponding map, but not close enough, then the
610  * player can't be on another map that may be closer,
611  * so by setting it up this way, we trim processing
612  * some.
613  */
614  if (pl->ob->map == map) {
615  if ((abs(pl->ob->x-x) <= pl->socket->mapx/2)
616  && (abs(pl->ob->y-y) <= pl->socket->mapy/2))
617  pl->do_los = 1;
618  }
619  /* Now we check to see if player is on adjacent
620  * maps to the one that changed and also within
621  * view. The tile_maps[] could be null, but in that
622  * case it should never match the pl->ob->map, so
623  * we want ever try to dereference any of the data in it.
624  */
625 
626  /* The logic for 0 and 3 is to see how far the player is
627  * from the edge of the map (height/width) - pl->ob->(x,y)
628  * and to add current position on this map - that gives a
629  * distance.
630  * For 1 and 2, we check to see how far the given
631  * coordinate (x,y) is from the corresponding edge,
632  * and then add the players location, which gives
633  * a distance.
634  */
635  else if (pl->ob->map == map->tile_map[0]) {
636  if ((abs(pl->ob->x-x) <= pl->socket->mapx/2)
637  && (abs(y+MAP_HEIGHT(map->tile_map[0])-pl->ob->y) <= pl->socket->mapy/2))
638  pl->do_los = 1;
639  } else if (pl->ob->map == map->tile_map[2]) {
640  if ((abs(pl->ob->x-x) <= pl->socket->mapx/2)
641  && (abs(pl->ob->y+MAP_HEIGHT(map)-y) <= pl->socket->mapy/2))
642  pl->do_los = 1;
643  } else if (pl->ob->map == map->tile_map[1]) {
644  if ((abs(pl->ob->x+MAP_WIDTH(map)-x) <= pl->socket->mapx/2)
645  && (abs(pl->ob->y-y) <= pl->socket->mapy/2))
646  pl->do_los = 1;
647  } else if (pl->ob->map == map->tile_map[3]) {
648  if ((abs(x+MAP_WIDTH(map->tile_map[3])-pl->ob->x) <= pl->socket->mapx/2)
649  && (abs(pl->ob->y-y) <= pl->socket->mapy/2))
650  pl->do_los = 1;
651  }
652  }
653 }
654 
665 void print_los(object *op) {
666  int x, y;
667  char buf[MAP_CLIENT_X*2+20], buf2[10];
668 
669  snprintf(buf, sizeof(buf), "[fixed] ");
670  for (x = 0; x < op->contr->socket->mapx; x++) {
671  snprintf(buf2, sizeof(buf2), "%2d", x);
672  strncat(buf, buf2, sizeof(buf)-strlen(buf)-1);
673  }
675  for (y = 0; y < op->contr->socket->mapy; y++) {
676  snprintf(buf, sizeof(buf), "[fixed]%2d:", y);
677  for (x = 0; x < op->contr->socket->mapx; x++) {
678  snprintf(buf2, sizeof(buf2), " %1d", op->contr->blocked_los[x][y] == LOS_BLOCKED ? 1 : 0);
679  strncat(buf, buf2, sizeof(buf)-strlen(buf)-1);
680  }
682  }
683 }
684 
695 void make_sure_seen(const object *op) {
696  player *pl;
697 
698  for (pl = first_player; pl; pl = pl->next)
699  if (pl->ob->map == op->map
700  && pl->ob->y-pl->socket->mapy/2 <= op->y
701  && pl->ob->y+pl->socket->mapy/2 >= op->y
702  && pl->ob->x-pl->socket->mapx/2 <= op->x
703  && pl->ob->x+pl->socket->mapx/2 >= op->x)
704  pl->blocked_los[pl->socket->mapx/2+op->x-pl->ob->x][pl->socket->mapy/2+op->y-pl->ob->y] = LOS_NO_DARKNESS;
705 }
706 
718 void make_sure_not_seen(const object *op) {
719  player *pl;
720 
721  for (pl = first_player; pl; pl = pl->next)
722  if (pl->ob->map == op->map
723  && pl->ob->y-pl->socket->mapy/2 <= op->y
724  && pl->ob->y+pl->socket->mapy/2 >= op->y
725  && pl->ob->x-pl->socket->mapx/2 <= op->x
726  && pl->ob->x+pl->socket->mapx/2 >= op->x)
727  pl->do_los = 1;
728 }
MAP_CLIENT_X
#define MAP_CLIENT_X
Definition: config.h:237
make_sure_not_seen
void make_sure_not_seen(const object *op)
Definition: los.cpp:718
LOS_BLOCKED
#define LOS_BLOCKED
Definition: los.cpp:48
global.h
first_player
player * first_player
Definition: init.cpp:106
banquet.l
l
Definition: banquet.py:164
set_wall
static void set_wall(player *pl, int x, int y)
Definition: los.cpp:188
llevError
@ llevError
Definition: logger.h:11
FABS
#define FABS(x)
Definition: define.h:22
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
blocks::y
int y[4]
Definition: los.cpp:53
player
Definition: player.h:105
diamondslots.x
x
Definition: diamondslots.py:15
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
blinded_sight
static void blinded_sight(player *pl)
Definition: los.cpp:492
FLAG_SEE_IN_DARK
#define FLAG_SEE_IN_DARK
Definition: define.h:337
MIN
#define MIN(x, y)
Definition: compat.h:21
blocks::x
int x[4]
Definition: los.cpp:53
expand_lighted_sight
static void expand_lighted_sight(object *op)
Definition: los.cpp:360
MAP_DARKNESS
#define MAP_DARKNESS(m)
Definition: map.h:70
FLAG_BLIND
#define FLAG_BLIND
Definition: define.h:336
buf
StringBuffer * buf
Definition: readable.cpp:1565
ihypot
int ihypot(int a, int b)
Definition: utils.cpp:570
MSG_TYPE_COMMAND
#define MSG_TYPE_COMMAND
Definition: newclient.h:393
MAX
#define MAX(x, y)
Definition: compat.h:24
MSG_TYPE_COMMAND_DEBUG
#define MSG_TYPE_COMMAND_DEBUG
Definition: newclient.h:517
m
static event_registration m
Definition: citylife.cpp:425
clear_los
void clear_los(player *pl)
Definition: los.cpp:270
blocks::index
int index
Definition: los.cpp:54
MAP_CLIENT_Y
#define MAP_CLIENT_Y
Definition: config.h:238
disinfect.map
map
Definition: disinfect.py:4
freearr_y
short freearr_y[SIZEOFFREE]
Definition: object.cpp:305
init_block
void init_block(void)
Definition: los.cpp:106
MAX_DARKNESS
#define MAX_DARKNESS
Definition: define.h:454
has_carried_lights
int has_carried_lights(const object *op)
Definition: los.cpp:346
SEE_IN_DARK_LEVELS
#define SEE_IN_DARK_LEVELS
Definition: los.cpp:43
GET_MAP_LIGHT
#define GET_MAP_LIGHT(M, X, Y)
Definition: map.h:162
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:73
P_OUT_OF_MAP
#define P_OUT_OF_MAP
Definition: map.h:247
set_block
static void set_block(int x, int y, int bx, int by)
Definition: los.cpp:79
print_los
void print_los(object *op)
Definition: los.cpp:665
block
static blocks block[MAP_CLIENT_X][MAP_CLIENT_Y]
Definition: los.cpp:57
FLAG_REMOVED
#define FLAG_REMOVED
Definition: define.h:232
FLAG_WIZ
#define FLAG_WIZ
Definition: define.h:231
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
get_map_flags
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.cpp:300
mapstruct
Definition: map.h:313
give.op
op
Definition: give.py:33
diamondslots.y
y
Definition: diamondslots.py:16
npc_dialog.index
int index
Definition: npc_dialog.py:102
check_wall
static void check_wall(object *op, int x, int y)
Definition: los.cpp:235
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:75
update_all_map_los
void update_all_map_los(mapstruct *map)
Definition: los.cpp:567
LOS_NO_DARKNESS
#define LOS_NO_DARKNESS
Definition: los.cpp:49
expand_sight
static void expand_sight(object *op)
Definition: los.cpp:291
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.cpp:308
blocks
Definition: los.cpp:52
XRAY_RADIUS
#define XRAY_RADIUS
Definition: los.cpp:37
update_all_los
void update_all_los(const mapstruct *map, int x, int y)
Definition: los.cpp:595
FLAG_XRAYS
#define FLAG_XRAYS
Definition: define.h:300
update_los
void update_los(object *op)
Definition: los.cpp:509
freearr_x
short freearr_x[SIZEOFFREE]
Definition: object.cpp:299
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
MAX_LIGHT_RADII
#define MAX_LIGHT_RADII
Definition: define.h:450
make_sure_seen
void make_sure_seen(const object *op)
Definition: los.cpp:695
llevDebug
@ llevDebug
Definition: logger.h:13
SPACE_BLOCK
#define SPACE_BLOCK
Definition: los.cpp:32
P_BLOCKSVIEW
#define P_BLOCKSVIEW
Definition: map.h:224
LOS_MARKED
#define LOS_MARKED
Definition: los.cpp:50