|
@@ -11,6 +11,8 @@
|
|
|
|
|
|
using namespace Framework;
|
|
using namespace Framework;
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
InventoryInteraction::InventoryInteraction(Inventory* current, Inventory* other, Direction dir)
|
|
InventoryInteraction::InventoryInteraction(Inventory* current, Inventory* other, Direction dir)
|
|
: current(current),
|
|
: current(current),
|
|
other(other),
|
|
other(other),
|
|
@@ -97,80 +99,16 @@ void InventoryInteraction::transaction(Inventory* zSource, Inventory* zTarget, I
|
|
while (sourceSlot && (sourceSlot->getNumberOfItems() == 0 || (zFilter && !zFilter->matchSourceSlot(sourceSlot))))
|
|
while (sourceSlot && (sourceSlot->getNumberOfItems() == 0 || (zFilter && !zFilter->matchSourceSlot(sourceSlot))))
|
|
sourceSlot++;
|
|
sourceSlot++;
|
|
if (!sourceSlot) break;
|
|
if (!sourceSlot) break;
|
|
- // TODO: use target cache ot get list of slots that already contains the source ite
|
|
|
|
|
|
+ // TODO: use target cache ot get list of slots that already contains the source item
|
|
bool needNext = 1;
|
|
bool needNext = 1;
|
|
for (auto targetSlot = zTarget->pushSlotsOrder->begin(); targetSlot; )
|
|
for (auto targetSlot = zTarget->pushSlotsOrder->begin(); targetSlot; )
|
|
{
|
|
{
|
|
while (targetSlot && (targetSlot->isFull() || (zFilter && !zFilter->matchTargetSlot(targetSlot))))
|
|
while (targetSlot && (targetSlot->isFull() || (zFilter && !zFilter->matchTargetSlot(targetSlot))))
|
|
targetSlot++;
|
|
targetSlot++;
|
|
if (!targetSlot) break;
|
|
if (!targetSlot) break;
|
|
- if (targetSlot->zStack())
|
|
|
|
- {
|
|
|
|
- if (sourceSlot->zStack()->zItem()->canBeStackedWith(targetSlot->zStack()->zItem()))
|
|
|
|
- {
|
|
|
|
- int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), sourceView), count);
|
|
|
|
- int tmp = number;
|
|
|
|
- if (number > 0 && zSource->allowPullStack(sourceSlot, sourceView) && zTarget->allowPushStack(targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp))
|
|
|
|
- {
|
|
|
|
- number = MIN(number, tmp);
|
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut(number, dir);
|
|
|
|
- if (stack)
|
|
|
|
- {
|
|
|
|
- targetSlot->addItems(stack, dir);
|
|
|
|
- zSource->updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
|
- zSource->afterPullStack(sourceSlot, sourceView, targetSlot->zStack()->zItem(), number);
|
|
|
|
- zTarget->afterPushStack(targetSlot, targetView, targetSlot->zStack()->zItem(), number);
|
|
|
|
- if (stack->getSize())
|
|
|
|
- throw stack;
|
|
|
|
- stack->release();
|
|
|
|
- count -= number;
|
|
|
|
- if (count == 0)
|
|
|
|
- return;
|
|
|
|
- needNext = 0;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- targetSlot++;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- targetSlot++;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- targetSlot++;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), sourceView), count);
|
|
|
|
- int tmp = number;
|
|
|
|
- if (number > 0 && zSource->allowPullStack(sourceSlot, sourceView) && zTarget->allowPushStack(targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp))
|
|
|
|
- {
|
|
|
|
- number = MIN(number, tmp);
|
|
|
|
- if (number > 0)
|
|
|
|
- {
|
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut(number, dir);
|
|
|
|
- if (stack)
|
|
|
|
- {
|
|
|
|
- targetSlot->addItems(stack, dir);
|
|
|
|
- zSource->updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
|
- zTarget->updateCache(targetSlot, -1);
|
|
|
|
- zSource->afterPullStack(sourceSlot, sourceView, targetSlot->zStack()->zItem(), number);
|
|
|
|
- zTarget->afterPushStack(targetSlot, targetView, targetSlot->zStack()->zItem(), number);
|
|
|
|
- if (stack->getSize())
|
|
|
|
- throw stack;
|
|
|
|
- stack->release();
|
|
|
|
- count -= number;
|
|
|
|
- if (count == 0)
|
|
|
|
- return;
|
|
|
|
- needNext = 0;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- targetSlot++;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- targetSlot++;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- targetSlot++;
|
|
|
|
- }
|
|
|
|
|
|
+ needNext &= !Inventory::unsafeMove(zSource, zTarget, sourceSlot, targetSlot, sourceView, targetView, count);
|
|
|
|
+ if (count == 0)
|
|
|
|
+ return;
|
|
if (sourceSlot->getNumberOfItems() == 0)
|
|
if (sourceSlot->getNumberOfItems() == 0)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -464,95 +402,32 @@ void Inventory::localTransaction(Array< ItemSlot* >* zSourceSlots, Array< ItemSl
|
|
{
|
|
{
|
|
cs.lock();
|
|
cs.lock();
|
|
auto sourceSlot = zSourceSlots ? zSourceSlots->begin() : pullSlotsOrder->begin();
|
|
auto sourceSlot = zSourceSlots ? zSourceSlots->begin() : pullSlotsOrder->begin();
|
|
- for (auto targetSlot = zTargetSlots->begin(); targetSlot; )
|
|
|
|
|
|
+ while (true)
|
|
{
|
|
{
|
|
- int amount = count;
|
|
|
|
- if (!targetSlot->isFull())
|
|
|
|
|
|
+ while (sourceSlot && (sourceSlot->getNumberOfItems() == 0 || (zFilter && !zFilter->matchSourceSlot(sourceSlot))))
|
|
|
|
+ sourceSlot++;
|
|
|
|
+ if (!sourceSlot)
|
|
{
|
|
{
|
|
- if (targetSlot->zStack())
|
|
|
|
- {
|
|
|
|
- Array<ItemSlot*>* zSurceListe = itemCache->safeGet(targetSlot->zStack()->zItem()->zItemType()->getId(), 0);
|
|
|
|
- if (zSurceListe)
|
|
|
|
- {
|
|
|
|
- Array<int> toDelete;
|
|
|
|
- int index = 0;
|
|
|
|
- for (auto sourceSlot = zSurceListe->begin(); sourceSlot; sourceSlot++, index++)
|
|
|
|
- {
|
|
|
|
- if (zSourceSlots && zSourceSlots->getWertIndex(sourceSlot) < 0)
|
|
|
|
- continue;
|
|
|
|
- if (zFilter && !zFilter->matchItem(sourceSlot->zStack()->zItem()))
|
|
|
|
- continue;
|
|
|
|
- int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), inDir), count);
|
|
|
|
- if (number > 0)
|
|
|
|
- {
|
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut(number, outDir);
|
|
|
|
- if (stack)
|
|
|
|
- {
|
|
|
|
- if (!sourceSlot->zStack())
|
|
|
|
- toDelete.add(index, 0);
|
|
|
|
- targetSlot->addItems(stack, inDir);
|
|
|
|
- updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
|
- afterPullStack(sourceSlot, outDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
- afterPushStack(targetSlot, inDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
- if (stack->getSize())
|
|
|
|
- {
|
|
|
|
- cs.unlock();
|
|
|
|
- throw stack;
|
|
|
|
- }
|
|
|
|
- stack->release();
|
|
|
|
- count -= number;
|
|
|
|
- if (count == 0)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- for (auto indexToDelete = toDelete.begin(); indexToDelete; indexToDelete++)
|
|
|
|
- zSurceListe->remove(indexToDelete);
|
|
|
|
- if (count == 0)
|
|
|
|
- {
|
|
|
|
- cs.unlock();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
|
|
+ cs.unlock();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ bool needNext = 1;
|
|
|
|
+ for (auto targetSlot = zTargetSlots->begin(); targetSlot; )
|
|
|
|
+ {
|
|
|
|
+ while (targetSlot && (targetSlot->isFull() || (zFilter && !zFilter->matchTargetSlot(targetSlot))))
|
|
|
|
+ targetSlot++;
|
|
|
|
+ if (!targetSlot) break;
|
|
|
|
+ needNext &= !Inventory::unsafeMove(this, this, sourceSlot, targetSlot, outDir, inDir, count);
|
|
|
|
+ if (count == 0)
|
|
{
|
|
{
|
|
- while (sourceSlot && (!sourceSlot->zStack() || (zFilter && !zFilter->matchItem(sourceSlot->zStack()->zItem()))))
|
|
|
|
- sourceSlot++;
|
|
|
|
- if (!sourceSlot)
|
|
|
|
- {
|
|
|
|
- cs.unlock();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), inDir), count);
|
|
|
|
- if (number > 0)
|
|
|
|
- {
|
|
|
|
- ItemStack* stack = sourceSlot->takeItemsOut(number, outDir);
|
|
|
|
- if (stack)
|
|
|
|
- {
|
|
|
|
- targetSlot->addItems(stack, inDir);
|
|
|
|
- updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
|
- updateCache(targetSlot, -1);
|
|
|
|
- afterPullStack(sourceSlot, outDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
- afterPushStack(targetSlot, inDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
- if (stack->getSize())
|
|
|
|
- {
|
|
|
|
- cs.unlock();
|
|
|
|
- throw stack;
|
|
|
|
- }
|
|
|
|
- stack->release();
|
|
|
|
- count -= number;
|
|
|
|
- if (count == 0)
|
|
|
|
- {
|
|
|
|
- cs.unlock();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ cs.unlock();
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
+ if (sourceSlot->getNumberOfItems() == 0)
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- if (amount == count || targetSlot->isFull())
|
|
|
|
- targetSlot++;
|
|
|
|
|
|
+ if (needNext)
|
|
|
|
+ sourceSlot++;
|
|
}
|
|
}
|
|
cs.unlock();
|
|
cs.unlock();
|
|
}
|
|
}
|
|
@@ -770,4 +645,72 @@ void Inventory::registerAfterPushStackCall(std::function<void(ItemSlot* zSlot, D
|
|
void Inventory::registerObserverAddedCall(std::function<void(Entity* zSource, Framework::Text id)> call)
|
|
void Inventory::registerObserverAddedCall(std::function<void(Entity* zSource, Framework::Text id)> call)
|
|
{
|
|
{
|
|
observerAddedCalls.add(call);
|
|
observerAddedCalls.add(call);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool Inventory::unsafeMove(Inventory* zSource, Inventory* zTarget, Iterator<ItemSlot*>& sourceSlot, Iterator<ItemSlot*>& targetSlot, Direction outDir, Direction inDir, int& count)
|
|
|
|
+{
|
|
|
|
+ if (targetSlot->zStack())
|
|
|
|
+ {
|
|
|
|
+ if (sourceSlot->zStack()->zItem()->canBeStackedWith(targetSlot->zStack()->zItem()))
|
|
|
|
+ {
|
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), outDir), count);
|
|
|
|
+ int tmp = number;
|
|
|
|
+ if (number > 0 && zSource->allowPullStack(sourceSlot, outDir) && zTarget->allowPushStack(targetSlot, inDir, sourceSlot->zStack()->zItem(), tmp))
|
|
|
|
+ {
|
|
|
|
+ number = MIN(number, tmp);
|
|
|
|
+ ItemStack* stack = sourceSlot->takeItemsOut(number, outDir);
|
|
|
|
+ if (stack)
|
|
|
|
+ {
|
|
|
|
+ targetSlot->addItems(stack, inDir);
|
|
|
|
+ zSource->updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
|
+ zSource->afterPullStack(sourceSlot, outDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
+ zTarget->afterPushStack(targetSlot, inDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
+ if (stack->getSize())
|
|
|
|
+ throw stack;
|
|
|
|
+ stack->release();
|
|
|
|
+ count -= number;
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ targetSlot++;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ targetSlot++;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ targetSlot++;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ int number = MIN(targetSlot->numberOfAddableItems(sourceSlot->zStack(), outDir), count);
|
|
|
|
+ int tmp = number;
|
|
|
|
+ if (number > 0 && zSource->allowPullStack(sourceSlot, outDir) && zTarget->allowPushStack(targetSlot, inDir, sourceSlot->zStack()->zItem(), tmp))
|
|
|
|
+ {
|
|
|
|
+ number = MIN(number, tmp);
|
|
|
|
+ if (number > 0)
|
|
|
|
+ {
|
|
|
|
+ ItemStack* stack = sourceSlot->takeItemsOut(number, outDir);
|
|
|
|
+ if (stack)
|
|
|
|
+ {
|
|
|
|
+ targetSlot->addItems(stack, inDir);
|
|
|
|
+ zSource->updateCache(sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId());
|
|
|
|
+ zTarget->updateCache(targetSlot, -1);
|
|
|
|
+ zSource->afterPullStack(sourceSlot, outDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
+ zTarget->afterPushStack(targetSlot, inDir, targetSlot->zStack()->zItem(), number);
|
|
|
|
+ if (stack->getSize())
|
|
|
|
+ throw stack;
|
|
|
|
+ stack->release();
|
|
|
|
+ count -= number;
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ targetSlot++;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ targetSlot++;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ targetSlot++;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
}
|
|
}
|