Add a mutex to Chunk, safeguard all existing reads/writes.
* Clean up more imports. * Create FileManipulator class.master
parent
ad169fbb1e
commit
2380c7ea31
|
@ -1,5 +1,8 @@
|
|||
lib/*/*
|
||||
cmake-build-debug
|
||||
cmake-build-install
|
||||
cmake-build-release
|
||||
|
||||
.hidden
|
||||
|
||||
lib/*/*
|
||||
worlds
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<option name="clangTidyChecks" value="*,-android-*,-bugprone-bool-pointer-implicit-conversion,-cert-env33-c,-cert-dcl50-cpp,-cert-dcl59-cpp,-cppcoreguidelines-no-malloc,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-fuchsia-*,-google-*,google-default-arguments,google-explicit-constructor,google-runtime-member-string-references,google-runtime-operator,-hicpp-braces-around-statements,-hicpp-named-parameter,-hicpp-no-array-decay,-hicpp-no-assembler,-hicpp-no-malloc,-hicpp-function-size,-hicpp-special-member-functions,-hicpp-vararg,-llvm-*,-objc-*,-readability-else-after-return,-readability-implicit-bool-conversion,-readability-named-parameter,-readability-simplify-boolean-expr,-readability-braces-around-statements,-readability-identifier-naming,-readability-function-size,-readability-redundant-member-init,-misc-bool-pointer-implicit-conversion,-misc-definitions-in-headers,-misc-unused-alias-decls,-misc-unused-parameters,-misc-unused-using-decls,-modernize-use-using,-modernize-use-default-member-init,-clang-diagnostic-*,-clang-analyzer-*,-cert-msc30-c,-cert-msc50-cpp,-bugprone-integer-division,-modernize-use-auto" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="OCDFAInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="OCUnusedMacro" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
|
|
|
@ -7,7 +7,7 @@ out vec4 outColor;
|
|||
|
||||
in vec2 texCoords;
|
||||
|
||||
//uniform sampler2D gPosition;
|
||||
uniform sampler2D gPosition;
|
||||
uniform sampler2D gNormal;
|
||||
uniform sampler2D gColorSpec;
|
||||
uniform sampler2D ssaoSampler;
|
||||
|
@ -15,6 +15,7 @@ uniform sampler2D ssaoSampler;
|
|||
uniform vec3 camPosition;
|
||||
|
||||
void main() {
|
||||
vec3 fragPos = texture(gPosition, texCoords).rgb;
|
||||
vec3 normal = texture(gNormal, texCoords).rgb;
|
||||
vec3 color = texture(gColorSpec, texCoords).rgb;
|
||||
float ssao = texture(ssaoSampler, texCoords).r;
|
||||
|
@ -22,29 +23,14 @@ void main() {
|
|||
//Shade based on Normals
|
||||
float shading = (0.95 + abs(normal.x) * 0.1) + (normal.y * 0.15);
|
||||
color *= vec3(shading);
|
||||
|
||||
vec3 lighting = color;
|
||||
|
||||
//Apply Lighting
|
||||
// lighting *= 0.1;
|
||||
//
|
||||
// float radius = 16;
|
||||
//
|
||||
// float lightDist = length(camPosition - fragPos);
|
||||
// if (lightDist < radius) {
|
||||
// vec3 lightDir = normalize(camPosition - fragPos);
|
||||
// vec3 diffuse = max(dot(normal, lightDir) * 0.6 + 0.4, 0.0) * color * vec3(1, 1, 1);
|
||||
// diffuse *= 1 - min(lightDist / radius, 1);
|
||||
// lighting += diffuse;
|
||||
// }
|
||||
color *= ssao;
|
||||
|
||||
//Apply fog color based on distance from camera
|
||||
// float dist = distance(vec3(0, 0, 0), vec3(fragPos));
|
||||
// float dist = distance(camPosition, fragPos);
|
||||
// float nearFog = min(max(dist - 200, 0) / 100, 1);
|
||||
// float farFog = min(max(dist - 250, 0) / 100, 1);
|
||||
|
||||
// color = mix(mix(vec3(lighting), NEAR_FOG, nearFog), FAR_FOG, farFog);
|
||||
color = lighting * ssao;
|
||||
//
|
||||
// color = mix(mix(color, NEAR_FOG, nearFog), FAR_FOG, farFog);
|
||||
|
||||
outColor = vec4(color, 1);
|
||||
}
|
|
@ -111,8 +111,8 @@ set(ZEPHA_SRC
|
|||
def/ClientGame.h
|
||||
world/chunk/Region.cpp
|
||||
world/chunk/MapBlock.cpp
|
||||
util/Util.h
|
||||
world/block/PointedThing.h
|
||||
util/Util.h
|
||||
world/PointedThing.h
|
||||
game/hud/components/compound/GuiLabelledGraph.cpp
|
||||
game/hud/components/compound/GuiLabelledGraph.cpp
|
||||
game/entity/engine/ParticleEntity.cpp
|
||||
|
@ -331,6 +331,6 @@ set(ZEPHA_SRC
|
|||
game/scene/world/graph/FarMeshGenerator.h
|
||||
game/scene/world/FarMapMeshDetails.h
|
||||
lua/api/class/LuaGuiElement.cpp
|
||||
lua/api/class/LuaGuiElement.h world/Dimension.cpp world/Dimension.h)
|
||||
lua/api/class/LuaGuiElement.h world/Dimension.cpp world/Dimension.h world/fs/FileManipulator.cpp world/fs/FileManipulator.h)
|
||||
|
||||
add_library (Zepha_Core ${ZEPHA_SRC})
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
#include "Client.h"
|
||||
|
||||
#include "../util/Timer.h"
|
||||
#include "scene/GameScene.h"
|
||||
#include "scene/ConnectScene.h"
|
||||
#include "scene/MainMenuScene.h"
|
||||
#include "scene/LuaErrorScene.h"
|
||||
|
||||
Client::Client(const std::string& path, const Address &addr, glm::ivec2 dims) :
|
||||
state(path.substr(0, path.find_last_of('/') + 1), renderer),
|
||||
renderer(dims),
|
||||
|
|
|
@ -7,11 +7,6 @@
|
|||
#include "ClientState.h"
|
||||
#include "graph/Renderer.h"
|
||||
#include "graph/scene/SceneManager.h"
|
||||
#include "scene/MainMenuScene.h"
|
||||
#include "scene/ConnectScene.h"
|
||||
#include "scene/GameScene.h"
|
||||
#include "scene/LuaErrorScene.h"
|
||||
#include "../util/Timer.h"
|
||||
#include "../server/LocalServerInstance.h"
|
||||
|
||||
class Client {
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "graph/Renderer.h"
|
||||
#include "scene/net/ClientNetworkInterpreter.h"
|
||||
#include "../def/ClientGame.h"
|
||||
#include "scene/net/ServerConnection.h"
|
||||
|
||||
class Renderer;
|
||||
|
||||
class ClientState {
|
||||
public:
|
||||
ClientState(const std::string& path, Renderer& renderer);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "Entity.h"
|
||||
|
||||
#include "../graph/Renderer.h"
|
||||
|
||||
Entity::Entity() : model(std::make_unique<Model>()) {}
|
||||
|
||||
Entity::Entity(std::shared_ptr<Model> model) : animState(*model), model(model) {}
|
||||
|
|
|
@ -141,11 +141,13 @@ void Renderer::endDeferredCalls() {
|
|||
light.set(light.uniforms.camPosition, camera.getPos());
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, blur.colorBuffer);
|
||||
glBindTexture(GL_TEXTURE_2D, light.gPosition);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, light.gNormal);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, light.gColorSpec);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, blur.colorBuffer);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
renderQuad();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../Renderer.h"
|
||||
class Renderer;
|
||||
|
||||
class Drawable {
|
||||
public:
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Drawable.h"
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
// Created by aurailus on 25/11/18.
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ChunkMesh.h"
|
||||
|
||||
#include "ChunkVertex.h"
|
||||
|
||||
void ChunkMesh::create(const std::vector<ChunkVertex>& vertices, const std::vector<unsigned int>& indices) {
|
||||
indCount = static_cast<GLsizei>(indices.size());
|
||||
|
||||
|
|
|
@ -4,13 +4,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Mesh.h"
|
||||
#include "ChunkVertex.h"
|
||||
|
||||
class ChunkVertex;
|
||||
|
||||
class ChunkMesh : public Mesh {
|
||||
public:
|
||||
ChunkMesh() = default;
|
||||
ChunkMesh(const ChunkMesh& o) { assert(false); };
|
||||
ChunkMesh(const ChunkMesh& o) { throw std::runtime_error("No copy constructor for ChunkMeshes"); };
|
||||
|
||||
void create(const std::vector<ChunkVertex>& vertices, const std::vector<unsigned int>& indices);
|
||||
|
||||
|
|
|
@ -14,12 +14,14 @@ void LightingShader::postCreate() {
|
|||
uniforms.gPosition = get("gPosition");
|
||||
uniforms.gNormal = get("gNormal");
|
||||
uniforms.gColorSpec = get("gColorSpec");
|
||||
uniforms.ssaoSampler = get("ssaoSampler");
|
||||
uniforms.camPosition = get("camPosition");
|
||||
|
||||
use();
|
||||
set(uniforms.gPosition, 0);
|
||||
set(uniforms.gNormal, 1);
|
||||
set(uniforms.gColorSpec, 2);
|
||||
set(uniforms.ssaoSampler, 3);
|
||||
|
||||
glGenFramebuffers(1, &gBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
GLint gPosition;
|
||||
GLint gNormal;
|
||||
GLint gColorSpec;
|
||||
GLint ssaoSampler;
|
||||
|
||||
GLint camPosition;
|
||||
};
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
//
|
||||
|
||||
#include "GameGui.h"
|
||||
#include "components/compound/GuiInventoryList.h"
|
||||
|
||||
#include "../graph/Renderer.h"
|
||||
|
||||
GameGui::GameGui(LocalInventoryRefs& refs, glm::vec2 bufferSize, ClientGame& defs, Renderer& renderer) :
|
||||
refs(refs),
|
||||
|
|
|
@ -5,16 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "GameGuiBuilder.h"
|
||||
#include "SerialGui.h"
|
||||
#include "components/basic/GuiText.h"
|
||||
#include "components/basic/GuiRect.h"
|
||||
#include "components/basic/GuiContainer.h"
|
||||
#include "../graph/drawable/DrawableGroup.h"
|
||||
#include "../inventory/ServerInventoryList.h"
|
||||
#include "../entity/Entity.h"
|
||||
#include "../../util/Util.h"
|
||||
#include "components/compound/GuiInventoryList.h"
|
||||
#include "../inventory/Inventory.h"
|
||||
|
||||
class GameGui {
|
||||
public:
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
//
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "GuiComponent.h"
|
||||
|
||||
#include "../../graph/Renderer.h"
|
||||
|
||||
GuiComponent::GuiComponent(const std::string& key) :
|
||||
key(key) {}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "../../entity/Entity.h"
|
||||
|
||||
class Window;
|
||||
|
||||
class GuiComponent : public Drawable {
|
||||
public:
|
||||
enum class CallbackType { PRIMARY, SECONDARY, HOVER };
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "GuiModel.h"
|
||||
|
||||
#include "../../SerialGui.h"
|
||||
#include "../../../graph/Renderer.h"
|
||||
#include "../../../../def/ClientGame.h"
|
||||
#include "../../../../def/model/ModelStore.h"
|
||||
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
#include <string>
|
||||
|
||||
#include "GuiContainer.h"
|
||||
#include "../../../../def/ItemDef.h"
|
||||
#include "../../SerialGui.h"
|
||||
|
||||
class ClientGame;
|
||||
class ModelStore;
|
||||
class LuaGuiElement;
|
||||
|
||||
class GuiModel : public GuiComponent {
|
||||
public:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "ConnectScene.h"
|
||||
|
||||
#include "../graph/Renderer.h"
|
||||
#include "../../util/net/Packet.h"
|
||||
#include "../../util/net/PacketType.h"
|
||||
#include "../../util/net/PacketView.h"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "GameScene.h"
|
||||
|
||||
#include "../graph/Renderer.h"
|
||||
#include "../../util/net/Packet.h"
|
||||
#include "../../util/net/PacketView.h"
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "world/Player.h"
|
||||
#include "../ClientState.h"
|
||||
#include "../hud/DebugGui.h"
|
||||
#include "../graph/scene/Scene.h"
|
||||
|
||||
#include "world/Player.h"
|
||||
#include "../hud/DebugGui.h"
|
||||
|
||||
class GameScene : public Scene {
|
||||
public:
|
||||
explicit GameScene(ClientState& state);
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
//
|
||||
|
||||
#include "LuaErrorScene.h"
|
||||
|
||||
#include "../graph/Renderer.h"
|
||||
#include "../../def/texture/Font.h"
|
||||
#include "../hud/components/basic/GuiRect.h"
|
||||
#include "../hud/components/basic/GuiText.h"
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../graph/scene/Scene.h"
|
||||
|
||||
#include "../hud/components/basic/GuiContainer.h"
|
||||
|
||||
class LuaErrorScene : public Scene {
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
#include "MainMenuScene.h"
|
||||
|
||||
#include "../graph/Renderer.h"
|
||||
#include "../hud/components/basic/GuiText.h"
|
||||
#include "../hud/components/compound/GuiImageButton.h"
|
||||
|
||||
MainMenuScene::MainMenuScene(ClientState& state) :
|
||||
Scene(state),
|
||||
sandbox(sandboxArea, state, menuContainer) {
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <json/json.hpp>
|
||||
#include "../../game/ClientState.h"
|
||||
|
||||
#include "../../game/graph/scene/Scene.h"
|
||||
#include "../hud/components/basic/GuiText.h"
|
||||
#include "../hud/components/basic/GuiContainer.h"
|
||||
#include "../hud/components/compound/GuiImageButton.h"
|
||||
#include "menu/Subgame.h"
|
||||
|
||||
#include "menu/MenuSandbox.h"
|
||||
|
||||
class ClientState;
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
class MainMenuScene : public Scene {
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
#include <vector>
|
||||
#include <glm/vec3.hpp>
|
||||
#include "../../graph/meshtypes/ChunkMesh.h"
|
||||
|
||||
#include "../../graph/meshtypes/ChunkVertex.h"
|
||||
|
||||
struct ChunkMeshDetails {
|
||||
std::vector<ChunkVertex> vertices;
|
||||
|
|
|
@ -101,6 +101,7 @@ unsigned short LocalWorld::getBiome(glm::vec3 pos) {
|
|||
auto local = Space::Block::relative::toChunk(pos);
|
||||
|
||||
auto chunk = getChunk(chunkPos);
|
||||
auto l = chunk->aquireLock();
|
||||
if (chunk != nullptr) return chunk->getBiome(local);
|
||||
return BiomeAtlas::INVALID;
|
||||
}
|
||||
|
|
|
@ -90,11 +90,6 @@ void MeshGenStream::Thread::exec() {
|
|||
auto& u = tasks[i];
|
||||
if (!u.busy) continue;
|
||||
|
||||
if (u.thisChunk == nullptr) {
|
||||
std::cout << Util::vecToString(u.thisChunk->pos) << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
ChunkMeshGenerator m(u.meshDetails, game.defs, game.biomes, u.thisChunk, u.adjacentChunks, offsetSamplers);
|
||||
hasNoTasks = false;
|
||||
u.busy = false;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Player.h"
|
||||
|
||||
#include "../../../util/Ray.h"
|
||||
#include "../../graph/Renderer.h"
|
||||
#include "../../../world/chunk/Chunk.h"
|
||||
|
||||
Player::Player(LocalWorld& world, ClientGame& defs, Renderer& renderer, LocalInventoryRefs& refs) :
|
||||
|
@ -141,19 +142,22 @@ void Player::updateCamera() {
|
|||
|
||||
void Player::findPointedThing(Input &input) {
|
||||
glm::ivec3 chunkPos = {};
|
||||
|
||||
std::unique_lock<std::mutex> lock {};
|
||||
std::shared_ptr<Chunk> blockChunk = nullptr;
|
||||
|
||||
for (Ray ray(this); ray.getLength() < LOOK_DISTANCE; ray.step(LOOK_PRECISION)) {
|
||||
glm::vec3 rayEnd = ray.getEnd();
|
||||
glm::ivec3 roundedPos = glm::floor(rayEnd);
|
||||
|
||||
auto currChunkPos = Space::Chunk::world::fromBlock(roundedPos);
|
||||
if (glm::ivec3(currChunkPos) != chunkPos || blockChunk == nullptr) {
|
||||
glm::ivec3 currChunkPos = Space::Chunk::world::fromBlock(roundedPos);
|
||||
if (currChunkPos != chunkPos || blockChunk == nullptr) {
|
||||
chunkPos = currChunkPos;
|
||||
blockChunk = world.getChunk(chunkPos);
|
||||
}
|
||||
if (blockChunk == nullptr) continue;
|
||||
|
||||
if (blockChunk == nullptr) continue;
|
||||
lock = blockChunk->aquireLock();
|
||||
}
|
||||
|
||||
unsigned int blockID = blockChunk->getBlock(Space::Block::relative::toChunk(roundedPos));
|
||||
auto& boxes = game.defs.blockFromId(blockID).sBoxes;
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
#include "../../graph/drawable/Drawable.h"
|
||||
|
||||
#include "../../hud/GameGui.h"
|
||||
#include "../../../world/block/PointedThing.h"
|
||||
#include "../../../world/PointedThing.h"
|
||||
#include "../../entity/engine/WireframeEntity.h"
|
||||
|
||||
class Input;
|
||||
class LuaGuiElement;
|
||||
class LocalInventory;
|
||||
class LocalInventoryRefs;
|
||||
|
|
|
@ -66,8 +66,8 @@ private:
|
|||
std::thread thread;
|
||||
};
|
||||
|
||||
MapGen* gen;
|
||||
std::shared_ptr<MapGenProps> props;
|
||||
MapGen* gen;
|
||||
|
||||
std::vector<Thread> threads;
|
||||
std::list<std::unique_ptr<PacketView>> queuedPacketTasks;
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include "../ChunkMeshDetails.h"
|
||||
#include "../../../../util/Vec.h"
|
||||
#include "../../../../world/chunk/Chunk.h"
|
||||
#include "../../../../def/item/BlockModel.h"
|
||||
#include "../../../../def/gen/NoiseSample.h"
|
||||
#include "../../../../def/gen/LocalBiomeAtlas.h"
|
||||
#include "../../../../def/LocalDefinitionAtlas.h"
|
||||
|
||||
ChunkMeshGenerator::ChunkMeshGenerator(ChunkMeshDetails* meshDetails, LocalDefinitionAtlas& defs, LocalBiomeAtlas& biomes,
|
||||
std::shared_ptr<Chunk> chunk, std::array<std::shared_ptr<Chunk>, 6> adjacent,
|
||||
|
@ -24,6 +28,11 @@ ChunkMeshGenerator::ChunkMeshGenerator(ChunkMeshDetails* meshDetails, LocalDefin
|
|||
meshDetails->vertices.reserve(5000);
|
||||
meshDetails->indices.reserve(7000);
|
||||
|
||||
// Lock the related chunks
|
||||
std::array<std::unique_lock<std::mutex>, 7> locks;
|
||||
locks[0] = std::move(chunk->aquireLock());
|
||||
for (unsigned int i = 0; i < 6; i++) locks[i+1] = std::move(adjacent[i]->aquireLock());
|
||||
|
||||
const auto& blockData = chunk->cGetBlocks();
|
||||
const auto& biomeData = chunk->cGetBiomes();
|
||||
|
||||
|
|
|
@ -4,15 +4,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "OCUnusedMacroInspection"
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#include "../../../../def/ClientGame.h"
|
||||
#include "../../../../def/gen/NoiseSample.h"
|
||||
#include <memory>
|
||||
|
||||
class LocalDefinitionAtlas;
|
||||
class ChunkMeshDetails;
|
||||
class LocalBiomeAtlas;
|
||||
class NoiseSample;
|
||||
class BlockDef;
|
||||
class MeshPart;
|
||||
class Chunk;
|
||||
|
||||
class ChunkMeshGenerator {
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include "../../../graph/Renderer.h"
|
||||
|
||||
class Renderer;
|
||||
|
||||
struct ChunkRenderElem {
|
||||
virtual void draw(Renderer& renderer) = 0;
|
||||
|
|
|
@ -2,10 +2,16 @@
|
|||
// Created by aurailus on 15/12/18.
|
||||
//
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include "MeshChunk.h"
|
||||
|
||||
#include "../../../graph/Renderer.h"
|
||||
#include "../../../graph/meshtypes/ChunkMesh.h"
|
||||
|
||||
void MeshChunk::create(std::vector<ChunkVertex> &vertices, std::vector<unsigned int> &indices) {
|
||||
this->mesh = std::make_unique<ChunkMesh>();
|
||||
this->mesh = std::make_shared<ChunkMesh>();
|
||||
mesh->create(vertices, indices);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "ChunkRenderElem.h"
|
||||
#include "../../../graph/drawable/Drawable.h"
|
||||
#include "../../../graph/meshtypes/ChunkVertex.h"
|
||||
#include "../../../graph/meshtypes/ChunkMesh.h"
|
||||
|
||||
class ChunkMesh;
|
||||
class ChunkVertex;
|
||||
|
||||
class MeshChunk : public ChunkRenderElem, Drawable {
|
||||
public:
|
||||
MeshChunk() = default;
|
||||
|
@ -21,6 +24,6 @@ public:
|
|||
void setPos(glm::vec3 pos);
|
||||
glm::vec3 getPos() override;
|
||||
private:
|
||||
std::unique_ptr<ChunkMesh> mesh = nullptr;
|
||||
std::shared_ptr<ChunkMesh> mesh = nullptr;
|
||||
glm::vec3 pos {};
|
||||
};
|
|
@ -5,11 +5,12 @@
|
|||
#include "LocalLuaParser.h"
|
||||
|
||||
#include "../ErrorFormatter.h"
|
||||
#include "../../game/ClientState.h"
|
||||
#include "../../game/graph/Renderer.h"
|
||||
#include "../register/RegisterBlocks.h"
|
||||
#include "../register/RegisterItems.h"
|
||||
#include "../register/RegisterBiomes.h"
|
||||
#include "../register/RegisterKeybinds.h"
|
||||
#include "../../game/ClientState.h"
|
||||
|
||||
// Usertypes
|
||||
#include "../api/class/LuaGuiElement.h"
|
||||
|
|
|
@ -21,7 +21,7 @@ Server::Server(unsigned short port, const std::string& subgame) :
|
|||
world(seed, defs, clientList) {
|
||||
|
||||
defs.init(world);
|
||||
world.init();
|
||||
world.init("world");
|
||||
config.init();
|
||||
|
||||
std::cout << Log::info << "Server started successfully, listening for clients." << Log::endl;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../conn/ServerClient.h"
|
||||
#include "../../world/chunk/Chunk.h"
|
||||
#include "../../world/chunk/MapBlock.h"
|
||||
#include "../../world/fs/FileManipulator.h"
|
||||
|
||||
ServerWorld::ServerWorld(unsigned int seed, ServerGame& game, ClientList& clients) :
|
||||
clientList(clients),
|
||||
|
@ -51,8 +52,11 @@ ServerWorld::ServerWorld(unsigned int seed, ServerGame& game, ClientList& client
|
|||
}
|
||||
}
|
||||
|
||||
void ServerWorld::init() {
|
||||
void ServerWorld::init(const std::string& worldDir) {
|
||||
genStream = std::make_unique<ServerGenStream>(seed, game);
|
||||
fileManip = std::make_shared<FileManipulator>("worlds/" + worldDir + "/");
|
||||
|
||||
generateMapBlock({0, 0, 0});
|
||||
}
|
||||
|
||||
void ServerWorld::update(double delta) {
|
||||
|
@ -67,6 +71,7 @@ void ServerWorld::update(double delta) {
|
|||
for (const auto& chunk : mb.chunks) {
|
||||
changed.insert(chunk->pos);
|
||||
dimension.setChunk(chunk);
|
||||
// fileManip->commitChunk(*chunk);
|
||||
}
|
||||
|
||||
auto resend = dimension.calculateEdgeLight(mb.pos);
|
||||
|
@ -178,7 +183,11 @@ void ServerWorld::sendChunk(const std::shared_ptr<Chunk>& chunk, ServerClient &p
|
|||
if (chunk == nullptr || !chunk->generated) return;
|
||||
|
||||
Packet r(PacketType::CHUNK);
|
||||
|
||||
auto l = chunk->aquireLock();
|
||||
r.data = chunk->serialize();
|
||||
l.release();
|
||||
|
||||
r.sendTo(peer.peer, PacketChannel::CHUNK);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
class ServerGame;
|
||||
class ClientList;
|
||||
class ServerClient;
|
||||
class FileManipulator;
|
||||
class ServerGenStream;
|
||||
|
||||
class ServerWorld : public World {
|
||||
|
@ -22,7 +23,7 @@ public:
|
|||
|
||||
explicit ServerWorld(unsigned int seed, ServerGame& game, ClientList& clients);
|
||||
|
||||
void init();
|
||||
void init(const std::string& worldDir);
|
||||
void update(double delta) override;
|
||||
|
||||
unsigned int getBlock(glm::ivec3 pos) override;
|
||||
|
@ -44,6 +45,9 @@ private:
|
|||
unsigned int seed;
|
||||
ServerGame& game;
|
||||
ClientList& clientList;
|
||||
|
||||
std::string worldDir;
|
||||
std::shared_ptr<FileManipulator> fileManip;
|
||||
|
||||
unsigned int generatedMapBlocks = 0;
|
||||
std::vector<glm::ivec3> generateOrder;
|
||||
|
|
|
@ -63,6 +63,16 @@ template <> inline Serializer& Serializer::append<unsigned short>(const unsigned
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <> inline Serializer& Serializer::append<char>(const char& elem) {
|
||||
data += elem;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <> inline Serializer& Serializer::append<unsigned char>(const unsigned char& elem) {
|
||||
data += elem;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <> inline Serializer& Serializer::append<float>(const float& elem) {
|
||||
float_union cv = { elem };
|
||||
data += cv.bytes[0];
|
||||
|
|
|
@ -8,9 +8,12 @@
|
|||
#include "../def/DefinitionAtlas.h"
|
||||
|
||||
bool Dimension::setBlock(glm::ivec3 pos, unsigned int block) {
|
||||
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
if (!chunk) return false;
|
||||
auto l = chunk->aquireLock();
|
||||
|
||||
if (!DimensionBase::setBlock(pos, block)) return false;
|
||||
|
||||
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
auto &def = defs.blockFromId(block);
|
||||
|
||||
glm::ivec4 oldLight = chunk->getLight(Space::Block::index(pos));
|
||||
|
@ -22,6 +25,8 @@ bool Dimension::setBlock(glm::ivec3 pos, unsigned int block) {
|
|||
if (def.lightPropagates) reflowLight(pos);
|
||||
if (!def.lightPropagates && getLight(pos, chunk.get()).w != 0) removeSunlight(pos);
|
||||
|
||||
l.release();
|
||||
|
||||
propogateRemoveNodes();
|
||||
|
||||
return true;
|
||||
|
@ -55,11 +60,19 @@ std::unordered_set<glm::ivec3, Vec::ivec3> Dimension::calculateEdgeLight(glm::iv
|
|||
}
|
||||
|
||||
std::unordered_set<glm::ivec3, Vec::ivec3> Dimension::propogateAddNodes() {
|
||||
std::vector<std::unique_lock<std::mutex>> collectedLocks;
|
||||
std::unordered_set<glm::ivec3, Vec::ivec3> chunksUpdated {};
|
||||
|
||||
for (unsigned int channel = 0; channel < lightAddQueue.size(); channel++) {
|
||||
while (!lightAddQueue[channel].empty()) {
|
||||
LightAddNode& node = lightAddQueue[channel].front();
|
||||
|
||||
Chunk* chunk = node.chunk;
|
||||
if (!chunksUpdated.count(chunk->pos)) {
|
||||
chunksUpdated.insert(chunk->pos);
|
||||
collectedLocks.push_back(std::move(chunk->aquireLock()));
|
||||
}
|
||||
|
||||
unsigned char lightLevel = node.chunk->getLight(node.index, channel);
|
||||
glm::ivec3 worldPos = node.chunk->pos * 16 + Space::Block::fromIndex(node.index);
|
||||
|
||||
|
@ -71,8 +84,11 @@ std::unordered_set<glm::ivec3, Vec::ivec3> Dimension::propogateAddNodes() {
|
|||
else {
|
||||
chunk = getChunk(Space::Chunk::world::fromBlock(check)).get();
|
||||
if (!chunk) continue;
|
||||
chunksUpdated.insert(chunk->pos);
|
||||
chunk->dirty = true;
|
||||
if (!chunksUpdated.count(chunk->pos)) {
|
||||
chunksUpdated.insert(chunk->pos);
|
||||
collectedLocks.push_back(std::move(chunk->aquireLock()));
|
||||
chunk->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool sunDown = (channel == SUNLIGHT_CHANNEL && lightLevel == 15 && i.y == -1);
|
||||
|
@ -91,6 +107,7 @@ std::unordered_set<glm::ivec3, Vec::ivec3> Dimension::propogateAddNodes() {
|
|||
}
|
||||
|
||||
std::unordered_set<glm::ivec3, Vec::ivec3> Dimension::propogateRemoveNodes() {
|
||||
std::vector<std::unique_lock<std::mutex>> collectedLocks;
|
||||
std::unordered_set<glm::ivec3, Vec::ivec3> chunksUpdated {};
|
||||
|
||||
for (unsigned int channel = 0; channel < lightRemoveQueue.size(); channel++) {
|
||||
|
@ -106,8 +123,11 @@ std::unordered_set<glm::ivec3, Vec::ivec3> Dimension::propogateRemoveNodes() {
|
|||
else {
|
||||
chunk = getChunk(Space::Chunk::world::fromBlock(check)).get();
|
||||
if (!chunk) continue;
|
||||
chunksUpdated.insert(chunk->pos);
|
||||
chunk->dirty = true;
|
||||
if (!chunksUpdated.count(chunk->pos)) {
|
||||
chunksUpdated.insert(chunk->pos);
|
||||
collectedLocks.push_back(std::move(chunk->aquireLock()));
|
||||
chunk->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char checkLight = chunk->getLight(ind, channel);
|
||||
|
@ -147,6 +167,9 @@ glm::ivec4 Dimension::getLight(glm::ivec3 worldPos, Chunk *chunk) {
|
|||
}
|
||||
|
||||
void Dimension::calculateHorizontalEdge(std::shared_ptr<Chunk> a, std::shared_ptr<Chunk> b) {
|
||||
auto l1 = a->aquireLock();
|
||||
auto l2 = b->aquireLock();
|
||||
|
||||
for (unsigned int j = 0; j < 256; j++) {
|
||||
glm::ivec3 diff = a->pos - b->pos;
|
||||
|
||||
|
@ -166,6 +189,9 @@ void Dimension::calculateHorizontalEdge(std::shared_ptr<Chunk> a, std::shared_pt
|
|||
}
|
||||
|
||||
void Dimension::calculateVerticalEdge(std::shared_ptr<Chunk> above, std::shared_ptr<Chunk> below) {
|
||||
auto l1 = above->aquireLock();
|
||||
auto l2 = below->aquireLock();
|
||||
|
||||
for (unsigned int j = 0; j < 256; j++) {
|
||||
unsigned int xx = j / 16;
|
||||
unsigned int zz = j % 16;
|
||||
|
|
|
@ -60,13 +60,16 @@ void DimensionBase::removeChunk(glm::ivec3 pos){
|
|||
|
||||
unsigned int DimensionBase::getBlock(glm::ivec3 pos) {
|
||||
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
if (chunk) return chunk->getBlock(Space::Block::relative::toChunk(pos));
|
||||
return 0;
|
||||
if (!chunk) return 0;
|
||||
auto l = chunk->aquireLock();
|
||||
|
||||
return chunk->getBlock(Space::Block::relative::toChunk(pos));
|
||||
}
|
||||
|
||||
bool DimensionBase::setBlock(glm::ivec3 pos, unsigned int block) {
|
||||
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
if (!chunk) return false;
|
||||
auto l = chunk->aquireLock();
|
||||
|
||||
auto &def = defs.blockFromId(block);
|
||||
return chunk->setBlock(Space::Block::relative::toChunk(pos), block);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "../world/chunk/Chunk.h"
|
||||
#include "../world/chunk/Region.h"
|
||||
#include "../game/graph/Renderer.h"
|
||||
#include "../util/net/PacketView.h"
|
||||
#include "../world/chunk/MapBlock.h"
|
||||
#include "../lua/api/class/LocalLuaEntity.h"
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../def/item/BlockDef.h"
|
||||
#include "../../def/ClientGame.h"
|
||||
#include "../def/item/BlockDef.h"
|
||||
#include "../def/ClientGame.h"
|
||||
|
||||
class PointedThing {
|
||||
public:
|
|
@ -21,6 +21,18 @@ Chunk::Chunk(const std::vector<unsigned int>& blocks, const std::vector<unsigned
|
|||
recalculateRenderableBlocks();
|
||||
}
|
||||
|
||||
Chunk::Chunk(const Chunk& o) :
|
||||
partial(o.partial),
|
||||
generated(o.generated),
|
||||
dirty(o.dirty),
|
||||
shouldRender(o.shouldRender),
|
||||
pos(o.pos),
|
||||
blocks(o.blocks),
|
||||
biomes(o.biomes),
|
||||
blockLight(o.blockLight),
|
||||
sunLight(o.sunLight),
|
||||
renderableBlocks(o.renderableBlocks) {}
|
||||
|
||||
bool Chunk::setBlock(unsigned int ind, unsigned int blk) {
|
||||
if (!RIE::write(ind, blk, blocks, 4096)) return false;
|
||||
if (blk == DefinitionAtlas::AIR && !(renderableBlocks = std::max(renderableBlocks - 1, 0))) shouldRender = false;
|
||||
|
@ -64,7 +76,7 @@ std::string Chunk::serialize() {
|
|||
|
||||
void Chunk::deserialize(Deserializer& d) {
|
||||
std::string gzipped = d.read<std::string>();
|
||||
if (!gzip::is_compressed(gzipped.data(), gzipped.length())) throw "Invalid Blocks GZip Data.";
|
||||
if (!gzip::is_compressed(gzipped.data(), gzipped.length())) throw "Chunk contains invalid gzipped data.";
|
||||
|
||||
std::vector<unsigned char> sunLight {};
|
||||
std::vector<unsigned short> blockLight {};
|
||||
|
@ -103,4 +115,4 @@ void Chunk::recalculateRenderableBlocks() {
|
|||
shouldRender = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
#include <array>
|
||||
#include <vector>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <mutex>
|
||||
|
||||
#include "../../util/RIE.h"
|
||||
#include "../../util/Space.h"
|
||||
|
@ -36,6 +37,9 @@ public:
|
|||
Chunk() = default;
|
||||
explicit Chunk(const std::vector<unsigned int>& blocks, const std::vector<unsigned short>& biomes);
|
||||
Chunk(const std::vector<unsigned int>& blocks, const std::vector<unsigned short>& biomes, glm::ivec3 pos);
|
||||
Chunk(const Chunk& o);
|
||||
|
||||
inline std::unique_lock<std::mutex> aquireLock();
|
||||
|
||||
inline unsigned int getBlock(unsigned int ind) const;
|
||||
bool setBlock(unsigned int ind, unsigned int blk);
|
||||
|
@ -72,6 +76,8 @@ public:
|
|||
glm::ivec3 pos;
|
||||
|
||||
private:
|
||||
std::mutex m;
|
||||
|
||||
std::vector<unsigned int> blocks {0, 0};
|
||||
std::vector<unsigned short> biomes {0, 0};
|
||||
|
||||
|
@ -84,6 +90,11 @@ private:
|
|||
inline void setSunlight(unsigned int ind, unsigned char val);
|
||||
};
|
||||
|
||||
std::unique_lock<std::mutex> Chunk::aquireLock() {
|
||||
std::unique_lock<std::mutex> lock(m, std::defer_lock);
|
||||
return std::move(lock);
|
||||
}
|
||||
|
||||
inline unsigned int Chunk::getBlock(const glm::ivec3& pos) const {
|
||||
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return 0; // Invalid
|
||||
return getBlock(Space::Block::index(pos));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//
|
||||
// The MapBlock class, contains 64 Chunks in a 4^3 cube.
|
||||
// Created by aurailus on 18/04/19.
|
||||
//
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
//
|
||||
// Created by aurailus on 04/04/19.
|
||||
//
|
||||
//
|
||||
// The Region class, contains 64 MapBlocks in a 4^3 cube.
|
||||
// Created by aurailus on 18/04/19.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
//
|
||||
// Created by aurailus on 2020-06-24.
|
||||
//
|
||||
// File Format:
|
||||
// 12 bytes -- Region Location Vec3
|
||||
// 2 * 4096 bytes - Chunk offset within the file. -1 means it doesn't exist
|
||||
// 1024 byte subsections for containing Chunks.
|
||||
//
|
||||
// Chunk Format:
|
||||
// 4 bytes - Data length
|
||||
// [remaining] - Serialized Chunk data
|
||||
//
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "FileManipulator.h"
|
||||
|
||||
#include "../chunk/Chunk.h"
|
||||
#include "../../util/Util.h"
|
||||
#include "../../util/net/Serializer.h"
|
||||
#include "../../util/net/Deserializer.h"
|
||||
|
||||
FileManipulator::FileManipulator(const std::string &worldPath) :
|
||||
path(worldPath) {
|
||||
}
|
||||
|
||||
void FileManipulator::commitChunk(Chunk &chunk) {
|
||||
// return;
|
||||
glm::ivec3 reg = Space::Region::world::fromChunk(chunk.pos);
|
||||
unsigned int chunkInd = Space::Chunk::index(chunk.pos);
|
||||
|
||||
std::string fileName = std::to_string(reg.x) + "_" + std::to_string(reg.y) + "_" + std::to_string(reg.z);
|
||||
std::string filePath = path + "/" + fileName;
|
||||
createRegionFileIfNotExists(reg);
|
||||
|
||||
std::string chunkData = chunk.serialize();
|
||||
unsigned int dataBlockSize = floor(chunkData.length() / BLOCK_SIZE);
|
||||
|
||||
std::fstream file(filePath, std::ios::in|std::ios::out|std::ios::binary);
|
||||
if (!file.is_open()) throw std::runtime_error("Couldn't open file.");
|
||||
|
||||
std::array<short, 4096> chunkOffsets {};
|
||||
populateChunkOffsets(file, chunkOffsets);
|
||||
|
||||
unsigned int currentBlock = chunkOffsets[chunkInd];
|
||||
unsigned int nextBlock = (chunkInd == 63 ? 10000 : chunkOffsets[chunkInd + 1]);
|
||||
|
||||
if (dataBlockSize > nextBlock - currentBlock)
|
||||
shiftChunks(file, chunkOffsets, chunkInd + 1, dataBlockSize - (nextBlock - currentBlock));
|
||||
writeChunk(file, chunkOffsets[chunkInd], chunkData);
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
void FileManipulator::writeChunk(std::fstream& file, unsigned int offset, const std::string& data) {
|
||||
file.seekp(META_OFFSET + offset * BLOCK_SIZE);
|
||||
file.write(data.data(), data.length());
|
||||
}
|
||||
|
||||
void FileManipulator::shiftChunks(std::fstream &file, std::array<short, 4096>& offsets, unsigned int ind, unsigned int amt) {
|
||||
std::cout << "Shifting by " << amt << std::endl;
|
||||
|
||||
unsigned int startPos = offsets[ind] * BLOCK_SIZE + META_OFFSET;
|
||||
unsigned int endPos; {
|
||||
char *buff = new char[4];
|
||||
file.seekg(META_OFFSET + offsets[63] * BLOCK_SIZE);
|
||||
file.read(buff, 4);
|
||||
endPos = META_OFFSET + BLOCK_SIZE * offsets[63] + Deserializer(buff, 4).read<unsigned int>();
|
||||
}
|
||||
|
||||
unsigned int len = endPos - startPos;
|
||||
char* buff = new char[len];
|
||||
file.seekg(offsets[ind]);
|
||||
file.read(buff, len);
|
||||
file.seekp(offsets[ind] + amt * BLOCK_SIZE);
|
||||
file.write(buff, len);
|
||||
delete[] buff;
|
||||
|
||||
for (unsigned int i = ind; i < 4096; i++) {
|
||||
offsets[i] += amt;
|
||||
Serializer s;
|
||||
s.append<short>(offsets[i]);
|
||||
file.seekp(12 + i * 2);
|
||||
file.write(s.data.data(), s.data.length());
|
||||
file.close();
|
||||
}
|
||||
|
||||
std::cout << "Shift done" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void FileManipulator::populateChunkOffsets(std::fstream& file, std::array<short, 4096>& offsets) {
|
||||
file.seekg(12);
|
||||
char* buff = new char[2];
|
||||
for (unsigned int i = 0; i < 4096; i++) {
|
||||
file.read(buff, 2);
|
||||
offsets[i] = Deserializer(buff, 2).read<short>();
|
||||
}
|
||||
delete[] buff;
|
||||
}
|
||||
|
||||
void FileManipulator::createRegionFileIfNotExists(glm::ivec3 pos) {
|
||||
std::string fileName = std::to_string(pos.x) + "_" + std::to_string(pos.y) + "_" + std::to_string(pos.z);
|
||||
std::string filePath = path + fileName;
|
||||
|
||||
if (cf_file_exists(filePath.data())) return;
|
||||
|
||||
std::fstream file(filePath, std::ios::out|std::ios::binary);
|
||||
if (!file.is_open()) throw std::runtime_error("Couldn't open file.");
|
||||
file.seekp(0);
|
||||
|
||||
Serializer s;
|
||||
s.append(pos);
|
||||
for (int i = 0; i < 4096; i++) s.append<short>(i);
|
||||
for (int i = 0; i < 4096 * BLOCK_SIZE; i++) s.append<char>(0);
|
||||
|
||||
file.write(s.data.data(), s.data.length());
|
||||
file.close();
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// FileManipulator reads and writes world files.
|
||||
// Created by aurailus on 2020-06-24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <cute_files/cute_files.h>
|
||||
|
||||
class Chunk;
|
||||
|
||||
class FileManipulator {
|
||||
static constexpr unsigned int META_OFFSET = 12 + 2 * 4096;
|
||||
static constexpr unsigned int BLOCK_SIZE = 256;
|
||||
public:
|
||||
FileManipulator(const std::string& worldPath);
|
||||
|
||||
void commitChunk(Chunk& chunk);
|
||||
|
||||
private:
|
||||
static void writeChunk(std::fstream& file, unsigned int offset, const std::string& data);
|
||||
static void shiftChunks(std::fstream& file, std::array<short, 4096>& offsets, unsigned int ind, unsigned int amt);
|
||||
static void populateChunkOffsets(std::fstream& file, std::array<short, 4096>& offsets);
|
||||
void createRegionFileIfNotExists(glm::ivec3 pos);
|
||||
|
||||
std::string path;
|
||||
};
|
|
@ -4,6 +4,7 @@ for i = 1, 5, 1 do
|
|||
solid = false,
|
||||
name = "Tall Grass",
|
||||
model = "base:cross_plant",
|
||||
light_propagates = true,
|
||||
textures = {
|
||||
"tint(0, zeus:default:tallgrass_"..i..")"
|
||||
},
|
||||
|
|
|
@ -1,31 +1,39 @@
|
|||
local woo = "zeus:default:wood"
|
||||
local lea = "zeus:default:leaves"
|
||||
local inv = "invalid"
|
||||
-- local woo = "zeus:default:wood"
|
||||
-- local lea = "zeus:default:leaves"
|
||||
-- local inv = "invalid"
|
||||
--
|
||||
-- local shrub_layer_0 = {
|
||||
-- { inv, inv, inv },
|
||||
-- { inv, woo, inv },
|
||||
-- { inv, inv, inv }
|
||||
-- }
|
||||
--
|
||||
-- local shrub_layer_1 = {
|
||||
-- { inv, lea, inv },
|
||||
-- { lea, woo, lea },
|
||||
-- { inv, lea, inv }
|
||||
-- }
|
||||
--
|
||||
-- local shrub_layer_2 = {
|
||||
-- { inv, inv, inv },
|
||||
-- { inv, lea, inv },
|
||||
-- { inv, inv, inv }
|
||||
-- }
|
||||
--
|
||||
-- local shrub = zepha.create_structure({
|
||||
-- origin = V{1, 1, 1},
|
||||
-- schematic = {
|
||||
-- shrub_layer_0,
|
||||
-- shrub_layer_1,
|
||||
-- shrub_layer_2,
|
||||
-- }
|
||||
-- })
|
||||
|
||||
local shrub_layer_0 = {
|
||||
{ inv, inv, inv },
|
||||
{ inv, woo, inv },
|
||||
{ inv, inv, inv }
|
||||
}
|
||||
|
||||
local shrub_layer_1 = {
|
||||
{ inv, lea, inv },
|
||||
{ lea, woo, lea },
|
||||
{ inv, lea, inv }
|
||||
}
|
||||
|
||||
local shrub_layer_2 = {
|
||||
{ inv, inv, inv },
|
||||
{ inv, lea, inv },
|
||||
{ inv, inv, inv }
|
||||
}
|
||||
|
||||
local shrub = zepha.create_structure({
|
||||
origin = V{1, 1, 1},
|
||||
origin = V{},
|
||||
schematic = {
|
||||
shrub_layer_0,
|
||||
shrub_layer_1,
|
||||
shrub_layer_2,
|
||||
{{"zeus:default:tallgrass_4"}}
|
||||
}
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue