From 275e4af9fdb31effcefe0c30237188875ba02f2d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 Nov 2023 02:20:13 +0300 Subject: [PATCH] World structure update + new blocks --- res/textures/blocks/blue_lamp.png | Bin 0 -> 6291 bytes res/textures/blocks/green_lamp.png | Bin 0 -> 6290 bytes res/textures/blocks/red_lamp.png | Bin 0 -> 6293 bytes src/definitions.cpp | 12 ++++++++++++ src/files/WorldFiles.cpp | 30 +++++++++++++++++++++++++++-- src/files/WorldFiles.h | 7 ++++++- src/files/binary_io.cpp | 18 +++++++++++++++++ src/files/binary_io.h | 2 ++ src/world/World.cpp | 5 ++++- 9 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 res/textures/blocks/blue_lamp.png create mode 100644 res/textures/blocks/green_lamp.png create mode 100644 res/textures/blocks/red_lamp.png diff --git a/res/textures/blocks/blue_lamp.png b/res/textures/blocks/blue_lamp.png new file mode 100644 index 0000000000000000000000000000000000000000..ffb019645a0ebdf409343e426224e27146b597e2 GIT binary patch literal 6291 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 TdPhSGFwY8>DFaIUre^#N#!%gt literal 0 HcmV?d00001 diff --git a/res/textures/blocks/red_lamp.png b/res/textures/blocks/red_lamp.png new file mode 100644 index 0000000000000000000000000000000000000000..15d0223820a22c3272590e9d5933ac7513c8f49a GIT binary patch literal 6293 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 + + 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); }