#pragma once #include #include #include #include "util.h" #include "common.h" #include "Tile.h" namespace Swan { class World; class Game; class Chunk { public: using RelPos = TilePos; static constexpr size_t DATA_SIZE = CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID) + // Tiles CHUNK_WIDTH * CHUNK_HEIGHT; // Light levels // What does this chunk want the world gen to do after a tick? enum class TickAction { DEACTIVATE, DELETE, NOTHING, }; Chunk(ChunkPos pos): pos_(pos) { data_.reset(new uint8_t[DATA_SIZE]); memset(getLightData(), 0, CHUNK_WIDTH * CHUNK_HEIGHT); } Tile::ID *getTileData() { assert(isActive()); return (Tile::ID *)data_.get(); } uint8_t *getLightData() { assert(isActive()); return data_.get() + CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID); } Tile::ID getTileID(RelPos pos) { return getTileData()[pos.y * CHUNK_WIDTH + pos.x]; } void setTileID(RelPos pos, Tile::ID id, SDL_Texture *tex) { getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id; drawList_.push_back({ pos, tex }); } void setTileData(RelPos pos, Tile::ID id) { getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id; needRender_ = true; } uint8_t getLightLevel(RelPos pos) { return getLightData()[pos.y * CHUNK_WIDTH + pos.x]; } void setLightData(const uint8_t *data) { memcpy(getLightData(), data, CHUNK_WIDTH * CHUNK_HEIGHT); needLightRender_ = true; } void render(const Context &ctx, SDL_Renderer *rnd); void renderLight(const Context &ctx, SDL_Renderer *rnd); void compress(); void decompress(); void draw(const Context &ctx, Win &win); TickAction tick(float dt); bool isActive() { return deactivateTimer_ > 0; } void keepActive(); void markModified() { isModified_ = true; } ChunkPos pos_; private: static constexpr float DEACTIVATE_INTERVAL = 20; void renderList(SDL_Renderer *rnd); bool isCompressed() { return compressedSize_ != -1; } std::unique_ptr data_; std::vector> drawList_; ssize_t compressedSize_ = -1; // -1 if not compressed, a positive number if compressed bool needRender_ = false; bool needLightRender_ = false; float deactivateTimer_ = DEACTIVATE_INTERVAL; bool isModified_ = false; CPtr texture_; CPtr lightTexture_; }; }