Parent implemetation for Server/Local InventoryList shared methods
parent
7c0e1cefd7
commit
5cd56de9d0
|
@ -313,6 +313,6 @@ set(ZEPHA_SRC
|
|||
lua/api/class/LocalLuaInventory.cpp
|
||||
lua/api/class/LocalLuaInventory.h
|
||||
lua/api/class/LocalLuaInventoryList.cpp
|
||||
lua/api/class/LocalLuaInventoryList.h game/inventory/InventoryRefs.cpp game/inventory/InventoryRefs.h)
|
||||
lua/api/class/LocalLuaInventoryList.h game/inventory/InventoryRefs.cpp game/inventory/InventoryRefs.h game/inventory/InventoryList.cpp game/inventory/InventoryList.h)
|
||||
|
||||
add_library (Zepha_Core ${ZEPHA_SRC})
|
|
@ -0,0 +1,223 @@
|
|||
//
|
||||
// Created by aurailus on 2020-02-28.
|
||||
//
|
||||
|
||||
#include "InventoryList.h"
|
||||
|
||||
#include "../../lua/api/class/LuaItemStack.h"
|
||||
|
||||
unsigned short InventoryList::getLength() const {
|
||||
return itemstacks.size();
|
||||
}
|
||||
|
||||
unsigned short InventoryList::getWidth() const {
|
||||
return width;
|
||||
}
|
||||
|
||||
std::string InventoryList::getName() const {
|
||||
return listName;
|
||||
}
|
||||
|
||||
// List Manipulation Functions
|
||||
|
||||
ItemStack InventoryList::placeStack(unsigned short i, const ItemStack &stack, bool playerInitiated) {
|
||||
auto otherStack = getStack(i);
|
||||
|
||||
unsigned short allowedTake = otherStack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
|
||||
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i+1, LuaItemStack(otherStack, defs))), allowedTake);
|
||||
}
|
||||
unsigned short allowedPut = stack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowPut = luaCallbacks[static_cast<int>(Callback::ALLOW_PUT)];
|
||||
if (allowPut) allowedPut = std::min(static_cast<unsigned short>(allowPut(i+1, LuaItemStack(stack, defs))), allowedPut);
|
||||
}
|
||||
|
||||
sol::function on_put = luaCallbacks[static_cast<int>(Callback::ON_PUT)];
|
||||
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
|
||||
|
||||
if (stack.count == 0) {
|
||||
if (allowedTake == otherStack.count) setStack(i, {});
|
||||
else setStack(i, {otherStack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
|
||||
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return {otherStack.id, allowedTake};
|
||||
}
|
||||
else {
|
||||
if (otherStack.count) {
|
||||
if (otherStack.id == stack.id) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
if (allowedPut >= stack.count && allowedPut + otherStack.count < maxStack) {
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {};
|
||||
}
|
||||
else if (allowedPut > 0) {
|
||||
allowedPut = std::min(allowedPut, static_cast<unsigned short>(maxStack - otherStack.count));
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
|
||||
}
|
||||
else {
|
||||
allowedTake = std::min(allowedTake, static_cast<unsigned short>(maxStack - stack.count));
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
|
||||
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count + allowedTake)};
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (stack.count <= allowedPut && otherStack.count <= allowedTake) {
|
||||
setStack(i, stack);
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
if (on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return otherStack;
|
||||
}
|
||||
else {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack InventoryList::splitStack(unsigned short i, bool playerInitiated) {
|
||||
auto stack = getStack(i);
|
||||
|
||||
unsigned short allowedTake = stack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
|
||||
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i + 1, LuaItemStack(stack, defs))), allowedTake);
|
||||
}
|
||||
|
||||
unsigned short initialCount = stack.count;
|
||||
unsigned short takeCount = std::min(static_cast<unsigned short>(ceil(initialCount / 2.f)), allowedTake);
|
||||
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(initialCount - takeCount)});
|
||||
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
|
||||
if (on_take) on_take(i+1, stack);
|
||||
return {stack.id, takeCount};
|
||||
}
|
||||
|
||||
ItemStack InventoryList::addStack(ItemStack stack, bool playerInitiated) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
|
||||
unsigned short i = 0;
|
||||
while (i < itemstacks.size() && stack.count > 0) {
|
||||
if (itemstacks[i].count == 0) {
|
||||
if (stack.count <= maxStack) {
|
||||
itemstacks[i] = stack;
|
||||
manipulated();
|
||||
return ItemStack{};
|
||||
}
|
||||
else {
|
||||
itemstacks[i] = stack;
|
||||
itemstacks[i].count = maxStack;
|
||||
stack.count -= maxStack;
|
||||
}
|
||||
}
|
||||
else if (itemstacks[i].id == stack.id) {
|
||||
unsigned int fits = maxStack - itemstacks[i].count;
|
||||
if (fits >= stack.count) {
|
||||
itemstacks[i].count += stack.count;
|
||||
manipulated();
|
||||
return ItemStack {};
|
||||
}
|
||||
else {
|
||||
stack.count -= fits;
|
||||
itemstacks[i].count += fits;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
manipulated();
|
||||
return stack;
|
||||
}
|
||||
|
||||
unsigned short InventoryList::stackFits(const ItemStack &stack) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
|
||||
unsigned short i = 0;
|
||||
unsigned short fits = 0;
|
||||
|
||||
while (i < itemstacks.size() && fits < stack.count) {
|
||||
if (itemstacks[i].count == 0) {
|
||||
fits += std::min(static_cast<unsigned short>(maxStack), stack.count);
|
||||
}
|
||||
else if (itemstacks[i].id == stack.id) {
|
||||
unsigned int canfit = maxStack - itemstacks[i].count;
|
||||
if (canfit >= stack.count - fits) {
|
||||
fits += stack.count - fits;
|
||||
}
|
||||
else {
|
||||
fits = stack.count;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return fits;
|
||||
}
|
||||
|
||||
ItemStack InventoryList::takeStack(ItemStack request, bool playerInitiated) {
|
||||
unsigned short i = 0;
|
||||
unsigned short to_remove = request.count;
|
||||
|
||||
while (i < itemstacks.size() && request.count > 0) {
|
||||
if (itemstacks[i].id == request.id) {
|
||||
unsigned int can_take = itemstacks[i].count;
|
||||
if (can_take >= to_remove) {
|
||||
itemstacks[i].count -= to_remove;
|
||||
manipulated();
|
||||
return request;
|
||||
}
|
||||
else {
|
||||
to_remove -= can_take;
|
||||
itemstacks[i] = ItemStack {};
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
request.count = (request.count - to_remove);
|
||||
manipulated();
|
||||
return request;
|
||||
}
|
||||
|
||||
ItemStack InventoryList::removeStack(unsigned short ind, unsigned short count) {
|
||||
auto stack = getStack(ind);
|
||||
if (count >= stack.count) {
|
||||
setStack(ind, {0, 0});
|
||||
return stack;
|
||||
}
|
||||
else {
|
||||
stack.count -= count;
|
||||
setStack(ind, stack);
|
||||
stack.count = count;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack InventoryList::getStack(unsigned short i) const {
|
||||
return itemstacks[i];
|
||||
}
|
||||
|
||||
void InventoryList::setStack(unsigned short i, const ItemStack &stack) {
|
||||
if (stack != getStack(i)) {
|
||||
itemstacks[i] = stack;
|
||||
manipulated();
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryList::setLuaCallback(InventoryList::Callback type, sol::function cb) {
|
||||
luaCallbacks[static_cast<size_t>(type)] = cb;
|
||||
}
|
||||
|
||||
sol::function InventoryList::getLuaCallback(InventoryList::Callback type) {
|
||||
return luaCallbacks[static_cast<size_t>(type)];
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// Created by aurailus on 2020-02-28.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "ItemStack.h"
|
||||
|
||||
#include "../../def/DefinitionAtlas.h"
|
||||
|
||||
class InventoryList {
|
||||
public:
|
||||
enum class Callback {
|
||||
ALLOW_TAKE,
|
||||
ALLOW_PUT,
|
||||
ON_TAKE,
|
||||
ON_PUT
|
||||
};
|
||||
|
||||
InventoryList(DefinitionAtlas& defs) : defs(defs) {};
|
||||
InventoryList(DefinitionAtlas& defs, const std::string& invName, const std::string& listName, unsigned short size, unsigned short width) :
|
||||
defs(defs), invName(invName), listName(listName), width(width), itemstacks(size) {};
|
||||
|
||||
unsigned short getLength() const;
|
||||
unsigned short getWidth() const;
|
||||
std::string getName() const;
|
||||
|
||||
// Place the stack at i into the existing stack, returning overflow or other stack.
|
||||
virtual ItemStack placeStack(unsigned short i, const ItemStack& stack, bool playerInitiated = false);
|
||||
// Split the stack at i and return half of it, rounded up
|
||||
virtual ItemStack splitStack(unsigned short i, bool playerInitiated = false);
|
||||
// Adds as much of `stack` to the inventory as possible, returns leftover.
|
||||
virtual ItemStack addStack(ItemStack stack, bool playerInitiated = false);
|
||||
// Returns how many of `stack`'s items fit, from 0 to stack.count.
|
||||
virtual unsigned short stackFits(const ItemStack& stack);
|
||||
// Attempts to remove the usertype and amount of items specified by `stack`. Returns actual ItemStack of what was removed.
|
||||
virtual ItemStack takeStack(ItemStack request, bool playerInitiated = false);
|
||||
// Removes up to count items from ind, returns the items removed
|
||||
virtual ItemStack removeStack(unsigned short ind, unsigned short count);
|
||||
|
||||
ItemStack getStack(unsigned short i) const;
|
||||
void setStack(unsigned short i, const ItemStack& stack);
|
||||
|
||||
sol::function getLuaCallback(Callback type);
|
||||
void setLuaCallback(Callback type, sol::function cb);
|
||||
|
||||
DefinitionAtlas& defs;
|
||||
|
||||
protected:
|
||||
virtual void manipulated() = 0;
|
||||
|
||||
std::string invName {}, listName {};
|
||||
unsigned short width = 0;
|
||||
|
||||
std::vector<ItemStack> itemstacks {};
|
||||
|
||||
std::array<sol::function, 4> luaCallbacks = {};
|
||||
};
|
|
@ -5,7 +5,7 @@
|
|||
#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, name, length, width)}});
|
||||
lists.insert({name, {(maintain ? -1 : 0), std::make_shared<LocalInventoryList>(defs, this->name, name, length, width)}});
|
||||
}
|
||||
|
||||
std::shared_ptr<LocalInventoryList> LocalInventory::operator[](std::string name) {
|
||||
|
|
|
@ -2,243 +2,23 @@
|
|||
// Created by aurailus on 2019-10-29.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "LocalInventoryList.h"
|
||||
|
||||
#include "../../lua/api/class/LuaItemStack.h"
|
||||
|
||||
LocalInventoryList::LocalInventoryList(DefinitionAtlas& defs, const std::string& name, unsigned short size, unsigned short width) :
|
||||
defs(defs),
|
||||
name(name),
|
||||
itemstacks(size),
|
||||
width(width) {}
|
||||
LocalInventoryList::LocalInventoryList(DefinitionAtlas& defs, const std::string& invName,
|
||||
const std::string& listName, unsigned short size, unsigned short width) :
|
||||
InventoryList(defs, invName, listName, size, width) {}
|
||||
|
||||
void LocalInventoryList::setData(unsigned int size, unsigned int width, std::vector<ItemStack> stacks) {
|
||||
this->width = width;
|
||||
this->itemstacks = stacks;
|
||||
triggerCallback();
|
||||
manipulated();
|
||||
}
|
||||
|
||||
void LocalInventoryList::setGuiCallback(std::function<void()> cb) {
|
||||
this->guiCallback = cb;
|
||||
}
|
||||
|
||||
void LocalInventoryList::setLuaCallback(LocalInventoryList::Callback type, sol::function cb) {
|
||||
luaCallbacks[static_cast<size_t>(type)] = cb;
|
||||
}
|
||||
|
||||
sol::function LocalInventoryList::getLuaCallback(LocalInventoryList::Callback type) {
|
||||
return luaCallbacks[static_cast<size_t>(type)];
|
||||
}
|
||||
|
||||
ItemStack LocalInventoryList::getStack(unsigned short i) {
|
||||
return itemstacks[i];
|
||||
}
|
||||
|
||||
void LocalInventoryList::setStack(unsigned short i, const ItemStack &stack) {
|
||||
if (stack != getStack(i)) {
|
||||
itemstacks[i] = stack;
|
||||
triggerCallback();
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack LocalInventoryList::placeStack(unsigned short i, const ItemStack &stack, bool playerInitiated) {
|
||||
auto otherStack = getStack(i);
|
||||
|
||||
unsigned short allowedTake = otherStack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
|
||||
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i+1, LuaItemStack(otherStack, defs))), allowedTake);
|
||||
}
|
||||
unsigned short allowedPut = stack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowPut = luaCallbacks[static_cast<int>(Callback::ALLOW_PUT)];
|
||||
if (allowPut) allowedPut = std::min(static_cast<unsigned short>(allowPut(i+1, LuaItemStack(stack, defs))), allowedPut);
|
||||
}
|
||||
|
||||
sol::function on_put = luaCallbacks[static_cast<int>(Callback::ON_PUT)];
|
||||
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
|
||||
|
||||
if (stack.count == 0) {
|
||||
if (allowedTake == otherStack.count) setStack(i, {});
|
||||
else setStack(i, {otherStack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
|
||||
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return {otherStack.id, allowedTake};
|
||||
}
|
||||
else {
|
||||
if (otherStack.count) {
|
||||
if (otherStack.id == stack.id) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
if (allowedPut >= stack.count && allowedPut + otherStack.count < maxStack) {
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {};
|
||||
}
|
||||
else if (allowedPut > 0) {
|
||||
allowedPut = std::min(allowedPut, static_cast<unsigned short>(maxStack - otherStack.count));
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
|
||||
}
|
||||
else {
|
||||
allowedTake = std::min(allowedTake, static_cast<unsigned short>(maxStack - stack.count));
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
|
||||
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count + allowedTake)};
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (stack.count <= allowedPut && otherStack.count <= allowedTake) {
|
||||
setStack(i, stack);
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
if (on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return otherStack;
|
||||
}
|
||||
else {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack LocalInventoryList::splitStack(unsigned short i, bool playerInitiated) {
|
||||
auto stack = getStack(i);
|
||||
|
||||
unsigned short allowedTake = stack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
|
||||
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i + 1, LuaItemStack(stack, defs))), allowedTake);
|
||||
}
|
||||
|
||||
unsigned short initialCount = stack.count;
|
||||
unsigned short takeCount = std::min(static_cast<unsigned short>(ceil(initialCount / 2.f)), allowedTake);
|
||||
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(initialCount - takeCount)});
|
||||
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
|
||||
if (on_take) on_take(i+1, stack);
|
||||
return {stack.id, takeCount};
|
||||
}
|
||||
|
||||
ItemStack LocalInventoryList::addStack(ItemStack stack, bool playerInitiated) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
|
||||
unsigned short i = 0;
|
||||
while (i < itemstacks.size() && stack.count > 0) {
|
||||
if (itemstacks[i].count == 0) {
|
||||
if (stack.count <= maxStack) {
|
||||
itemstacks[i] = stack;
|
||||
triggerCallback();
|
||||
return ItemStack{};
|
||||
}
|
||||
else {
|
||||
itemstacks[i] = stack;
|
||||
itemstacks[i].count = maxStack;
|
||||
stack.count -= maxStack;
|
||||
}
|
||||
}
|
||||
else if (itemstacks[i].id == stack.id) {
|
||||
unsigned int fits = maxStack - itemstacks[i].count;
|
||||
if (fits >= stack.count) {
|
||||
itemstacks[i].count += stack.count;
|
||||
triggerCallback();
|
||||
return ItemStack {};
|
||||
}
|
||||
else {
|
||||
stack.count -= fits;
|
||||
itemstacks[i].count += fits;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
triggerCallback();
|
||||
return stack;
|
||||
}
|
||||
|
||||
unsigned short LocalInventoryList::stackFits(const ItemStack &stack) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
|
||||
unsigned short i = 0;
|
||||
unsigned short fits = 0;
|
||||
|
||||
while (i < itemstacks.size() && fits < stack.count) {
|
||||
if (itemstacks[i].count == 0) {
|
||||
fits += std::min(static_cast<unsigned short>(maxStack), stack.count);
|
||||
}
|
||||
else if (itemstacks[i].id == stack.id) {
|
||||
unsigned int canfit = maxStack - itemstacks[i].count;
|
||||
if (canfit >= stack.count - fits) {
|
||||
fits += stack.count - fits;
|
||||
}
|
||||
else {
|
||||
fits = stack.count;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return fits;
|
||||
}
|
||||
|
||||
ItemStack LocalInventoryList::takeStack(ItemStack request, bool playerInitiated) {
|
||||
unsigned short i = 0;
|
||||
unsigned short to_remove = request.count;
|
||||
|
||||
while (i < itemstacks.size() && request.count > 0) {
|
||||
if (itemstacks[i].id == request.id) {
|
||||
unsigned int can_take = itemstacks[i].count;
|
||||
if (can_take >= to_remove) {
|
||||
itemstacks[i].count -= to_remove;
|
||||
triggerCallback();
|
||||
return request;
|
||||
}
|
||||
else {
|
||||
to_remove -= can_take;
|
||||
itemstacks[i] = ItemStack {};
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
request.count = (request.count - to_remove);
|
||||
triggerCallback();
|
||||
return request;
|
||||
}
|
||||
|
||||
ItemStack LocalInventoryList::removeStack(unsigned short ind, unsigned short count) {
|
||||
auto stack = getStack(ind);
|
||||
if (count >= stack.count) {
|
||||
setStack(ind, {0, 0});
|
||||
return stack;
|
||||
}
|
||||
else {
|
||||
stack.count -= count;
|
||||
setStack(ind, stack);
|
||||
stack.count = count;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
void LocalInventoryList::triggerCallback() {
|
||||
void LocalInventoryList::manipulated(){
|
||||
if (guiCallback != nullptr) guiCallback();
|
||||
}
|
||||
|
||||
unsigned short LocalInventoryList::getLength() {
|
||||
return itemstacks.size();
|
||||
}
|
||||
|
||||
unsigned short LocalInventoryList::getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
std::string LocalInventoryList::getName() {
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -4,54 +4,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include "InventoryList.h"
|
||||
|
||||
#include "ItemStack.h"
|
||||
|
||||
class LocalInventoryList {
|
||||
class LocalInventoryList : public InventoryList {
|
||||
public:
|
||||
enum class Callback { ALLOW_TAKE, ALLOW_PUT, ON_TAKE, ON_PUT };
|
||||
|
||||
LocalInventoryList(DefinitionAtlas& defs, const std::string& name, unsigned short size, unsigned short width);
|
||||
|
||||
unsigned short getLength();
|
||||
unsigned short getWidth();
|
||||
std::string getName();
|
||||
LocalInventoryList(DefinitionAtlas& defs, const std::string& invName,
|
||||
const std::string& listName, unsigned short size, unsigned short width);
|
||||
|
||||
void setData(unsigned int size, unsigned int width, std::vector<ItemStack> stacks);
|
||||
|
||||
// Place the stack at i into the existing stack, returning overflow or other stack.
|
||||
ItemStack placeStack(unsigned short i, const ItemStack& stack, bool playerInitiated = false);
|
||||
// Split the stack at i and return half of it, rounded up
|
||||
ItemStack splitStack(unsigned short i, bool playerInitiated = false);
|
||||
// Adds as much of `stack` to the inventory as possible, returns leftover.
|
||||
ItemStack addStack(ItemStack stack, bool playerInitiated = false);
|
||||
// Returns how many of `stack`'s items fit, from 0 to stack.count.
|
||||
unsigned short stackFits(const ItemStack& stack);
|
||||
// Attempts to remove the type and amount of items specified by `stack`. Returns actual ItemStack of what was removed.
|
||||
ItemStack takeStack(ItemStack request, bool playerInitiated = false);
|
||||
|
||||
void setStack(unsigned short i, const ItemStack& stack);
|
||||
ItemStack getStack(unsigned short i);
|
||||
|
||||
// Removes up to count items from ind, returns the items removed
|
||||
ItemStack removeStack(unsigned short ind, unsigned short count);
|
||||
|
||||
void setGuiCallback(std::function<void()> cb);
|
||||
void setLuaCallback(Callback type, sol::function cb);
|
||||
sol::function getLuaCallback(Callback type);
|
||||
|
||||
DefinitionAtlas& defs;
|
||||
|
||||
private:
|
||||
void triggerCallback();
|
||||
|
||||
std::vector<ItemStack> itemstacks {};
|
||||
unsigned short width = 0;
|
||||
std::string name;
|
||||
|
||||
void manipulated() override;
|
||||
std::function<void()> guiCallback = nullptr;
|
||||
std::array<sol::function, 4> luaCallbacks = {};
|
||||
};
|
||||
|
|
|
@ -12,232 +12,16 @@
|
|||
#include "../../server/conn/ClientList.h"
|
||||
#include "../../lua/api/class/LuaItemStack.h"
|
||||
|
||||
ServerInventoryList::ServerInventoryList(DefinitionAtlas& defs, ClientList* list, const std::string& invName, const std::string& name, unsigned short size, unsigned short width) :
|
||||
defs(defs),
|
||||
name(name),
|
||||
width(width),
|
||||
clients(list),
|
||||
invName(invName),
|
||||
itemstacks(size) {}
|
||||
ServerInventoryList::ServerInventoryList(DefinitionAtlas& defs, ClientList* list,
|
||||
const std::string& invName, const std::string& listName, unsigned short size, unsigned short width) :
|
||||
|
||||
void ServerInventoryList::setLuaCallback(ServerInventoryList::Callback type, sol::function cb) {
|
||||
luaCallbacks[static_cast<size_t>(type)] = cb;
|
||||
}
|
||||
InventoryList(defs, invName, listName, size, width),
|
||||
clients(list) {}
|
||||
|
||||
sol::function ServerInventoryList::getLuaCallback(ServerInventoryList::Callback type) {
|
||||
return luaCallbacks[static_cast<size_t>(type)];
|
||||
}
|
||||
|
||||
ItemStack ServerInventoryList::getStack(unsigned short i) {
|
||||
return itemstacks[i];
|
||||
}
|
||||
|
||||
void ServerInventoryList::setStack(unsigned short i, const ItemStack &stack) {
|
||||
if (stack != getStack(i)) {
|
||||
itemstacks[i] = stack;
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack ServerInventoryList::placeStack(unsigned short i, const ItemStack &stack, bool playerInitiated) {
|
||||
auto otherStack = getStack(i);
|
||||
|
||||
unsigned short allowedTake = otherStack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
|
||||
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i+1, LuaItemStack(otherStack, defs))), allowedTake);
|
||||
}
|
||||
unsigned short allowedPut = stack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowPut = luaCallbacks[static_cast<int>(Callback::ALLOW_PUT)];
|
||||
if (allowPut) allowedPut = std::min(static_cast<unsigned short>(allowPut(i+1, LuaItemStack(stack, defs))), allowedPut);
|
||||
}
|
||||
|
||||
sol::function on_put = luaCallbacks[static_cast<int>(Callback::ON_PUT)];
|
||||
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
|
||||
|
||||
if (stack.count == 0) {
|
||||
if (allowedTake == otherStack.count) setStack(i, {});
|
||||
else setStack(i, {otherStack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
|
||||
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return {otherStack.id, allowedTake};
|
||||
}
|
||||
else {
|
||||
if (otherStack.count) {
|
||||
if (otherStack.id == stack.id) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
if (allowedPut >= stack.count && allowedPut + otherStack.count < maxStack) {
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {};
|
||||
}
|
||||
else if (allowedPut > 0) {
|
||||
allowedPut = std::min(allowedPut, static_cast<unsigned short>(maxStack - otherStack.count));
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
|
||||
}
|
||||
else {
|
||||
allowedTake = std::min(allowedTake, static_cast<unsigned short>(maxStack - stack.count));
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
|
||||
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count + allowedTake)};
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (stack.count <= allowedPut && otherStack.count <= allowedTake) {
|
||||
setStack(i, stack);
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
if (on_take) on_take(i+1, LuaItemStack(otherStack, defs));
|
||||
return otherStack;
|
||||
}
|
||||
else {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
|
||||
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
|
||||
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack ServerInventoryList::splitStack(unsigned short i, bool playerInitiated) {
|
||||
auto stack = getStack(i);
|
||||
|
||||
unsigned short allowedTake = stack.count;
|
||||
if (playerInitiated) {
|
||||
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
|
||||
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i + 1, LuaItemStack(stack, defs))), allowedTake);
|
||||
}
|
||||
|
||||
unsigned short initialCount = stack.count;
|
||||
unsigned short takeCount = std::min(static_cast<unsigned short>(ceil(initialCount / 2.f)), allowedTake);
|
||||
|
||||
setStack(i, {stack.id, static_cast<unsigned short>(initialCount - takeCount)});
|
||||
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
|
||||
if (on_take) on_take(i+1, stack);
|
||||
return {stack.id, takeCount};
|
||||
}
|
||||
|
||||
ItemStack ServerInventoryList::addStack(ItemStack stack, bool playerInitiated) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
|
||||
unsigned short i = 0;
|
||||
while (i < itemstacks.size() && stack.count > 0) {
|
||||
if (itemstacks[i].count == 0) {
|
||||
if (stack.count <= maxStack) {
|
||||
itemstacks[i] = stack;
|
||||
setDirty();
|
||||
return ItemStack{};
|
||||
}
|
||||
else {
|
||||
itemstacks[i] = stack;
|
||||
itemstacks[i].count = maxStack;
|
||||
stack.count -= maxStack;
|
||||
}
|
||||
}
|
||||
else if (itemstacks[i].id == stack.id) {
|
||||
unsigned int fits = maxStack - itemstacks[i].count;
|
||||
if (fits >= stack.count) {
|
||||
itemstacks[i].count += stack.count;
|
||||
setDirty();
|
||||
return ItemStack {};
|
||||
}
|
||||
else {
|
||||
stack.count -= fits;
|
||||
itemstacks[i].count += fits;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
setDirty();
|
||||
return stack;
|
||||
}
|
||||
|
||||
unsigned short ServerInventoryList::stackFits(const ItemStack &stack) {
|
||||
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
|
||||
|
||||
unsigned short i = 0;
|
||||
unsigned short fits = 0;
|
||||
|
||||
while (i < itemstacks.size() && fits < stack.count) {
|
||||
if (itemstacks[i].count == 0) {
|
||||
fits += std::min(static_cast<unsigned short>(maxStack), stack.count);
|
||||
}
|
||||
else if (itemstacks[i].id == stack.id) {
|
||||
unsigned int canfit = maxStack - itemstacks[i].count;
|
||||
if (canfit >= stack.count - fits) {
|
||||
fits += stack.count - fits;
|
||||
}
|
||||
else {
|
||||
fits = stack.count;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return fits;
|
||||
}
|
||||
|
||||
ItemStack ServerInventoryList::takeStack(ItemStack request, bool playerInitiated) {
|
||||
unsigned short i = 0;
|
||||
unsigned short to_remove = request.count;
|
||||
|
||||
while (i < itemstacks.size() && request.count > 0) {
|
||||
if (itemstacks[i].id == request.id) {
|
||||
unsigned int can_take = itemstacks[i].count;
|
||||
if (can_take >= to_remove) {
|
||||
itemstacks[i].count -= to_remove;
|
||||
setDirty();
|
||||
return request;
|
||||
}
|
||||
else {
|
||||
to_remove -= can_take;
|
||||
itemstacks[i] = ItemStack {};
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
request.count = (request.count - to_remove);
|
||||
setDirty();
|
||||
return request;
|
||||
}
|
||||
|
||||
ItemStack ServerInventoryList::removeStack(unsigned short ind, unsigned short count) {
|
||||
auto stack = getStack(ind);
|
||||
if (count >= stack.count) {
|
||||
setStack(ind, {0, 0});
|
||||
return stack;
|
||||
}
|
||||
else {
|
||||
stack.count -= count;
|
||||
setStack(ind, stack);
|
||||
stack.count = count;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerInventoryList::setDirty() {
|
||||
void ServerInventoryList::manipulated(){
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
unsigned short ServerInventoryList::getLength() {
|
||||
return itemstacks.size();
|
||||
}
|
||||
|
||||
unsigned short ServerInventoryList::getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
std::string ServerInventoryList::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
bool ServerInventoryList::addWatcher(unsigned int cid) {
|
||||
auto& client = clients->getClient(cid);
|
||||
if (!client) return false;
|
||||
|
@ -261,8 +45,9 @@ bool ServerInventoryList::removeWatcher(unsigned int cid) {
|
|||
|
||||
Packet ServerInventoryList::createPacket() {
|
||||
Serializer s{};
|
||||
|
||||
s.append<std::string>(invName)
|
||||
.append<std::string>(name)
|
||||
.append<std::string>(listName)
|
||||
.append<unsigned int>(itemstacks.size())
|
||||
.append<unsigned int>(width);
|
||||
|
||||
|
|
|
@ -5,42 +5,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "ItemStack.h"
|
||||
#include "InventoryList.h"
|
||||
|
||||
class ClientList;
|
||||
class ServerClient;
|
||||
class Packet;
|
||||
|
||||
class ServerInventoryList {
|
||||
class ServerInventoryList : public InventoryList {
|
||||
public:
|
||||
enum class Callback { ALLOW_TAKE, ALLOW_PUT, ON_TAKE, ON_PUT };
|
||||
|
||||
ServerInventoryList(DefinitionAtlas& defs, ClientList* list, const std::string& invName,
|
||||
const std::string& name, unsigned short size, unsigned short width);
|
||||
|
||||
unsigned short getLength();
|
||||
unsigned short getWidth();
|
||||
std::string getName();
|
||||
|
||||
// Place the stack at i into the existing stack, returning overflow or other stack.
|
||||
ItemStack placeStack(unsigned short i, const ItemStack& stack, bool playerInitiated = false);
|
||||
// Split the stack at i and return half of it, rounded up
|
||||
ItemStack splitStack(unsigned short i, bool playerInitiated = false);
|
||||
// Adds as much of `stack` to the inventory as possible, returns leftover.
|
||||
ItemStack addStack(ItemStack stack, bool playerInitiated = false);
|
||||
// Returns how many of `stack`'s items fit, from 0 to stack.count.
|
||||
unsigned short stackFits(const ItemStack& stack);
|
||||
// Attempts to remove the usertype and amount of items specified by `stack`. Returns actual ItemStack of what was removed.
|
||||
ItemStack takeStack(ItemStack request, bool playerInitiated = false);
|
||||
|
||||
void setStack(unsigned short i, const ItemStack& stack);
|
||||
ItemStack getStack(unsigned short i);
|
||||
|
||||
// Removes up to count items from ind, returns the items removed
|
||||
ItemStack removeStack(unsigned short ind, unsigned short count);
|
||||
const std::string& listName, unsigned short size, unsigned short width);
|
||||
|
||||
bool addWatcher(unsigned int cid);
|
||||
bool removeWatcher(unsigned int cid);
|
||||
|
@ -48,22 +23,13 @@ public:
|
|||
void sendAll();
|
||||
void sendTo(std::shared_ptr<ServerClient> client);
|
||||
|
||||
void setLuaCallback(Callback type, sol::function cb);
|
||||
sol::function getLuaCallback(Callback type);
|
||||
|
||||
DefinitionAtlas& defs;
|
||||
bool dirty = false;
|
||||
|
||||
private:
|
||||
void setDirty();
|
||||
void manipulated() override;
|
||||
|
||||
Packet createPacket();
|
||||
|
||||
std::vector<ItemStack> itemstacks {};
|
||||
unsigned short width = 0;
|
||||
std::string name;
|
||||
std::string invName;
|
||||
|
||||
std::array<sol::function, 4> luaCallbacks = {};
|
||||
|
||||
ClientList* clients;
|
||||
std::list<unsigned int> watchers;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue