Skip to content

Commit

Permalink
[LuaGUIState] Now handles Shift+Left click to move items quickly.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed Feb 29, 2020
1 parent 7ce30d3 commit 4d9a2fb
Show file tree
Hide file tree
Showing 20 changed files with 218 additions and 47 deletions.
46 changes: 46 additions & 0 deletions client/source/gui/AbstractInventoryWidget.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <[email protected]>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef ABSTRACTINVENTORYWIDGET_HPP_
#define ABSTRACTINVENTORYWIDGET_HPP_

#include "ItemWidget.hpp"

class AbstractInventoryWidget : public Widget {
public:
AbstractInventoryWidget(Widget *parent) : Widget(parent) {}

virtual void sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) = 0;
virtual bool receiveItemStack(const ItemWidget *itemStack) = 0;

const std::string &shiftDestination() const { return m_shiftDestination; }
void setShiftDestination(const std::string &shiftDestination) { m_shiftDestination = shiftDestination; }

private:
std::string m_shiftDestination;
};

#endif // ABSTRACTINVENTORYWIDGET_HPP_
30 changes: 26 additions & 4 deletions client/source/gui/CraftingWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,25 @@
#include "Registry.hpp"

CraftingWidget::CraftingWidget(ClientCommandHandler &client, Inventory &craftingInventory, Widget *parent)
: Widget(parent), m_client(client), m_craftingInventory(craftingInventory)
: AbstractInventoryWidget(parent), m_client(client), m_craftingInventory(craftingInventory)
{
}

void CraftingWidget::init(unsigned int offset, unsigned int size) {
m_craftingInventoryWidget.init(m_craftingInventory, offset, size * size);
// m_craftingInventoryWidget.setPosition(29, 16, 0);

m_craftingResultInventoryWidget.init(m_craftingResultInventory);
// m_craftingResultInventoryWidget.setPosition(123, 34, 0);

m_craftingInventoryWidget.setParent(this);
m_craftingResultInventoryWidget.setParent(this);
}

