Merge branch 'main' into devtools

This commit is contained in:
MihailRis
2024-05-13 00:15:14 +03:00
25 changed files with 336 additions and 318 deletions
+6 -4
View File
@@ -33,8 +33,10 @@ ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsC
} }
} }
ContentLUT* ContentLUT::create(const fs::path& filename, std::shared_ptr<ContentLUT> ContentLUT::create(
const Content* content) { const fs::path& filename,
const Content* content
) {
auto root = files::read_json(filename); auto root = files::read_json(filename);
auto blocklist = root->list("blocks"); auto blocklist = root->list("blocks");
auto itemlist = root->list("items"); auto itemlist = root->list("items");
@@ -47,7 +49,7 @@ ContentLUT* ContentLUT::create(const fs::path& filename,
? std::max(itemlist->size(), indices->countItemDefs()) ? std::max(itemlist->size(), indices->countItemDefs())
: indices->countItemDefs(); : indices->countItemDefs();
auto lut = std::make_unique<ContentLUT>(content, blocks_c, items_c); auto lut = std::make_shared<ContentLUT>(content, blocks_c, items_c);
if (blocklist) { if (blocklist) {
for (size_t i = 0; i < blocklist->size(); i++) { for (size_t i = 0; i < blocklist->size(); i++) {
@@ -74,7 +76,7 @@ ContentLUT* ContentLUT::create(const fs::path& filename,
} }
if (lut->hasContentReorder() || lut->hasMissingContent()) { if (lut->hasContentReorder() || lut->hasMissingContent()) {
return lut.release(); return lut;
} else { } else {
return nullptr; return nullptr;
} }
+1 -1
View File
@@ -70,7 +70,7 @@ public:
} }
} }
static ContentLUT* create( static std::shared_ptr<ContentLUT> create(
const fs::path& filename, const fs::path& filename,
const Content* content const Content* content
); );
+1
View File
@@ -3,6 +3,7 @@
#include <ctime> #include <ctime>
#include <iomanip> #include <iomanip>
#include <chrono> #include <chrono>
#include <iostream>
using namespace debug; using namespace debug;
-1
View File
@@ -3,7 +3,6 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <iostream>
#include <mutex> #include <mutex>
namespace debug { namespace debug {
+7 -6
View File
@@ -74,7 +74,8 @@ void langs::loadLocalesInfo(const fs::path& resdir, std::string& fallback) {
auto langs = root->map("langs"); auto langs = root->map("langs");
if (langs) { if (langs) {
std::cout << "locales "; auto logline = logger.info();
logline << "locales ";
for (auto& entry : langs->values) { for (auto& entry : langs->values) {
auto langInfo = entry.second; auto langInfo = entry.second;
@@ -84,10 +85,10 @@ void langs::loadLocalesInfo(const fs::path& resdir, std::string& fallback) {
} else { } else {
continue; continue;
} }
std::cout << "[" << entry.first << " (" << name << ")] "; logline << "[" << entry.first << " (" << name << ")] ";
langs::locales_info[entry.first] = LocaleInfo {entry.first, name}; langs::locales_info[entry.first] = LocaleInfo {entry.first, name};
} }
std::cout << "added" << std::endl; logline << "added";
} }
} }
@@ -97,17 +98,17 @@ std::string langs::locale_by_envlocale(const std::string& envlocale, const fs::p
loadLocalesInfo(resdir, fallback); loadLocalesInfo(resdir, fallback);
} }
if (locales_info.find(envlocale) != locales_info.end()) { if (locales_info.find(envlocale) != locales_info.end()) {
std::cout << "locale " << envlocale << " is automatically selected" << std::endl; logger.info() << "locale " << envlocale << " is automatically selected";
return envlocale; return envlocale;
} }
else { else {
for (const auto& loc : locales_info) { for (const auto& loc : locales_info) {
if (loc.first.find(envlocale.substr(0, 2)) != std::string::npos) { if (loc.first.find(envlocale.substr(0, 2)) != std::string::npos) {
std::cout << "locale " << loc.first << " is automatically selected" << std::endl; logger.info() << "locale " << loc.first << " is automatically selected";
return loc.first; return loc.first;
} }
} }
std::cout << "locale " << fallback << " is automatically selected" << std::endl; logger.info() << "locale " << fallback << " is automatically selected";
return fallback; return fallback;
} }
} }
+2 -2
View File
@@ -24,7 +24,7 @@
static debug::Logger logger("level-screen"); static debug::Logger logger("level-screen");
LevelScreen::LevelScreen(Engine* engine, Level* level) LevelScreen::LevelScreen(Engine* engine, std::unique_ptr<Level> level)
: Screen(engine), postProcessing(std::make_unique<PostProcessing>()) : Screen(engine), postProcessing(std::make_unique<PostProcessing>())
{ {
auto& settings = engine->getSettings(); auto& settings = engine->getSettings();
@@ -32,7 +32,7 @@ LevelScreen::LevelScreen(Engine* engine, Level* level)
auto menu = engine->getGUI()->getMenu(); auto menu = engine->getGUI()->getMenu();
menu->reset(); menu->reset();
controller = std::make_unique<LevelController>(settings, level); controller = std::make_unique<LevelController>(settings, std::move(level));
frontend = std::make_unique<LevelFrontend>(controller.get(), assets); frontend = std::make_unique<LevelFrontend>(controller.get(), assets);
worldRenderer = std::make_unique<WorldRenderer>(engine, frontend.get(), controller->getPlayer()); worldRenderer = std::make_unique<WorldRenderer>(engine, frontend.get(), controller->getPlayer());
+1 -1
View File
@@ -28,7 +28,7 @@ class LevelScreen : public Screen {
void updateHotkeys(); void updateHotkeys();
void initializeContent(); void initializeContent();
public: public:
LevelScreen(Engine* engine, Level* level); LevelScreen(Engine* engine, std::unique_ptr<Level> level);
~LevelScreen(); ~LevelScreen();
void update(float delta) override; void update(float delta) override;
+15 -15
View File
@@ -7,25 +7,25 @@ class Chunks;
class ContentIndices; class ContentIndices;
struct lightentry { struct lightentry {
int x; int x;
int y; int y;
int z; int z;
unsigned char light; unsigned char light;
}; };
class LightSolver { class LightSolver {
std::queue<lightentry> addqueue; std::queue<lightentry> addqueue;
std::queue<lightentry> remqueue; std::queue<lightentry> remqueue;
const ContentIndices* const contentIds; const ContentIndices* const contentIds;
Chunks* chunks; Chunks* chunks;
int channel; int channel;
public: public:
LightSolver(const ContentIndices* contentIds, Chunks* chunks, int channel); LightSolver(const ContentIndices* contentIds, Chunks* chunks, int channel);
void add(int x, int y, int z); void add(int x, int y, int z);
void add(int x, int y, int z, int emission); void add(int x, int y, int z, int emission);
void remove(int x, int y, int z); void remove(int x, int y, int z);
void solve(); void solve();
}; };
#endif /* LIGHTING_LIGHTSOLVER_HPP_ */ #endif // LIGHTING_LIGHTSOLVER_HPP_
+161 -162
View File
@@ -1,5 +1,3 @@
#include <memory>
#include "Lighting.hpp" #include "Lighting.hpp"
#include "LightSolver.hpp" #include "LightSolver.hpp"
#include "Lightmap.hpp" #include "Lightmap.hpp"
@@ -9,82 +7,83 @@
#include "../voxels/voxel.hpp" #include "../voxels/voxel.hpp"
#include "../voxels/Block.hpp" #include "../voxels/Block.hpp"
#include "../constants.hpp" #include "../constants.hpp"
#include "../typedefs.hpp"
#include "../util/timeutil.hpp" #include "../util/timeutil.hpp"
#include <memory>
Lighting::Lighting(const Content* content, Chunks* chunks) Lighting::Lighting(const Content* content, Chunks* chunks)
: content(content), chunks(chunks) { : content(content), chunks(chunks) {
auto indices = content->getIndices(); auto indices = content->getIndices();
solverR = std::make_unique<LightSolver>(indices, chunks, 0); solverR = std::make_unique<LightSolver>(indices, chunks, 0);
solverG = std::make_unique<LightSolver>(indices, chunks, 1); solverG = std::make_unique<LightSolver>(indices, chunks, 1);
solverB = std::make_unique<LightSolver>(indices, chunks, 2); solverB = std::make_unique<LightSolver>(indices, chunks, 2);
solverS = std::make_unique<LightSolver>(indices, chunks, 3); solverS = std::make_unique<LightSolver>(indices, chunks, 3);
} }
Lighting::~Lighting(){ Lighting::~Lighting(){
} }
void Lighting::clear(){ void Lighting::clear(){
for (size_t index = 0; index < chunks->volume; index++){ for (size_t index = 0; index < chunks->volume; index++){
auto chunk = chunks->chunks[index]; auto chunk = chunks->chunks[index];
if (chunk == nullptr) if (chunk == nullptr)
continue; continue;
Lightmap& lightmap = chunk->lightmap; Lightmap& lightmap = chunk->lightmap;
for (int i = 0; i < CHUNK_VOL; i++){ for (int i = 0; i < CHUNK_VOL; i++){
lightmap.map[i] = 0; lightmap.map[i] = 0;
} }
} }
} }
void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){ void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){
auto* blockDefs = indices->getBlockDefs(); auto* blockDefs = indices->getBlockDefs();
int highestPoint = 0; int highestPoint = 0;
for (int z = 0; z < CHUNK_D; z++){ for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){ for (int x = 0; x < CHUNK_W; x++){
for (int y = CHUNK_H-1; y >= 0; y--){ for (int y = CHUNK_H-1; y >= 0; y--){
int index = (y * CHUNK_D + z) * CHUNK_W + x; int index = (y * CHUNK_D + z) * CHUNK_W + x;
voxel& vox = chunk->voxels[index]; voxel& vox = chunk->voxels[index];
const Block* block = blockDefs[vox.id]; const Block* block = blockDefs[vox.id];
if (!block->skyLightPassing) { if (!block->skyLightPassing) {
if (highestPoint < y) if (highestPoint < y)
highestPoint = y; highestPoint = y;
break; break;
} }
chunk->lightmap.setS(x,y,z, 15); chunk->lightmap.setS(x,y,z, 15);
} }
} }
} }
if (highestPoint < CHUNK_H-1) if (highestPoint < CHUNK_H-1)
highestPoint++; highestPoint++;
chunk->lightmap.highestPoint = highestPoint; chunk->lightmap.highestPoint = highestPoint;
} }
void Lighting::buildSkyLight(int cx, int cz){ void Lighting::buildSkyLight(int cx, int cz){
const Block* const* blockDefs = content->getIndices()->getBlockDefs(); const Block* const* blockDefs = content->getIndices()->getBlockDefs();
Chunk* chunk = chunks->getChunk(cx, cz); Chunk* chunk = chunks->getChunk(cx, cz);
for (int z = 0; z < CHUNK_D; z++){ for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){ for (int x = 0; x < CHUNK_W; x++){
for (int y = chunk->lightmap.highestPoint; y >= 0; y--){ for (int y = chunk->lightmap.highestPoint; y >= 0; y--){
int gx = x + cx * CHUNK_W; int gx = x + cx * CHUNK_W;
int gz = z + cz * CHUNK_D; int gz = z + cz * CHUNK_D;
while (y > 0 && !blockDefs[chunk->voxels[vox_index(x, y, z)].id]->lightPassing) { while (y > 0 && !blockDefs[chunk->voxels[vox_index(x, y, z)].id]->lightPassing) {
y--; y--;
} }
if (chunk->lightmap.getS(x, y, z) != 15) { if (chunk->lightmap.getS(x, y, z) != 15) {
solverS->add(gx,y+1,gz); solverS->add(gx,y+1,gz);
for (; y >= 0; y--){ for (; y >= 0; y--){
solverS->add(gx+1,y,gz); solverS->add(gx+1,y,gz);
solverS->add(gx-1,y,gz); solverS->add(gx-1,y,gz);
solverS->add(gx,y,gz+1); solverS->add(gx,y,gz+1);
solverS->add(gx,y,gz-1); solverS->add(gx,y,gz-1);
} }
} }
} }
} }
} }
solverS->solve(); solverS->solve();
} }
void Lighting::onChunkLoaded(int cx, int cz, bool expand){ void Lighting::onChunkLoaded(int cx, int cz, bool expand){
@@ -93,113 +92,113 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand){
LightSolver* solverB = this->solverB.get(); LightSolver* solverB = this->solverB.get();
LightSolver* solverS = this->solverS.get(); LightSolver* solverS = this->solverS.get();
const Block* const* blockDefs = content->getIndices()->getBlockDefs(); const Block* const* blockDefs = content->getIndices()->getBlockDefs();
const Chunk* chunk = chunks->getChunk(cx, cz); const Chunk* chunk = chunks->getChunk(cx, cz);
for (uint y = 0; y < CHUNK_H; y++){ for (uint y = 0; y < CHUNK_H; y++){
for (uint z = 0; z < CHUNK_D; z++){ for (uint z = 0; z < CHUNK_D; z++){
for (uint x = 0; x < CHUNK_W; x++){ for (uint x = 0; x < CHUNK_W; x++){
const voxel& vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]; const voxel& vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
const Block* block = blockDefs[vox.id]; const Block* block = blockDefs[vox.id];
int gx = x + cx * CHUNK_W; int gx = x + cx * CHUNK_W;
int gz = z + cz * CHUNK_D; int gz = z + cz * CHUNK_D;
if (block->rt.emissive){ if (block->rt.emissive){
solverR->add(gx,y,gz,block->emission[0]); solverR->add(gx,y,gz,block->emission[0]);
solverG->add(gx,y,gz,block->emission[1]); solverG->add(gx,y,gz,block->emission[1]);
solverB->add(gx,y,gz,block->emission[2]); solverB->add(gx,y,gz,block->emission[2]);
} }
} }
} }
} }
if (expand) { if (expand) {
for (int x = 0; x < CHUNK_W; x += CHUNK_W-1) { for (int x = 0; x < CHUNK_W; x += CHUNK_W-1) {
for (int y = 0; y < CHUNK_H; y++) { for (int y = 0; y < CHUNK_H; y++) {
for (int z = 0; z < CHUNK_D; z++) { for (int z = 0; z < CHUNK_D; z++) {
int gx = x + cx * CHUNK_W; int gx = x + cx * CHUNK_W;
int gz = z + cz * CHUNK_D; int gz = z + cz * CHUNK_D;
int rgbs = chunk->lightmap.get(x, y, z); int rgbs = chunk->lightmap.get(x, y, z);
if (rgbs){ if (rgbs){
solverR->add(gx,y,gz, Lightmap::extract(rgbs, 0)); solverR->add(gx,y,gz, Lightmap::extract(rgbs, 0));
solverG->add(gx,y,gz, Lightmap::extract(rgbs, 1)); solverG->add(gx,y,gz, Lightmap::extract(rgbs, 1));
solverB->add(gx,y,gz, Lightmap::extract(rgbs, 2)); solverB->add(gx,y,gz, Lightmap::extract(rgbs, 2));
solverS->add(gx,y,gz, Lightmap::extract(rgbs, 3)); solverS->add(gx,y,gz, Lightmap::extract(rgbs, 3));
} }
} }
} }
} }
for (int z = 0; z < CHUNK_D; z += CHUNK_D-1) { for (int z = 0; z < CHUNK_D; z += CHUNK_D-1) {
for (int y = 0; y < CHUNK_H; y++) { for (int y = 0; y < CHUNK_H; y++) {
for (int x = 0; x < CHUNK_W; x++) { for (int x = 0; x < CHUNK_W; x++) {
int gx = x + cx * CHUNK_W; int gx = x + cx * CHUNK_W;
int gz = z + cz * CHUNK_D; int gz = z + cz * CHUNK_D;
int rgbs = chunk->lightmap.get(x, y, z); int rgbs = chunk->lightmap.get(x, y, z);
if (rgbs){ if (rgbs){
solverR->add(gx,y,gz, Lightmap::extract(rgbs, 0)); solverR->add(gx,y,gz, Lightmap::extract(rgbs, 0));
solverG->add(gx,y,gz, Lightmap::extract(rgbs, 1)); solverG->add(gx,y,gz, Lightmap::extract(rgbs, 1));
solverB->add(gx,y,gz, Lightmap::extract(rgbs, 2)); solverB->add(gx,y,gz, Lightmap::extract(rgbs, 2));
solverS->add(gx,y,gz, Lightmap::extract(rgbs, 3)); solverS->add(gx,y,gz, Lightmap::extract(rgbs, 3));
} }
} }
} }
} }
} }
solverR->solve(); solverR->solve();
solverG->solve(); solverG->solve();
solverB->solve(); solverB->solve();
solverS->solve(); solverS->solve();
} }
void Lighting::onBlockSet(int x, int y, int z, blockid_t id){ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
Block* block = content->getIndices()->getBlockDef(id); Block* block = content->getIndices()->getBlockDef(id);
solverR->remove(x,y,z); solverR->remove(x,y,z);
solverG->remove(x,y,z); solverG->remove(x,y,z);
solverB->remove(x,y,z); solverB->remove(x,y,z);
if (id == 0){ if (id == 0){
solverR->solve(); solverR->solve();
solverG->solve(); solverG->solve();
solverB->solve(); solverB->solve();
if (chunks->getLight(x,y+1,z, 3) == 0xF){ if (chunks->getLight(x,y+1,z, 3) == 0xF){
for (int i = y; i >= 0; i--){ for (int i = y; i >= 0; i--){
voxel* vox = chunks->get(x,i,z); voxel* vox = chunks->get(x,i,z);
if ((vox == nullptr || vox->id != 0) && block->skyLightPassing) if ((vox == nullptr || vox->id != 0) && block->skyLightPassing)
break; break;
solverS->add(x,i,z, 0xF); solverS->add(x,i,z, 0xF);
} }
} }
solverR->add(x,y+1,z); solverG->add(x,y+1,z); solverB->add(x,y+1,z); solverS->add(x,y+1,z); solverR->add(x,y+1,z); solverG->add(x,y+1,z); solverB->add(x,y+1,z); solverS->add(x,y+1,z);
solverR->add(x,y-1,z); solverG->add(x,y-1,z); solverB->add(x,y-1,z); solverS->add(x,y-1,z); solverR->add(x,y-1,z); solverG->add(x,y-1,z); solverB->add(x,y-1,z); solverS->add(x,y-1,z);
solverR->add(x+1,y,z); solverG->add(x+1,y,z); solverB->add(x+1,y,z); solverS->add(x+1,y,z); solverR->add(x+1,y,z); solverG->add(x+1,y,z); solverB->add(x+1,y,z); solverS->add(x+1,y,z);
solverR->add(x-1,y,z); solverG->add(x-1,y,z); solverB->add(x-1,y,z); solverS->add(x-1,y,z); solverR->add(x-1,y,z); solverG->add(x-1,y,z); solverB->add(x-1,y,z); solverS->add(x-1,y,z);
solverR->add(x,y,z+1); solverG->add(x,y,z+1); solverB->add(x,y,z+1); solverS->add(x,y,z+1); solverR->add(x,y,z+1); solverG->add(x,y,z+1); solverB->add(x,y,z+1); solverS->add(x,y,z+1);
solverR->add(x,y,z-1); solverG->add(x,y,z-1); solverB->add(x,y,z-1); solverS->add(x,y,z-1); solverR->add(x,y,z-1); solverG->add(x,y,z-1); solverB->add(x,y,z-1); solverS->add(x,y,z-1);
solverR->solve(); solverR->solve();
solverG->solve(); solverG->solve();
solverB->solve(); solverB->solve();
solverS->solve(); solverS->solve();
} else { } else {
if (!block->skyLightPassing){ if (!block->skyLightPassing){
solverS->remove(x,y,z); solverS->remove(x,y,z);
for (int i = y-1; i >= 0; i--){ for (int i = y-1; i >= 0; i--){
solverS->remove(x,i,z); solverS->remove(x,i,z);
if (i == 0 || chunks->get(x,i-1,z)->id != 0){ if (i == 0 || chunks->get(x,i-1,z)->id != 0){
break; break;
} }
} }
solverS->solve(); solverS->solve();
} }
solverR->solve(); solverR->solve();
solverG->solve(); solverG->solve();
solverB->solve(); solverB->solve();
if (block->emission[0] || block->emission[1] || block->emission[2]){ if (block->emission[0] || block->emission[1] || block->emission[2]){
solverR->add(x,y,z,block->emission[0]); solverR->add(x,y,z,block->emission[0]);
solverG->add(x,y,z,block->emission[1]); solverG->add(x,y,z,block->emission[1]);
solverB->add(x,y,z,block->emission[2]); solverB->add(x,y,z,block->emission[2]);
solverR->solve(); solverR->solve();
solverG->solve(); solverG->solve();
solverB->solve(); solverB->solve();
} }
} }
} }
+13 -13
View File
@@ -10,22 +10,22 @@ class Chunks;
class LightSolver; class LightSolver;
class Lighting { class Lighting {
const Content* const content; const Content* const content;
Chunks* chunks; Chunks* chunks;
std::unique_ptr<LightSolver> solverR; std::unique_ptr<LightSolver> solverR;
std::unique_ptr<LightSolver> solverG; std::unique_ptr<LightSolver> solverG;
std::unique_ptr<LightSolver> solverB; std::unique_ptr<LightSolver> solverB;
std::unique_ptr<LightSolver> solverS; std::unique_ptr<LightSolver> solverS;
public: public:
Lighting(const Content* content, Chunks* chunks); Lighting(const Content* content, Chunks* chunks);
~Lighting(); ~Lighting();
void clear(); void clear();
void buildSkyLight(int cx, int cz); void buildSkyLight(int cx, int cz);
void onChunkLoaded(int cx, int cz, bool expand); void onChunkLoaded(int cx, int cz, bool expand);
void onBlockSet(int x, int y, int z, blockid_t id); void onBlockSet(int x, int y, int z, blockid_t id);
static void prebuildSkyLight(Chunk* chunk, const ContentIndices* indices); static void prebuildSkyLight(Chunk* chunk, const ContentIndices* indices);
}; };
#endif /* LIGHTING_LIGHTING_HPP_ */ #endif /* LIGHTING_LIGHTING_HPP_ */
+1 -1
View File
@@ -87,4 +87,4 @@ public:
static std::unique_ptr<light_t[]> decode(const ubyte* buffer); static std::unique_ptr<light_t[]> decode(const ubyte* buffer);
}; };
#endif /* LIGHTING_LIGHTMAP_HPP_ */ #endif // LIGHTING_LIGHTMAP_HPP_
+47 -47
View File
@@ -24,10 +24,10 @@ const uint MIN_SURROUNDING = 9;
ChunksController::ChunksController(Level* level, uint padding) ChunksController::ChunksController(Level* level, uint padding)
: level(level), : level(level),
chunks(level->chunks.get()), chunks(level->chunks.get()),
lighting(level->lighting.get()), lighting(level->lighting.get()),
padding(padding), padding(padding),
generator(WorldGenerators::createGenerator(level->getWorld()->getGenerator(), level->content)) { generator(WorldGenerators::createGenerator(level->getWorld()->getGenerator(), level->content)) {
} }
ChunksController::~ChunksController(){ ChunksController::~ChunksController(){
@@ -37,7 +37,7 @@ void ChunksController::update(int64_t maxDuration) {
int64_t mcstotal = 0; int64_t mcstotal = 0;
for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) { for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) {
timeutil::Timer timer; timeutil::Timer timer;
if (loadVisible()) { if (loadVisible()) {
int64_t mcs = timer.stop(); int64_t mcs = timer.stop();
if (mcstotal + mcs < maxDuration * 1000) { if (mcstotal + mcs < maxDuration * 1000) {
@@ -50,44 +50,44 @@ void ChunksController::update(int64_t maxDuration) {
} }
bool ChunksController::loadVisible(){ bool ChunksController::loadVisible(){
const int w = chunks->w; const int w = chunks->w;
const int d = chunks->d; const int d = chunks->d;
int nearX = 0; int nearX = 0;
int nearZ = 0; int nearZ = 0;
int minDistance = ((w-padding*2)/2)*((w-padding*2)/2); int minDistance = ((w-padding*2)/2)*((w-padding*2)/2);
for (uint z = padding; z < d-padding; z++){ for (uint z = padding; z < d-padding; z++){
for (uint x = padding; x < w-padding; x++){ for (uint x = padding; x < w-padding; x++){
int index = z * w + x; int index = z * w + x;
auto chunk = chunks->chunks[index]; auto chunk = chunks->chunks[index];
if (chunk != nullptr){ if (chunk != nullptr){
if (chunk->isLoaded() && !chunk->isLighted()) { if (chunk->isLoaded() && !chunk->isLighted()) {
if (buildLights(chunk)) { if (buildLights(chunk)) {
return true; return true;
} }
} }
continue; continue;
} }
int lx = x - w / 2; int lx = x - w / 2;
int lz = z - d / 2; int lz = z - d / 2;
int distance = (lx * lx + lz * lz); int distance = (lx * lx + lz * lz);
if (distance < minDistance){ if (distance < minDistance){
minDistance = distance; minDistance = distance;
nearX = x; nearX = x;
nearZ = z; nearZ = z;
} }
} }
} }
auto chunk = chunks->chunks[nearZ * w + nearX]; auto chunk = chunks->chunks[nearZ * w + nearX];
if (chunk != nullptr) { if (chunk != nullptr) {
return false; return false;
} }
const int ox = chunks->ox; const int ox = chunks->ox;
const int oz = chunks->oz; const int oz = chunks->oz;
createChunk(nearX+ox, nearZ+oz); createChunk(nearX+ox, nearZ+oz);
return true; return true;
} }
bool ChunksController::buildLights(std::shared_ptr<Chunk> chunk) { bool ChunksController::buildLights(std::shared_ptr<Chunk> chunk) {
@@ -112,22 +112,22 @@ bool ChunksController::buildLights(std::shared_ptr<Chunk> chunk) {
void ChunksController::createChunk(int x, int z) { void ChunksController::createChunk(int x, int z) {
auto chunk = level->chunksStorage->create(x, z); auto chunk = level->chunksStorage->create(x, z);
chunks->putChunk(chunk); chunks->putChunk(chunk);
if (!chunk->isLoaded()) { if (!chunk->isLoaded()) {
generator->generate( generator->generate(
chunk->voxels, x, z, chunk->voxels, x, z,
level->getWorld()->getSeed() level->getWorld()->getSeed()
); );
chunk->setUnsaved(true); chunk->setUnsaved(true);
} }
chunk->updateHeights(); chunk->updateHeights();
if (!chunk->isLoadedLights()) { if (!chunk->isLoadedLights()) {
Lighting::prebuildSkyLight( Lighting::prebuildSkyLight(
chunk.get(), level->content->getIndices() chunk.get(), level->content->getIndices()
); );
} }
chunk->setLoaded(true); chunk->setLoaded(true);
chunk->setReady(true); chunk->setReady(true);
} }
+1 -1
View File
@@ -31,4 +31,4 @@ public:
void update(int64_t maxDuration); void update(int64_t maxDuration);
}; };
#endif /* VOXELS_CHUNKSCONTROLLER_HPP_ */ #endif // VOXELS_CHUNKSCONTROLLER_HPP_
+4 -4
View File
@@ -110,8 +110,8 @@ static void loadWorld(Engine* engine, fs::path folder) {
auto& packs = engine->getContentPacks(); auto& packs = engine->getContentPacks();
auto& settings = engine->getSettings(); auto& settings = engine->getSettings();
Level* level = World::load(folder, settings, content, packs); auto level = World::load(folder, settings, content, packs);
engine->setScreen(std::make_shared<LevelScreen>(engine, level)); engine->setScreen(std::make_shared<LevelScreen>(engine, std::move(level)));
} catch (const world_load_error& error) { } catch (const world_load_error& error) {
guiutil::alert( guiutil::alert(
engine->getGUI(), langs::get(L"Error")+L": "+ engine->getGUI(), langs::get(L"Error")+L": "+
@@ -197,13 +197,13 @@ void EngineController::createWorld(
return; return;
} }
Level* level = World::create( auto level = World::create(
name, generatorID, folder, seed, name, generatorID, folder, seed,
engine->getSettings(), engine->getSettings(),
engine->getContent(), engine->getContent(),
engine->getContentPacks() engine->getContentPacks()
); );
engine->setScreen(std::make_shared<LevelScreen>(engine, level)); engine->setScreen(std::make_shared<LevelScreen>(engine, std::move(level)));
} }
void EngineController::reopenWorld(World* world) { void EngineController::reopenWorld(World* world) {
+6 -6
View File
@@ -10,18 +10,18 @@
static debug::Logger logger("level-control"); static debug::Logger logger("level-control");
LevelController::LevelController(EngineSettings& settings, Level* level) LevelController::LevelController(EngineSettings& settings, std::unique_ptr<Level> level)
: settings(settings), level(level), : settings(settings), level(std::move(level)),
blocks(std::make_unique<BlocksController>(level, settings.chunks.padding.get())), blocks(std::make_unique<BlocksController>(this->level.get(), settings.chunks.padding.get())),
chunks(std::make_unique<ChunksController>(level, settings.chunks.padding.get())), chunks(std::make_unique<ChunksController>(this->level.get(), settings.chunks.padding.get())),
player(std::make_unique<PlayerController>(level, settings, blocks.get())) { player(std::make_unique<PlayerController>(this->level.get(), settings, blocks.get())) {
scripting::on_world_load(this); scripting::on_world_load(this);
} }
void LevelController::update(float delta, bool input, bool pause) { void LevelController::update(float delta, bool input, bool pause) {
player->update(delta, input, pause); player->update(delta, input, pause);
glm::vec3 position = player->getPlayer()->hitbox->position; glm::vec3 position = player->getPlayer()->hitbox->position;
level->loadMatrix(position.x, position.z, level->loadMatrix(position.x, position.z,
settings.chunks.loadDistance.get() + settings.chunks.loadDistance.get() +
settings.chunks.padding.get() * 2); settings.chunks.padding.get() * 2);
+1 -1
View File
@@ -20,7 +20,7 @@ class LevelController {
std::unique_ptr<ChunksController> chunks; std::unique_ptr<ChunksController> chunks;
std::unique_ptr<PlayerController> player; std::unique_ptr<PlayerController> player;
public: public:
LevelController(EngineSettings& settings, Level* level); LevelController(EngineSettings& settings, std::unique_ptr<Level> level);
/// @param delta time elapsed since the last update /// @param delta time elapsed since the last update
/// @param input is user input allowed to be handled /// @param input is user input allowed to be handled
+1 -2
View File
@@ -34,7 +34,6 @@ const float RUN_ZOOM = 1.1f;
const float C_ZOOM = 0.1f; const float C_ZOOM = 0.1f;
const float CROUCH_SHIFT_Y = -0.2f; const float CROUCH_SHIFT_Y = -0.2f;
CameraControl::CameraControl(std::shared_ptr<Player> player, const CameraSettings& settings) CameraControl::CameraControl(std::shared_ptr<Player> player, const CameraSettings& settings)
: player(player), : player(player),
camera(player->camera), camera(player->camera),
@@ -136,7 +135,7 @@ void CameraControl::switchCamera() {
} }
} }
void CameraControl::update(PlayerInput& input, float delta, Chunks* chunks) { void CameraControl::update(const PlayerInput& input, float delta, Chunks* chunks) {
offset = glm::vec3(0.0f, 0.7f, 0.0f); offset = glm::vec3(0.0f, 0.7f, 0.0f);
if (settings.shaking.get() && !input.cheat) { if (settings.shaking.get() && !input.cheat) {
+5 -5
View File
@@ -1,14 +1,14 @@
#ifndef PLAYER_CONTROL_HPP_ #ifndef PLAYER_CONTROL_HPP_
#define PLAYER_CONTROL_HPP_ #define PLAYER_CONTROL_HPP_
#include "../settings.hpp"
#include "../objects/Player.hpp"
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "../settings.hpp"
#include "../objects/Player.hpp"
class Camera; class Camera;
class Level; class Level;
class Block; class Block;
@@ -38,7 +38,7 @@ class CameraControl {
public: public:
CameraControl(std::shared_ptr<Player> player, const CameraSettings& settings); CameraControl(std::shared_ptr<Player> player, const CameraSettings& settings);
void updateMouse(PlayerInput& input); void updateMouse(PlayerInput& input);
void update(PlayerInput& input, float delta, Chunks* chunks); void update(const PlayerInput& input, float delta, Chunks* chunks);
void refresh(); void refresh();
}; };
@@ -55,7 +55,7 @@ using on_block_interaction = std::function<void(
class PlayerController { class PlayerController {
Level* level; Level* level;
std::shared_ptr<Player> player; std::shared_ptr<Player> player;
PlayerInput input; PlayerInput input {};
CameraControl camControl; CameraControl camControl;
BlocksController* blocksController; BlocksController* blocksController;
+1 -1
View File
@@ -34,7 +34,7 @@ static bool processCallback(
try { try {
return state->eval(*env, src, file) != 0; return state->eval(*env, src, file) != 0;
} catch (lua::luaerror& err) { } catch (lua::luaerror& err) {
std::cerr << err.what() << std::endl; logger.error() << err.what();
return false; return false;
} }
} }
@@ -8,6 +8,8 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <string> #include <string>
#include <string>
namespace scripting { namespace scripting {
using common_func = std::function<dynamic::Value(const std::vector<dynamic::Value>&)>; using common_func = std::function<dynamic::Value(const std::vector<dynamic::Value>&)>;
+7 -4
View File
@@ -12,8 +12,11 @@
#include "../items/Inventory.hpp" #include "../items/Inventory.hpp"
#include "../items/Inventories.hpp" #include "../items/Inventories.hpp"
Level::Level(World* world, const Content* content, EngineSettings& settings) Level::Level(
: world(world), std::unique_ptr<World> world,
const Content* content,
EngineSettings& settings
) : world(std::move(world)),
content(content), content(content),
chunksStorage(std::make_unique<ChunksStorage>(this)), chunksStorage(std::make_unique<ChunksStorage>(this)),
physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))), physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))),
@@ -21,7 +24,7 @@ Level::Level(World* world, const Content* content, EngineSettings& settings)
settings(settings) settings(settings)
{ {
auto inv = std::make_shared<Inventory>( auto inv = std::make_shared<Inventory>(
world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE this->world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE
); );
auto player = spawnObject<Player>( auto player = spawnObject<Player>(
glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv
@@ -32,7 +35,7 @@ Level::Level(World* world, const Content* content, EngineSettings& settings)
settings.chunks.padding.get() settings.chunks.padding.get()
) * 2; ) * 2;
chunks = std::make_unique<Chunks>( chunks = std::make_unique<Chunks>(
matrixSize, matrixSize, 0, 0, world->wfile.get(), events.get(), content matrixSize, matrixSize, 0, 0, this->world->wfile.get(), events.get(), content
); );
lighting = std::make_unique<Lighting>(content, chunks.get()); lighting = std::make_unique<Lighting>(content, chunks.get());
+5 -1
View File
@@ -38,7 +38,11 @@ public:
const EngineSettings& settings; const EngineSettings& settings;
Level(World* world, const Content* content, EngineSettings& settings); Level(
std::unique_ptr<World> world,
const Content* content,
EngineSettings& settings
);
~Level(); ~Level();
void loadMatrix(int32_t x, int32_t z, uint32_t radius); void loadMatrix(int32_t x, int32_t z, uint32_t radius);
+1 -1
View File
@@ -11,7 +11,7 @@ enum lvl_event_type {
EVT_CHUNK_HIDDEN, EVT_CHUNK_HIDDEN,
}; };
typedef std::function<void(lvl_event_type, Chunk*)> chunk_event_func; using chunk_event_func = std::function<void(lvl_event_type, Chunk*)>;
class LevelEvents { class LevelEvents {
std::unordered_map<lvl_event_type, std::vector<chunk_event_func>> chunk_callbacks; std::unordered_map<lvl_event_type, std::vector<chunk_event_func>> chunk_callbacks;
+41 -32
View File
@@ -1,8 +1,10 @@
#include "World.hpp" #include "World.hpp"
#include "Level.hpp" #include "Level.hpp"
#include "../content/Content.hpp" #include "../content/Content.hpp"
#include "../content/ContentLUT.hpp" #include "../content/ContentLUT.hpp"
#include "../debug/Logger.hpp"
#include "../files/WorldFiles.hpp" #include "../files/WorldFiles.hpp"
#include "../items/Inventories.hpp" #include "../items/Inventories.hpp"
#include "../objects/Player.hpp" #include "../objects/Player.hpp"
@@ -13,9 +15,10 @@
#include "../world/WorldGenerators.hpp" #include "../world/WorldGenerators.hpp"
#include <memory> #include <memory>
#include <iostream>
#include <glm/glm.hpp> #include <glm/glm.hpp>
static debug::Logger logger("world");
world_load_error::world_load_error(std::string message) world_load_error::world_load_error(std::string message)
: std::runtime_error(message) { : std::runtime_error(message) {
} }
@@ -64,35 +67,38 @@ void World::write(Level* level) {
} }
wfile->write(this, content); wfile->write(this, content);
auto playerFile = dynamic::Map(); auto playerFile = dynamic::Map();
{
auto& players = playerFile.putList("players"); auto& players = playerFile.putList("players");
for (auto object : level->objects) { for (auto object : level->objects) {
if (std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object)) { if (auto player = std::dynamic_pointer_cast<Player>(object)) {
players.put(player->serialize()); players.put(player->serialize());
}
} }
} }
files::write_json(wfile->getPlayerFile(), &playerFile); files::write_json(wfile->getPlayerFile(), &playerFile);
} }
Level* World::create(std::string name, std::unique_ptr<Level> World::create(
std::string generator, std::string name,
fs::path directory, std::string generator,
uint64_t seed, fs::path directory,
EngineSettings& settings, uint64_t seed,
const Content* content, EngineSettings& settings,
const std::vector<ContentPack>& packs const Content* content,
const std::vector<ContentPack>& packs
) { ) {
auto world = new World(name, generator, directory, seed, settings, content, packs); auto world = std::make_unique<World>(
auto level = new Level(world, content, settings); name, generator, directory, seed, settings, content, packs
return level; );
return std::make_unique<Level>(std::move(world), content, settings);
} }
Level* World::load(fs::path directory, std::unique_ptr<Level> World::load(
EngineSettings& settings, fs::path directory,
const Content* content, EngineSettings& settings,
const std::vector<ContentPack>& packs) { const Content* content,
const std::vector<ContentPack>& packs
) {
auto world = std::make_unique<World>( auto world = std::make_unique<World>(
".", WorldGenerators::getDefaultGeneratorID(), directory, 0, settings, content, packs ".", WorldGenerators::getDefaultGeneratorID(), directory, 0, settings, content, packs
); );
@@ -102,23 +108,27 @@ Level* World::load(fs::path directory,
throw world_load_error("could not to find world.json"); throw world_load_error("could not to find world.json");
} }
auto level = new Level(world.get(), content, settings); auto level = std::make_unique<Level>(std::move(world), content, settings);
{ {
fs::path file = wfile->getPlayerFile(); fs::path file = wfile->getPlayerFile();
if (!fs::is_regular_file(file)) { if (!fs::is_regular_file(file)) {
std::cerr << "warning: player.json does not exists" << std::endl; logger.warning() << "player.json does not exists";
} else { } else {
auto playerFile = files::read_json(file); auto playerFile = files::read_json(file);
if (playerFile->has("players")) { if (playerFile->has("players")) {
level->objects.clear(); level->objects.clear();
auto players = playerFile->list("players"); auto players = playerFile->list("players");
for (size_t i = 0; i < players->size(); i++) { for (size_t i = 0; i < players->size(); i++) {
auto player = level->spawnObject<Player>(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, level->inventories->create(DEF_PLAYER_INVENTORY_SIZE)); auto player = level->spawnObject<Player>(
glm::vec3(0, DEF_PLAYER_Y, 0),
DEF_PLAYER_SPEED,
level->inventories->create(DEF_PLAYER_INVENTORY_SIZE)
);
player->deserialize(players->map(i)); player->deserialize(players->map(i));
level->inventories->store(player->getInventory()); level->inventories->store(player->getInventory());
} }
} else { } else {
auto player = level->getObject<Player>(0); auto player = level->getObject<Player>(0);
player->deserialize(playerFile.get()); player->deserialize(playerFile.get());
level->inventories->store(player->getInventory()); level->inventories->store(player->getInventory());
} }
@@ -128,8 +138,10 @@ Level* World::load(fs::path directory,
return level; return level;
} }
ContentLUT* World::checkIndices(const fs::path& directory, std::shared_ptr<ContentLUT> World::checkIndices(
const Content* content) { const fs::path& directory,
const Content* content
) {
fs::path indicesFile = directory/fs::path("indices.json"); fs::path indicesFile = directory/fs::path("indices.json");
if (fs::is_regular_file(indicesFile)) { if (fs::is_regular_file(indicesFile)) {
return ContentLUT::create(indicesFile, content); return ContentLUT::create(indicesFile, content);
@@ -178,10 +190,9 @@ void World::deserialize(dynamic::Map* root) {
generator = root->get("generator", generator); generator = root->get("generator", generator);
seed = root->get("seed", seed); seed = root->get("seed", seed);
if(generator == "") { if (generator == "") {
generator = WorldGenerators::getDefaultGeneratorID(); generator = WorldGenerators::getDefaultGeneratorID();
} }
auto verobj = root->map("version"); auto verobj = root->map("version");
if (verobj) { if (verobj) {
int major=0, minor=-1; int major=0, minor=-1;
@@ -189,14 +200,12 @@ void World::deserialize(dynamic::Map* root) {
verobj->num("minor", minor); verobj->num("minor", minor);
std::cout << "world version: " << major << "." << minor << std::endl; std::cout << "world version: " << major << "." << minor << std::endl;
} }
auto timeobj = root->map("time"); auto timeobj = root->map("time");
if (timeobj) { if (timeobj) {
timeobj->num("day-time", daytime); timeobj->num("day-time", daytime);
timeobj->num("day-time-speed", daytimeSpeed); timeobj->num("day-time-speed", daytimeSpeed);
timeobj->num("total-time", totalTime); timeobj->num("total-time", totalTime);
} }
nextInventoryId = root->get("next-inventory-id", 2); nextInventoryId = root->get("next-inventory-id", 2);
} }
+6 -7
View File
@@ -12,13 +12,10 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <filesystem> #include <filesystem>
#include <stdexcept>
class Content; class Content;
class WorldFiles; class WorldFiles;
class Chunks;
class Level; class Level;
class Player;
class ContentLUT; class ContentLUT;
namespace fs = std::filesystem; namespace fs = std::filesystem;
@@ -75,7 +72,9 @@ public:
/// @param directory world directory /// @param directory world directory
/// @param content current Content instance /// @param content current Content instance
/// @return ContentLUT if world convert required else nullptr /// @return ContentLUT if world convert required else nullptr
static ContentLUT* checkIndices(const fs::path& directory, const Content* content); static std::shared_ptr<ContentLUT> checkIndices(
const fs::path& directory, const Content* content
);
/// @brief Create new world /// @brief Create new world
/// @param name internal world name /// @param name internal world name
@@ -87,7 +86,7 @@ public:
/// with all world content-packs applied /// with all world content-packs applied
/// @param packs vector of all world content-packs /// @param packs vector of all world content-packs
/// @return Level instance containing World instance /// @return Level instance containing World instance
static Level* create( static std::unique_ptr<Level> create(
std::string name, std::string name,
std::string generator, std::string generator,
fs::path directory, fs::path directory,
@@ -105,7 +104,7 @@ public:
/// @param packs vector of all world content-packs /// @param packs vector of all world content-packs
/// @return Level instance containing World instance /// @return Level instance containing World instance
/// @throws world_load_error on world.json load error /// @throws world_load_error on world.json load error
static Level* load( static std::unique_ptr<Level> load(
fs::path directory, fs::path directory,
EngineSettings& settings, EngineSettings& settings,
const Content* content, const Content* content,
@@ -148,4 +147,4 @@ public:
void deserialize(dynamic::Map *src) override; void deserialize(dynamic::Map *src) override;
}; };
#endif /* WORLD_WORLD_HPP_ */ #endif // WORLD_WORLD_HPP_