Browse Source

fix not executed recipie modifiers due to wrong filtering in locl inventory transactions

Kolja Strohm 2 years ago
parent
commit
667b3bbc39
4 changed files with 110 additions and 152 deletions
  1. 95 152
      FactoryCraft/Inventory.cpp
  2. 3 0
      FactoryCraft/Inventory.h
  3. 10 0
      FactoryCraft/ItemFilter.cpp
  4. 2 0
      FactoryCraft/ItemFilter.h

+ 95 - 152
FactoryCraft/Inventory.cpp

@@ -11,6 +11,8 @@
 
 using namespace Framework;
 
+
+
 InventoryInteraction::InventoryInteraction(Inventory* current, Inventory* other, Direction dir)
 	: current(current),
 	other(other),
@@ -97,80 +99,16 @@ void InventoryInteraction::transaction(Inventory* zSource, Inventory* zTarget, I
 		while (sourceSlot && (sourceSlot->getNumberOfItems() == 0 || (zFilter && !zFilter->matchSourceSlot(sourceSlot))))
 			sourceSlot++;
 		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;
 		for (auto targetSlot = zTarget->pushSlotsOrder->begin(); targetSlot; )
 		{
 			while (targetSlot && (targetSlot->isFull() || (zFilter && !zFilter->matchTargetSlot(targetSlot))))
 				targetSlot++;
 			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)
 				break;
 		}
@@ -464,95 +402,32 @@ void Inventory::localTransaction(Array< ItemSlot* >* zSourceSlots, Array< ItemSl
 	{
 		cs.lock();
 		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();
 	}
@@ -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)
 {
 	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;
 }

+ 3 - 0
FactoryCraft/Inventory.h

@@ -82,4 +82,7 @@ public:
 	void registerObserverAddedCall(std::function<void(Entity* zSource, Framework::Text id)> call);
 
 	friend InventoryInteraction;
+
+private:
+	static bool unsafeMove(Inventory* zSource, Inventory* zTarget, Framework::Iterator<ItemSlot*>& sourceSlot, Framework::Iterator<ItemSlot*>& targetSlot, Direction outDir, Direction inDir, int& count);
 };

+ 10 - 0
FactoryCraft/ItemFilter.cpp

@@ -42,6 +42,16 @@ bool CombinedItemFilter::matchItem(const Item* zItem) const
 	return op(filterA->matchItem(zItem), filterB->matchItem(zItem));
 }
 
+bool CombinedItemFilter::matchSourceSlot(ItemSlot* zSlot) const
+{
+	return op(filterA->matchSourceSlot(zSlot), filterB->matchSourceSlot(zSlot));
+}
+
+bool CombinedItemFilter::matchTargetSlot(ItemSlot* zSlot) const
+{
+	return op(filterA->matchTargetSlot(zSlot), filterB->matchTargetSlot(zSlot));
+}
+
 
 AnyItemFilter::AnyItemFilter()
 	: ItemFilter()

+ 2 - 0
FactoryCraft/ItemFilter.h

@@ -29,6 +29,8 @@ public:
 	CombinedItemFilter(ItemFilter* filterA, ItemFilter* filterB, std::function<bool(bool, bool)> op);
 	~CombinedItemFilter();
 	bool matchItem(const Item* zItem) const override;
+	bool matchSourceSlot(ItemSlot* zSlot) const override;
+	bool matchTargetSlot(ItemSlot* zSlot) const override;
 };