Crossfire Client, Trunk  R20922
mapdata.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 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 "client.h"
20 
21 #include <assert.h>
22 #include <stdbool.h>
23 
24 #include "external.h"
25 #include "mapdata.h"
26 
30 #define FOG_MAP_SIZE 512
31 
36 #define FOG_BORDER_MIN 128
37 
41 #define MAX_FACE_SIZE 16
42 
43 /* Max it can currently be. Important right now because
44  * animation has to look at everything that may be viewable,
45  * and reducing this size basically reduces processing it needs
46  * to do by 75% (64^2 vs 33^2)
47  */
48 #define CURRENT_MAX_VIEW 33
49 
63 struct BigCell {
64  struct BigCell *next;
65  struct BigCell *prev;
66 
69 
70  guint16 x, y;
71  guint8 layer;
72 };
73 
74 
75 static void recenter_virtual_map_view(int diff_x, int diff_y);
76 static void mapdata_get_image_size(int face, guint8 *w, guint8 *h);
77 
78 
79 static int width; //< width of current map view
80 static int height; //< height of current map view
81 
82 
87 static struct BigCell *bigfaces_head;
88 
95 
96 static struct Map the_map;
97 
101 static void clear_cells(int x, int y, int len_y) {
102  int clear_cells_i, j;
103  memset(mapdata_cell(x, y), 0, sizeof(struct MapCell)*len_y);
104 
105  for (clear_cells_i = 0; clear_cells_i < (len_y); clear_cells_i++) {
106  for (j=0; j < MAXLAYERS; j++) {
107  mapdata_cell(x, y+clear_cells_i)->heads[j].size_x = 1;
108  mapdata_cell(x, y+clear_cells_i)->heads[j].size_y = 1;
109  }
110  }
111 }
112 
116 inline struct MapCell *mapdata_cell(int x, int y) {
117  return &the_map._cells[x][y];
118 }
119 
123 bool mapdata_contains(int x, int y) {
124  if (x < 0 || y < 0 || the_map.width <= x || the_map.height <= y) {
125  return false;
126  }
127 
128  return true;
129 }
130 
131 bool mapdata_can_smooth(int x, int y, int layer) {
132  return (mapdata_cell(x, y)->heads[layer].face == 0 && layer > 0) ||
133  mapdata_cell(x, y)->smooth[layer];
134 }
135 
139 void mapdata_size(int *x, int *y) {
140  if (x != NULL) {
141  *x = the_map.width;
142  }
143 
144  if (y != NULL) {
145  *y = the_map.height;
146  }
147 }
148 
157 static void set_darkness(int x, int y, int darkness)
158 {
159  mapdata_cell(x, y)->have_darkness = 1;
160  if (mapdata_cell(x, y)->darkness == darkness) {
161  return;
162  }
163 
164  mapdata_cell(x, y)->darkness = darkness;
165  mapdata_cell(x, y)->need_update = 1;
166 
167  /* pretty ugly - since the light code with pngximage uses neighboring
168  * spaces to adjust the darkness, we now need to let the neighbors know
169  * they should update their darkness now.
170  */
174  if (x > 1) {
175  mapdata_cell(x-1, y)->need_update = 1;
176  }
177  if (y > 1) {
178  mapdata_cell(x, y-1)->need_update = 1;
179  }
180  if (x < width-1) {
181  mapdata_cell(x+1, y)->need_update = 1;
182  }
183  if (y < height-1) {
184  mapdata_cell(x, y+1)->need_update = 1;
185  }
186  }
187 }
188 
189 static void mark_resmooth(int x, int y, int layer)
190 {
191  int sdx,sdy;
192  if (mapdata_cell(x, y)->smooth[layer]>1) {
193  for (sdx=-1; sdx<2; sdx++)
194  for (sdy=-1; sdy<2; sdy++)
195  if ( (sdx || sdy) /* ignore (0,0) */
196  && ( (x+sdx >0) && (x+sdx < the_map.width) && /* only inside map */
197  (y+sdy >0) && (y+sdy < the_map.height) ) ) {
198  mapdata_cell(x+sdx, y+sdy)->need_resmooth=1;
199  }
200  }
201 }
210 static void expand_clear_face(int x, int y, int w, int h, int layer)
211 {
212  int dx, dy;
213  struct MapCell *cell;
214 
215  assert(0 <= x && x < the_map.width);
216  assert(0 <= y && y < the_map.height);
217  assert(1 <= w && w <= MAX_FACE_SIZE);
218  assert(1 <= h && h <= MAX_FACE_SIZE);
219 
220  assert(0 <= x-w+1 && x-w+1 < the_map.width);
221  assert(0 <= y-h+1 && y-h+1 < the_map.height);
222 
223  cell = mapdata_cell(x, y);
224 
225  for (dx = 0; dx < w; dx++) {
226  for (dy = !dx; dy < h; dy++) {
227  struct MapCellTailLayer *tail = &mapdata_cell(x-dx, y-dy)->tails[layer];
228  assert(0 <= x-dx && x-dx < the_map.width);
229  assert(0 <= y-dy && y-dy < the_map.height);
230  assert(0 <= layer && layer < MAXLAYERS);
231 
232  /* Do not clear faces that already have been overwritten by another
233  * face.
234  */
235  if (tail->face == cell->heads[layer].face
236  && tail->size_x == dx
237  && tail->size_y == dy) {
238  tail->face = 0;
239  tail->size_x = 0;
240  tail->size_y = 0;
241  mapdata_cell(x-dx, y-dy)->need_update = 1;
242  }
243  mark_resmooth(x-dx,y-dy,layer);
244  }
245  }
246 
247  cell->heads[layer].face = 0;
248  cell->heads[layer].animation = 0;
249  cell->heads[layer].animation_speed = 0;
250  cell->heads[layer].animation_left = 0;
251  cell->heads[layer].animation_phase = 0;
252  cell->heads[layer].size_x = 1;
253  cell->heads[layer].size_y = 1;
254  cell->need_update = 1;
255  cell->need_resmooth = 1;
256  mark_resmooth(x,y,layer);
257 }
258 
265 static void expand_clear_face_from_layer(int x, int y, int layer)
266 {
267  const struct MapCellLayer *cell;
268 
269  assert(0 <= x && x < the_map.width);
270  assert(0 <= y && y < the_map.height);
271  assert(0 <= layer && layer < MAXLAYERS);
272 
273  cell = &mapdata_cell(x, y)->heads[layer];
274  if (cell->size_x && cell->size_y) {
275  expand_clear_face(x, y, cell->size_x, cell->size_y, layer);
276  }
277 }
278 
292 static void expand_set_face(int x, int y, int layer, gint16 face, int clear)
293 {
294  struct MapCell *cell;
295  int dx, dy;
296  guint8 w, h;
297 
298  assert(0 <= x && x < the_map.width);
299  assert(0 <= y && y < the_map.height);
300  assert(0 <= layer && layer < MAXLAYERS);
301 
302  cell = mapdata_cell(x, y);
303 
304  if (clear) {
305  expand_clear_face_from_layer(x, y, layer);
306  }
307 
308  mapdata_get_image_size(face, &w, &h);
309  assert(1 <= w && w <= MAX_FACE_SIZE);
310  assert(1 <= h && h <= MAX_FACE_SIZE);
311  cell->heads[layer].face = face;
312  cell->heads[layer].size_x = w;
313  cell->heads[layer].size_y = h;
314  cell->need_update=1;
315  mark_resmooth(x,y,layer);
316 
317  for (dx = 0; dx < w; dx++) {
318  for (dy = !dx; dy < h; dy++) {
319  struct MapCellTailLayer *tail = &mapdata_cell(x-dx, y-dy)->tails[layer];
320  assert(0 <= x-dx && x-dx < the_map.width);
321  assert(0 <= y-dy && y-dy < the_map.height);
322  assert(0 <= layer && layer < MAXLAYERS);
323 
324  tail->face = face;
325  tail->size_x = dx;
326  tail->size_y = dy;
327  mapdata_cell(x-dx, y-dy)->need_update = 1;
328  mark_resmooth(x-dx,y-dy,layer);
329  }
330  }
331 }
332 
343 static void expand_clear_bigface(int x, int y, int w, int h, int layer, int set_need_update)
344 {
345  int dx, dy;
346  struct MapCellLayer *head;
347 
348  assert(0 <= x && x < MAX_VIEW);
349  assert(0 <= y && y < MAX_VIEW);
350  assert(1 <= w && w <= MAX_FACE_SIZE);
351  assert(1 <= h && h <= MAX_FACE_SIZE);
352 
353  head = &bigfaces[x][y][layer].head;
354 
355  for (dx = 0; dx < w && dx <= x; dx++) {
356  for (dy = !dx; dy < h && dy <= y; dy++) {
357  struct MapCellTailLayer *tail = &bigfaces[x-dx][y-dy][layer].tail;
358  assert(0 <= x-dx && x-dx < MAX_VIEW);
359  assert(0 <= y-dy && y-dy < MAX_VIEW);
360  assert(0 <= layer && layer < MAXLAYERS);
361 
362  /* Do not clear faces that already have been overwritten by another
363  * face.
364  */
365  if (tail->face == head->face
366  && tail->size_x == dx
367  && tail->size_y == dy) {
368  tail->face = 0;
369  tail->size_x = 0;
370  tail->size_y = 0;
371 
372  if (0 <= x-dx && x-dx < width
373  && 0 <= y-dy && y-dy < height) {
374  assert(0 <= pl_pos.x+x-dx && pl_pos.x+x-dx < the_map.width);
375  assert(0 <= pl_pos.y+y-dy && pl_pos.y+y-dy < the_map.height);
376  if (set_need_update) {
377  mapdata_cell(pl_pos.x+x-dx, pl_pos.y+y-dy)->need_update = 1;
378  }
379  }
380  }
381  }
382  }
383 
384  head->face = 0;
385  head->size_x = 1;
386  head->size_y = 1;
387 }
388 
397 static void expand_clear_bigface_from_layer(int x, int y, int layer, int set_need_update)
398 {
399  struct BigCell *headcell;
400  const struct MapCellLayer *head;
401 
402  assert(0 <= x && x < MAX_VIEW);
403  assert(0 <= y && y < MAX_VIEW);
404  assert(0 <= layer && layer < MAXLAYERS);
405 
406  headcell = &bigfaces[x][y][layer];
407  head = &headcell->head;
408  if (head->face != 0) {
409  assert(headcell->prev != NULL || headcell == bigfaces_head);
410 
411  /* remove from bigfaces_head list */
412  if (headcell->prev != NULL) {
413  headcell->prev->next = headcell->next;
414  }
415  if (headcell->next != NULL) {
416  headcell->next->prev = headcell->prev;
417  }
418  if (bigfaces_head == headcell) {
419  assert(headcell->prev == NULL);
420  bigfaces_head = headcell->next;
421  } else {
422  assert(headcell->prev != NULL);
423  }
424  headcell->prev = NULL;
425  headcell->next = NULL;
426 
427  expand_clear_bigface(x, y, head->size_x, head->size_y, layer, set_need_update);
428  } else {
429  assert(headcell->prev == NULL && headcell != bigfaces_head);
430  assert(head->size_x == 1);
431  assert(head->size_y == 1);
432  }
433 }
434 
443 static void expand_set_bigface(int x, int y, int layer, gint16 face, int clear)
444 {
445  struct BigCell *headcell;
446  struct MapCellLayer *head;
447  int dx, dy;
448  guint8 w, h;
449 
450  assert(0 <= x && x < MAX_VIEW);
451  assert(0 <= y && y < MAX_VIEW);
452  assert(0 <= layer && layer < MAXLAYERS);
453 
454  headcell = &bigfaces[x][y][layer];
455  head = &headcell->head;
456  if (clear) {
457  expand_clear_bigface_from_layer(x, y, layer, 1);
458  }
459 
460  /* add to bigfaces_head list */
461  if (face != 0) {
462  assert(headcell->prev == NULL);
463  assert(headcell->next == NULL);
464  assert(headcell != bigfaces_head);
465  if (bigfaces_head != NULL) {
466  assert(bigfaces_head->prev == NULL);
467  bigfaces_head->prev = headcell;
468  }
469  headcell->next = bigfaces_head;
470  bigfaces_head = headcell;
471  }
472 
473  mapdata_get_image_size(face, &w, &h);
474  assert(1 <= w && w <= MAX_FACE_SIZE);
475  assert(1 <= h && h <= MAX_FACE_SIZE);
476  head->face = face;
477  head->size_x = w;
478  head->size_y = h;
479 
480  for (dx = 0; dx < w && dx <= x; dx++) {
481  for (dy = !dx; dy < h && dy <= y; dy++) {
482  struct MapCellTailLayer *tail = &bigfaces[x-dx][y-dy][layer].tail;
483  assert(0 <= x-dx && x-dx < MAX_VIEW);
484  assert(0 <= y-dy && y-dy < MAX_VIEW);
485  assert(0 <= layer && layer < MAXLAYERS);
486 
487  tail->face = face;
488  tail->size_x = dx;
489  tail->size_y = dy;
490 
491  if (0 <= x-dx && x-dx < width
492  && 0 <= y-dy && y-dy < height) {
493  assert(0 <= pl_pos.x+x-dx && pl_pos.x+x-dx < the_map.width);
494  assert(0 <= pl_pos.y+y-dy && pl_pos.y+y-dy < the_map.height);
495  mapdata_cell(pl_pos.x+x-dx, pl_pos.y+y-dy)->need_update = 1;
496  }
497  }
498  }
499 }
500 
508 static void expand_need_update(int x, int y, int w, int h)
509 {
510  int dx, dy;
511 
512  assert(0 <= x && x < the_map.width);
513  assert(0 <= y && y < the_map.height);
514  assert(1 <= w && w <= MAX_FACE_SIZE);
515  assert(1 <= h && h <= MAX_FACE_SIZE);
516 
517  assert(0 <= x-w+1 && x-w+1 < the_map.width);
518  assert(0 <= y-h+1 && y-h+1 < the_map.height);
519 
520  for (dx = 0; dx < w; dx++) {
521  for (dy = 0; dy < h; dy++) {
522  struct MapCell *cell = mapdata_cell(x-dx, y-dy);
523  assert(0 <= x-dx && x-dx < the_map.width);
524  assert(0 <= y-dy && y-dy < the_map.height);
525  cell->need_update = 1;
526  }
527  }
528 }
529 
536 static void expand_need_update_from_layer(int x, int y, int layer)
537 {
538  struct MapCellLayer *head;
539 
540  assert(0 <= x && x < the_map.width);
541  assert(0 <= y && y < the_map.height);
542  assert(0 <= layer && layer < MAXLAYERS);
543 
544  head = &mapdata_cell(x, y)->heads[layer];
545  if (head->face != 0) {
546  expand_need_update(x, y, head->size_x, head->size_y);
547  } else {
548  assert(head->size_x == 1);
549  assert(head->size_y == 1);
550  }
551 }
552 
557 static void mapdata_alloc(struct Map* const map, const int width, const int height) {
558  map->_cells = (struct MapCell **)g_new(struct MapCell, width * (height + 1));
559  g_assert(map->_cells != NULL); // g_new() always succeeds
560  map->width = width;
561  map->height = height;
562 
563  /* Skip past the first row of pointers to rows and assign the
564  * start of the actual map data
565  */
566  map->_cells[0] = (struct MapCell *)((char *)map->_cells+(sizeof(struct MapCell *)*map->width));
567 
568  /* Finish assigning the beginning of each row relative to the
569  * first row assigned above
570  */
571  for (int i = 0; i < map->width; i++) {
572  map->_cells[i] = map->_cells[0]+i*map->height;
573  }
574 }
575 
576 static void mapdata_init(void)
577 {
578  int x, y;
579  int i;
580 
582 
583  width = 0;
584  height = 0;
585  pl_pos.x = the_map.width/2-width/2;
586  pl_pos.y = the_map.height/2-height/2;
587 
588  for (x = 0; x < the_map.width; x++) {
589  clear_cells(x, 0, the_map.height);
590  }
591 
592  for (y = 0; y < MAX_VIEW; y++) {
593  for (x = 0; x < MAX_VIEW; x++) {
594  for (i = 0; i < MAXLAYERS; i++) {
595  bigfaces[x][y][i].next = NULL;
596  bigfaces[x][y][i].prev = NULL;
597  bigfaces[x][y][i].head.face = 0;
598  bigfaces[x][y][i].head.size_x = 1;
599  bigfaces[x][y][i].head.size_y = 1;
600  bigfaces[x][y][i].tail.face = 0;
601  bigfaces[x][y][i].tail.size_x = 0;
602  bigfaces[x][y][i].tail.size_y = 0;
603  bigfaces[x][y][i].x = x;
604  bigfaces[x][y][i].y = y;
605  bigfaces[x][y][i].layer = i;
606  }
607  }
608  }
609  bigfaces_head = NULL;
610 }
611 
612 void mapdata_free(void) {
613  if (the_map._cells != NULL) {
614  g_free(the_map._cells);
615  the_map._cells = NULL;
616  }
617 }
618 
619 void mapdata_set_size(int viewx, int viewy)
620 {
621  mapdata_free();
622  mapdata_init();
623 
624  width = viewx;
625  height = viewy;
626  pl_pos.x = the_map.width/2-width/2;
627  pl_pos.y = the_map.height/2-height/2;
628 }
629 
630 int mapdata_is_inside(int x, int y)
631 {
632  return(x >= 0 && x < width && y >= 0 && y < height);
633 }
634 
635 /* mapdate_clear_space() is used by Map2Cmd()
636  * Basically, server has told us there is nothing on
637  * this space. So clear it.
638  */
639 void mapdata_clear_space(int x, int y)
640 {
641  int px, py;
642  int i;
643 
644  assert(0 <= x && x < MAX_VIEW);
645  assert(0 <= y && y < MAX_VIEW);
646 
647  px = pl_pos.x+x;
648  py = pl_pos.y+y;
649  assert(0 <= px && px < the_map.width);
650  assert(0 <= py && py < the_map.height);
651 
652  if (x < width && y < height) {
653  /* tile is visible */
654 
655  /* visible tile is now blank ==> do not clear but mark as cleared */
656  if (!mapdata_cell(px, py)->cleared) {
657  mapdata_cell(px, py)->cleared = 1;
658  mapdata_cell(px, py)->need_update = 1;
659 
660  for (i=0; i < MAXLAYERS; i++)
661  if (mapdata_cell(px, py)->heads[i].face) {
663  }
664  }
665  } else {
666  /* tile is invisible (outside view area, i.e. big face update) */
667 
668  for (i = 0; i < MAXLAYERS; i++) {
669  expand_set_bigface(x, y, i, 0, TRUE);
670  }
671  }
672 }
673 
674 
675 /* With map2, we basically process a piece of data at a time. Thus,
676  * for each piece, we don't know what the final state of the space
677  * will be. So once Map2Cmd() has processed all the information for
678  * a space, it calls mapdata_set_check_space() which can see if
679  * the space is cleared or other inconsistencies.
680  */
682 {
683  int px, py;
684  int is_blank;
685  int i;
686  struct MapCell *cell;
687 
688  assert(0 <= x && x < MAX_VIEW);
689  assert(0 <= y && y < MAX_VIEW);
690 
691  px = pl_pos.x+x;
692  py = pl_pos.y+y;
693 
694  assert(0 <= px && px < the_map.width);
695  assert(0 <= py && py < the_map.height);
696 
697 
698  is_blank=1;
699  cell = mapdata_cell(px, py);
700  for (i=0; i < MAXLAYERS; i++) {
701  if (cell->heads[i].face>0 || cell->tails[i].face>0) {
702  is_blank=0;
703  break;
704  }
705  }
706 
707  if (cell->have_darkness) {
708  is_blank=0;
709  }
710 
711  /* We only care if this space needs to be blanked out */
712  if (!is_blank) {
713  return;
714  }
715 
716  if (x < width && y < height) {
717  /* tile is visible */
718 
719  /* visible tile is now blank ==> do not clear but mark as cleared */
720  if (!mapdata_cell(px, py)->cleared) {
721  mapdata_cell(px, py)->cleared = 1;
722  mapdata_cell(px, py)->need_update = 1;
723 
724  for (i=0; i < MAXLAYERS; i++) {
726  }
727  }
728  }
729 }
730 
731 
732 
733 /* This just sets the darkness for a space.
734  * Used by Map2Cmd()
735  */
736 void mapdata_set_darkness(int x, int y, int darkness)
737 {
738  int px, py;
739 
740  assert(0 <= x && x < MAX_VIEW);
741  assert(0 <= y && y < MAX_VIEW);
742 
743  px = pl_pos.x+x;
744  py = pl_pos.y+y;
745  assert(0 <= px && px < the_map.width);
746  assert(0 <= py && py < the_map.height);
747 
748  /* Ignore darkness information for tile outside the viewable area: if
749  * such a tile becomes visible again, it is either "fog of war" (and
750  * darkness information is ignored) or it will be updated (including
751  * the darkness information).
752  */
753  if (darkness != -1 && x < width && y < height) {
754  set_darkness(px, py, 255-darkness);
755  }
756 }
757 
758 /* Sets smooth information for layer */
759 void mapdata_set_smooth(int x, int y, guint8 smooth, int layer)
760 {
761  static int dx[8]= {0,1,1,1,0,-1,-1,-1};
762  static int dy[8]= {-1,-1,0,1,1,1,0,-1};
763  int rx, ry, px, py, i;
764 
765  assert(0 <= x && x < MAX_VIEW);
766  assert(0 <= y && y < MAX_VIEW);
767 
768  px = pl_pos.x+x;
769  py = pl_pos.y+y;
770  assert(0 <= px && px < the_map.width);
771  assert(0 <= py && py < the_map.height);
772 
773  if (mapdata_cell(px, py)->smooth[layer] != smooth) {
774  for (i=0; i<8; i++) {
775  rx=px+dx[i];
776  ry=py+dy[i];
777  if ( (rx<0) || (ry<0) || (the_map.width<=rx) || (the_map.height<=ry)) {
778  continue;
779  }
780  mapdata_cell(rx, ry)->need_resmooth=1;
781  }
782  mapdata_cell(px, py)->need_resmooth=1;
783  mapdata_cell(px, py)->smooth[layer] = smooth;
784  }
785 }
786 
787 /* If old cell data is set and is to be cleared, clear it.
788  * This used to be in mapdata_set_face_layer(), however it needs to be
789  * called here, earlier in the Map2Cmd() because otherwise darkness
790  * doesn't work went sent before the layer data when that square was
791  * going to be cleared. This is used by the Map2Cmd()
792  */
793 void mapdata_clear_old(int x, int y)
794 {
795  int px, py;
796  int i;
797 
798  assert(0 <= x && x < MAX_VIEW);
799  assert(0 <= y && y < MAX_VIEW);
800 
801  px = pl_pos.x+x;
802  py = pl_pos.y+y;
803  assert(0 <= px && px < the_map.width);
804  assert(0 <= py && py < the_map.height);
805 
806  if (x < width && y < height)
807  if (mapdata_cell(px, py)->cleared) {
808  for (i=0; i < MAXLAYERS; i++) {
809  expand_clear_face_from_layer(px, py, i);
810  }
811 
812  mapdata_cell(px, py)->darkness = 0;
813  mapdata_cell(px, py)->have_darkness = 0;
814  }
815 }
816 
817 /* This is vaguely related to the mapdata_set_face() above, but rather
818  * than take all the faces, takes 1 face and the layer this face is
819  * on. This is used by the Map2Cmd()
820  */
821 void mapdata_set_face_layer(int x, int y, gint16 face, int layer)
822 {
823  int px, py;
824 
825  assert(0 <= x && x < MAX_VIEW);
826  assert(0 <= y && y < MAX_VIEW);
827 
828  px = pl_pos.x+x;
829  py = pl_pos.y+y;
830  assert(0 <= px && px < the_map.width);
831  assert(0 <= py && py < the_map.height);
832 
833  if (x < width && y < height) {
834  mapdata_cell(px, py)->need_update = 1;
835  if (face >0) {
836  expand_set_face(px, py, layer, face, TRUE);
837  } else {
838  expand_clear_face_from_layer(px, py, layer);
839  }
840 
841  mapdata_cell(px, py)->cleared = 0;
842  } else {
843  expand_set_bigface(x, y, layer, face, TRUE);
844  }
845 }
846 
847 
848 /* This is vaguely related to the mapdata_set_face() above, but rather
849  * than take all the faces, takes 1 face and the layer this face is
850  * on. This is used by the Map2Cmd()
851  */
852 void mapdata_set_anim_layer(int x, int y, guint16 anim, guint8 anim_speed, int layer)
853 {
854  int px, py;
855  int i, face, animation, phase, speed_left;
856 
857  assert(0 <= x && x < MAX_VIEW);
858  assert(0 <= y && y < MAX_VIEW);
859 
860  px = pl_pos.x+x;
861  py = pl_pos.y+y;
862  assert(0 <= px && px < the_map.width);
863  assert(0 <= py && py < the_map.height);
864 
865  animation = anim & ANIM_MASK;
866  face = 0;
867 
868  /* Random animation is pretty easy */
869  if ((anim & ANIM_FLAGS_MASK) == ANIM_RANDOM) {
870  const guint8 num_animations = animations[animation].num_animations;
871  if (num_animations == 0) {
872  LOG(LOG_WARNING, "mapdata_set_anim_layer",
873  "animating object with zero animations");
874  return;
875  }
876  phase = g_random_int() % num_animations;
877  face = animations[animation].faces[phase];
878  speed_left = anim_speed % g_random_int();
879  } else if ((anim & ANIM_FLAGS_MASK) == ANIM_SYNC) {
880  animations[animation].speed = anim_speed;
881  phase = animations[animation].phase;
882  speed_left = animations[animation].speed_left;
883  face = animations[animation].faces[phase];
884  }
885 
886  if (x < width && y < height) {
887  mapdata_cell(px, py)->need_update = 1;
888  if (mapdata_cell(px, py)->cleared) {
889  for (i=0; i < MAXLAYERS; i++) {
890  expand_clear_face_from_layer(px, py, i);
891  }
892 
893  mapdata_cell(px, py)->darkness = 0;
894  mapdata_cell(px, py)->have_darkness = 0;
895  }
896  if (face >0) {
897  expand_set_face(px, py, layer, face, TRUE);
898  mapdata_cell(px, py)->heads[layer].animation = animation;
899  mapdata_cell(px, py)->heads[layer].animation_phase = phase;
900  mapdata_cell(px, py)->heads[layer].animation_speed = anim_speed;
901  mapdata_cell(px, py)->heads[layer].animation_left = speed_left;
902  } else {
903  expand_clear_face_from_layer(px, py, layer);
904  }
905 
906  mapdata_cell(px, py)->cleared = 0;
907 
908  } else {
909  expand_set_bigface(x, y, layer, face, TRUE);
910  }
911 }
912 
913 
914 void mapdata_scroll(int dx, int dy)
915 {
916  int x, y;
917 
919 
921  struct BigCell *cell;
922 
923  /* Mark all tiles as "need_update" that are overlapped by a big face
924  * from outside the view area.
925  */
926  for (cell = bigfaces_head; cell != NULL; cell = cell->next) {
927  for (x = 0; x < cell->head.size_x; x++) {
928  for (y = !x; y < cell->head.size_y; y++) {
929  if (0 <= cell->x-x && cell->x-x < width
930  && 0 <= cell->y-y && cell->y-y < height) {
931  mapdata_cell(pl_pos.x+cell->x-x, pl_pos.y+cell->y-y)->need_update = 1;
932  }
933  }
934  }
935  }
936  } else {
937  /* Emulate map scrolling by redrawing all tiles. */
938  for (x = 0; x < width; x++) {
939  for (y = 0; y < height; y++) {
941  }
942  }
943  }
944 
945  pl_pos.x += dx;
946  pl_pos.y += dy;
947 
948  /* clear all newly visible tiles */
949  if (dx > 0) {
950  for (y = 0; y < height; y++) {
951  for (x = width-dx; x < width; x++) {
952  mapdata_cell(pl_pos.x+x, pl_pos.y+y)->cleared = 1;
954  }
955  }
956  } else {
957  for (y = 0; y < height; y++) {
958  for (x = 0; x < -dx; x++) {
959  mapdata_cell(pl_pos.x+x, pl_pos.y+y)->cleared = 1;
961  }
962  }
963  }
964 
965  if (dy > 0) {
966  for (x = 0; x < width; x++) {
967  for (y = height-dy; y < height; y++) {
968  mapdata_cell(pl_pos.x+x, pl_pos.y+y)->cleared = 1;
970  }
971  }
972  } else {
973  for (x = 0; x < width; x++) {
974  for (y = 0; y < -dy; y++) {
975  mapdata_cell(pl_pos.x+x, pl_pos.y+y)->cleared = 1;
977  }
978  }
979  }
980 
981  /* Remove all big faces outside the view area. */
982  while (bigfaces_head != NULL) {
983  expand_clear_bigface_from_layer(bigfaces_head->x, bigfaces_head->y, bigfaces_head->layer, 0);
984  }
985 }
986 
987 void mapdata_newmap(void)
988 {
989  int x, y;
990 
991  /* Clear the_map.cells[]. */
992  for (x = 0; x < the_map.width; x++) {
993  clear_cells(x, 0, the_map.height);
994  for (y = 0; y < the_map.height; y++) {
995  mapdata_cell(x, y)->need_update = 1;
996  }
997  }
998 
999  /* Clear bigfaces[]. */
1000  while (bigfaces_head != NULL) {
1001  expand_clear_bigface_from_layer(bigfaces_head->x, bigfaces_head->y, bigfaces_head->layer, 0);
1002  }
1003 }
1004 
1008 static bool mapdata_has_tile(int x, int y, int layer) {
1009  if (0 <= x && x < width && 0 <= y && y < height) {
1010  if (0 <= layer && layer < MAXLAYERS) {
1011  return true;
1012  }
1013  }
1014 
1015  return false;
1016 }
1017 
1025 gint16 mapdata_face(int x, int y, int layer) {
1026  if (!mapdata_has_tile(x, y, layer)) {
1027  return 0;
1028  }
1029 
1030  return mapdata_cell(pl_pos.x+x, pl_pos.y+y)->heads[layer].face;
1031 }
1032 
1033 gint16 mapdata_face_info(int mx, int my, int layer, int *dx, int *dy) {
1034  struct MapCellLayer *head = &mapdata_cell(mx, my)->heads[layer];
1035  struct MapCellTailLayer *tail = &mapdata_cell(mx, my)->tails[layer];
1036  if (head->face != 0) {
1037  const int width = head->size_x, height = head->size_y;
1038  *dx = 1 - width, *dy = 1 - height;
1039  return head->face;
1040  } else if (tail->face != 0) {
1041  struct MapCellLayer *head_ptr = &mapdata_cell(mx + tail->size_x, my + tail->size_y)->heads[layer];
1042  const int width = head_ptr->size_x, height = head_ptr->size_y;
1043  *dx = tail->size_x - width + 1, *dy = tail->size_y - height + 1;
1044  return tail->face;
1045  } else {
1046  return 0;
1047  }
1048 }
1049 
1059 gint16 mapdata_bigface(int x, int y, int layer, int *ww, int *hh) {
1060  gint16 result;
1061 
1062  if (!mapdata_has_tile(x, y, layer)) {
1063  return 0;
1064  }
1065 
1066  result = mapdata_cell(pl_pos.x+x, pl_pos.y+y)->tails[layer].face;
1067  if (result != 0) {
1068  int clear_bigface;
1069  int dx = mapdata_cell(pl_pos.x+x, pl_pos.y+y)->tails[layer].size_x;
1070  int dy = mapdata_cell(pl_pos.x+x, pl_pos.y+y)->tails[layer].size_y;
1071  int w = mapdata_cell(pl_pos.x+x+dx, pl_pos.y+y+dy)->heads[layer].size_x;
1072  int h = mapdata_cell(pl_pos.x+x+dx, pl_pos.y+y+dy)->heads[layer].size_y;
1073  assert(1 <= w && w <= MAX_FACE_SIZE);
1074  assert(1 <= h && h <= MAX_FACE_SIZE);
1075  assert(0 <= dx && dx < w);
1076  assert(0 <= dy && dy < h);
1077 
1078  /* Now check if we are about to display an obsolete big face: such a
1079  * face has a cleared ("fog of war") head but the current tile is not
1080  * fog of war. Since the server would have sent an appropriate head
1081  * tile if it was already valid, just clear the big face and do not
1082  * return it.
1083  */
1084  if (mapdata_cell(pl_pos.x+x, pl_pos.y+y)->cleared) {
1085  /* Current face is a "fog of war" tile ==> do not clear
1086  * old information.
1087  */
1088  clear_bigface = 0;
1089  } else {
1090  if (x+dx < width && y+dy < height) {
1091  /* Clear face if current tile is valid but the
1092  * head is marked as cleared.
1093  */
1094  clear_bigface = mapdata_cell(pl_pos.x+x+dx, pl_pos.y+y+dy)->cleared;
1095  } else {
1096  /* Clear face if current tile is valid but the
1097  * head is not set.
1098  */
1099  clear_bigface = bigfaces[x+dx][y+dy][layer].head.face == 0;
1100  }
1101  }
1102 
1103  if (!clear_bigface) {
1104  *ww = w-1-dx;
1105  *hh = h-1-dy;
1106  return(result);
1107  }
1108 
1109  assert(mapdata_cell(pl_pos.x+x, pl_pos.y+y)->tails[layer].face == result);
1110  expand_clear_face_from_layer(pl_pos.x+x+dx, pl_pos.y+y+dy, layer);
1111  assert(mapdata_cell(pl_pos.x+x, pl_pos.y+y)->tails[layer].face == 0);
1112  }
1113 
1114  result = bigfaces[x][y][layer].tail.face;
1115  if (result != 0) {
1116  int dx = bigfaces[x][y][layer].tail.size_x;
1117  int dy = bigfaces[x][y][layer].tail.size_y;
1118  int w = bigfaces[x+dx][y+dy][layer].head.size_x;
1119  int h = bigfaces[x+dx][y+dy][layer].head.size_y;
1120  assert(0 <= dx && dx < w);
1121  assert(0 <= dy && dy < h);
1122  *ww = w-1-dx;
1123  *hh = h-1-dy;
1124  return(result);
1125  }
1126 
1127  *ww = 1;
1128  *hh = 1;
1129  return(0);
1130 }
1131 
1132 /* This is used by the opengl logic.
1133  * Basically the opengl code draws the the entire image,
1134  * and doesn't care if if portions are off the edge
1135  * (opengl takes care of that). So basically, this
1136  * function returns only if the head for a space is set,
1137  * otherwise, returns 0 - we don't care about the tails
1138  * or other details really.
1139  */
1140 gint16 mapdata_bigface_head(int x, int y, int layer, int *ww, int *hh) {
1141  gint16 result;
1142 
1143  if (!mapdata_has_tile(x, y, layer)) {
1144  return 0;
1145  }
1146 
1147  result = bigfaces[x][y][layer].head.face;
1148  if (result != 0) {
1149  int w = bigfaces[x][y][layer].head.size_x;
1150  int h = bigfaces[x][y][layer].head.size_y;
1151  *ww = w;
1152  *hh = h;
1153  return(result);
1154  }
1155 
1156  *ww = 1;
1157  *hh = 1;
1158  return(0);
1159 }
1160 
1169 static void recenter_virtual_map_view(int diff_x, int diff_y)
1170 {
1171  int new_x, new_y;
1172  int shift_x, shift_y;
1173  int src_x, src_y;
1174  int dst_x, dst_y;
1175  int len_x, len_y;
1176  int sx;
1177  int dx;
1178  int i;
1179 
1180  /* shift player position in virtual map */
1181  new_x = pl_pos.x+diff_x;
1182  new_y = pl_pos.y+diff_y;
1183 
1184  /* determine neccessary amount to shift */
1185 
1186  /* if(new_x < 1) is not possible: a big face may reach up to
1187  * (MAX_FACE_SIZE-1) tiles to the left of pl_pos. Therefore maintain a
1188  * border of at least MAX_FACE_SIZE to the left of the virtual map
1189  * edge.
1190  */
1191  if (new_x < MAX_FACE_SIZE) {
1192  shift_x = FOG_BORDER_MIN+MAX_FACE_SIZE-new_x;
1193  /* This yields: new_x+shift_x == FOG_BORDER_MIN+MAX_FACE_SIZE,
1194  * i.e. left border is FOG_BORDER_MIN+MAX_FACE_SIZE after
1195  * shifting.
1196  */
1197  } else if (new_x+MAX_VIEW > the_map.width) {
1198  shift_x = the_map.width-FOG_BORDER_MIN-MAX_VIEW-new_x;
1199  /* This yields: new_x+shift_x ==
1200  * the_map.width-FOG_BODER_MIN-MAX_VIEW, i.e. right border is
1201  * FOGBORDER_MIN after shifting.
1202  */
1203  } else {
1204  shift_x = 0;
1205  }
1206 
1207  /* Same as above but for y. */
1208  if (new_y < MAX_FACE_SIZE) {
1209  shift_y = FOG_BORDER_MIN+MAX_FACE_SIZE-new_y;
1210  } else if (new_y+MAX_VIEW > the_map.height) {
1211  shift_y = the_map.height-FOG_BORDER_MIN-MAX_VIEW-new_y;
1212  } else {
1213  shift_y = 0;
1214  }
1215 
1216  /* No shift neccessary? ==> nothing to do. */
1217  if (shift_x == 0 && shift_y == 0) {
1218  return;
1219  }
1220 
1221  /* If shifting at all: maintain a border size of FOG_BORDER_MIN to all
1222  * directions. For example: if pl_pos=30/MAX_FACE_SIZE, and map_scroll is
1223  * 0/-1: shift pl_pos to FOG_BORDER_MIN+1/FOG_BORDER_MIN+1, not to
1224  * 30/FOG_BORDER_MIN+1.
1225  */
1226  if (shift_x == 0) {
1227  if (new_x < FOG_BORDER_MIN+MAX_FACE_SIZE) {
1228  shift_x = FOG_BORDER_MIN+MAX_FACE_SIZE-new_x;
1229  } else if (new_x+MAX_VIEW+FOG_BORDER_MIN > the_map.width) {
1230  shift_x = the_map.width-FOG_BORDER_MIN-MAX_VIEW-new_x;
1231  }
1232  }
1233  if (shift_y == 0) {
1234  if (new_y < FOG_BORDER_MIN+MAX_FACE_SIZE) {
1235  shift_y = FOG_BORDER_MIN+MAX_FACE_SIZE-new_y;
1236  } else if (new_y+MAX_VIEW+FOG_BORDER_MIN > the_map.height) {
1237  shift_y = the_map.height-FOG_BORDER_MIN-MAX_VIEW-new_y;
1238  }
1239  }
1240 
1241  /* Shift for more than virtual map size? ==> clear whole virtual map
1242  * and recenter.
1243  */
1244  if (shift_x <= -the_map.width || shift_x >= the_map.width
1245  || shift_y <= -the_map.height || shift_y >= the_map.height) {
1246  for (dx = 0; dx < the_map.width; dx++) {
1247  clear_cells(dx, 0, the_map.height);
1248  }
1249 
1250  pl_pos.x = the_map.width/2-width/2;
1251  pl_pos.y = the_map.height/2-height/2;
1252  return;
1253  }
1254 
1255  /* Move player position. */
1256  pl_pos.x += shift_x;
1257  pl_pos.y += shift_y;
1258 
1259  /* Actually shift the virtual map by shift_x/shift_y */
1260  if (shift_x < 0) {
1261  src_x = -shift_x;
1262  dst_x = 0;
1263  len_x = the_map.width+shift_x;
1264  } else {
1265  src_x = 0;
1266  dst_x = shift_x;
1267  len_x = the_map.width-shift_x;
1268  }
1269 
1270  if (shift_y < 0) {
1271  src_y = -shift_y;
1272  dst_y = 0;
1273  len_y = the_map.height+shift_y;
1274  } else {
1275  src_y = 0;
1276  dst_y = shift_y;
1277  len_y = the_map.height-shift_y;
1278  }
1279 
1280  if (shift_x < 0) {
1281  for (sx = src_x, dx = dst_x, i = 0; i < len_x; sx++, dx++, i++) {
1282  /* srcx!=dstx ==> can use memcpy since source and
1283  * destination to not overlap.
1284  */
1285  memcpy(mapdata_cell(dx, dst_y), mapdata_cell(sx, src_y), len_y*sizeof(struct MapCell));
1286  }
1287  } else if (shift_x > 0) {
1288  for (sx = src_x+len_x-1, dx = dst_x+len_x-1, i = 0; i < len_x; sx--, dx--, i++) {
1289  /* srcx!=dstx ==> can use memcpy since source and
1290  * destination to not overlap.
1291  */
1292  memcpy(mapdata_cell(dx, dst_y), mapdata_cell(sx, src_y), len_y*sizeof(struct MapCell));
1293  }
1294  } else {
1295  assert(src_x == dst_x);
1296  for (dx = src_x, i = 0; i < len_x; dx++, i++) {
1297  /* srcx==dstx ==> use memmove since source and
1298  * destination probably do overlap.
1299  */
1300  memmove(mapdata_cell(dx, dst_y), mapdata_cell(dx, src_y), len_y*sizeof(struct MapCell));
1301  }
1302  }
1303 
1304  /* Clear newly opened area */
1305  for (dx = 0; dx < dst_x; dx++) {
1306  clear_cells(dx, 0, the_map.height);
1307  }
1308  for (dx = dst_x+len_x; dx < the_map.width; dx++) {
1309  clear_cells(dx, 0, the_map.height);
1310  }
1311  if (shift_y > 0) {
1312  for (dx = 0; dx < len_x; dx++) {
1313  clear_cells(dx+dst_x, 0, shift_y);
1314  }
1315  } else if (shift_y < 0) {
1316  for (dx = 0; dx < len_x; dx++) {
1317  clear_cells(dx+dst_x, the_map.height+shift_y, -shift_y);
1318  }
1319  }
1320 }
1321 
1326 static void mapdata_get_image_size(int face, guint8 *w, guint8 *h)
1327 {
1328  get_map_image_size(face, w, h);
1329  if (*w < 1) {
1330  *w = 1;
1331  }
1332  if (*h < 1) {
1333  *h = 1;
1334  }
1335  if (*w > MAX_FACE_SIZE) {
1336  *w = MAX_FACE_SIZE;
1337  }
1338  if (*h > MAX_FACE_SIZE) {
1339  *h = MAX_FACE_SIZE;
1340  }
1341 }
1342 
1343 /* This basically goes through all the map spaces and does the necessary
1344  * animation.
1345  */
1347 {
1348  int x, y, layer, face;
1349  struct MapCellLayer *cell;
1350 
1351 
1352  /* For synchronized animations, what we do is set the initial values
1353  * in the mapdata to the fields in the animations[] array. In this way,
1354  * the code below the iterates the spaces doesn't need to do anything
1355  * special. But we have to update the animations[] array here to
1356  * keep in sync.
1357  */
1358  for (x=0; x < MAXANIM; x++) {
1359  if (animations[x].speed) {
1360  animations[x].speed_left++;
1361  if (animations[x].speed_left >= animations[x].speed) {
1362  animations[x].speed_left=0;
1363  animations[x].phase++;
1364  if (animations[x].phase >= animations[x].num_animations) {
1365  animations[x].phase=0;
1366  }
1367  }
1368  }
1369  }
1370 
1371  for (x=0; x < CURRENT_MAX_VIEW; x++) {
1372  for (y=0; y < CURRENT_MAX_VIEW; y++) {
1373 
1374  /* Short cut some processing here. It makes sense to me
1375  * not to animate stuff out of view
1376  */
1377  if (mapdata_cell(pl_pos.x + x, pl_pos.y + y)->cleared) {
1378  continue;
1379  }
1380 
1381  for (layer=0; layer<MAXLAYERS; layer++) {
1382  /* Using the cell structure just makes life easier here */
1383  cell = &mapdata_cell(pl_pos.x+x, pl_pos.y+y)->heads[layer];
1384 
1385  if (cell->animation) {
1386  cell->animation_left++;
1387  if (cell->animation_left >= cell->animation_speed) {
1388  cell->animation_left=0;
1389  cell->animation_phase++;
1390  if (cell->animation_phase >= animations[cell->animation].num_animations) {
1391  cell->animation_phase=0;
1392  }
1393  face = animations[cell->animation].faces[cell->animation_phase];
1394 
1395  /* I don't think we send any to the client, but it is possible
1396  * for animations to have blank faces.
1397  */
1398  if (face >0) {
1399  expand_set_face(pl_pos.x + x, pl_pos.y + y, layer, face, FALSE);
1400  } else {
1401  expand_clear_face_from_layer(pl_pos.x + x, pl_pos.y + y , layer);
1402  }
1403  }
1404  }
1405  cell = &bigfaces[x][y][layer].head;
1406  if (cell->animation) {
1407  cell->animation_left++;
1408  if (cell->animation_left >= cell->animation_speed) {
1409  cell->animation_left=0;
1410  cell->animation_phase++;
1411  if (cell->animation_phase >= animations[cell->animation].num_animations) {
1412  cell->animation_phase=0;
1413  }
1414  face = animations[cell->animation].faces[cell->animation_phase];
1415 
1416  /* I don't think we send any to the client, but it is possible
1417  * for animations to have blank faces.
1418  */
1419  expand_set_bigface(x, y, layer, face, FALSE);
1420  }
1421  }
1422  }
1423  }
1424  }
1425 }
Animations animations[MAXANIM]
Definition: commands.c:1141
static int height
Definition: mapdata.c:80
gint16 mapdata_bigface(int x, int y, int layer, int *ww, int *hh)
Definition: mapdata.c:1059
guint8 have_darkness
Definition: mapdata.h:62
void get_map_image_size(int face, guint8 *w, guint8 *h)
Definition: image.c:483
#define ANIM_RANDOM
Definition: newclient.h:322
void mapdata_set_smooth(int x, int y, guint8 smooth, int layer)
Definition: mapdata.c:759
gint16 use_config[CONFIG_NUMS]
Definition: init.c:40
void mapdata_animation(void)
Definition: mapdata.c:1346
struct MapCellTailLayer tail
Definition: mapdata.c:68
void mapdata_set_check_space(int x, int y)
Definition: mapdata.c:681
void mapdata_clear_space(int x, int y)
Definition: mapdata.c:639
guint8 num_animations
Definition: client.h:100
#define CONFIG_LIGHTING
Definition: client.h:201
static void mapdata_alloc(struct Map *const map, const int width, const int height)
Definition: mapdata.c:557
#define CONFIG_DISPLAYMODE
Definition: client.h:194
int width
Definition: mapdata.h:70
Warning that something might not work.
Definition: client.h:443
guint8 smooth[MAXLAYERS]
Definition: mapdata.h:59
struct MapCell * mapdata_cell(int x, int y)
Definition: mapdata.c:116
void mapdata_set_face_layer(int x, int y, gint16 face, int layer)
Definition: mapdata.c:821
static void expand_clear_face(int x, int y, int w, int h, int layer)
Definition: mapdata.c:210
static void expand_need_update(int x, int y, int w, int h)
Definition: mapdata.c:508
#define CFG_LT_PIXEL_BEST
Definition: client.h:231
#define ANIM_MASK
Definition: newclient.h:331
#define ANIM_FLAGS_MASK
Definition: newclient.h:325
static void mapdata_get_image_size(int face, guint8 *w, guint8 *h)
Definition: mapdata.c:1326
gint8 size_x
Definition: mapdata.h:38
void mapdata_newmap(void)
Definition: mapdata.c:987
gint16 animation
Definition: mapdata.h:30
gint8 size_x
Definition: mapdata.h:20
#define CONFIG_MAPSCROLL
Definition: client.h:213
struct MapCell ** _cells
Definition: mapdata.h:69
static void expand_need_update_from_layer(int x, int y, int layer)
Definition: mapdata.c:536
void mapdata_set_anim_layer(int x, int y, guint16 anim, guint8 anim_speed, int layer)
Definition: mapdata.c:852
gint16 mapdata_face(int x, int y, int layer)
Definition: mapdata.c:1025
gint16 mapdata_bigface_head(int x, int y, int layer, int *ww, int *hh)
Definition: mapdata.c:1140
static void recenter_virtual_map_view(int diff_x, int diff_y)
Definition: mapdata.c:1169
static int width
Definition: mapdata.c:79
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:109
guint16 x
Definition: mapdata.c:70
#define FOG_BORDER_MIN
Definition: mapdata.c:36
int height
Definition: mapdata.h:71
guint8 cleared
Definition: mapdata.h:64
static struct BigCell * bigfaces_head
Definition: mapdata.c:87
static void expand_set_bigface(int x, int y, int layer, gint16 face, int clear)
Definition: mapdata.c:443
guint8 speed
Definition: client.h:104
bool mapdata_can_smooth(int x, int y, int layer)
Definition: mapdata.c:131
static void mark_resmooth(int x, int y, int layer)
Definition: mapdata.c:189
Definition: mapdata.h:67
gint8 size_y
Definition: mapdata.h:21
#define FOG_MAP_SIZE
Definition: mapdata.c:30
void mapdata_size(int *x, int *y)
Definition: mapdata.c:139
struct MapCellLayer head
Definition: mapdata.c:67
void mapdata_clear_old(int x, int y)
Definition: mapdata.c:793
int display_mapscroll(int dx, int dy)
Definition: map.c:122
void mapdata_free(void)
Definition: mapdata.c:612
static struct Map the_map
Definition: mapdata.c:96
static void expand_clear_bigface_from_layer(int x, int y, int layer, int set_need_update)
Definition: mapdata.c:397
guint8 need_resmooth
Definition: mapdata.h:63
gint16 mapdata_face_info(int mx, int my, int layer, int *dx, int *dy)
Definition: mapdata.c:1033
gint16 face
Definition: mapdata.h:37
static void mapdata_init(void)
Definition: mapdata.c:576
static void set_darkness(int x, int y, int darkness)
Definition: mapdata.c:157
gint16 want_config[CONFIG_NUMS]
Definition: init.c:40
gint8 size_y
Definition: mapdata.h:39
static void expand_clear_face_from_layer(int x, int y, int layer)
Definition: mapdata.c:265
bool mapdata_contains(int x, int y)
Definition: mapdata.c:123
static void expand_clear_bigface(int x, int y, int w, int h, int layer, int set_need_update)
Definition: mapdata.c:343
#define ANIM_SYNC
Definition: newclient.h:323
static bool mapdata_has_tile(int x, int y, int layer)
Definition: mapdata.c:1008
guint8 animation_speed
Definition: mapdata.h:31
#define MAXLAYERS
Definition: mapdata.h:6
guint8 need_update
Definition: mapdata.h:61
void mapdata_scroll(int dx, int dy)
Definition: mapdata.c:914
static void clear_cells(int x, int y, int len_y)
Definition: mapdata.c:101
static void expand_set_face(int x, int y, int layer, gint16 face, int clear)
Definition: mapdata.c:292
guint16 y
Definition: mapdata.c:70
#define CURRENT_MAX_VIEW
Definition: mapdata.c:48
#define CFG_DM_SDL
Definition: client.h:240
guint16 * faces
Definition: client.h:107
guint8 speed_left
Definition: client.h:105
int mapdata_is_inside(int x, int y)
Definition: mapdata.c:630
#define CFG_LT_PIXEL
Definition: client.h:230
struct BigCell * next
Definition: mapdata.c:64
guint8 animation_phase
Definition: mapdata.h:33
#define MAX_VIEW
Definition: mapdata.h:11
#define MAX_FACE_SIZE
Definition: mapdata.c:41
gint16 face
Definition: mapdata.h:19
struct MapCellLayer heads[MAXLAYERS]
Definition: mapdata.h:57
#define MAXANIM
Definition: client.h:86
guint8 layer
Definition: mapdata.c:71
static struct BigCell bigfaces[MAX_VIEW][MAX_VIEW][MAXLAYERS]
Definition: mapdata.c:94
void mapdata_set_size(int viewx, int viewy)
Definition: mapdata.c:619
guint8 animation_left
Definition: mapdata.h:32
guint8 darkness
Definition: mapdata.h:60
void mapdata_set_darkness(int x, int y, int darkness)
Definition: mapdata.c:736
PlayerPosition pl_pos
Definition: map.c:37
struct MapCellTailLayer tails[MAXLAYERS]
Definition: mapdata.h:58
guint8 phase
Definition: client.h:106
struct BigCell * prev
Definition: mapdata.c:65
static item * map
Definition: item.c:28