diff --git a/res/textures/blocks/blue_lamp.png b/res/textures/blocks/blue_lamp.png new file mode 100644 index 00000000..ffb01964 Binary files /dev/null and b/res/textures/blocks/blue_lamp.png differ diff --git a/res/textures/blocks/green_lamp.png b/res/textures/blocks/green_lamp.png new file mode 100644 index 00000000..cea33901 Binary files /dev/null and b/res/textures/blocks/green_lamp.png differ diff --git a/res/textures/blocks/red_lamp.png b/res/textures/blocks/red_lamp.png new file mode 100644 index 00000000..15d02238 Binary files /dev/null and b/res/textures/blocks/red_lamp.png differ diff --git a/src/definitions.cpp b/src/definitions.cpp index 748b8812..6378d523 100644 --- a/src/definitions.cpp +++ b/src/definitions.cpp @@ -89,6 +89,18 @@ void setup_definitions(ContentBuilder* builder) { block = new Block("base:rust", "rust"); builder->add(block); + + block = new Block("base:red_lamp", "red_lamp"); + block->emission[0] = 15; + builder->add(block); + + block = new Block("base:green_lamp", "green_lamp"); + block->emission[1] = 15; + builder->add(block); + + block = new Block("base:blue_lamp", "blue_lamp"); + block->emission[2] = 15; + builder->add(block); } void setup_bindings() { diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 92ea421f..85664a6c 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -4,9 +4,11 @@ #include "rle.h" #include "binary_io.h" #include "../window/Camera.h" +#include "../content/Content.h" #include "../objects/Player.h" #include "../physics/Hitbox.h" #include "../voxels/voxel.h" +#include "../voxels/Block.h" #include "../voxels/Chunk.h" #include "../typedefs.h" #include "../maths/voxmaths.h" @@ -102,8 +104,12 @@ void WorldFiles::put(Chunk* chunk){ region.compressedSizes[chunk_index] = compressedSize; } +path WorldFiles::getRegionsFolder() const { + return directory/path("regions"); +} + path WorldFiles::getRegionFile(int x, int y) const { - return directory/path(std::to_string(x) + "_" + std::to_string(y) + ".bin"); + return getRegionsFolder()/path(std::to_string(x) + "_" + std::to_string(y) + ".bin"); } path WorldFiles::getPlayerFile() const { @@ -114,6 +120,10 @@ path WorldFiles::getWorldFile() const { return directory/path("world.bin"); } +path WorldFiles::getBlockIndicesFile() const { + return directory/path("blocks.idx"); +} + ubyte* WorldFiles::getChunk(int x, int y){ int regionX = floordiv(x, REGION_SIZE); int regionY = floordiv(y, REGION_SIZE); @@ -190,13 +200,15 @@ ubyte* WorldFiles::readChunkData(int x, int y, uint32_t& length){ return data; } -void WorldFiles::write(const WorldInfo info){ +void WorldFiles::write(const WorldInfo info, const Content* content) { + path directory = getRegionsFolder(); if (!std::filesystem::is_directory(directory)) { std::filesystem::create_directories(directory); } writeWorldInfo(info); if (generatorTestMode) return; + writeIndices(content->indices); for (auto it = regions.begin(); it != regions.end(); it++){ if (it->second.chunksData == nullptr || !it->second.unsaved) continue; @@ -205,6 +217,20 @@ void WorldFiles::write(const WorldInfo info){ } } +void WorldFiles::writeIndices(const ContentIndices* indices) { + /* Blocks indices */ { + BinaryWriter out; + uint count = indices->countBlockDefs(); + out.putInt16(count); + for (uint i = 0; i < count; i++) { + const Block* def = indices->getBlockDef(i); + out.putShortStr(def->name); + } + files::write_bytes(getBlockIndicesFile(), + (const char*)out.data(), out.size()); + } +} + void WorldFiles::writeWorldInfo(const WorldInfo& info) { BinaryWriter out; out.putCStr(WORLD_FORMAT_MAGIC); diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index 912f4341..5b8832a7 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -23,6 +23,8 @@ class Player; class Chunk; +class Content; +class ContentIndices; struct WorldRegion { ubyte** chunksData; @@ -38,9 +40,11 @@ struct WorldInfo { class WorldFiles { void writeWorldInfo(const WorldInfo& info); + std::filesystem::path getRegionsFolder() const; std::filesystem::path getRegionFile(int x, int y) const; std::filesystem::path getPlayerFile() const; std::filesystem::path getWorldFile() const; + std::filesystem::path getBlockIndicesFile() const; public: std::unordered_map regions; std::filesystem::path directory; @@ -58,7 +62,8 @@ public: ubyte* getChunk(int x, int y); void writeRegion(int x, int y, WorldRegion& entry); void writePlayer(Player* player); - void write(const WorldInfo info); + void write(const WorldInfo info, const Content* content); + void writeIndices(const ContentIndices* indices); }; #endif /* FILES_WORLDFILES_H_ */ \ No newline at end of file diff --git a/src/files/binary_io.cpp b/src/files/binary_io.cpp index 696437d0..94c8e7ba 100644 --- a/src/files/binary_io.cpp +++ b/src/files/binary_io.cpp @@ -27,6 +27,15 @@ void BinaryWriter::put(const string& s) { put((const ubyte*)s.data(), len); } +void BinaryWriter::putShortStr(const string& s) { + size_t len = s.length(); + if (len > 255) { + throw std::domain_error("length > 255"); + } + put(len); + put((const ubyte*)s.data(), len); +} + void BinaryWriter::put(const ubyte* arr, size_t size) { buffer.reserve(buffer.size() + size); for (size_t i = 0; i < size; i++) { @@ -144,6 +153,15 @@ string BinaryReader::getString() { return string((const char*)(data+pos-length), length); } +string BinaryReader::getShortString() { + ubyte length = get(); + if (pos+length > size) { + throw std::underflow_error("unexpected end"); + } + pos += length; + return string((const char*)(data+pos-length), length); +} + bool BinaryReader::hasNext() const { return pos < size; } diff --git a/src/files/binary_io.h b/src/files/binary_io.h index cd68fd59..ac7a7299 100644 --- a/src/files/binary_io.h +++ b/src/files/binary_io.h @@ -16,6 +16,7 @@ public: void putFloat32(float val); void put(const std::string& s); void put(const ubyte* arr, size_t size); + void putShortStr(const std::string& s); inline size_t size() const { return buffer.size(); @@ -39,6 +40,7 @@ public: int64_t getInt64(); float getFloat32(); std::string getString(); + std::string getShortString(); bool hasNext() const; }; diff --git a/src/world/World.cpp b/src/world/World.cpp index 8a1b4029..535fcbc9 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -5,6 +5,7 @@ #include "Level.h" #include "../files/WorldFiles.h" +#include "../content/Content.h" #include "../voxels/Chunk.h" #include "../voxels/Chunks.h" #include "../voxels/ChunksStorage.h" @@ -29,6 +30,8 @@ World::~World(){ } void World::write(Level* level) { + const Content* content = level->content; + Chunks* chunks = level->chunks; for (size_t i = 0; i < chunks->volume; i++) { @@ -38,7 +41,7 @@ void World::write(Level* level) { wfile->put(chunk.get()); } - wfile->write(WorldInfo {name, wfile->directory, seed}); + wfile->write(WorldInfo {name, wfile->directory, seed}, content); wfile->writePlayer(level->player); }