void CraftingWidget::onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget) {
m_craftingInventoryWidget.onMouseEvent(event, mouseItemWidget);
m_craftingResultInventoryWidget.onMouseEvent(event, mouseItemWidget, true);

m_currentInventoryWidget = m_craftingResultInventoryWidget.currentItemWidget()
? &m_craftingResultInventoryWidget : &m_craftingInventoryWidget;

if (m_recipe && !m_craftingResultInventory.getStack(0, 0).item().id()) {
for (u8 x = 0 ; x < m_craftingInventory.width() ; ++x) {
for (u8 y = 0 ; y < m_craftingInventory.height() ; ++y) {
Expand Down Expand Up @@ -77,6 +80,25 @@ void CraftingWidget::update() {
}
}

void CraftingWidget::sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) {
if (m_currentInventoryWidget && dest->receiveItemStack(itemStack)) {
m_currentInventoryWidget->inventory()->clearStack(itemStack->x(), itemStack->y());
m_currentInventoryWidget->update();
m_currentInventoryWidget->sendUpdatePacket();
}
}

bool CraftingWidget::receiveItemStack(const ItemWidget *itemStack) {
bool stackAdded = m_craftingInventory.addStack(itemStack->stack().item().stringID(), itemStack->stack().amount());

if (stackAdded) {
m_craftingInventoryWidget.update();
m_craftingInventoryWidget.sendUpdatePacket();
}

return stackAdded;
}

void CraftingWidget::draw(gk::RenderTarget &target, gk::RenderStates states) const {
states.transform *= getTransform();

Expand Down
18 changes: 11 additions & 7 deletions client/source/gui/CraftingWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

class Recipe;

class CraftingWidget : public Widget {
class CraftingWidget : public AbstractInventoryWidget {
public:
CraftingWidget(ClientCommandHandler &client, Inventory &craftingInventory, Widget *parent = nullptr);

Expand All @@ -41,22 +41,26 @@ class CraftingWidget : public Widget {

void update() override;

void sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) override;
bool receiveItemStack(const ItemWidget *itemStack) override;

const ItemWidget *currentItemWidget() const { return m_craftingResultInventoryWidget.currentItemWidget() ? m_craftingResultInventoryWidget.currentItemWidget() : m_craftingInventoryWidget.currentItemWidget(); }

InventoryWidget &craftingInventoryWidget() { return m_craftingInventoryWidget; }
InventoryWidget &craftingResultInventoryWidget() { return m_craftingResultInventoryWidget; }

protected:
private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;

ClientCommandHandler &m_client;

InventoryWidget *m_currentInventoryWidget = nullptr;

Inventory &m_craftingInventory;
InventoryWidget m_craftingInventoryWidget{m_client, this};
InventoryWidget m_craftingInventoryWidget{m_client};

Inventory m_craftingResultInventory{1, 1};
InventoryWidget m_craftingResultInventoryWidget{m_client, this};

private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
InventoryWidget m_craftingResultInventoryWidget{m_client};

const Recipe *m_recipe = nullptr;
};
Expand Down
17 changes: 17 additions & 0 deletions client/source/gui/InventoryWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,23 @@ void InventoryWidget::update() {
it.update();
}

void InventoryWidget::sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) {
if (dest->receiveItemStack(itemStack)) {
m_inventory->clearStack(itemStack->x(), itemStack->y());
update();
sendUpdatePacket();
}
}

bool InventoryWidget::receiveItemStack(const ItemWidget *itemStack) {
bool stackAdded = m_inventory->addStack(itemStack->stack().item().stringID(), itemStack->stack().amount());

if (stackAdded)
sendUpdatePacket();

return stackAdded;
}

void InventoryWidget::sendUpdatePacket() {
if (m_inventory->inBlock()) {
m_client.sendBlockInvUpdate(*m_inventory);
Expand Down
14 changes: 10 additions & 4 deletions client/source/gui/InventoryWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,34 @@

#include <gk/graphics/RectangleShape.hpp>

#include "AbstractInventoryWidget.hpp"
#include "MouseItemWidget.hpp"

class ClientCommandHandler;

class InventoryWidget : public Widget {
class InventoryWidget : public AbstractInventoryWidget {
public:
InventoryWidget(ClientCommandHandler &client, Widget *parent = nullptr)
: Widget(parent), m_client(client) {}
: AbstractInventoryWidget(parent), m_client(client) {}

void init(Inventory &inventory, unsigned int offset = 0, unsigned int size = 0);

void onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget, bool isReadOnly = false);

void update() override;

void sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) override;
bool receiveItemStack(const ItemWidget *itemStack) override;

void sendUpdatePacket();

Inventory *inventory() { return m_inventory; }

const ItemWidget *currentItemWidget() const { return m_currentItemWidget; }

private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;

void sendUpdatePacket();

ClientCommandHandler &m_client;

Inventory *m_inventory = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions client/source/gui/ItemWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class ItemWidget : public Widget {
const ItemStack &stack() const { return m_inventory.getStack(m_x, m_y); }
void setStack(const std::string &name, unsigned int amount = 1);

unsigned int x() const { return m_x; }
unsigned int y() const { return m_y; }

protected:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;

Expand Down
1 change: 1 addition & 0 deletions client/source/gui/MouseItemWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class MouseItemWidget : public ItemWidget {

void onEvent(const SDL_Event &event) override;

const ItemWidget *currentItemWidget() const { return m_currentItemWidget; }
void updateCurrentItem(const ItemWidget *currentItemWidget);

void swapItems(ItemWidget &widget, bool isReadOnly = false);
Expand Down
2 changes: 1 addition & 1 deletion client/source/gui/Widget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Widget : public gk::Drawable, public gk::Transformable {

gk::FloatRect getGlobalBounds() const;

const Widget *parent() { return m_parent; }
const Widget *parent() const { return m_parent; }
void setParent(Widget *parent) { m_parent = parent; }

unsigned int width() const { return m_width; }
Expand Down
76 changes: 54 additions & 22 deletions client/source/states/LuaGUIState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@

#include <gk/core/ApplicationStateStack.hpp>
#include <gk/core/Debug.hpp>
#include <gk/core/input/GamePad.hpp>
#include <gk/core/Mouse.hpp>
#include <gk/graphics/Color.hpp>

#include "ClientPlayer.hpp"
#include "ClientWorld.hpp"
#include "Config.hpp"
#include "GameKey.hpp"
#include "InventoryWidget.hpp"
#include "LuaGUIState.hpp"
#include "LuaWidget.hpp"
Expand Down Expand Up @@ -69,13 +71,37 @@ void LuaGUIState::onEvent(const SDL_Event &event) {
for (auto &it : m_widgets)
it->onEvent(event);

for (auto &it : m_inventoryWidgets)
it.onMouseEvent(event, m_mouseItemWidget, false);
if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT
&& m_currentInventoryWidget && !m_currentInventoryWidget->shiftDestination().empty()
&& m_mouseItemWidget.currentItemWidget() && gk::GamePad::isKeyPressed(GameKey::Shift)) {
AbstractInventoryWidget *dest = nullptr;

for (auto &it : m_craftingWidgets)
it.onMouseEvent(event, m_mouseItemWidget);
auto it = m_craftingWidgets.find(m_currentInventoryWidget->shiftDestination());
if (it != m_craftingWidgets.end())
dest = &it->second;

if (!dest) {
auto it = m_inventoryWidgets.find(m_currentInventoryWidget->shiftDestination());
if (it != m_inventoryWidgets.end())
dest = &it->second;
}

if (!dest) {
DEBUG("ERROR: Destination not found: '" + m_currentInventoryWidget->shiftDestination() + "'");
return;
}

m_mouseItemWidget.onEvent(event);
m_currentInventoryWidget->sendItemStackToDest(m_mouseItemWidget.currentItemWidget(), dest);
}
else {
for (auto &it : m_inventoryWidgets)
it.second.onMouseEvent(event, m_mouseItemWidget, false);

for (auto &it : m_craftingWidgets)
it.second.onMouseEvent(event, m_mouseItemWidget);

m_mouseItemWidget.onEvent(event);
}
}

void LuaGUIState::update() {
Expand All @@ -85,21 +111,24 @@ void LuaGUIState::update() {
it->update();

for (auto &it : m_craftingWidgets) {
it.update();
it.second.update();
}

for (auto &it : m_inventoryWidgets) {
it.update();
it.second.update();
}

const ItemWidget *currentItemWidget = nullptr;
m_currentInventoryWidget = nullptr;
for (auto &it : m_inventoryWidgets) {
if (!currentItemWidget)
currentItemWidget = it.currentItemWidget();
if (!currentItemWidget && ((currentItemWidget = it.second.currentItemWidget()))) {
m_currentInventoryWidget = &it.second;
}
}
for (auto &it : m_craftingWidgets) {
if (!currentItemWidget)
currentItemWidget = it.currentItemWidget();
if (!currentItemWidget && ((currentItemWidget = it.second.currentItemWidget()))) {
m_currentInventoryWidget = &it.second;
}
}

m_mouseItemWidget.updateCurrentItem(currentItemWidget);
Expand All @@ -121,10 +150,10 @@ void LuaGUIState::draw(gk::RenderTarget &target, gk::RenderStates states) const
target.draw(*it, states);

for (auto &it : m_inventoryWidgets)
target.draw(it, states);
target.draw(it.second, states);

for (auto &it : m_craftingWidgets)
target.draw(it, states);
target.draw(it.second, states);

target.draw(m_mouseItemWidget, states);
}
Expand Down Expand Up @@ -175,12 +204,12 @@ void LuaGUIState::loadTextButton(const std::string &, s32 x, s32 y, sf::Packet &
}

void LuaGUIState::loadInventoryWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet) {
std::string inventory, playerName, inventory_name;
std::string inventory, playerName, inventory_name, shiftDestination;
gk::Vector3i block;
u16 width, height;
u16 offset, count;
packet >> inventory >> playerName >> inventory_name
>> block.x >> block.y >> block.z
>> block.x >> block.y >> block.z >> shiftDestination
>> width >> height >> offset >> count;

Inventory *widgetInventory = nullptr;
Expand Down Expand Up @@ -211,23 +240,25 @@ void LuaGUIState::loadInventoryWidget(const std::string &name, s32 x, s32 y, sf:
}

if (widgetInventory) {
m_inventoryWidgets.emplace_back(m_client, &m_mainWidget);
m_inventoryWidgets.emplace(name, InventoryWidget{m_client, &m_mainWidget});

auto &inventoryWidget = m_inventoryWidgets.back();
auto &inventoryWidget = m_inventoryWidgets.at(name);
inventoryWidget.setPosition(x, y);
inventoryWidget.init(*widgetInventory, offset, count);
inventoryWidget.setShiftDestination(shiftDestination);
}
else {
DEBUG("ERROR: Inventory widget '" + name + "' is invalid");
}
}

void LuaGUIState::loadCraftingWidget(const std::string &, s32 x, s32 y, sf::Packet &packet) {
std::string inventory;
void LuaGUIState::loadCraftingWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet) {
std::string inventory, shiftDestination;
gk::Vector3i block;
u16 offset, size;
s32 resultX, resultY;
packet >> inventory >> block.x >> block.y >> block.z >> offset >> size >> resultX >> resultY;
packet >> inventory >> block.x >> block.y >> block.z >> offset >> size
>> shiftDestination >> resultX >> resultY;

Inventory *craftingInventory = nullptr;
if (inventory == "block") {
Expand All @@ -245,12 +276,13 @@ void LuaGUIState::loadCraftingWidget(const std::string &, s32 x, s32 y, sf::Pack
}

if (craftingInventory) {
m_craftingWidgets.emplace_back(m_client, *craftingInventory, &m_mainWidget);
m_craftingWidgets.emplace(name, CraftingWidget{m_client, *craftingInventory, &m_mainWidget});

auto &craftingWidget = m_craftingWidgets.back();
auto &craftingWidget = m_craftingWidgets.at(name);
craftingWidget.init(offset, size);
craftingWidget.craftingInventoryWidget().setPosition(x, y);
craftingWidget.craftingResultInventoryWidget().setPosition(resultX, resultY);
craftingWidget.setShiftDestination(shiftDestination);
}
else {
DEBUG("ERROR: Crafting inventory is invalid");
Expand Down
Loading

0 comments on commit 4d9a2fb

Please sign in to comment.