|
@@ -38,7 +38,7 @@ BasicShapedCrafter::BasicShapedCrafter(
|
|
zInventory->registerAfterPushStackCall(onChange);
|
|
zInventory->registerAfterPushStackCall(onChange);
|
|
zInventory->registerObserverAddedCall(
|
|
zInventory->registerObserverAddedCall(
|
|
[this](Entity* zSource, Framework::Text id) {
|
|
[this](Entity* zSource, Framework::Text id) {
|
|
- ShapedRecipie* old = currentRecipie;
|
|
|
|
|
|
+ Recipie* old = currentRecipie;
|
|
calculateOutputPreview();
|
|
calculateOutputPreview();
|
|
if (old == currentRecipie)
|
|
if (old == currentRecipie)
|
|
{
|
|
{
|
|
@@ -91,8 +91,10 @@ void BasicShapedCrafter::getOutputPreview(NetworkMessage* zMessage)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-bool BasicShapedCrafter::isAllAvailable(
|
|
|
|
- Framework::RCArray<ItemFilter>& filters, int width, int height)
|
|
|
|
|
|
+bool BasicShapedCrafter::isAllAvailable(Framework::RCArray<ItemFilter>& filters,
|
|
|
|
+ Framework::Array<int>& inputAmount,
|
|
|
|
+ int width,
|
|
|
|
+ int height)
|
|
{
|
|
{
|
|
for (int x = 0; x <= this->width - width; x++)
|
|
for (int x = 0; x <= this->width - width; x++)
|
|
{
|
|
{
|
|
@@ -107,7 +109,10 @@ bool BasicShapedCrafter::isAllAvailable(
|
|
ItemSlot* s
|
|
ItemSlot* s
|
|
= craftingInput.get((h + y) * this->width + (x + w));
|
|
= craftingInput.get((h + y) * this->width + (x + w));
|
|
const Item* item = 0;
|
|
const Item* item = 0;
|
|
- if (s && s->zStack()) item = s->zStack()->zItem();
|
|
|
|
|
|
+ if (s && s->zStack()
|
|
|
|
+ && s->zStack()->getSize() >= inputAmount.get(
|
|
|
|
+ (h + y) * this->width + (x + w)))
|
|
|
|
+ item = s->zStack()->zItem();
|
|
wrong |= (item && !f) || (!item && f);
|
|
wrong |= (item && !f) || (!item && f);
|
|
wrong |= item && f && !f->matchItem(item);
|
|
wrong |= item && f && !f->matchItem(item);
|
|
if (wrong) break;
|
|
if (wrong) break;
|
|
@@ -133,6 +138,40 @@ bool BasicShapedCrafter::isAllAvailable(
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool BasicShapedCrafter::isAllAvailable(
|
|
|
|
+ Framework::RCArray<ItemFilter>& filters, Framework::Array<int>& inputAmount)
|
|
|
|
+{
|
|
|
|
+ bool* used = new bool[craftingInput.getEintragAnzahl()];
|
|
|
|
+ memset(used, 0, sizeof(bool) * craftingInput.getEintragAnzahl());
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (ItemFilter* filter : filters)
|
|
|
|
+ {
|
|
|
|
+ bool found = 0;
|
|
|
|
+ for (int i = 0; i < craftingInput.getEintragAnzahl(); i++)
|
|
|
|
+ {
|
|
|
|
+ if (used[i]) continue;
|
|
|
|
+ ItemSlot* slot = craftingInput.get(i);
|
|
|
|
+ if (slot && slot->zStack()
|
|
|
|
+ && slot->zStack()->getSize() >= inputAmount.get(index)
|
|
|
|
+ && slot->zStack()->zItem()
|
|
|
|
+ && filter->matchItem(slot->zStack()->zItem()))
|
|
|
|
+ {
|
|
|
|
+ found = 1;
|
|
|
|
+ used[i] = 1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!found)
|
|
|
|
+ {
|
|
|
|
+ delete[] used;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ delete[] used;
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
bool BasicShapedCrafter::hasFreeSpace(const Item* zItem, int amount)
|
|
bool BasicShapedCrafter::hasFreeSpace(const Item* zItem, int amount)
|
|
{
|
|
{
|
|
ItemStack* stack
|
|
ItemStack* stack
|
|
@@ -143,13 +182,15 @@ bool BasicShapedCrafter::hasFreeSpace(const Item* zItem, int amount)
|
|
}
|
|
}
|
|
|
|
|
|
bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
- Framework::RCArray<ItemModifier>& modfiers,
|
|
|
|
|
|
+ Framework::RCArray<ItemModifier>& modifiers,
|
|
|
|
+ Framework::Array<int>& inputAmount,
|
|
int width,
|
|
int width,
|
|
int height)
|
|
int height)
|
|
{
|
|
{
|
|
int beginX = this->width;
|
|
int beginX = this->width;
|
|
int beginY = this->height;
|
|
int beginY = this->height;
|
|
- SourceSlotBlacklistFilter otherSlots;
|
|
|
|
|
|
+ SourceSlotBlacklistFilter otherSlotsSource;
|
|
|
|
+ TargetSlotBlacklistFilter otherSlotsTarget;
|
|
for (int i = 0; i < craftingInput.getEintragAnzahl(); i++)
|
|
for (int i = 0; i < craftingInput.getEintragAnzahl(); i++)
|
|
{
|
|
{
|
|
if (!craftingInput.get(i)->isEmpty())
|
|
if (!craftingInput.get(i)->isEmpty())
|
|
@@ -159,7 +200,8 @@ bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
beginX = MIN(beginX, x);
|
|
beginX = MIN(beginX, x);
|
|
beginY = MIN(beginY, y);
|
|
beginY = MIN(beginY, y);
|
|
}
|
|
}
|
|
- otherSlots.addBlackListSlotId(craftingInput.get(i)->getId());
|
|
|
|
|
|
+ otherSlotsSource.addBlackListSlotId(craftingInput.get(i)->getId());
|
|
|
|
+ otherSlotsTarget.addBlackListSlotId(craftingInput.get(i)->getId());
|
|
}
|
|
}
|
|
for (int x = 0; x < width; x++)
|
|
for (int x = 0; x < width; x++)
|
|
{
|
|
{
|
|
@@ -167,12 +209,27 @@ bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
{
|
|
{
|
|
ItemSlot* target
|
|
ItemSlot* target
|
|
= craftingInput.get((y + beginY) * this->width + x + beginX);
|
|
= craftingInput.get((y + beginY) * this->width + x + beginX);
|
|
- ItemStack* stack = zInventory->takeItemsOut(target, 1, INSIDE);
|
|
|
|
|
|
+ ItemStack* stack = zInventory->takeItemsOut(
|
|
|
|
+ target, target->getNumberOfItems(), INSIDE);
|
|
if (stack)
|
|
if (stack)
|
|
{
|
|
{
|
|
|
|
+ if (stack->getSize()
|
|
|
|
+ > inputAmount.get(y * width + x))
|
|
|
|
+ {
|
|
|
|
+ ItemStack* overflow = stack->split(
|
|
|
|
+ stack->getSize()
|
|
|
|
+ - inputAmount.get(y * width + x));
|
|
|
|
+ zInventory->unsaveAddItem(
|
|
|
|
+ overflow, INSIDE, &otherSlotsTarget);
|
|
|
|
+ if (overflow->getSize() > 0)
|
|
|
|
+ {
|
|
|
|
+ // TODO: drop items
|
|
|
|
+ }
|
|
|
|
+ overflow->release();
|
|
|
|
+ }
|
|
if (stack->getSize() > 0 && stack->zItem())
|
|
if (stack->getSize() > 0 && stack->zItem())
|
|
{
|
|
{
|
|
- ItemModifier* m = modfiers.z(y * width + x);
|
|
|
|
|
|
+ ItemModifier* m = modifiers.z(y * width + x);
|
|
if (m) m->applyOn((Item*)stack->zItem());
|
|
if (m) m->applyOn((Item*)stack->zItem());
|
|
}
|
|
}
|
|
if (stack->zItem()->getHp() == 0)
|
|
if (stack->zItem()->getHp() == 0)
|
|
@@ -184,8 +241,10 @@ bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
stack->release();
|
|
stack->release();
|
|
if (broken)
|
|
if (broken)
|
|
{
|
|
{
|
|
- ItemStack* brokenStack = new ItemStack(broken, 1);
|
|
|
|
- zInventory->unsaveAddItem(brokenStack, INSIDE);
|
|
|
|
|
|
+ ItemStack* brokenStack
|
|
|
|
+ = new ItemStack(broken, stack->getSize());
|
|
|
|
+ zInventory->unsaveAddItem(
|
|
|
|
+ brokenStack, INSIDE, &otherSlotsTarget);
|
|
// TODO: if brokenStack is not empty spawn an item
|
|
// TODO: if brokenStack is not empty spawn an item
|
|
// entity
|
|
// entity
|
|
brokenStack->release();
|
|
brokenStack->release();
|
|
@@ -193,8 +252,6 @@ bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- // TODO: transfer all items from target to other slots or
|
|
|
|
- // drop them
|
|
|
|
zInventory->addItems(target, stack, INSIDE);
|
|
zInventory->addItems(target, stack, INSIDE);
|
|
// TODO: if stack is not empty spawn an item entity
|
|
// TODO: if stack is not empty spawn an item entity
|
|
}
|
|
}
|
|
@@ -208,7 +265,7 @@ bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
tmp.add(target);
|
|
tmp.add(target);
|
|
CombinedItemFilter combinedFilter(
|
|
CombinedItemFilter combinedFilter(
|
|
dynamic_cast<ItemFilter*>(f->getThis()),
|
|
dynamic_cast<ItemFilter*>(f->getThis()),
|
|
- dynamic_cast<ItemFilter*>(otherSlots.getThis()),
|
|
|
|
|
|
+ dynamic_cast<ItemFilter*>(otherSlotsSource.getThis()),
|
|
[](bool a, bool b) { return a && b; });
|
|
[](bool a, bool b) { return a && b; });
|
|
zInventory->localTransaction(
|
|
zInventory->localTransaction(
|
|
0, &tmp, &combinedFilter, 1, NO_DIRECTION, INSIDE);
|
|
0, &tmp, &combinedFilter, 1, NO_DIRECTION, INSIDE);
|
|
@@ -219,9 +276,107 @@ bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters,
|
|
|
|
+ Framework::RCArray<ItemModifier>& modifiers,
|
|
|
|
+ Framework::Array<int>& inputAmount)
|
|
|
|
+{
|
|
|
|
+ SourceSlotBlacklistFilter otherSlotsSource;
|
|
|
|
+ TargetSlotBlacklistFilter otherSlotsTarget;
|
|
|
|
+ for (int i = 0; i < craftingInput.getEintragAnzahl(); i++)
|
|
|
|
+ {
|
|
|
|
+ otherSlotsSource.addBlackListSlotId(craftingInput.get(i)->getId());
|
|
|
|
+ otherSlotsTarget.addBlackListSlotId(craftingInput.get(i)->getId());
|
|
|
|
+ }
|
|
|
|
+ bool* used = new bool[craftingInput.getEintragAnzahl()];
|
|
|
|
+ memset(used, 0, sizeof(bool) * craftingInput.getEintragAnzahl());
|
|
|
|
+ for (int i = 0; i < filters.getEintragAnzahl(); i++)
|
|
|
|
+ {
|
|
|
|
+ for (int j = 0; j < craftingInput.getEintragAnzahl(); j++)
|
|
|
|
+ {
|
|
|
|
+ if (used[j]) continue;
|
|
|
|
+ ItemSlot* target = craftingInput.get(j);
|
|
|
|
+ if (target && target->zStack()
|
|
|
|
+ && target->zStack()->getSize() >= inputAmount.get(i)
|
|
|
|
+ && target->zStack()->zItem()
|
|
|
|
+ && filters.z(i)->matchItem(target->zStack()->zItem()))
|
|
|
|
+ {
|
|
|
|
+ used[i] = 1;
|
|
|
|
+ ItemStack* stack = zInventory->takeItemsOut(
|
|
|
|
+ target, target->getNumberOfItems(), INSIDE);
|
|
|
|
+ if (stack)
|
|
|
|
+ {
|
|
|
|
+ if (stack->getSize() > inputAmount.get(i))
|
|
|
|
+ {
|
|
|
|
+ ItemStack* overflow = stack->split(
|
|
|
|
+ stack->getSize() - inputAmount.get(i));
|
|
|
|
+ zInventory->unsaveAddItem(
|
|
|
|
+ overflow, INSIDE, &otherSlotsTarget);
|
|
|
|
+ if (overflow->getSize() > 0)
|
|
|
|
+ {
|
|
|
|
+ // TODO: drop items
|
|
|
|
+ }
|
|
|
|
+ overflow->release();
|
|
|
|
+ }
|
|
|
|
+ if (stack->getSize() > 0 && stack->zItem())
|
|
|
|
+ {
|
|
|
|
+ ItemModifier* m = modifiers.z(i);
|
|
|
|
+ if (m) m->applyOn((Item*)stack->zItem());
|
|
|
|
+ }
|
|
|
|
+ if (stack->zItem()->getHp() == 0)
|
|
|
|
+ stack->release();
|
|
|
|
+ else if (stack->zItem()->getDurability() == 0)
|
|
|
|
+ {
|
|
|
|
+ Item* broken = stack->zItem()->zItemType()->breakItem(
|
|
|
|
+ stack->zItem());
|
|
|
|
+ stack->release();
|
|
|
|
+ if (broken)
|
|
|
|
+ {
|
|
|
|
+ ItemStack* brokenStack
|
|
|
|
+ = new ItemStack(broken, stack->getSize());
|
|
|
|
+ zInventory->unsaveAddItem(
|
|
|
|
+ brokenStack, INSIDE, &otherSlotsTarget);
|
|
|
|
+ // TODO: if brokenStack is not empty spawn an item
|
|
|
|
+ // entity
|
|
|
|
+ brokenStack->release();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ zInventory->addItems(target, stack, INSIDE);
|
|
|
|
+ // TODO: if stack is not empty spawn an item entity
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ ItemFilter* f = filters.z(i);
|
|
|
|
+ if (f)
|
|
|
|
+ {
|
|
|
|
+ if (target->isEmpty())
|
|
|
|
+ {
|
|
|
|
+ Framework::Array<ItemSlot*> tmp;
|
|
|
|
+ tmp.add(target);
|
|
|
|
+ CombinedItemFilter combinedFilter(
|
|
|
|
+ dynamic_cast<ItemFilter*>(f->getThis()),
|
|
|
|
+ dynamic_cast<ItemFilter*>(
|
|
|
|
+ otherSlotsSource.getThis()),
|
|
|
|
+ [](bool a, bool b) { return a && b; });
|
|
|
|
+ zInventory->localTransaction(
|
|
|
|
+ 0, &tmp, &combinedFilter, 1, NO_DIRECTION, INSIDE);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ delete[] used;
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
void BasicShapedCrafter::addCraftingResult(ItemStack* stack)
|
|
void BasicShapedCrafter::addCraftingResult(ItemStack* stack)
|
|
{
|
|
{
|
|
- zInventory->unsaveAddItem(stack, NO_DIRECTION);
|
|
|
|
|
|
+ TargetSlotBlacklistFilter otherSlotsTarget;
|
|
|
|
+ for (int i = 0; i < craftingInput.getEintragAnzahl(); i++)
|
|
|
|
+ otherSlotsTarget.addBlackListSlotId(craftingInput.get(i)->getId());
|
|
|
|
+ zInventory->unsaveAddItem(stack, NO_DIRECTION, &otherSlotsTarget);
|
|
}
|
|
}
|
|
|
|
|
|
void BasicShapedCrafter::applyCurrentRecipie()
|
|
void BasicShapedCrafter::applyCurrentRecipie()
|
|
@@ -232,11 +387,11 @@ void BasicShapedCrafter::applyCurrentRecipie()
|
|
|
|
|
|
void BasicShapedCrafter::calculateOutputPreview()
|
|
void BasicShapedCrafter::calculateOutputPreview()
|
|
{
|
|
{
|
|
- ShapedRecipieList* recipies
|
|
|
|
- = Game::INSTANCE->getRecipies().zShapedRecipieList(recipieList);
|
|
|
|
|
|
+ RecipieList* recipies
|
|
|
|
+ = Game::INSTANCE->getRecipies().zRecipieList(recipieList);
|
|
if (recipies)
|
|
if (recipies)
|
|
{
|
|
{
|
|
- ShapedRecipie* recipie = recipies->zFirstRecipie(this);
|
|
|
|
|
|
+ Recipie* recipie = recipies->zFirstRecipie(this);
|
|
if (recipie != currentRecipie)
|
|
if (recipie != currentRecipie)
|
|
{
|
|
{
|
|
currentRecipie = recipie;
|
|
currentRecipie = recipie;
|