World structure update + new blocks

This commit is contained in:
MihailRis 2023-11-24 02:20:13 +03:00
parent cc556bc19b
commit 275e4af9fd
9 changed files with 70 additions and 4 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -89,6 +89,18 @@ void setup_definitions(ContentBuilder* builder) {
block = new Block("base:rust", "rust"); block = new Block("base:rust", "rust");
builder->add(block); 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() { void setup_bindings() {

View File

@ -4,9 +4,11 @@
#include "rle.h" #include "rle.h"
#include "binary_io.h" #include "binary_io.h"
#include "../window/Camera.h" #include "../window/Camera.h"
#include "../content/Content.h"
#include "../objects/Player.h" #include "../objects/Player.h"
#include "../physics/Hitbox.h" #include "../physics/Hitbox.h"
#include "../voxels/voxel.h" #include "../voxels/voxel.h"
#include "../voxels/Block.h"
#include "../voxels/Chunk.h" #include "../voxels/Chunk.h"
#include "../typedefs.h" #include "../typedefs.h"
#include "../maths/voxmaths.h" #include "../maths/voxmaths.h"
@ -102,8 +104,12 @@ void WorldFiles::put(Chunk* chunk){
region.compressedSizes[chunk_index] = compressedSize; region.compressedSizes[chunk_index] = compressedSize;
} }
path WorldFiles::getRegionsFolder() const {
return directory/path("regions");
}
path WorldFiles::getRegionFile(int x, int y) const { 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 { path WorldFiles::getPlayerFile() const {
@ -114,6 +120,10 @@ path WorldFiles::getWorldFile() const {
return directory/path("world.bin"); return directory/path("world.bin");
} }
path WorldFiles::getBlockIndicesFile() const {
return directory/path("blocks.idx");
}
ubyte* WorldFiles::getChunk(int x, int y){ ubyte* WorldFiles::getChunk(int x, int y){
int regionX = floordiv(x, REGION_SIZE); int regionX = floordiv(x, REGION_SIZE);
int regionY = floordiv(y, REGION_SIZE); int regionY = floordiv(y, REGION_SIZE);
@ -190,13 +200,15 @@ ubyte* WorldFiles::readChunkData(int x, int y, uint32_t& length){
return data; 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)) { if (!std::filesystem::is_directory(directory)) {
std::filesystem::create_directories(directory); std::filesystem::create_directories(directory);
} }
writeWorldInfo(info); writeWorldInfo(info);
if (generatorTestMode) if (generatorTestMode)
return; return;
writeIndices(content->indices);
for (auto it = regions.begin(); it != regions.end(); it++){ for (auto it = regions.begin(); it != regions.end(); it++){
if (it->second.chunksData == nullptr || !it->second.unsaved) if (it->second.chunksData == nullptr || !it->second.unsaved)
continue; 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) { void WorldFiles::writeWorldInfo(const WorldInfo& info) {
BinaryWriter out; BinaryWriter out;
out.putCStr(WORLD_FORMAT_MAGIC); out.putCStr(WORLD_FORMAT_MAGIC);

View File

@ -23,6 +23,8 @@
class Player; class Player;
class Chunk; class Chunk;
class Content;
class ContentIndices;
struct WorldRegion { struct WorldRegion {
ubyte** chunksData; ubyte** chunksData;
@ -38,9 +40,11 @@ struct WorldInfo {
class WorldFiles { class WorldFiles {
void writeWorldInfo(const WorldInfo& info); void writeWorldInfo(const WorldInfo& info);
std::filesystem::path getRegionsFolder() const;
std::filesystem::path getRegionFile(int x, int y) const; std::filesystem::path getRegionFile(int x, int y) const;
std::filesystem::path getPlayerFile() const; std::filesystem::path getPlayerFile() const;
std::filesystem::path getWorldFile() const; std::filesystem::path getWorldFile() const;
std::filesystem::path getBlockIndicesFile() const;
public: public:
std::unordered_map<glm::ivec2, WorldRegion> regions; std::unordered_map<glm::ivec2, WorldRegion> regions;
std::filesystem::path directory; std::filesystem::path directory;
@ -58,7 +62,8 @@ public:
ubyte* getChunk(int x, int y); ubyte* getChunk(int x, int y);
void writeRegion(int x, int y, WorldRegion& entry); void writeRegion(int x, int y, WorldRegion& entry);
void writePlayer(Player* player); 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_ */ #endif /* FILES_WORLDFILES_H_ */

View File

@ -27,6 +27,15 @@ void BinaryWriter::put(const string& s) {
put((const ubyte*)s.data(), len); 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) { void BinaryWriter::put(const ubyte* arr, size_t size) {
buffer.reserve(buffer.size() + size); buffer.reserve(buffer.size() + size);
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
@ -144,6 +153,15 @@ string BinaryReader::getString() {
return string((const char*)(data+pos-length), length); 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 { bool BinaryReader::hasNext() const {
return pos < size; return pos < size;
} }

View File

@ -16,6 +16,7 @@ public:
void putFloat32(float val); void putFloat32(float val);
void put(const std::string& s); void put(const std::string& s);
void put(const ubyte* arr, size_t size); void put(const ubyte* arr, size_t size);
void putShortStr(const std::string& s);
inline size_t size() const { inline size_t size() const {
return buffer.size(); return buffer.size();
@ -39,6 +40,7 @@ public:
int64_t getInt64(); int64_t getInt64();
float getFloat32(); float getFloat32();
std::string getString(); std::string getString();
std::string getShortString();
bool hasNext() const; bool hasNext() const;
}; };

View File

@ -5,6 +5,7 @@
#include "Level.h" #include "Level.h"
#include "../files/WorldFiles.h" #include "../files/WorldFiles.h"
#include "../content/Content.h"
#include "../voxels/Chunk.h" #include "../voxels/Chunk.h"
#include "../voxels/Chunks.h" #include "../voxels/Chunks.h"
#include "../voxels/ChunksStorage.h" #include "../voxels/ChunksStorage.h"
@ -29,6 +30,8 @@ World::~World(){
} }
void World::write(Level* level) { void World::write(Level* level) {
const Content* content = level->content;
Chunks* chunks = level->chunks; Chunks* chunks = level->chunks;
for (size_t i = 0; i < chunks->volume; i++) { for (size_t i = 0; i < chunks->volume; i++) {
@ -38,7 +41,7 @@ void World::write(Level* level) {
wfile->put(chunk.get()); wfile->put(chunk.get());
} }
wfile->write(WorldInfo {name, wfile->directory, seed}); wfile->write(WorldInfo {name, wfile->directory, seed}, content);
wfile->writePlayer(level->player); wfile->writePlayer(level->player);
} }