Server-side inventory functionality! **yay**
parent
26e770b1bd
commit
8bd2e404cd
|
@ -90,7 +90,7 @@ void GuiInventoryList::leftClick(bool down, glm::ivec2 pos) {
|
|||
|
||||
if (index < 0 || index >= list->getLength()) return;
|
||||
|
||||
hand->setStack(0, list->placeStack(index, hand->getStack(0), true));
|
||||
list->primaryInteract(*hand, index);
|
||||
}
|
||||
|
||||
void GuiInventoryList::rightClick(bool down, glm::ivec2 pos) {
|
||||
|
@ -105,24 +105,7 @@ void GuiInventoryList::rightClick(bool down, glm::ivec2 pos) {
|
|||
unsigned short index = slot.x + slot.y * list->getWidth();
|
||||
if (index >= list->getLength()) return;
|
||||
|
||||
auto handStack = hand->getStack(0);
|
||||
if (handStack.count == 0) {
|
||||
hand->setStack(0, list->splitStack(index, true));
|
||||
}
|
||||
else {
|
||||
auto handStack = hand->getStack(0);
|
||||
auto listStack = list->getStack(index);
|
||||
if (listStack.id == 0 || listStack.id == handStack.id) {
|
||||
auto overflow = list->placeStack(index, {handStack.id, 1}, true);
|
||||
handStack.count -= 1;
|
||||
if (handStack.count == 0) handStack.id = 0;
|
||||
if (overflow.count != 0) handStack.count += overflow.count;
|
||||
hand->setStack(0, handStack);
|
||||
}
|
||||
else {
|
||||
hand->setStack(0, list->placeStack(index, hand->getStack(0), true));
|
||||
}
|
||||
}
|
||||
list->secondaryInteract(*hand, index);
|
||||
}
|
||||
|
||||
void GuiInventoryList::drawContents() {
|
||||
|
|
|
@ -203,6 +203,30 @@ ItemStack InventoryList::removeStack(unsigned short ind, unsigned short count) {
|
|||
}
|
||||
}
|
||||
|
||||
void InventoryList::primaryInteract(InventoryList& hand, unsigned short ind) {
|
||||
hand.setStack(0, placeStack(ind, hand.getStack(0), true));
|
||||
}
|
||||
|
||||
void InventoryList::secondaryInteract(InventoryList &hand, unsigned short ind) {
|
||||
auto handStack = hand.getStack(0);
|
||||
if (handStack.count == 0) {
|
||||
hand.setStack(0, splitStack(ind, true));
|
||||
}
|
||||
else {
|
||||
auto listStack = getStack(ind);
|
||||
if (listStack.id == 0 || listStack.id == handStack.id) {
|
||||
auto overflow = placeStack(ind, {handStack.id, 1}, true);
|
||||
handStack.count -= 1;
|
||||
if (handStack.count == 0) handStack.id = 0;
|
||||
if (overflow.count != 0) handStack.count += overflow.count;
|
||||
hand.setStack(0, handStack);
|
||||
}
|
||||
else {
|
||||
hand.setStack(0, placeStack(ind, hand.getStack(0), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack InventoryList::getStack(unsigned short i) const {
|
||||
return itemstacks[i];
|
||||
}
|
||||
|
|
|
@ -39,6 +39,11 @@ public:
|
|||
// Removes up to count items from ind, returns the items removed
|
||||
virtual ItemStack removeStack(unsigned short ind, unsigned short count);
|
||||
|
||||
// Primary interaction - The action performed when left clicking an inventory slot.
|
||||
virtual void primaryInteract(InventoryList& hand, unsigned short ind);
|
||||
// Secondary interaction - The action performed when right clicking an inventory slot.
|
||||
virtual void secondaryInteract(InventoryList& hand, unsigned short ind);
|
||||
|
||||
ItemStack getStack(unsigned short i) const;
|
||||
void setStack(unsigned short i, const ItemStack& stack);
|
||||
|
||||
|
|
|
@ -44,3 +44,13 @@ bool InventoryRefs::removeWatcher(const std::string &inv, const std::string &lis
|
|||
inventories[inv]->operator[](list)->removeWatcher(cid);
|
||||
return true;
|
||||
}
|
||||
|
||||
void InventoryRefs::primaryInteract(const std::string &inv, const std::string &list, unsigned short ind, unsigned int cid) {
|
||||
std::cout << "primary interaction" << std::endl;
|
||||
inventories[inv]->operator[](list)->primaryInteract(*inventories["player:" + std::to_string(cid)]->operator[]("hand"), ind);
|
||||
}
|
||||
|
||||
void InventoryRefs::secondaryInteract(const std::string &inv, const std::string &list, unsigned short ind, unsigned int cid) {
|
||||
std::cout << "secondary interaction" << std::endl;
|
||||
inventories[inv]->operator[](list)->secondaryInteract(*inventories["player:" + std::to_string(cid)]->operator[]("hand"), ind);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ public:
|
|||
|
||||
bool addWatcher(const std::string& inv, const std::string& list, unsigned int cid);
|
||||
bool removeWatcher(const std::string& inv, const std::string& list, unsigned int cid);
|
||||
|
||||
void primaryInteract(const std::string& inv, const std::string& list, unsigned short ind, unsigned int cid);
|
||||
void secondaryInteract(const std::string& inv, const std::string& list, unsigned short ind, unsigned int cid);
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<Inventory>> inventories {};
|
||||
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
#include "LocalInventory.h"
|
||||
|
||||
void LocalInventory::createList(std::string name, unsigned short length, unsigned short width, bool maintain) {
|
||||
lists.insert({name, {(maintain ? -1 : 0), std::make_shared<LocalInventoryList>(defs, this->name, name, length, width)}});
|
||||
namespace ph = std::placeholders;
|
||||
|
||||
lists.insert({name, {(maintain ? -1 : 0),
|
||||
std::make_shared<LocalInventoryList>(defs, this->name, name, length, width,
|
||||
std::bind(primaryCallback, this->name, name, ph::_1), std::bind(secondaryCallback, this->name, name, ph::_1))}});
|
||||
}
|
||||
|
||||
std::shared_ptr<LocalInventoryList> LocalInventory::operator[](std::string name) {
|
||||
|
|
|
@ -11,7 +11,11 @@
|
|||
|
||||
class LocalInventory {
|
||||
public:
|
||||
LocalInventory(DefinitionAtlas& defs, const std::string& name) : defs(defs), name(name) {};
|
||||
typedef std::function<void(const std::string& inv, const std::string& list, unsigned short)> inv_callback_fn;
|
||||
|
||||
LocalInventory(DefinitionAtlas& defs, const std::string& name,
|
||||
inv_callback_fn primaryCallback, inv_callback_fn secondaryCallback) :
|
||||
defs(defs), name(name), primaryCallback(primaryCallback), secondaryCallback(secondaryCallback) {};
|
||||
|
||||
void createList(std::string name, unsigned short length, unsigned short width, bool maintain = false);
|
||||
std::shared_ptr<LocalInventoryList> operator[](std::string name);
|
||||
|
@ -22,4 +26,7 @@ public:
|
|||
private:
|
||||
std::string name;
|
||||
std::unordered_map<std::string, std::pair<double, std::shared_ptr<LocalInventoryList>>> lists;
|
||||
|
||||
inv_callback_fn primaryCallback;
|
||||
inv_callback_fn secondaryCallback;
|
||||
};
|
||||
|
|
|
@ -5,8 +5,22 @@
|
|||
#include "LocalInventoryList.h"
|
||||
|
||||
LocalInventoryList::LocalInventoryList(DefinitionAtlas& defs, const std::string& invName,
|
||||
const std::string& listName, unsigned short size, unsigned short width) :
|
||||
InventoryList(defs, invName, listName, size, width) {}
|
||||
const std::string& listName, unsigned short size, unsigned short width,
|
||||
std::function<void(unsigned short)> primaryCallback, std::function<void(unsigned short)> secondaryCallback) :
|
||||
InventoryList(defs, invName, listName, size, width),
|
||||
|
||||
primaryCallback(primaryCallback),
|
||||
secondaryCallback(secondaryCallback) {}
|
||||
|
||||
void LocalInventoryList::primaryInteract(InventoryList &hand, unsigned short ind) {
|
||||
InventoryList::primaryInteract(hand, ind);
|
||||
primaryCallback(ind);
|
||||
}
|
||||
|
||||
void LocalInventoryList::secondaryInteract(InventoryList &hand, unsigned short ind) {
|
||||
InventoryList::secondaryInteract(hand, ind);
|
||||
secondaryCallback(ind);
|
||||
}
|
||||
|
||||
void LocalInventoryList::setData(unsigned int size, unsigned int width, std::vector<ItemStack> stacks) {
|
||||
this->width = width;
|
||||
|
@ -18,7 +32,6 @@ void LocalInventoryList::setGuiCallback(std::function<void()> cb) {
|
|||
this->guiCallback = cb;
|
||||
}
|
||||
|
||||
void LocalInventoryList::manipulated(){
|
||||
void LocalInventoryList::manipulated() {
|
||||
if (guiCallback != nullptr) guiCallback();
|
||||
}
|
||||
|
||||
}
|
|
@ -9,7 +9,11 @@
|
|||
class LocalInventoryList : public InventoryList {
|
||||
public:
|
||||
LocalInventoryList(DefinitionAtlas& defs, const std::string& invName,
|
||||
const std::string& listName, unsigned short size, unsigned short width);
|
||||
const std::string& listName, unsigned short size, unsigned short width,
|
||||
std::function<void(unsigned short)> primaryCallback, std::function<void(unsigned short)> secondaryCallback);
|
||||
|
||||
void primaryInteract(InventoryList& hand, unsigned short ind) override;
|
||||
void secondaryInteract(InventoryList& hand, unsigned short ind) override;
|
||||
|
||||
void setData(unsigned int size, unsigned int width, std::vector<ItemStack> stacks);
|
||||
void setGuiCallback(std::function<void()> cb);
|
||||
|
@ -17,4 +21,6 @@ public:
|
|||
private:
|
||||
void manipulated() override;
|
||||
std::function<void()> guiCallback = nullptr;
|
||||
std::function<void(unsigned short)> primaryCallback = nullptr;
|
||||
std::function<void(unsigned short)> secondaryCallback = nullptr;
|
||||
};
|
||||
|
|
|
@ -6,17 +6,17 @@
|
|||
|
||||
#include "../scene/net/ClientNetworkInterpreter.h"
|
||||
|
||||
LocalInventoryRefs::LocalInventoryRefs(LocalDefinitionAtlas& defs) :
|
||||
defs(defs) {
|
||||
LocalInventoryRefs::LocalInventoryRefs(LocalDefinitionAtlas& defs, ClientNetworkInterpreter& net) : defs(defs) {
|
||||
namespace ph = std::placeholders;
|
||||
|
||||
inventories.insert({"current_player", std::make_shared<LocalInventory>(defs, "current_player")});
|
||||
this->watchFn = std::bind(&ClientNetworkInterpreter::watchInv, &net, ph::_1, ph::_2);
|
||||
this->primaryCallback = std::bind(&ClientNetworkInterpreter::primaryInteract, &net, ph::_1, ph::_2, ph::_3);
|
||||
this->secondaryCallback = std::bind(&ClientNetworkInterpreter::secondaryInteract, &net, ph::_1, ph::_2, ph::_3);
|
||||
|
||||
inventories.insert({"current_player", std::make_shared<LocalInventory>(defs, "current_player", primaryCallback, secondaryCallback)});
|
||||
inventories["current_player"]->createList("hand", 1, 1, true);
|
||||
}
|
||||
|
||||
void LocalInventoryRefs::setWatchFunction(std::function<void(std::string, std::string)> watchFn) {
|
||||
this->watchFn = watchFn;
|
||||
}
|
||||
|
||||
void LocalInventoryRefs::update(double delta, ClientNetworkInterpreter& net) {
|
||||
time += delta;
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
class LocalInventoryRefs {
|
||||
public:
|
||||
LocalInventoryRefs(LocalDefinitionAtlas& defs);
|
||||
typedef std::function<void(const std::string& inv, const std::string& list, unsigned short)> inv_callback_fn;
|
||||
|
||||
void setWatchFunction(std::function<void(std::string, std::string)> watchFn);
|
||||
LocalInventoryRefs(LocalDefinitionAtlas& defs, ClientNetworkInterpreter& net);
|
||||
|
||||
void update(double delta, ClientNetworkInterpreter& net);
|
||||
void packetReceived(std::unique_ptr<Packet> p);
|
||||
|
@ -27,6 +27,8 @@ private:
|
|||
std::unordered_map<std::string, std::shared_ptr<LocalInventory>> inventories {};
|
||||
|
||||
std::function<void(std::string, std::string)> watchFn = nullptr;
|
||||
inv_callback_fn primaryCallback = nullptr;
|
||||
inv_callback_fn secondaryCallback = nullptr;
|
||||
|
||||
LocalDefinitionAtlas& defs;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ Packet ServerInventoryList::createPacket() {
|
|||
s.append<unsigned int>(stack.id);
|
||||
}
|
||||
|
||||
return s.packet(PacketType::INVENTORY, false);
|
||||
return s.packet(PacketType::INV_DATA, false);
|
||||
}
|
||||
|
||||
void ServerInventoryList::sendTo(std::shared_ptr<ServerClient> client) {
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
#include "GameScene.h"
|
||||
|
||||
GameScene::GameScene(ClientState& state) : Scene(state),
|
||||
refs(game.defs),
|
||||
game(state.defs),
|
||||
world(game, &net),
|
||||
refs(game.defs, net),
|
||||
net(state.connection, game, player),
|
||||
player(world, game, state.renderer, refs),
|
||||
debugGui(state.renderer.window.getSize(), game) {
|
||||
|
@ -21,8 +21,6 @@ GameScene::GameScene(ClientState& state) : Scene(state),
|
|||
net.init(&world, std::bind(&LocalInventoryRefs::packetReceived, refs, ph::_1));
|
||||
game.init(world, player);
|
||||
|
||||
refs.setWatchFunction(std::bind(&ClientNetworkInterpreter::watchInv, &net, ph::_1, ph::_2));
|
||||
|
||||
state.renderer.window.addResizeCallback("gamescene", std::bind(&DebugGui::bufferResized, debugGui, ph::_1));
|
||||
state.renderer.setClearColor(148, 194, 240);
|
||||
state.renderer.window.lockMouse(true);
|
||||
|
|
|
@ -20,8 +20,8 @@ public:
|
|||
public:
|
||||
ClientGame& game;
|
||||
|
||||
LocalInventoryRefs refs;
|
||||
ClientNetworkInterpreter net;
|
||||
LocalInventoryRefs refs;
|
||||
LocalWorld world;
|
||||
Player player;
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<Packet> p) {
|
|||
std::cout << Log::err << "Invalid inventory " << source << ":" << list << " was requested by client." << Log::endl;
|
||||
exit(1);
|
||||
}
|
||||
case PacketType::INVENTORY: {
|
||||
case PacketType::INV_DATA: {
|
||||
onInvPacket(std::move(p));
|
||||
break;
|
||||
}
|
||||
|
@ -158,10 +158,20 @@ void ClientNetworkInterpreter::setBlock(glm::ivec3 pos, unsigned int block) {
|
|||
|
||||
void ClientNetworkInterpreter::watchInv(const std::string& inv, const std::string& list) {
|
||||
Serializer().append(inv).append(list)
|
||||
.packet(PacketType::WATCH_INV).sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
||||
.packet(PacketType::INV_WATCH).sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
||||
}
|
||||
|
||||
void ClientNetworkInterpreter::unwatchInv(const std::string& inv, const std::string& list) {
|
||||
Serializer().append(inv).append(list)
|
||||
.packet(PacketType::UNWATCH_INV).sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
||||
}
|
||||
.packet(PacketType::INV_UNWATCH).sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
||||
}
|
||||
|
||||
void ClientNetworkInterpreter::primaryInteract(const std::string &inv, const std::string &list, unsigned short ind) {
|
||||
Serializer().append<unsigned short>(0).append(inv).append(list).append<unsigned short>(ind)
|
||||
.packet(PacketType::INV_INTERACT).sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
||||
}
|
||||
|
||||
void ClientNetworkInterpreter::secondaryInteract(const std::string &inv, const std::string &list, unsigned short ind) {
|
||||
Serializer().append<unsigned short>(1).append(inv).append(list).append<unsigned short>(ind)
|
||||
.packet(PacketType::INV_INTERACT).sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ public:
|
|||
void watchInv(const std::string& inv, const std::string& list);
|
||||
void unwatchInv(const std::string& inv, const std::string& list);
|
||||
|
||||
void primaryInteract(const std::string& inv, const std::string& list, unsigned short ind);
|
||||
void secondaryInteract(const std::string& inv, const std::string& list, unsigned short ind);
|
||||
|
||||
int recvPackets = 0;
|
||||
int serverSideChunkGens = 0;
|
||||
private:
|
||||
|
|
|
@ -155,7 +155,7 @@ void Server::handlePlayerPacket(ServerClient &client, Packet& p) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case PacketType::WATCH_INV: {
|
||||
case PacketType::INV_WATCH: {
|
||||
Deserializer d(p.data);
|
||||
|
||||
std::string source = d.read<std::string>();
|
||||
|
@ -173,7 +173,7 @@ void Server::handlePlayerPacket(ServerClient &client, Packet& p) {
|
|||
|
||||
break;
|
||||
}
|
||||
case PacketType::UNWATCH_INV: {
|
||||
case PacketType::INV_UNWATCH: {
|
||||
Deserializer d(p.data);
|
||||
|
||||
std::string source = d.read<std::string>();
|
||||
|
@ -189,6 +189,23 @@ void Server::handlePlayerPacket(ServerClient &client, Packet& p) {
|
|||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PacketType::INV_INTERACT: {
|
||||
Deserializer d(p.data);
|
||||
|
||||
unsigned short type = d.read<unsigned short>();
|
||||
|
||||
std::string source = d.read<std::string>();
|
||||
std::string list = d.read<std::string>();
|
||||
unsigned short ind = d.read<unsigned short>();
|
||||
|
||||
// TODO: When inventory saving / loading is implemented there will need to be a cross-save identifier.
|
||||
if (source == "current_player") source = "player:" + std::to_string(client.cid);
|
||||
|
||||
if (type == 0) refs.primaryInteract(source, list, ind, client.cid);
|
||||
else refs.secondaryInteract(source, list, ind, client.cid);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,10 @@ enum class PacketType {
|
|||
ENTITY_REMOVED,
|
||||
|
||||
// Inventory
|
||||
WATCH_INV,
|
||||
UNWATCH_INV,
|
||||
INV_WATCH,
|
||||
INV_UNWATCH,
|
||||
INV_INVALID,
|
||||
INVENTORY
|
||||
INV_DATA,
|
||||
INV_INTERACT
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ zepha.register_keybind("zeus:inventory:open_inventory", {
|
|||
position: 0px 50px
|
||||
size: 218px 100px
|
||||
padding: 20px 10px 8px 10px
|
||||
background: asset(zeus:inventory:inventory)
|
||||
background: zeus:inventory:inventory
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
|
@ -31,7 +31,7 @@ zepha.register_keybind("zeus:inventory:open_inventory", {
|
|||
position: 0px -48px
|
||||
size: 218px 100px
|
||||
padding: 20px 10px 8px 10px
|
||||
background: asset(zeus:inventory:chest)
|
||||
background: zeus:inventory:chest
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
|
|
|
@ -51,15 +51,6 @@ zepha.register_keybind("zeus:inventory:open_inventory", {
|
|||
position: 41px -8px
|
||||
size: 34px 52px
|
||||
overflow: hidden
|
||||
|
||||
model
|
||||
scale: 86 86
|
||||
position: 15px 52px
|
||||
type: model
|
||||
source: zeus:default:player
|
||||
texture: zeus:default:player
|
||||
anim_range: 0 300
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,3 +4,10 @@ zepha.register_item("zeus:materials:flint", {
|
|||
"zeus:materials:flint",
|
||||
}
|
||||
})
|
||||
|
||||
crafting.register_recipe({
|
||||
output = "zeus:materials:flint",
|
||||
recipe = {
|
||||
{"zeus:default:cobblestone"},
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue