Creative window added on key 'H'.

This commit is contained in:
Quentin Bazin 2020-02-29 18:07:01 +01:00
parent 5d7e5158e8
commit 45c797cd5f
21 changed files with 301 additions and 82 deletions

View File

@ -24,6 +24,7 @@ The long-term goal of this project is to provide a viable alternative to Minecra
- Movement: <kbd>W</kbd><kbd>A</kbd><kbd>S</kbd><kbd>D</kbd>
- Inventory: <kbd>E</kbd>
- Creative window: <kbd>H</kbd>
- Chat: <kbd>T</kbd>
- Jump: <kbd>Space</kbd>
- Sprint: <kbd>Ctrl</kbd>

View File

@ -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();
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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<InventoryWidget> m_inventoryWidgets;
std::vector<std::unique_ptr<Widget>> m_widgets;
std::vector<std::unique_ptr<gk::Drawable>> m_drawables;
Inventory m_inventory;
std::unordered_map<std::string, Inventory> m_inventories;
ClientPlayer &m_player;
ClientWorld &m_world;

View File

@ -36,6 +36,7 @@ namespace LuaWidget {
InventoryWidget = 2,
CraftingWidget = 3,
ProgressBarWidget = 4,
Inventory = 5,
};
}

View File

@ -45,6 +45,8 @@ namespace GameKey {
Use,
Inventory,
CreativeWindow,
Chat,
Command,
};

View File

@ -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;
}
}

View File

@ -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_

View File

@ -32,32 +32,33 @@
std::string Network::commandToString(Network::Command command) {
std::map<Network::Command, std::string> 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];
}

View File

@ -32,38 +32,39 @@
namespace Network {
enum class Command {
// Client commands
ClientConnect = 0, // <TCP> [NetworkCommand][u16 udp port] (from Client only)
ClientDisconnect = 1, // <TCP> [NetworkCommand] (from Client only)
ClientOk = 2, // <TCP> [NetworkCommand][u16 client id] (from Server only)
ClientRefused = 3, // <TCP> [NetworkCommand] (from Server only)
ClientConnect = 0, // <TCP> [NetworkCommand][u16 udp port] (from Client only)
ClientDisconnect = 1, // <TCP> [NetworkCommand] (from Client only)
ClientOk = 2, // <TCP> [NetworkCommand][u16 client id] (from Server only)
ClientRefused = 3, // <TCP> [NetworkCommand] (from Server only)
// Input commands
KeyState = 4, // <UDP> [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]...
KeyState = 4, // <UDP> [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]...
// Chunk commands
ChunkData = 5, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
ChunkRequest = 6, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
ChunkData = 5, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
ChunkRequest = 6, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
// Player commands
PlayerPlaceBlock = 7, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
PlayerDigBlock = 8, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
PlayerInvUpdate = 9, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
PlayerPosUpdate = 10, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
PlayerSpawn = 11, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
PlayerInventory = 12, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerPlaceBlock = 7, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
PlayerDigBlock = 8, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
PlayerInvUpdate = 9, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
PlayerPosUpdate = 10, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
PlayerSpawn = 11, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
PlayerInventory = 12, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerCreativeWindow = 13, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
// Block commands
BlockUpdate = 13, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
BlockActivated = 14, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
BlockGUIData = 15, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
BlockInvUpdate = 16, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
BlockDataUpdate = 17, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]
BlockUpdate = 14, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
BlockActivated = 15, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
BlockGUIData = 16, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
BlockInvUpdate = 17, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
BlockDataUpdate = 18, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]
// Registry commands
RegistryData = 18, // <TCP> [NetworkCommand][Block block] (from Server only)
RegistryData = 19, // <TCP> [NetworkCommand][Block block] (from Server only)
// Chat commands
ChatMessage = 19, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)
ChatMessage = 20, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)
};
std::string commandToString(Command command);

View File

@ -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

View File

@ -1,19 +1,21 @@
<!-- Key names are defined here: https://wiki.libsdl.org/SDL_Keycode -->
<keys>
<key name="Left" scancode="A" />
<key name="Right" scancode="D" />
<key name="Up" scancode="W" />
<key name="Down" scancode="S" />
<key name="Left" scancode="A" />
<key name="Right" scancode="D" />
<key name="Up" scancode="W" />
<key name="Down" scancode="S" />
<key name="Jump" scancode="Space" />
<key name="Fly" scancode="X" />
<key name="Sneak" scancode="Left Shift" />
<key name="Sprint" scancode="Left Ctrl" />
<key name="Jump" scancode="Space" />
<key name="Fly" scancode="X" />
<key name="Sneak" scancode="Left Shift" />
<key name="Sprint" scancode="Left Ctrl" />
<key name="Dig" scancode="L" />
<key name="Use" scancode="M" />
<key name="Dig" scancode="L" />
<key name="Use" scancode="M" />
<key name="Inventory" scancode="E" />
<key name="Chat" scancode="T" />
<key name="Command" scancode="Keypad /" />
<key name="Inventory" scancode="E" />
<key name="CreativeWindow" scancode="H" />
<key name="Chat" scancode="T" />
<key name="Command" scancode="Keypad /" />
</keys>

View File

@ -1,5 +1,6 @@
<textures>
<texture name="block_destroy" path="resources/textures/block_destroy.png" />
<texture name="creative_window" path="resources/textures/creative_window.png" />
<texture name="font" path="resources/textures/font.png" />
<texture name="furnace" path="resources/textures/furnace.png" />
<texture name="inventory" path="resources/textures/inventory.png" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

View File

@ -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<std::string>("");
}
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>();
u16 count = table["count"].get<u16>();
float width = 0, height = 0;
u16 width = 0, height = 0;
sol::optional<sol::table> 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<std::string>();
u16 width = table["width"].get<u16>();
u16 height = table["height"].get<u16>();
m_data.inventoryList.emplace_back(width, height, name);
Inventory &inventory = m_data.inventoryList.back();
inventory.setUnlimited(table["is_unlimited"].get_or(false));
sol::optional<sol::table> itemsTable = table["items"];
if (itemsTable != sol::nullopt) {
for (auto &it : itemsTable.value()) {
std::string stringID = it.second.as<sol::table>()[1].get<std::string>();
u16 amount = it.second.as<sol::table>()[2].get_or<u16>(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>("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
);
}

View File

@ -29,6 +29,7 @@
#include <list>
#include "Inventory.hpp"
#include "LuaWidgetDef.hpp"
#include "ServerInfo.hpp"
@ -38,6 +39,7 @@ struct LuaGUIData {
std::list<LuaWidgetDef::InventoryWidget> inventoryWidgetList;
std::list<LuaWidgetDef::CraftingWidget> craftingWidgetList;
std::list<LuaWidgetDef::ProgressBarWidget> progressBarWidgetList;
std::list<Inventory> 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);

View File

@ -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;

View File

@ -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;