/* tile.h

   This file handles individual tiles. See tilemap.h for the structure that
   arranges tiles into a grid.
*/

#ifndef INCLUDED_TILE_H
#define INCLUDED_TILE_H

#include "ripples.h"


#define TILE_TYPE_SOLID  0
#define TILE_TYPE_LAVA   1
#define TILE_TYPE_LIQUID 2

#define N_TILE_TYPES     3


/* struct TILE_SURFACES, when used by all tiles in a tile map, provides a
   means of storing a float for every surface in the tile map, both tile
   surfaces and walls.

   's' stands for the tile's surface. The w* variables stand for the walls
   descending from the tile, but not the ascending walls.

   Descending walls cannot exist at the edge of the tile map. This leaves
   some variables free to represent the outer wall of the tile map. Hence,
   right at the edge of the tile map, the appropriate w* variables represent
   the ascending outer wall.

   This method is subsidence-proof, i.e. no adjustments need be made when
   tiles subside and the tile map changes.
*/

#define TILE_SURFACE 0
#define TILE_WALL_T  1
#define TILE_WALL_L  2
#define TILE_WALL_B  3
#define TILE_WALL_R  4

#define N_TILE_SURFACES 5

typedef struct TILE_SURFACES {
 float s[N_TILE_SURFACES];
} TILE_SURFACES;



typedef struct TILE {

 /* 'type' is set to a TILE_TYPE_* constant. This affects both behaviour and
    appearance.
 */
 int type;

 /* 'texture' is one of the TEXTURE_* constants defined in texture.h. It
    specifies textures for both the central tile and the descending walls. It
    does not apply to ascending walls, since these are governed by the upper
    tile. The outer wall has its own texture.
 */
 int texture;

 /* 'ripples' should always be set to null for textured tiles. For rippled
    tiles, it should be set to null if ripples are turned off (see
    options.h), and it should be set to null in levels in their initial
    state (as stored by level.h). When this field is null, liquid tiles will
    be flatshaded. On the other hand, during the game, if ripples are turned
    on, this should point to a RIPPLES struct (see ripples.h). Then the tile
    will ripple like water as soon as something disturbs it. Magic!
 */
 RIPPLES *ripples;

 /* The components of 'damage' start at zero and are increased each time an
    explosion particle hits the relevant surface.
 */
 TILE_SURFACES damage;

 /* The components of 'blood' start at zero and are increased each time a
    blood particle hits the relevant surface.
 */
 TILE_SURFACES blood;

 float z; /* The tile's height. 1.0 is equal to one tile's width. */

 /* LIFT will not be used...ignore next paragraph

	If 'lift' is nonzero, then u.lift is used to describe the lift. 'zv' is
    the speed of the lift and is always positive. The tile moves up and down
    at this speed between z_high and z_low. If 'going_up' is nonzero, the
    tile is currently moving upwards; otherwise it is currently moving
    downwards.

    If 'lift' is zero, u.lift is irrelevant and u.subsidence comes into play.
    Whenever an explosion particle hits the tile, or a wall descending from
    it, its impact speed (just the zv component if it hits the top of the
    tile, etc.) is multiplied by u.subsidence and the product is subtracted
    from 'z'.

    WARNING: do not use u.subsidence if 'lift' is nonzero!
 */
 int lift;

 union {
  struct {
   float z_high;
   float z_low;
   float zv;
   int going_up;
  } lift;

  float subsidence;
 } u;

 /* ----------------------------------------------------------------------
    All fields below this point are for temporary usage. They need not be
    initialised when the tile is created.
    ---------------------------------------------------------------------- */

} TILE;


#endif /* INCLUDED_TILE_H */
