#pragma once
#include "common.hpp"
#include <map>
typedef struct {
typedef enum { TILE_NONE=0, TILE_FLOOR=1, TILE_WATER=2, TILE_BOX=3, TILE_ROCK=4, TILE_DOOR=5, TILE_GOAL=6, TILE_PLAYER=7, TILE_NUM=8} tex_t;
typedef enum { TILE_MODEL_FLAT=0, TILE_MODEL_SPIKE_LOW=1, TILE_MODEL_CUBE_LOW=2, TILE_MODEL_SPIKE=3, TILE_MODEL_CUBE=4 } model_t;
typedef enum { TILE_ACTION_NONE=0, TILE_ACTION_FINISH, TILE_ACTION_GOTO, TILE_ACTION_SWITCH, TILE_ACTION_GOAL } action_t;
tex_t tile;
unsigned tile_border_type;
bool clip;
bool start;
bool movable;
model_t model;
action_t action;
union {
uint32_t action_arg1;
uint16_t action_arg2[2];
};
} tile_t;
extern const tile_t tile_defaults[tile_t::TILE_NUM];
class Layout {
private:
unsigned* const border_buf;
static unsigned id_cnt;
protected:
tile_t* const buf;
tile_t* const bottom_buf; // will be initialized with TILE_NONE
void find_borders(); // generate "shadows"
public:
const unsigned w, h;
const unsigned id;
Layout(unsigned, unsigned);
virtual ~Layout();
tile_t& at(unsigned x, unsigned y) { assert(x<w && y<h); return buf[(y*w)+x]; }
tile_t& at(unsigned i) { assert(i<w*h); return buf[i]; }
tile_t& below(unsigned x, unsigned y) { assert(x<w && y<h); return bottom_buf[(y*w)+x]; }
tile_t& below(unsigned i) { assert(i<w*h); return bottom_buf[i]; }
const tile_t& at(unsigned x, unsigned y) const { assert(x<w && y<h); return buf[(y*w)+x]; }
const tile_t& at(unsigned i) const { assert(i<w*h); return buf[i]; }
unsigned borders(unsigned x, unsigned y) const { assert(x<w && y<h); return border_buf[(y*w)+x]; }
virtual bool is_done() const { return true; }; // all layouts must be done for great success
virtual bool autoroute() const { return false; } // allow shortest path routes?
};
class World {
private:
unsigned player_x, player_y;
Layout* const world;
public:
const unsigned w, h;
const unsigned &x, &y;
World(Layout*);
~World();
bool player_step(int, int);
bool player_push(int, int);
bool player_goto(unsigned, unsigned);
const Layout* world_get() const;
const tile_t& at(unsigned, unsigned, unsigned&, unsigned&) const;
};
class Worlds {
private:
std::map<unsigned, World*> worlds;
World* get(unsigned);
public:
Worlds();
Worlds(unsigned, World*);
~Worlds();
World* world;
void push(unsigned, World*);
bool set(unsigned);
bool all_done() const;
};