From 45c797cd5fc1c932659644ecbc2ebb758e8235ea Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Sat, 29 Feb 2020 18:07:01 +0100 Subject: [PATCH] Creative window added on key 'H'. --- README.md | 1 + client/source/gui/InventoryWidget.cpp | 10 +- .../source/network/ClientCommandHandler.cpp | 7 ++ .../source/network/ClientCommandHandler.hpp | 1 + client/source/states/GameState.cpp | 3 + client/source/states/LuaGUIState.cpp | 42 +++++-- client/source/states/LuaGUIState.hpp | 4 +- common/source/core/LuaWidget.hpp | 1 + common/source/core/input/GameKey.hpp | 2 + common/source/inventory/Inventory.cpp | 16 ++- common/source/inventory/Inventory.hpp | 12 +- common/source/network/Network.cpp | 41 +++---- common/source/network/Network.hpp | 41 +++---- mods/default/init.lua | 112 ++++++++++++++++++ resources/config/keys.xml | 28 +++-- resources/config/textures.xml | 1 + resources/textures/creative_window.png | Bin 0 -> 1005 bytes server/source/lua/LuaGUI.cpp | 44 +++++-- server/source/lua/LuaGUI.hpp | 3 + server/source/lua/LuaWidgetDef.hpp | 6 +- .../source/network/ServerCommandHandler.cpp | 8 ++ 21 files changed, 301 insertions(+), 82 deletions(-) create mode 100644 resources/textures/creative_window.png diff --git a/README.md b/README.md index 15ac234a..698204d6 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ The long-term goal of this project is to provide a viable alternative to Minecra - Movement: WASD - Inventory: E +- Creative window: H - Chat: T - Jump: Space - Sprint: Ctrl diff --git a/client/source/gui/InventoryWidget.cpp b/client/source/gui/InventoryWidget.cpp index 0b4f5f51..275f6e60 100644 --- a/client/source/gui/InventoryWidget.cpp +++ b/client/source/gui/InventoryWidget.cpp @@ -59,13 +59,19 @@ void InventoryWidget::onMouseEvent(const SDL_Event &event, MouseItemWidget &mous } } else if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT && m_currentItemWidget) { - mouseItemWidget.swapItems(*m_currentItemWidget, isReadOnly); + if (m_inventory && !m_inventory->isUnlimited()) + mouseItemWidget.swapItems(*m_currentItemWidget, isReadOnly); + else if (m_inventory && mouseItemWidget.getStack().amount() == 0 && m_currentItemWidget->stack().amount() != 0) + mouseItemWidget.setStack(m_currentItemWidget->stack().item().stringID(), 64); sendUpdatePacket(); } else if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_RIGHT && m_currentItemWidget) { if (!isReadOnly) { - mouseItemWidget.putItem(*m_currentItemWidget); + if (m_inventory && !m_inventory->isUnlimited()) + mouseItemWidget.putItem(*m_currentItemWidget); + else if (m_inventory && mouseItemWidget.getStack().amount() == 0 && m_currentItemWidget->stack().amount() != 0) + mouseItemWidget.setStack(m_currentItemWidget->stack().item().stringID(), 1); sendUpdatePacket(); } diff --git a/client/source/network/ClientCommandHandler.cpp b/client/source/network/ClientCommandHandler.cpp index 6fe77355..c11a9451 100644 --- a/client/source/network/ClientCommandHandler.cpp +++ b/client/source/network/ClientCommandHandler.cpp @@ -77,6 +77,13 @@ void ClientCommandHandler::sendPlayerInventoryRequest() { m_client.send(packet); } +void ClientCommandHandler::sendPlayerCreativeWindowRequest() { + sf::Packet packet; + packet << Network::Command::PlayerCreativeWindow + << u16(Config::screenWidth) << u16(Config::screenHeight) << u8(Config::guiScale); + m_client.send(packet); +} + void ClientCommandHandler::sendBlockActivated(const glm::ivec4 &selectedBlock) { sf::Packet packet; packet << Network::Command::BlockActivated diff --git a/client/source/network/ClientCommandHandler.hpp b/client/source/network/ClientCommandHandler.hpp index 66b7cc04..66dc7e8b 100644 --- a/client/source/network/ClientCommandHandler.hpp +++ b/client/source/network/ClientCommandHandler.hpp @@ -49,6 +49,7 @@ class ClientCommandHandler { void sendPlayerDigBlock(const glm::ivec4 &selectedBlock); void sendPlayerPlaceBlock(s32 x, s32 y, s32 z, u32 block); void sendPlayerInventoryRequest(); + void sendPlayerCreativeWindowRequest(); void sendBlockActivated(const glm::ivec4 &selectedBlock); void sendBlockInvUpdate(Inventory &inventory); void sendChunkRequest(s32 chunkX, s32 chunkY, s32 chunkZ); diff --git a/client/source/states/GameState.cpp b/client/source/states/GameState.cpp index 2844c5a7..afa7ea6b 100644 --- a/client/source/states/GameState.cpp +++ b/client/source/states/GameState.cpp @@ -139,6 +139,9 @@ void GameState::update() { if (gk::GamePad::isKeyPressedOnce(GameKey::Inventory)) { m_clientCommandHandler.sendPlayerInventoryRequest(); } + else if (gk::GamePad::isKeyPressedOnce(GameKey::CreativeWindow)) { + m_clientCommandHandler.sendPlayerCreativeWindowRequest(); + } } m_player.updatePosition(m_world); diff --git a/client/source/states/LuaGUIState.cpp b/client/source/states/LuaGUIState.cpp index 27292247..0e286a32 100644 --- a/client/source/states/LuaGUIState.cpp +++ b/client/source/states/LuaGUIState.cpp @@ -132,8 +132,11 @@ void LuaGUIState::draw(gk::RenderTarget &target, gk::RenderStates states) const void LuaGUIState::loadGUI(sf::Packet &packet) { u8 type; std::string name; + packet >> type >> name; + s32 x, y; - packet >> type >> name >> x >> y; + if (type != LuaWidget::Inventory) + packet >> x >> y; if (type == LuaWidget::Image) loadImage(name, x, y, packet); @@ -145,6 +148,8 @@ void LuaGUIState::loadGUI(sf::Packet &packet) { loadProgressBarWidget(name, x, y, packet); else if (type == LuaWidget::CraftingWidget) loadCraftingWidget(name, x, y, packet); + else if (type == LuaWidget::Inventory) + loadInventory(name, packet); } void LuaGUIState::loadImage(const std::string &, s32 x, s32 y, sf::Packet &packet) { @@ -169,10 +174,10 @@ void LuaGUIState::loadTextButton(const std::string &, s32 x, s32 y, sf::Packet & m_widgets.emplace_back(button); } -void LuaGUIState::loadInventoryWidget(const std::string &, s32 x, s32 y, sf::Packet &packet) { +void LuaGUIState::loadInventoryWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet) { std::string inventory, playerName, inventory_name; gk::Vector3i block; - float width, height; + u16 width, height; u16 offset, count; packet >> inventory >> playerName >> inventory_name >> block.x >> block.y >> block.z @@ -191,6 +196,19 @@ void LuaGUIState::loadInventoryWidget(const std::string &, s32 x, s32 y, sf::Pac widgetInventory = &data->inventory; } + else if (inventory == "temp") { + if (inventory_name.empty()) { + m_inventories.emplace("_temp", Inventory{width, height}); + widgetInventory = &m_inventories.at("_temp"); + } + else { + auto it = m_inventories.find(inventory_name); + if (it == m_inventories.end()) + DEBUG("ERROR: Unable to find inventory '" + inventory_name + "' for widget '" + name + "'"); + + widgetInventory = &it->second; + } + } if (widgetInventory) { m_inventoryWidgets.emplace_back(m_client, &m_mainWidget); @@ -200,7 +218,7 @@ void LuaGUIState::loadInventoryWidget(const std::string &, s32 x, s32 y, sf::Pac inventoryWidget.init(*widgetInventory, offset, count); } else { - DEBUG("ERROR: Widget inventory is invalid"); + DEBUG("ERROR: Inventory widget '" + name + "' is invalid"); } } @@ -216,14 +234,14 @@ void LuaGUIState::loadCraftingWidget(const std::string &, s32 x, s32 y, sf::Pack BlockData *data = m_world.getBlockData(block.x, block.y, block.z); if (!data) { DEBUG("ERROR: No inventory found at", block.x, block.y, block.z); - return; } - - craftingInventory = &data->inventory; + else { + craftingInventory = &data->inventory; + } } else if (inventory == "temp") { - craftingInventory = &m_inventory; - m_inventory.resize(size, size); + m_inventories.emplace("_temp", Inventory{size, size}); + craftingInventory = &m_inventories.at("_temp"); } if (craftingInventory) { @@ -264,3 +282,9 @@ void LuaGUIState::loadProgressBarWidget(const std::string &, s32 x, s32 y, sf::P m_widgets.emplace_back(widget); } +void LuaGUIState::loadInventory(const std::string &name, sf::Packet &packet) { + m_inventories.emplace(name, Inventory{}); + + packet >> m_inventories.at(name); +} + diff --git a/client/source/states/LuaGUIState.hpp b/client/source/states/LuaGUIState.hpp index 76d7cd08..5f7f4f98 100644 --- a/client/source/states/LuaGUIState.hpp +++ b/client/source/states/LuaGUIState.hpp @@ -57,6 +57,7 @@ class LuaGUIState : public InterfaceState { void loadInventoryWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet); void loadCraftingWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet); void loadProgressBarWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet); + void loadInventory(const std::string &name, sf::Packet &packet); ClientCommandHandler &m_client; @@ -68,8 +69,7 @@ class LuaGUIState : public InterfaceState { std::deque m_inventoryWidgets; std::vector> m_widgets; std::vector> m_drawables; - - Inventory m_inventory; + std::unordered_map m_inventories; ClientPlayer &m_player; ClientWorld &m_world; diff --git a/common/source/core/LuaWidget.hpp b/common/source/core/LuaWidget.hpp index dc0d0774..52ec1a8b 100644 --- a/common/source/core/LuaWidget.hpp +++ b/common/source/core/LuaWidget.hpp @@ -36,6 +36,7 @@ namespace LuaWidget { InventoryWidget = 2, CraftingWidget = 3, ProgressBarWidget = 4, + Inventory = 5, }; } diff --git a/common/source/core/input/GameKey.hpp b/common/source/core/input/GameKey.hpp index c03a0fe2..e001c10e 100644 --- a/common/source/core/input/GameKey.hpp +++ b/common/source/core/input/GameKey.hpp @@ -45,6 +45,8 @@ namespace GameKey { Use, Inventory, + CreativeWindow, + Chat, Command, }; diff --git a/common/source/inventory/Inventory.cpp b/common/source/inventory/Inventory.cpp index 548c9487..cc22b0dd 100644 --- a/common/source/inventory/Inventory.cpp +++ b/common/source/inventory/Inventory.cpp @@ -48,8 +48,11 @@ void Inventory::addStack(const std::string &stringID, u16 amount) { } void Inventory::serialize(sf::Packet &packet) const { - packet << m_width << m_height << u8(m_inBlock) - << s32(m_blockPos.x) << s32(m_blockPos.y) << s32(m_blockPos.z); + packet << m_width << m_height << m_name << u8(m_inBlock) + << s32(m_blockPos.x) << s32(m_blockPos.y) << s32(m_blockPos.z) + << m_isUnlimited; + + packet << u16(m_items.size()); int i = 0; for (auto &it : m_items) { @@ -62,19 +65,24 @@ void Inventory::serialize(sf::Packet &packet) const { void Inventory::deserialize(sf::Packet &packet) { u8 inBlock; s32 bx, by, bz; - packet >> m_width >> m_height >> inBlock >> bx >> by >> bz; + packet >> m_width >> m_height >> m_name >> inBlock >> bx >> by >> bz >> m_isUnlimited; + 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); + u16 itemListSize, i = 0; + packet >> itemListSize; + std::string name; u16 amount; u8 x, y; - while (!packet.endOfPacket()) { + while (i < itemListSize) { packet >> name >> amount >> x >> y; setStack(x, y, name, amount); + ++i; } } diff --git a/common/source/inventory/Inventory.hpp b/common/source/inventory/Inventory.hpp index 0ee80572..4e0960df 100644 --- a/common/source/inventory/Inventory.hpp +++ b/common/source/inventory/Inventory.hpp @@ -37,8 +37,8 @@ class Inventory : public ISerializable { public: Inventory() = default; - Inventory(u16 width, u16 height) - : m_width(width), m_height(height) { m_items.resize(width * height); } + Inventory(u16 width, u16 height, const std::string &name = "") + : m_name(name), m_width(width), m_height(height) { m_items.resize(width * height); } const ItemStack &getStack(u16 x, u16 y) const { return m_items.at(x + y * m_width); } ItemStack &getStackRef(u16 x, u16 y) { return m_items.at(x + y * m_width); } @@ -48,6 +48,8 @@ class Inventory : public ISerializable { void serialize(sf::Packet &packet) const override; void deserialize(sf::Packet &packet) override; + const std::string &name() const { return m_name; } + 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); } @@ -63,7 +65,12 @@ class Inventory : public ISerializable { bool hasChanged() const { return m_hasChanged; } void setChanged(bool hasChanged) { m_hasChanged = hasChanged; } + bool isUnlimited() const { return m_isUnlimited; } + void setUnlimited(bool isUnlimited) { m_isUnlimited = isUnlimited; } + private: + std::string m_name; + u16 m_width = 0; u16 m_height = 0; @@ -73,6 +80,7 @@ class Inventory : public ISerializable { gk::Vector3i m_blockPos{0, 0, 0}; bool m_hasChanged = false; // Used to send inventory update packets + bool m_isUnlimited = false; }; #endif // INVENTORY_HPP_ diff --git a/common/source/network/Network.cpp b/common/source/network/Network.cpp index 4e5ca71d..dcfb107d 100644 --- a/common/source/network/Network.cpp +++ b/common/source/network/Network.cpp @@ -32,32 +32,33 @@ std::string Network::commandToString(Network::Command command) { std::map commandNames = { - {Network::Command::ClientConnect, "ClientConnect"}, - {Network::Command::ClientDisconnect, "ClientDisconnect"}, - {Network::Command::ClientOk, "ClientOk"}, - {Network::Command::ClientRefused, "ClientRefused"}, + {Network::Command::ClientConnect, "ClientConnect"}, + {Network::Command::ClientDisconnect, "ClientDisconnect"}, + {Network::Command::ClientOk, "ClientOk"}, + {Network::Command::ClientRefused, "ClientRefused"}, - {Network::Command::KeyState, "KeyState"}, + {Network::Command::KeyState, "KeyState"}, - {Network::Command::ChunkData, "ChunkData"}, - {Network::Command::ChunkRequest, "ChunkRequest"}, + {Network::Command::ChunkData, "ChunkData"}, + {Network::Command::ChunkRequest, "ChunkRequest"}, - {Network::Command::PlayerPlaceBlock, "PlayerPlaceBlock"}, - {Network::Command::PlayerDigBlock, "PlayerDigBlock"}, - {Network::Command::PlayerInvUpdate, "PlayerInvUpdate"}, - {Network::Command::PlayerPosUpdate, "PlayerPosUpdate"}, - {Network::Command::PlayerSpawn, "PlayerSpawn"}, - {Network::Command::PlayerInventory, "PlayerInventory"}, + {Network::Command::PlayerPlaceBlock, "PlayerPlaceBlock"}, + {Network::Command::PlayerDigBlock, "PlayerDigBlock"}, + {Network::Command::PlayerInvUpdate, "PlayerInvUpdate"}, + {Network::Command::PlayerPosUpdate, "PlayerPosUpdate"}, + {Network::Command::PlayerSpawn, "PlayerSpawn"}, + {Network::Command::PlayerInventory, "PlayerInventory"}, + {Network::Command::PlayerCreativeWindow, "PlayerCreativeWindow"}, - {Network::Command::BlockUpdate, "BlockUpdate"}, - {Network::Command::BlockActivated, "BlockActivated"}, - {Network::Command::BlockGUIData, "BlockGUIData"}, - {Network::Command::BlockInvUpdate, "BlockInvUpdate"}, - {Network::Command::BlockDataUpdate, "BlockDataUpdate"}, + {Network::Command::BlockUpdate, "BlockUpdate"}, + {Network::Command::BlockActivated, "BlockActivated"}, + {Network::Command::BlockGUIData, "BlockGUIData"}, + {Network::Command::BlockInvUpdate, "BlockInvUpdate"}, + {Network::Command::BlockDataUpdate, "BlockDataUpdate"}, - {Network::Command::RegistryData, "RegistryData"}, + {Network::Command::RegistryData, "RegistryData"}, - {Network::Command::ChatMessage, "ChatMessage"} + {Network::Command::ChatMessage, "ChatMessage"} }; return commandNames[command]; } diff --git a/common/source/network/Network.hpp b/common/source/network/Network.hpp index c587c9c3..c57e5053 100644 --- a/common/source/network/Network.hpp +++ b/common/source/network/Network.hpp @@ -32,38 +32,39 @@ namespace Network { enum class Command { // Client commands - ClientConnect = 0, // [NetworkCommand][u16 udp port] (from Client only) - ClientDisconnect = 1, // [NetworkCommand] (from Client only) - ClientOk = 2, // [NetworkCommand][u16 client id] (from Server only) - ClientRefused = 3, // [NetworkCommand] (from Server only) + ClientConnect = 0, // [NetworkCommand][u16 udp port] (from Client only) + ClientDisconnect = 1, // [NetworkCommand] (from Client only) + ClientOk = 2, // [NetworkCommand][u16 client id] (from Server only) + ClientRefused = 3, // [NetworkCommand] (from Server only) // Input commands - KeyState = 4, // [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]... + KeyState = 4, // [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]... // Chunk commands - ChunkData = 5, // [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only) - ChunkRequest = 6, // [NetworkCommand][s32 cx, cy, cz] (from Client only) + ChunkData = 5, // [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only) + ChunkRequest = 6, // [NetworkCommand][s32 cx, cy, cz] (from Client only) // Player commands - PlayerPlaceBlock = 7, // [NetworkCommand][s32 x, y, z][u32 block] (from Client only) - PlayerDigBlock = 8, // [NetworkCommand][s32 x, y, z] (from Client only) - PlayerInvUpdate = 9, // [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME] - PlayerPosUpdate = 10, // [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME - PlayerSpawn = 11, // [NetworkCommand][u16 client id][s32 x, y, z] (from Server only) - PlayerInventory = 12, // [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) + PlayerPlaceBlock = 7, // [NetworkCommand][s32 x, y, z][u32 block] (from Client only) + PlayerDigBlock = 8, // [NetworkCommand][s32 x, y, z] (from Client only) + PlayerInvUpdate = 9, // [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME] + PlayerPosUpdate = 10, // [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME + PlayerSpawn = 11, // [NetworkCommand][u16 client id][s32 x, y, z] (from Server only) + PlayerInventory = 12, // [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) + PlayerCreativeWindow = 13, // [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) // Block commands - BlockUpdate = 13, // [NetworkCommand][s32 x, y, z][u32 block] (from Server only) - BlockActivated = 14, // [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) - BlockGUIData = 15, // [NetworkCommand][LuaGUIData data] (from Server only) - BlockInvUpdate = 16, // [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME] - BlockDataUpdate = 17, // [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME] + BlockUpdate = 14, // [NetworkCommand][s32 x, y, z][u32 block] (from Server only) + BlockActivated = 15, // [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) + BlockGUIData = 16, // [NetworkCommand][LuaGUIData data] (from Server only) + BlockInvUpdate = 17, // [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME] + BlockDataUpdate = 18, // [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME] // Registry commands - RegistryData = 18, // [NetworkCommand][Block block] (from Server only) + RegistryData = 19, // [NetworkCommand][Block block] (from Server only) // Chat commands - ChatMessage = 19, // [NetworkCommand][u16 client id][std::string message] (both) + ChatMessage = 20, // [NetworkCommand][u16 client id][std::string message] (both) }; std::string commandToString(Command command); diff --git a/mods/default/init.lua b/mods/default/init.lua index 9a846893..da3d31e2 100644 --- a/mods/default/init.lua +++ b/mods/default/init.lua @@ -122,3 +122,115 @@ function show_inventory(client, screen_width, screen_height, gui_scale) gui:show(client) end + +function show_creative_window(client, screen_width, screen_height, gui_scale) + local gui = LuaGUI.new() + + -- FIXME: Replace this by gui:set_size() and gui:set_centered() + local gui_pos = { + x = math.floor(screen_width / gui_scale / 2.0 - 195 / 2.0 + 0.5), + y = math.floor(screen_height / gui_scale / 2.0 - 136 / 2.0 + 0.5) + } + + gui:image { + name = "img_background", + pos = gui_pos, + + texture = "texture-creative_window", + clip = {x = 0, y = 0, width = 195, height = 136}, + } + + gui:inventory_data { + name = "inv_data", + + width = 9, + height = 5, + + items = { + -- Blocks + {"default:dirt"}, + {"default:cobblestone"}, + {"default:grass"}, + {"default:leaves"}, + {"default:wood"}, + {"default:stone"}, + {"default:sand"}, + {"default:water"}, + {"default:glass"}, + {"default:coal_ore"}, + {"default:planks"}, + {"default:glowstone"}, + {"default:workbench"}, + {"default:furnace"}, + {"default:iron_ore"}, + {"default:flower"}, + {"default:tallgrass"}, + {"default:stone_bricks"}, + {"default:bricks"}, + {"default:clay"}, + + -- Items + {"default:stick"}, + -- {"default:stone_axe"}, + -- {"default:stone_hoe"}, + -- {"default:stone_pickaxe"}, + -- {"default:stone_shovel"}, + -- {"default:stone_sword"}, + {"default:coal"}, + {"default:iron_ingot"}, + {"default:charcoal"}, + -- {"default:wooden_axe"}, + -- {"default:wooden_hoe"}, + -- {"default:wooden_pickaxe"}, + -- {"default:wooden_shovel"}, + -- {"default:wooden_sword"}, + {"default:brick"}, + {"default:clay_ball"}, + {"default:diamond"}, + {"default:gold_ingot"}, + -- {"default:iron_pickaxe"}, + -- {"default:iron_sword"}, + -- {"default:iron_axe"}, + -- {"default:iron_hoe"}, + -- {"default:iron_shovel"}, + -- {"default:diamond_pickaxe"}, + -- {"default:diamond_sword"}, + -- {"default:diamond_axe"}, + -- {"default:diamond_hoe"}, + -- {"default:diamond_shovel"}, + -- {"default:golden_pickaxe"}, + -- {"default:golden_sword"}, + -- {"default:golden_axe"}, + -- {"default:golden_hoe"}, + -- {"default:golden_shovel"}, + }, + + is_unlimited = true, + } + + gui:inventory { + name = "inv_creative_items", + pos = {x = gui_pos.x + 8, y = gui_pos.y + 17}, + + inventory = "temp", + inventory_name = "inv_data", + size = {x = 9, y = 5}, + + offset = 0, + count = 9 * 5, + } + + gui:inventory { + name = "inv_hotbar", + pos = {x = gui_pos.x + 8, y = gui_pos.y + 111}, + + inventory = "player", + player = "player", + inventory_name = "main", + size = {x = 9, y = 1}, + offset = 0, + count = 9, + } + + gui:show(client); +end diff --git a/resources/config/keys.xml b/resources/config/keys.xml index 54402e54..16069af1 100644 --- a/resources/config/keys.xml +++ b/resources/config/keys.xml @@ -1,19 +1,21 @@ - - - - + + + + - - - - + + + + - - + + - - - + + + + + diff --git a/resources/config/textures.xml b/resources/config/textures.xml index aabd9822..e4fd054b 100644 --- a/resources/config/textures.xml +++ b/resources/config/textures.xml @@ -1,5 +1,6 @@ + diff --git a/resources/textures/creative_window.png b/resources/textures/creative_window.png new file mode 100644 index 0000000000000000000000000000000000000000..be178b743a2c901d9882b068275747d6e0853bbe GIT binary patch literal 1005 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdEuJopAr-gY-U;m5l_PQ> zu{2O{XKz%;1tTW$pxXx1pDt10yZhAo+U+^d8;d{3%KUKud*a8lkfTWkY7cbe8xlFp zuYSsx=Sp65wwPtn%4hucE+zZ#JG(Ea`o~{;Us^cr);3+g<-s>NLe9(A#ToBwJhSa` z>0I+$yZ14E*mXBA-E7Y1pKpBC7#bKDm>4)16p$G?DgW%Ro+)c)NLjruyFTP|+e2r@ zj9F@x$LybNI6iNRZT-i6U))`__cO}$A73(a|FN6N{-@?$`M&fxXFtRk3=~2Q3{u39}J`0A@Sn=BX>ixFgmhi|i zg4NuxWAMGK;(xvL+l|Rv+WG643)Wtf3vaY#!r}(BtoP< gJhovs@<)_?$p3rO>Yd!y0<$rLr>mdKI;Vst0BXzrt^fc4 literal 0 HcmV?d00001 diff --git a/server/source/lua/LuaGUI.cpp b/server/source/lua/LuaGUI.cpp index 3d6829c6..70c844dd 100644 --- a/server/source/lua/LuaGUI.cpp +++ b/server/source/lua/LuaGUI.cpp @@ -29,6 +29,7 @@ #include "LuaGUI.hpp" #include "LuaWidget.hpp" #include "Network.hpp" +#include "Registry.hpp" void LuaGUI::addImage(const sol::table &table) { // FIXME: Duplicated below @@ -108,6 +109,9 @@ void LuaGUI::addInventoryWidget(const sol::table &table) { block.z = blockTable.value()["z"]; } } + else if (inventory == "temp") { + inventory_name = table["inventory_name"].get_or(""); + } else { DEBUG("ERROR: Inventory source '" + inventory + "' is not valid"); } @@ -115,7 +119,7 @@ void LuaGUI::addInventoryWidget(const sol::table &table) { u16 offset = table["offset"].get(); u16 count = table["count"].get(); - float width = 0, height = 0; + u16 width = 0, height = 0; sol::optional size = table["size"]; if (size != sol::nullopt) { width = size.value()["x"]; @@ -246,10 +250,35 @@ void LuaGUI::addProgressBarWidget(const sol::table &table) { progressBarWidget.clipRect = clipRect; } +void LuaGUI::addInventory(const sol::table &table) { + std::string name = table["name"].get(); + + u16 width = table["width"].get(); + u16 height = table["height"].get(); + + m_data.inventoryList.emplace_back(width, height, name); + + Inventory &inventory = m_data.inventoryList.back(); + inventory.setUnlimited(table["is_unlimited"].get_or(false)); + + sol::optional itemsTable = table["items"]; + if (itemsTable != sol::nullopt) { + for (auto &it : itemsTable.value()) { + std::string stringID = it.second.as()[1].get(); + u16 amount = it.second.as()[2].get_or(1); + + inventory.addStack(stringID, amount); + } + } +} + void LuaGUI::show(Client &client) { sf::Packet packet; packet << Network::Command::BlockGUIData; + for (auto &it : m_data.inventoryList) + packet << u8(LuaWidget::Inventory) << it.name() << it; + for (auto &it : m_data.imageList) packet << u8(LuaWidget::Image) << it.name << it.x << it.y << it.texture @@ -280,13 +309,14 @@ void LuaGUI::show(Client &client) { void LuaGUI::initUsertype(sol::state &lua) { lua.new_usertype("LuaGUI", - "image", &LuaGUI::addImage, - "button", &LuaGUI::addTextButton, - "inventory", &LuaGUI::addInventoryWidget, - "crafting", &LuaGUI::addCraftingWidget, - "progress_bar", &LuaGUI::addProgressBarWidget, + "image", &LuaGUI::addImage, + "button", &LuaGUI::addTextButton, + "inventory", &LuaGUI::addInventoryWidget, + "crafting", &LuaGUI::addCraftingWidget, + "progress_bar", &LuaGUI::addProgressBarWidget, + "inventory_data", &LuaGUI::addInventory, - "show", &LuaGUI::show + "show", &LuaGUI::show ); } diff --git a/server/source/lua/LuaGUI.hpp b/server/source/lua/LuaGUI.hpp index 746b87fc..55659767 100644 --- a/server/source/lua/LuaGUI.hpp +++ b/server/source/lua/LuaGUI.hpp @@ -29,6 +29,7 @@ #include +#include "Inventory.hpp" #include "LuaWidgetDef.hpp" #include "ServerInfo.hpp" @@ -38,6 +39,7 @@ struct LuaGUIData { std::list inventoryWidgetList; std::list craftingWidgetList; std::list progressBarWidgetList; + std::list inventoryList; }; // This class is meant to be used ONLY in Lua @@ -48,6 +50,7 @@ class LuaGUI { void addInventoryWidget(const sol::table &table); void addCraftingWidget(const sol::table &table); void addProgressBarWidget(const sol::table &table); + void addInventory(const sol::table &table); void show(Client &client); diff --git a/server/source/lua/LuaWidgetDef.hpp b/server/source/lua/LuaWidgetDef.hpp index 0433024f..b633c381 100644 --- a/server/source/lua/LuaWidgetDef.hpp +++ b/server/source/lua/LuaWidgetDef.hpp @@ -56,12 +56,12 @@ struct InventoryWidget : public Widget { std::string inventory; std::string player; // inventory == "player" - std::string inventory_name; // inventory == "player" + std::string inventory_name; // inventory == "player" || inventory == "temp" gk::Vector3i block; // inventory == "block" - float width = 0; - float height = 0; + u16 width = 0; + u16 height = 0; u16 offset = 0; u16 count = 0; diff --git a/server/source/network/ServerCommandHandler.cpp b/server/source/network/ServerCommandHandler.cpp index f11ee1e9..074b108a 100644 --- a/server/source/network/ServerCommandHandler.cpp +++ b/server/source/network/ServerCommandHandler.cpp @@ -175,6 +175,14 @@ void ServerCommandHandler::setupCallbacks() { m_scriptEngine.lua()["show_inventory"](client, screenWidth, screenHeight, guiScale); }); + m_server.setCommandCallback(Network::Command::PlayerCreativeWindow, [this](Client &client, sf::Packet &packet) { + u16 screenWidth, screenHeight; + u8 guiScale; + packet >> screenWidth >> screenHeight >> guiScale; + + m_scriptEngine.lua()["show_creative_window"](client, screenWidth, screenHeight, guiScale); + }); + m_server.setCommandCallback(Network::Command::BlockActivated, [this](Client &client, sf::Packet &packet) { s32 x, y, z; u16 screenWidth, screenHeight;