#ifndef _BLOCK_
#define _BLOCK_
typedef struct Blocks Blocks;
typedef struct Block Block;
#include "common.h"
#include "isometric.h"
#include "block_type.h"
struct Blocks {
    LandArray * fixed;
    LandArray * dynamic;
    LandArray * transparent;
    LandArray * animated;
    bool rebuild_static_cache;
    bool rebuild_dynamic_cache;
};
struct Block {
    BlockType * block_type;
    Blocks * blocks;
    float x, y, z;
    float xs, ys, zs;
    float r, g, b, a;
    int frame, subframe;
    bool flipped;
    float dx, dy, dz;
    bool ground;
    int recursion_prevention;
    bool no_fall;
    int bid;
    bool pushed_something;
    bool mover;
    bool talk;
    bool thought;
    int speech;
    str text;
    str interject;
    LandArray * cache;
    float random_a;
    bool run;
};
void blocks_list_destroy(LandArray * (* list));
void blocks_clear(Blocks * self);
void blocks_reset(Blocks * self);
Blocks* blocks_new(void);
void blocks_destroy(Blocks * self);
Block* blocks_pick(Blocks * self, float xp, float yp, Viewport * viewport);
void block_init(Block * self, Blocks * blocks, float x, float y, float z, BlockType * block_type);
Block* block_new(Blocks * blocks, float x, float y, float z, BlockType * block_type);
void block_destroy(Block * self);
Block* block_allocate(void);
void block_post_init(Block * self);
void block_add(Block * self);
void block_add_if_no_overlap(Block * self);
Block* block_change_type(Block * self, int d);
Block* block_change_type_to(Block * self, char const * text);
void block_del(Block * self);
bool block_overlaps(Block * self, Block * other);
bool block_center_overlaps(Block * super, Block * c);
LandArray* block_colliders(Block * self);
float check_ground(Block * self, float x, float z);
bool block_move(Block * self, float dx, float dy, float dz);
void move_on_top(Block * self, float dx, float dy, float dz);
float block_distance(Block * self, Block * other);
bool block_push(Block * self, float odx, float ody, float odz);
int block_recursion_tag(void);
bool block_pull(Block * self, float dx, float dy, float dz);
int block_is_inside(Block * self, float xp, float yp, Viewport * viewport);
void block_get_bounding_rect(Block * self, Viewport * viewport, float * x1, float * y1, float * x2, float * y2);
int block_sort_order(Block * self, Block * other, Viewport * viewport);
void block_tick(Block * self);
bool block_touch(Block * self, Block * c, float dx, float dy, float dz);
bool blocks_preload(Blocks * self);
void blocks_shift(Blocks * self, int dx, int dy, int dz);
#endif
