From a10c037670c9add609a3c844cd4672cdb7a3f9db Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 7 Feb 2020 23:15:44 +0900 Subject: [PATCH] [BlockType] Removed everywhere. --- client/include/world/ClientChunk.hpp | 4 +- .../source/network/ClientCommandHandler.cpp | 9 +++- client/source/world/ClientWorld.cpp | 6 +-- common/include/inventory/BlockType.hpp | 39 ----------------- common/include/inventory/Inventory.hpp | 1 + common/include/world/Chunk.hpp | 9 +++- common/include/world/World.hpp | 1 + common/source/inventory/Inventory.cpp | 7 ++- common/source/world/Chunk.cpp | 43 +++++++++++++------ common/source/world/World.cpp | 8 ++++ mods/default/furnace.lua | 4 ++ mods/default/workbench.lua | 7 +-- server/include/world/ServerBlock.hpp | 3 +- server/include/world/ServerChunk.hpp | 5 ++- server/source/lua/LuaMod.cpp | 1 + server/source/lua/ScriptEngine.cpp | 6 ++- server/source/world/ServerBlock.cpp | 2 +- server/source/world/ServerChunk.cpp | 5 +++ server/source/world/ServerWorld.cpp | 19 +++++++- 19 files changed, 105 insertions(+), 74 deletions(-) delete mode 100644 common/include/inventory/BlockType.hpp diff --git a/client/include/world/ClientChunk.hpp b/client/include/world/ClientChunk.hpp index 635c6d41..1b0f61fd 100644 --- a/client/include/world/ClientChunk.hpp +++ b/client/include/world/ClientChunk.hpp @@ -25,8 +25,8 @@ class TextureAtlas; class ClientChunk : public Chunk { public: - ClientChunk(s32 x, s32 y, s32 z, TextureAtlas &textureAtlas) - : Chunk(x, y, z), m_textureAtlas(textureAtlas), m_builder{textureAtlas} {} + ClientChunk(s32 x, s32 y, s32 z, World &world, TextureAtlas &textureAtlas) + : Chunk(x, y, z, world), m_textureAtlas(textureAtlas), m_builder{textureAtlas} {} void update(); diff --git a/client/source/network/ClientCommandHandler.cpp b/client/source/network/ClientCommandHandler.cpp index 0aada876..08dcbdaf 100644 --- a/client/source/network/ClientCommandHandler.cpp +++ b/client/source/network/ClientCommandHandler.cpp @@ -145,9 +145,11 @@ void ClientCommandHandler::setupCallbacks() { packet >> pos.x >> pos.y >> pos.z; BlockData *data = m_world.getBlockData(pos.x, pos.y, pos.z); - if (data) { + if (!data) + data = m_world.addBlockData(pos.x, pos.y, pos.z); + + if (data) packet >> data->inventory; - } }); m_client.setCommandCallback(Network::Command::BlockDataUpdate, [this](sf::Packet &packet) { @@ -157,6 +159,9 @@ void ClientCommandHandler::setupCallbacks() { Chunk *chunk = m_world.getChunkAtBlockPos(pos.x, pos.y, pos.z); if (chunk) { BlockData *data = chunk->getBlockData(pos.x & (CHUNK_WIDTH - 1), pos.y & (CHUNK_HEIGHT - 1), pos.z & (CHUNK_DEPTH - 1)); + if (!data) + data = m_world.addBlockData(pos.x, pos.y, pos.z); + if (data) { bool useAltTiles; packet >> data->data >> useAltTiles; diff --git a/client/source/world/ClientWorld.cpp b/client/source/world/ClientWorld.cpp index 8925378e..153b7afe 100644 --- a/client/source/world/ClientWorld.cpp +++ b/client/source/world/ClientWorld.cpp @@ -31,7 +31,7 @@ void ClientWorld::init(float playerX, float playerY, float playerZ) { int pcy = std::floor(playerY / CHUNK_HEIGHT); int pcz = std::floor(playerZ / CHUNK_DEPTH); - m_chunks.emplace(gk::Vector3i{pcx, pcy, pcz}, new ClientChunk(pcx, pcy, pcz, m_textureAtlas)); + m_chunks.emplace(gk::Vector3i{pcx, pcy, pcz}, new ClientChunk(pcx, pcy, pcz, *this, m_textureAtlas)); } void ClientWorld::update() { @@ -78,7 +78,7 @@ void ClientWorld::receiveChunkData(sf::Packet &packet) { // Get the chunk from the map or create it if it doesn't exist ClientChunk *chunk = (ClientChunk *)getChunk(cx, cy, cz); if (!chunk) { - auto it = m_chunks.emplace(gk::Vector3i{cx, cy, cz}, new ClientChunk(cx, cy, cz, m_textureAtlas)); + auto it = m_chunks.emplace(gk::Vector3i{cx, cy, cz}, new ClientChunk(cx, cy, cz, *this, m_textureAtlas)); chunk = it.first->second.get(); } @@ -154,7 +154,7 @@ void ClientWorld::createChunkNeighbours(ClientChunk *chunk) { ClientChunk *neighbour = (ClientChunk *)getChunk(scx, scy, scz); if (!neighbour) { - auto it = m_chunks.emplace(gk::Vector3i{scx, scy, scz}, new ClientChunk(scx, scy, scz, m_textureAtlas)); + auto it = m_chunks.emplace(gk::Vector3i{scx, scy, scz}, new ClientChunk(scx, scy, scz, *this, m_textureAtlas)); neighbour = it.first->second.get(); } diff --git a/common/include/inventory/BlockType.hpp b/common/include/inventory/BlockType.hpp deleted file mode 100644 index 966393f5..00000000 --- a/common/include/inventory/BlockType.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ===================================================================================== - * - * Filename: BlockType.hpp - * - * Description: - * - * Created: 25/06/2018 17:49:32 - * - * Author: Quentin Bazin, - * - * ===================================================================================== - */ -#ifndef BLOCKTYPE_HPP_ -#define BLOCKTYPE_HPP_ - -namespace BlockType { - enum { - Air = 0, - Dirt = 1, - Cobblestone = 2, - Grass = 3, - Leaves = 4, - Wood = 5, - Stone = 6, - Sand = 7, - Water = 8, - Glass = 9, - CoalOre = 10, - Planks = 11, - Glowstone = 12, - Workbench = 13, - Furnace = 14, - IronOre = 15, - Flower = 16, - }; -} - -#endif // BLOCKTYPE_HPP_ diff --git a/common/include/inventory/Inventory.hpp b/common/include/inventory/Inventory.hpp index d0c26897..007bf834 100644 --- a/common/include/inventory/Inventory.hpp +++ b/common/include/inventory/Inventory.hpp @@ -36,6 +36,7 @@ class Inventory : public ISerializable { u16 width() const { return m_width; } u16 height() const { return m_height; } + void resize(u16 width, u16 height) { m_width = width; m_height = height; m_items.resize(width * height); } const std::vector &items() const { return m_items; } diff --git a/common/include/world/Chunk.hpp b/common/include/world/Chunk.hpp index 936ffa9b..5357ae87 100644 --- a/common/include/world/Chunk.hpp +++ b/common/include/world/Chunk.hpp @@ -27,6 +27,8 @@ #include "BlockData.hpp" #include "ChunkLightmap.hpp" +class World; + class Chunk : public gk::NonCopyable { public: enum { @@ -39,7 +41,7 @@ class Chunk : public gk::NonCopyable { }; public: - Chunk(s32 x, s32 y, s32 z); + Chunk(s32 x, s32 y, s32 z, World &world); virtual ~Chunk() = default; u16 getBlock(int x, int y, int z) const; @@ -49,7 +51,10 @@ class Chunk : public gk::NonCopyable { void setBlockRaw(int x, int y, int z, u16 block); + virtual void onBlockPlaced(int, int, int, const Block &) const {} + BlockData *getBlockData(int x, int y, int z) const; + BlockData *addBlockData(int x, int y, int z, int inventoryWidth = 0, int inventoryHeight = 0); s32 x() const { return m_x; } s32 y() const { return m_y; } @@ -85,6 +90,8 @@ class Chunk : public gk::NonCopyable { s32 m_y; s32 m_z; + World &m_world; + DataArray m_data; ChunkLightmap m_lightmap{this}; diff --git a/common/include/world/World.hpp b/common/include/world/World.hpp index 4d29224f..408bc001 100644 --- a/common/include/world/World.hpp +++ b/common/include/world/World.hpp @@ -26,6 +26,7 @@ class World { Chunk *getChunkAtBlockPos(int x, int y, int z) const; BlockData *getBlockData(int x, int y, int z) const; + BlockData *addBlockData(int x, int y, int z, int inventoryWidth = 0, int inventoryHeight = 0) const; u16 getBlock(int x, int y, int z) const; void setBlock(int x, int y, int z, u16 id) const; diff --git a/common/source/inventory/Inventory.cpp b/common/source/inventory/Inventory.cpp index 1ea5853a..b37cce6f 100644 --- a/common/source/inventory/Inventory.cpp +++ b/common/source/inventory/Inventory.cpp @@ -35,7 +35,7 @@ void Inventory::addStack(const std::string &name, u16 amount) { } void Inventory::serialize(sf::Packet &packet) const { - packet << u8(m_inBlock) + packet << m_width << m_height << u8(m_inBlock) << s32(m_blockPos.x) << s32(m_blockPos.y) << s32(m_blockPos.z); int i = 0; @@ -49,10 +49,13 @@ void Inventory::serialize(sf::Packet &packet) const { void Inventory::deserialize(sf::Packet &packet) { u8 inBlock; s32 bx, by, bz; - packet >> inBlock >> bx >> by >> bz; + packet >> m_width >> m_height >> inBlock >> bx >> by >> bz; m_inBlock = inBlock; m_blockPos = gk::Vector3i{bx, by, bz}; + if (m_items.size() != m_width * m_height) + m_items.resize(m_width * m_height); + std::string name; u16 amount; u8 x, y; diff --git a/common/source/world/Chunk.cpp b/common/source/world/Chunk.cpp index 0ac7aea5..17050438 100644 --- a/common/source/world/Chunk.cpp +++ b/common/source/world/Chunk.cpp @@ -15,12 +15,11 @@ #include -#include "BlockType.hpp" #include "Chunk.hpp" #include "Config.hpp" #include "Registry.hpp" -Chunk::Chunk(s32 x, s32 y, s32 z) { +Chunk::Chunk(s32 x, s32 y, s32 z, World &world) : m_world(world) { m_x = x; m_y = y; m_z = z; @@ -75,6 +74,8 @@ void Chunk::setBlock(int x, int y, int z, u16 type) { m_lightmap.removeSunlight(x, y, z); } + onBlockPlaced(x, y, z, block); + setBlockRaw(x, y, z, type); // FIXME @@ -112,16 +113,8 @@ void Chunk::setBlockRaw(int x, int y, int z, u16 type) { if (m_data[x][y][z] == type) return; - gk::Vector3i pos{x, y, z}; - gk::Vector3i absolutePos{x + m_x * CHUNK_WIDTH, y + m_y * CHUNK_HEIGHT, z + m_z * CHUNK_DEPTH}; - if (type == BlockType::Workbench) { - m_blockData.emplace(pos, new BlockData{absolutePos, 3, 3}); - } - else if (type == BlockType::Furnace) - m_blockData.emplace(pos, new BlockData{absolutePos, 3, 1}); - - if (m_data[x][y][z] == BlockType::Workbench || m_data[x][y][z] == BlockType::Furnace) { - auto it = m_blockData.find(pos); + if (type == 0) { + auto it = m_blockData.find(gk::Vector3i{x, y, z}); if (it != m_blockData.end()) m_blockData.erase(it); } @@ -139,9 +132,31 @@ BlockData *Chunk::getBlockData(int x, int y, int z) const { if(z < 0) return m_surroundingChunks[2] ? m_surroundingChunks[2]->getBlockData(x, y, z + CHUNK_DEPTH) : 0; if(z >= CHUNK_DEPTH) return m_surroundingChunks[3] ? m_surroundingChunks[3]->getBlockData(x, y, z - CHUNK_DEPTH) : 0; - auto it = m_blockData.find(gk::Vector3i{x, y, z}); - if (it == m_blockData.end()) + gk::Vector3i pos{x, y, z}; + auto it = m_blockData.find(pos); + if (it == m_blockData.end()) { return nullptr; + } + + return it->second.get(); +} + +BlockData *Chunk::addBlockData(int x, int y, int z, int inventoryWidth, int inventoryHeight) { + if(x < 0) return m_surroundingChunks[0] ? m_surroundingChunks[0]->addBlockData(x + CHUNK_WIDTH, y, z) : 0; + if(x >= CHUNK_WIDTH) return m_surroundingChunks[1] ? m_surroundingChunks[1]->addBlockData(x - CHUNK_WIDTH, y, z) : 0; + if(y < 0) return m_surroundingChunks[4] ? m_surroundingChunks[4]->addBlockData(x, y + CHUNK_HEIGHT, z) : 0; + if(y >= CHUNK_HEIGHT) return m_surroundingChunks[5] ? m_surroundingChunks[5]->addBlockData(x, y - CHUNK_HEIGHT, z) : 0; + if(z < 0) return m_surroundingChunks[2] ? m_surroundingChunks[2]->addBlockData(x, y, z + CHUNK_DEPTH) : 0; + if(z >= CHUNK_DEPTH) return m_surroundingChunks[3] ? m_surroundingChunks[3]->addBlockData(x, y, z - CHUNK_DEPTH) : 0; + + gk::Vector3i pos{x, y, z}; + auto it = m_blockData.find(pos); + if (it == m_blockData.end()) { + gk::Vector3i absolutePos{x + m_x * CHUNK_WIDTH, y + m_y * CHUNK_HEIGHT, z + m_z * CHUNK_DEPTH}; + BlockData *data = new BlockData{absolutePos, inventoryWidth, inventoryHeight}; + m_blockData.emplace(pos, data); + return data; + } return it->second.get(); } diff --git a/common/source/world/World.cpp b/common/source/world/World.cpp index b87e5100..724881d4 100644 --- a/common/source/world/World.cpp +++ b/common/source/world/World.cpp @@ -36,6 +36,14 @@ BlockData *World::getBlockData(int x, int y, int z) const { return nullptr; } +BlockData *World::addBlockData(int x, int y, int z, int inventoryWidth, int inventoryHeight) const { + Chunk *chunk = getChunkAtBlockPos(x, y, z); + if (chunk) + return chunk->addBlockData(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1), inventoryWidth, inventoryHeight); + + return nullptr; +} + u16 World::getBlock(int x, int y, int z) const { Chunk *chunk = getChunkAtBlockPos(x, y, z); if (chunk) diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua index 34159187..3206dbdf 100644 --- a/mods/default/furnace.lua +++ b/mods/default/furnace.lua @@ -4,6 +4,10 @@ mod:block { tiles = {"furnace_top.png", "furnace_top.png", "furnace_front.png", "furnace_side.png"}, alt_tiles = {"", "", "furnace_front_on.png", ""}, + on_block_placed = function(pos, world) + world:add_block_data(pos.x, pos.y, pos.z, 3, 1) + end, + on_block_activated = function(pos, player, world, client) local gui = LuaGUI.new() diff --git a/mods/default/workbench.lua b/mods/default/workbench.lua index 6ec8e3f5..7c969e7f 100644 --- a/mods/default/workbench.lua +++ b/mods/default/workbench.lua @@ -3,6 +3,10 @@ mod:block { name = "Workbench", tiles = {"crafting_table_top.png", "crafting_table_top.png", "crafting_table_front.png", "crafting_table_side.png"}, + on_block_placed = function(pos, world) + world:add_block_data(pos.x, pos.y, pos.z, 3, 3) + end, + on_block_activated = function(pos, player, world, client) local gui = LuaGUI.new() @@ -49,9 +53,6 @@ mod:block { pos = {x = gui_pos.x, y = gui_pos.y}, block = {x = pos.x, y = pos.y, z = pos.z}, - - -- offset = 0, - -- size = 4 } gui:image { diff --git a/server/include/world/ServerBlock.hpp b/server/include/world/ServerBlock.hpp index 79a145df..945b266f 100644 --- a/server/include/world/ServerBlock.hpp +++ b/server/include/world/ServerBlock.hpp @@ -27,12 +27,13 @@ class ServerBlock : public Block { void onTick(const glm::ivec3 &, std::unordered_map &, Chunk &, World &, Server &) const; bool onBlockActivated(const glm::ivec3 &pos, Player &player, World &world, Client &client) const; - void onBlockPlaced(const glm::ivec3 &pos, World &world); + void onBlockPlaced(const glm::ivec3 &pos, World &world) const; bool canUpdate() const { return m_onTick.valid(); } void setOnBlockActivated(const sol::function &function) { m_onBlockActivated = function; } void setOnTick(const sol::function &function) { m_onTick = function; m_canUpdate = m_onTick.valid(); } + void setOnBlockPlaced(const sol::function &function) { m_onBlockPlaced = function; } private: sol::unsafe_function m_onBlockActivated; diff --git a/server/include/world/ServerChunk.hpp b/server/include/world/ServerChunk.hpp index f5e34966..a31c97e6 100644 --- a/server/include/world/ServerChunk.hpp +++ b/server/include/world/ServerChunk.hpp @@ -21,13 +21,14 @@ class ServerPlayer; class Server; -class World; class ServerChunk : public Chunk { public: - ServerChunk(s32 x, s32 y, s32 z) : Chunk(x, y, z) {} + ServerChunk(s32 x, s32 y, s32 z, World &world) : Chunk(x, y, z, world) {} void updateLights(); + + void onBlockPlaced(int x, int y, int z, const Block &block) const; void tick(std::unordered_map &players, World &world, Server &server); bool isSent() const { return m_isSent; } diff --git a/server/source/lua/LuaMod.cpp b/server/source/lua/LuaMod.cpp index 0c085ab1..729d7bc4 100644 --- a/server/source/lua/LuaMod.cpp +++ b/server/source/lua/LuaMod.cpp @@ -35,6 +35,7 @@ void LuaMod::registerBlock(const sol::table &table) { block.setLightSource(table["is_light_source"].get_or(false)); block.setOnBlockActivated(onBlockActivated); block.setOnTick(onTick); + block.setOnBlockPlaced(table["on_block_placed"]); sol::optional boundingBox = table["bounding_box"]; if (boundingBox != sol::nullopt) { diff --git a/server/source/lua/ScriptEngine.cpp b/server/source/lua/ScriptEngine.cpp index 2717938e..a6807a75 100644 --- a/server/source/lua/ScriptEngine.cpp +++ b/server/source/lua/ScriptEngine.cpp @@ -44,7 +44,8 @@ void ScriptEngine::initUsertypes() { "get_block", &World::getBlock, "get_data", &World::getData, "set_data", &World::setData, - "get_block_data", &World::getBlockData + "get_block_data", &World::getBlockData, + "add_block_data", &World::addBlockData ); m_lua.new_usertype("ServerWorld", @@ -59,7 +60,8 @@ void ScriptEngine::initUsertypes() { m_lua.new_usertype("Chunk", "get_block", &Chunk::getBlock, "get_data", &Chunk::getData, - "get_block_data", &Chunk::getBlockData + "get_block_data", &Chunk::getBlockData, + "add_block_data", &Chunk::addBlockData ); m_lua.new_usertype("BlockData", diff --git a/server/source/world/ServerBlock.cpp b/server/source/world/ServerBlock.cpp index a11ee0c4..b1792b17 100644 --- a/server/source/world/ServerBlock.cpp +++ b/server/source/world/ServerBlock.cpp @@ -70,7 +70,7 @@ bool ServerBlock::onBlockActivated(const glm::ivec3 &pos, Player &player, World return false; } -void ServerBlock::onBlockPlaced(const glm::ivec3 &pos, World &world) { +void ServerBlock::onBlockPlaced(const glm::ivec3 &pos, World &world) const { try { if (m_onBlockPlaced) { m_onBlockPlaced(pos, world); diff --git a/server/source/world/ServerChunk.cpp b/server/source/world/ServerChunk.cpp index e5b79ed6..f6b8a229 100644 --- a/server/source/world/ServerChunk.cpp +++ b/server/source/world/ServerChunk.cpp @@ -23,6 +23,11 @@ void ServerChunk::updateLights() { } } +void ServerChunk::onBlockPlaced(int x, int y, int z, const Block &block) const { + const ServerBlock &serverBlock = (ServerBlock &)block; + serverBlock.onBlockPlaced(glm::ivec3{x, y, z}, m_world); +} + void ServerChunk::tick(std::unordered_map &players, World &world, Server &server) { if (!m_tickingBlocks.empty()) { for (auto &it : m_tickingBlocks) { diff --git a/server/source/world/ServerWorld.cpp b/server/source/world/ServerWorld.cpp index 70d25f67..5dd81b2e 100644 --- a/server/source/world/ServerWorld.cpp +++ b/server/source/world/ServerWorld.cpp @@ -73,7 +73,8 @@ void ServerWorld::createChunkNeighbours(ServerChunk *chunk) { new ServerChunk{ surroundingChunks[i].x, surroundingChunks[i].y, - surroundingChunks[i].z + surroundingChunks[i].z, + *this } ); @@ -95,6 +96,20 @@ void ServerWorld::sendChunkData(const Client &client, ServerChunk *chunk) { for (u16 z = 0 ; z < CHUNK_DEPTH ; ++z) { packet << u16(chunk->data()[x][y][z]); packet << chunk->lightmap().getLightData(x, y, z); + + BlockData *blockData = chunk->getBlockData(x, y, z); + if (blockData) { + sf::Packet packet1; + packet1 << Network::Command::BlockDataUpdate << s32(x) << s32(y) << s32(z); + packet1 << blockData->data << blockData->useAltTiles; + client.tcpSocket->send(packet1); + + sf::Packet packet2; + packet2 << Network::Command::BlockInvUpdate; + packet2 << s32(x) << s32(y) << s32(z); + packet2 << blockData->inventory; + client.tcpSocket->send(packet2); + } } } } @@ -108,7 +123,7 @@ void ServerWorld::sendChunkData(const Client &client, ServerChunk *chunk) { void ServerWorld::sendRequestedData(Client &client, int cx, int cy, int cz) { ServerChunk *chunk = (ServerChunk *)getChunk(cx, cy, cz); if (!chunk) { - auto it = m_chunks.emplace(gk::Vector3i{cx, cy, cz}, new ServerChunk(cx, cy, cz)); + auto it = m_chunks.emplace(gk::Vector3i{cx, cy, cz}, new ServerChunk(cx, cy, cz, *this)); chunk = it.first->second.get(); }