#ifndef WORLD_H
#define WORLD_H
#include <SDL.h>
#define CHUNK_DIM 128
typedef enum tile {
TILE_RED,
TILE_GREEN,
TILE_BLUE,
TILE_LIGHT,
MAX_COLLECTIBLE,
TILE_EMPTY,
TILE_WALL,
TILE_BLOCK_WHITE,
} tile;
extern SDL_Color tile_colors[];
#define PLAYER_STAMINA 10
#define PLAYER_WALK_DELAY 100
#define PLAYER_PLACE_DELAY 175
#define PLAYER_GRAVITY 30
typedef struct player {
SDL_Point pos;
int scores[MAX_COLLECTIBLE];
int stamina;
int walk_wait;
int place_wait;
int gravity_time;
} player;
typedef struct chunk {
SDL_Point pos;
Uint8 tiles[CHUNK_DIM * CHUNK_DIM];
SDL_Texture *tex;
SDL_bool dirty;
SDL_bool loaded;
SDL_bool active;
} chunk;
#define MAX_CHUNKS 16
#define SAVE_INTERVAL 120000
typedef struct world {
player player;
SDL_Point view_pos;
chunk chunks[MAX_CHUNKS];
int save_time;
} world;
static inline SDL_Point chunk_pos_at(SDL_Point world_pos) {
return (SDL_Point) {
SDL_floor((double) world_pos.x / CHUNK_DIM),
SDL_floor((double) world_pos.y / CHUNK_DIM),
};
}
static inline SDL_Point pos_in_chunk(SDL_Point world_pos) {
SDL_Point cpos = chunk_pos_at(world_pos);
return (SDL_Point) {
world_pos.x - cpos.x * CHUNK_DIM,
world_pos.y - cpos.y * CHUNK_DIM,
};
}
static inline int tile_index(SDL_Point pos) {
SDL_assert(pos.x < CHUNK_DIM && pos.y < CHUNK_DIM);
return pos.y * CHUNK_DIM + pos.x;
}
chunk *load_chunk(world *w, SDL_Point chunk_pos);
chunk *get_chunk(world *w, SDL_Point chunk_pos);
SDL_bool chunk_exists(world *w, SDL_Point chunk_pos);
tile get_tile(world *w, SDL_Point world_pos);
void set_tile(world *w, SDL_Point world_pos, tile t);
SDL_bool is_solid(tile t);
SDL_bool player_grounded(world *w);
void player_walk(world *w, int x, int y);
void player_place(world *w, int x, int y);
void player_destroy(world *w, int x, int y);
void player_collect(world *w, SDL_Point pos);
void tick_world(world *w);
#define VIEW_DIM 40
void draw_world(world *w, SDL_Window *win, SDL_Renderer *rend);
void init_world(world *w);
#endif