1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
#ifndef MAP_H
#define MAP_H
/** The protocol supports 10 layers, so set MAXLAYERS accordingly.
*/
#define MAXLAYERS 10
/**
* Maximum size of view area a server could support.
*/
#define MAX_VIEW 64
/* Map1 only used 3 layers. Trying to use 10 seems to cause
* problems for that code.
*/
#define MAP1_LAYERS 3
struct MapCellLayer {
gint16 face;
gint8 size_x;
gint8 size_y;
/* Link into animation information.
* animation is provided to us from the server in the map2 command.
* animation_speed is also provided.
* animation_left is how many ticks until animation changes - generated
* by client.
* animation_phase is current phase.
*/
gint16 animation;
guint8 animation_speed;
guint8 animation_left;
guint8 animation_phase;
};
struct MapCellTailLayer {
gint16 face;
gint8 size_x;
gint8 size_y;
};
/// A map cell can be in one of three states:
enum MapCellState {
EMPTY, //< No data from server, and no fog data
VISIBLE, //< Data from server
FOG //< No longer visible, but saved as fog of war data
};
/** The heads[] in the mapcell is used for single part objects
* or the head piece for multipart. The easiest way to think about
* it is that the heads[] contains the map information as specifically
* sent from the server. For the heads value, the size_x and size_y
* represent how many spaces (up and to the left) that image extends
* into.
* The tails are values that the client fills in - if we get
* a big head value, we fill in the tails value so that the display
* logic can easily redraw one space. In this case, the size_ values
* are offsets that point to the head. In this way, the draw logic
* can look at the size of the image, look at these values, and
* know what portion of it to draw.
*/
struct MapCell
{
struct MapCellLayer heads[MAXLAYERS];
struct MapCellTailLayer tails[MAXLAYERS];
struct MapLabel *label;
guint8 smooth[MAXLAYERS];
guint8 darkness; /* darkness: 0=fully illuminated, 255=pitch black */
guint8 need_update:1; /* set if tile should be redrawn */
guint8 need_resmooth:1; /* same has need update but for smoothing only */
enum MapCellState state:2;
};
struct MapLabel {
int subtype;
char *label;
struct MapLabel *next;
};
struct Map
{
struct MapCell **_cells; //< data, access via mapdata_cells()
int width; //< width of cells array
int height; //< height of cells array
};
struct MapCell *mapdata_cell(int x, int y);
bool mapdata_contains(int x, int y);
void mapdata_size(int *x, int *y);
bool mapdata_can_smooth(int x, int y, int layer);
/**
* Initializes the module. Allocates memory for the_map. This functions must be
* called before any other function is used, and whenever a new display size
* was negotiated with the server.
*/
void mapdata_set_size(int viewx, int viewy);
/**
* Deallocate map data. Do not call functions other than mapdata_set_size()
* after calling mapdata_free().
*/
void mapdata_free(void);
/**
* Scrolls the map view. Must be called whenever a map_scroll command was
* received from the server.
*/
void mapdata_scroll(int dx, int dy);
/**
* Clears the map view. Must be called whenever a newmap command was received
* from the server.
*/
void mapdata_newmap(void);
/**
* Checks whether the given coordinates are within the current display size (as
* set by mapdata_set_size).
*/
int mapdata_is_inside(int x, int y);
/**
* Returns the face to display at a given location. This function returns the
* "head" information, i.e. the face information sent by the server.
*/
gint16 mapdata_face(int x, int y, int layer) __attribute__((deprecated));
/**
* Return the face number of the pixmap in the given map cell and set the
* offset pointers to indicate where to correctly draw the face. Offsets are
* zero for single-tile maps and negative for multi-tile maps. This provides
* a consistent way to draw tiles no matter single or multi part.
* @param mx Virtual map x-coordinate
* @param my Virtual map y-coordinate
* @param layer Map layer number
* @param dx Pointer to store x-offset
* @param dy Pointer to store y-offset
* @return Pixmap face number, zero if the tile does not exist
*/
gint16 mapdata_face_info(int mx, int my, int layer, int *dx, int *dy);
/**
* Returns the face to display at a given location. This function returns the
* "tail" information, i.e. big faces expanded by the client.
*
* *ww and *hh return the offset of the current tile relative to the head;
* 0 <= *ww < (width of face), 0 <= *hh < (height of face).
*
* When drawing the map view, this function must be used instead than a direct
* access to the_map.cells[]. This is because the_map.cells[] eventually still
* contains obsolete (fog of war) big face information; this function detects
* and clears such faces.
*/
gint16 mapdata_bigface(int x, int y, int layer, int *ww, int *hh);
void mapdata_clear_space(int x, int y);
void mapdata_set_check_space(int x, int y);
void mapdata_set_darkness(int x, int y, int darkness);
void mapdata_set_smooth(int x, int y, guint8 smooth, int layer);
void mapdata_clear_label(int px, int py);
void mapdata_add_label(int x, int y, int subtype, const char *label);
void mapdata_clear_old(int x, int y);
void mapdata_set_face_layer(int x, int y, gint16 face, int layer);
void mapdata_set_anim_layer(int x, int y, guint16 anim, guint8 anim_speed, int layer);
gint16 mapdata_bigface_head(int x, int y, int layer, int *ww, int *hh);
void mapdata_animation(void);
int relative_direction(int dx, int dy);
extern PlayerPosition script_pos;
void pl_mpos(int *px, int *py);
void set_move_to(int dx, int dy);
void clear_move_to(void);
bool is_at_moveto(void);
void run_move_to(void);
extern int move_to_x, move_to_y;
extern bool move_to_attack;
extern int global_offset_x, want_offset_x;
extern int global_offset_y, want_offset_y;
#endif
|