package com.hypixel.hytale.server.core.inventory.container;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.inventory.transaction.ActionType;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackSlotTransaction;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction;
import com.hypixel.hytale.server.core.inventory.transaction.ListTransaction;
import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class InternalContainerUtilItemStack {
public InternalContainerUtilItemStack() {
}
protected static int testAddToExistingSlot(@Nonnull ItemContainer abstractItemContainer, short slot, ItemStack itemStack, int itemMaxStack, int testQuantityRemaining, boolean filter) {
ItemStack slotItemStack = abstractItemContainer.internal_getSlot(slot);
if (ItemStack.isEmpty(slotItemStack)) {
return testQuantityRemaining;
} else if (!slotItemStack.isStackableWith(itemStack)) {
return testQuantityRemaining;
} else if (filter && abstractItemContainer.cantAddToSlot(slot, itemStack, slotItemStack)) {
return testQuantityRemaining;
} else {
int quantity = slotItemStack.getQuantity();
int quantityAdjustment = Math.min(itemMaxStack - quantity, testQuantityRemaining);
testQuantityRemaining -= quantityAdjustment;
return testQuantityRemaining;
}
}
@Nonnull
protected static ItemStackSlotTransaction internal_addToExistingSlot(@Nonnull ItemContainer container, short slot, @Nonnull ItemStack itemStack, int itemMaxStack, boolean filter) {
ItemStack slotItemStack = container.internal_getSlot(slot);
if (ItemStack.isEmpty(slotItemStack)) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, false, false, filter, true, itemStack, itemStack);
} else if (!slotItemStack.isStackableWith(itemStack)) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, false, false, filter, true, itemStack, itemStack);
} else if (filter && container.cantAddToSlot(slot, itemStack, slotItemStack)) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, false, false, filter, true, itemStack, itemStack);
} else {
int quantityRemaining = itemStack.getQuantity();
int quantity = slotItemStack.getQuantity();
int quantityAdjustment = Math.min(itemMaxStack - quantity, quantityRemaining);
int newQuantity = quantity + quantityAdjustment;
quantityRemaining -= quantityAdjustment;
if (quantityAdjustment <= 0) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, false, false, filter, true, itemStack, itemStack);
} else {
ItemStack slotNew = slotItemStack.withQuantity(newQuantity);
if (newQuantity > 0) {
container.internal_setSlot(slot, slotNew);
} else {
container.internal_removeSlot(slot);
}
ItemStack remainder = quantityRemaining != itemStack.getQuantity() ? itemStack.withQuantity(quantityRemaining) : itemStack;
return new ItemStackSlotTransaction(true, ActionType.ADD, slot, slotItemStack, slotNew, (ItemStack)null, false, false, filter, true, itemStack, remainder);
}
}
}
@Nonnull
protected static ItemStackSlotTransaction internal_addToEmptySlot(@Nonnull ItemContainer container, short slot, @Nonnull ItemStack itemStack, int itemMaxStack, boolean filter) {
ItemStack slotItemStack = container.internal_getSlot(slot);
if (slotItemStack != null && !slotItemStack.isEmpty()) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, false, false, filter, false, itemStack, itemStack);
} else if (filter && container.cantAddToSlot(slot, itemStack, slotItemStack)) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, false, false, filter, false, itemStack, itemStack);
} else {
int quantityRemaining = itemStack.getQuantity();
int quantityAdjustment = Math.min(itemMaxStack, quantityRemaining);
quantityRemaining -= quantityAdjustment;
ItemStack slotNew = itemStack.withQuantity(quantityAdjustment);
container.internal_setSlot(slot, slotNew);
ItemStack remainder = itemStack.getQuantity() != quantityRemaining ? itemStack.withQuantity(quantityRemaining) : itemStack;
return new ItemStackSlotTransaction(true, ActionType.ADD, slot, slotItemStack, slotNew, (ItemStack)null, false, false, filter, false, itemStack, remainder);
}
}
protected static int testAddToEmptySlots(@Nonnull ItemContainer container, ItemStack itemStack, int itemMaxStack, int testQuantityRemaining, boolean filter) {
for(short i = 0; i < container.getCapacity() && testQuantityRemaining > 0; ++i) {
ItemStack slotItemStack = container.internal_getSlot(i);
if ((slotItemStack == null || slotItemStack.isEmpty()) && (!filter || !container.cantAddToSlot(i, itemStack, slotItemStack))) {
int quantityAdjustment = Math.min(itemMaxStack, testQuantityRemaining);
testQuantityRemaining -= quantityAdjustment;
}
}
return testQuantityRemaining;
}
protected static ItemStackSlotTransaction internal_addItemStackToSlot(@Nonnull ItemContainer itemContainer, short slot, @Nonnull ItemStack itemStack, boolean allOrNothing, boolean filter) {
ItemContainer.validateSlotIndex(slot, itemContainer.getCapacity());
return (ItemStackSlotTransaction)itemContainer.writeAction(() -> {
int quantityRemaining = itemStack.getQuantity();
ItemStack slotItemStack = itemContainer.internal_getSlot(slot);
if (filter && itemContainer.cantAddToSlot(slot, itemStack, slotItemStack)) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStack, itemStack);
} else if (slotItemStack == null) {
itemContainer.internal_setSlot(slot, itemStack);
return new ItemStackSlotTransaction(true, ActionType.ADD, slot, (ItemStack)null, itemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStack, (ItemStack)null);
} else {
int quantity = slotItemStack.getQuantity();
if (!itemStack.isStackableWith(slotItemStack)) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStack, itemStack);
} else {
int quantityAdjustment = Math.min(slotItemStack.getItem().getMaxStack() - quantity, quantityRemaining);
int newQuantity = quantity + quantityAdjustment;
quantityRemaining -= quantityAdjustment;
if (allOrNothing && quantityRemaining > 0) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStack, itemStack);
} else if (quantityAdjustment <= 0) {
return new ItemStackSlotTransaction(false, ActionType.ADD, slot, slotItemStack, slotItemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStack, itemStack);
} else {
ItemStack newItemStack = slotItemStack.withQuantity(newQuantity);
itemContainer.internal_setSlot(slot, newItemStack);
ItemStack remainder = itemStack.withQuantity(quantityRemaining);
return new ItemStackSlotTransaction(true, ActionType.ADD, slot, slotItemStack, newItemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStack, remainder);
}
}
}
});
}
@Nonnull
protected static ItemStackSlotTransaction internal_setItemStackForSlot(@Nonnull ItemContainer itemContainer, short slot, ItemStack itemStack, boolean filter) {
ItemContainer.validateSlotIndex(slot, itemContainer.getCapacity());
return (ItemStackSlotTransaction)itemContainer.writeAction(() -> {
ItemStack slotItemStack = itemContainer.internal_getSlot(slot);
if (filter && itemContainer.cantAddToSlot(slot, itemStack, slotItemStack)) {
return new ItemStackSlotTransaction(false, ActionType.SET, slot, slotItemStack, slotItemStack, (ItemStack)null, false, false, filter, false, itemStack, itemStack);
} else {
ItemStack oldItemStack = itemContainer.internal_setSlot(slot, itemStack);
return new ItemStackSlotTransaction(true, ActionType.SET, slot, oldItemStack, itemStack, (ItemStack)null, false, false, filter, false, itemStack, (ItemStack)null);
}
});
}
@Nonnull
protected static SlotTransaction internal_removeItemStackFromSlot(@Nonnull ItemContainer itemContainer, short slot, boolean filter) {
ItemContainer.validateSlotIndex(slot, itemContainer.getCapacity());
return (SlotTransaction)itemContainer.writeAction(() -> {
if (filter && itemContainer.cantRemoveFromSlot(slot)) {
ItemStack itemStack = itemContainer.internal_getSlot(slot);
return new ItemStackSlotTransaction(false, ActionType.REMOVE, slot, itemStack, itemStack, (ItemStack)null, false, false, filter, false, (ItemStack)null, itemStack);
} else {
ItemStack oldItemStack = itemContainer.internal_removeSlot(slot);
return new SlotTransaction(true, ActionType.REMOVE, slot, oldItemStack, (ItemStack)null, oldItemStack, false, false, false);
}
});
}
protected static ItemStackSlotTransaction internal_removeItemStackFromSlot(@Nonnull ItemContainer itemContainer, short slot, int quantityToRemove, boolean allOrNothing, boolean filter) {
ItemContainer.validateSlotIndex(slot, itemContainer.getCapacity());
ItemContainer.validateQuantity(quantityToRemove);
return (ItemStackSlotTransaction)itemContainer.writeAction(() -> {
if (filter && itemContainer.cantRemoveFromSlot(slot)) {
ItemStack itemStack = itemContainer.internal_getSlot(slot);
return new ItemStackSlotTransaction(false, ActionType.REMOVE, slot, itemStack, itemStack, (ItemStack)null, allOrNothing, false, filter, false, (ItemStack)null, itemStack.withQuantity(quantityToRemove));
} else {
ItemStack slotItemStack = itemContainer.internal_getSlot(slot);
if (slotItemStack == null) {
return new ItemStackSlotTransaction(false, ActionType.REMOVE, slot, (ItemStack)null, (ItemStack)null, (ItemStack)null, allOrNothing, false, filter, false, (ItemStack)null, (ItemStack)null);
} else {
int quantity = slotItemStack.getQuantity();
int quantityAdjustment = Math.min(quantity, quantityToRemove);
int newQuantity = quantity - quantityAdjustment;
int quantityRemaining = quantityToRemove - quantityAdjustment;
if (allOrNothing && quantityRemaining > 0) {
return new ItemStackSlotTransaction(false, ActionType.REMOVE, slot, slotItemStack, slotItemStack, (ItemStack)null, allOrNothing, false, filter, false, (ItemStack)null, slotItemStack.withQuantity(quantityRemaining));
} else {
ItemStack itemStack = slotItemStack.withQuantity(newQuantity);
itemContainer.internal_setSlot(slot, itemStack);
ItemStack newStack = slotItemStack.withQuantity(quantityAdjustment);
ItemStack remainder = slotItemStack.withQuantity(quantityRemaining);
return new ItemStackSlotTransaction(true, ActionType.REMOVE, slot, slotItemStack, itemStack, newStack, allOrNothing, false, filter, false, (ItemStack)null, remainder);
}
}
}
});
}
protected static ItemStackSlotTransaction internal_removeItemStackFromSlot(@Nonnull ItemContainer itemContainer, short slot, @Nullable ItemStack itemStackToRemove, int quantityToRemove, boolean allOrNothing, boolean filter) {
return internal_removeItemStackFromSlot(itemContainer, slot, itemStackToRemove, quantityToRemove, allOrNothing, filter, (a, b) -> ItemStack.isStackableWith(a, b));
}
protected static ItemStackSlotTransaction internal_removeItemStackFromSlot(@Nonnull ItemContainer itemContainer, short slot, @Nullable ItemStack itemStackToRemove, int quantityToRemove, boolean allOrNothing, boolean filter, BiPredicate<ItemStack, ItemStack> predicate) {
ItemContainer.validateSlotIndex(slot, itemContainer.getCapacity());
ItemContainer.validateQuantity(quantityToRemove);
return (ItemStackSlotTransaction)itemContainer.writeAction(() -> {
if (filter && itemContainer.cantRemoveFromSlot(slot)) {
ItemStack itemStack = itemContainer.internal_getSlot(slot);
return new ItemStackSlotTransaction(false, ActionType.REMOVE, slot, itemStack, itemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStackToRemove, itemStackToRemove);
} else {
ItemStack slotItemStack = itemContainer.internal_getSlot(slot);
if ((slotItemStack != null || itemStackToRemove == null) && (slotItemStack == null || itemStackToRemove != null) && (slotItemStack == null || predicate.test(slotItemStack, itemStackToRemove))) {
if (slotItemStack == null) {
return new ItemStackSlotTransaction(true, ActionType.REMOVE, slot, (ItemStack)null, (ItemStack)null, (ItemStack)null, allOrNothing, false, filter, false, itemStackToRemove, itemStackToRemove);
} else {
int quantity = slotItemStack.getQuantity();
int quantityAdjustment = Math.min(quantity, quantityToRemove);
int newQuantity = quantity - quantityAdjustment;
int quantityRemaining = quantityToRemove - quantityAdjustment;
if (allOrNothing && quantityRemaining > 0) {
return new ItemStackSlotTransaction(false, ActionType.REMOVE, slot, slotItemStack, slotItemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStackToRemove, itemStackToRemove);
} else {
ItemStack itemStack = slotItemStack.withQuantity(newQuantity);
itemContainer.internal_setSlot(slot, itemStack);
ItemStack newStack = slotItemStack.withQuantity(quantityAdjustment);
ItemStack remainder = itemStackToRemove.withQuantity(quantityRemaining);
return new ItemStackSlotTransaction(true, ActionType.REMOVE, slot, slotItemStack, itemStack, newStack, allOrNothing, false, filter, false, itemStackToRemove, remainder);
}
}
} else {
return new ItemStackSlotTransaction(false, ActionType.REMOVE, slot, slotItemStack, slotItemStack, (ItemStack)null, allOrNothing, false, filter, false, itemStackToRemove, itemStackToRemove);
}
}
});
}
protected static int testRemoveItemStackFromSlot(@Nonnull ItemContainer container, short slot, ItemStack itemStack, int testQuantityRemaining, boolean filter) {
return testRemoveItemStackFromSlot(container, slot, itemStack, testQuantityRemaining, filter, (a, b) -> ItemStack.isStackableWith(a, b));
}
protected static int testRemoveItemStackFromSlot(@Nonnull ItemContainer container, short slot, ItemStack itemStack, int testQuantityRemaining, boolean filter, BiPredicate<ItemStack, ItemStack> predicate) {
if (filter && container.cantRemoveFromSlot(slot)) {
return testQuantityRemaining;
} else {
ItemStack slotItemStack = container.internal_getSlot(slot);
if (ItemStack.isEmpty(slotItemStack)) {
return testQuantityRemaining;
} else if (!predicate.test(slotItemStack, itemStack)) {
return testQuantityRemaining;
} else {
int quantity = slotItemStack.getQuantity();
int quantityAdjustment = Math.min(quantity, testQuantityRemaining);
testQuantityRemaining -= quantityAdjustment;
return testQuantityRemaining;
}
}
}
protected static ItemStackTransaction internal_addItemStack(@Nonnull ItemContainer itemContainer, @Nonnull ItemStack itemStack, boolean allOrNothing, boolean fullStacks, boolean filter) {
Item item = itemStack.getItem();
if (item == null) {
throw new IllegalArgumentException(itemStack.getItemId() + " is an invalid item!");
} else {
int itemMaxStack = item.getMaxStack();
return (ItemStackTransaction)itemContainer.writeAction(() -> {
if (allOrNothing) {
int testQuantityRemaining = itemStack.getQuantity();
if (!fullStacks) {
testQuantityRemaining = testAddToExistingItemStacks(itemContainer, itemStack, itemMaxStack, testQuantityRemaining, filter);
}
testQuantityRemaining = testAddToEmptySlots(itemContainer, itemStack, itemMaxStack, testQuantityRemaining, filter);
if (testQuantityRemaining > 0) {
return new ItemStackTransaction(false, ActionType.ADD, itemStack, itemStack, allOrNothing, filter, Collections.emptyList());
}
}
List<ItemStackSlotTransaction> list = new ObjectArrayList<ItemStackSlotTransaction>();
ItemStack remaining = itemStack;
if (!fullStacks) {
for(short i = 0; i < itemContainer.getCapacity() && !ItemStack.isEmpty(remaining); ++i) {
ItemStackSlotTransaction transaction = internal_addToExistingSlot(itemContainer, i, remaining, itemMaxStack, filter);
list.add(transaction);
remaining = transaction.getRemainder();
}
}
for(short i = 0; i < itemContainer.getCapacity() && !ItemStack.isEmpty(remaining); ++i) {
ItemStackSlotTransaction transaction = internal_addToEmptySlot(itemContainer, i, remaining, itemMaxStack, filter);
list.add(transaction);
remaining = transaction.getRemainder();
}
return new ItemStackTransaction(true, ActionType.ADD, itemStack, remaining, allOrNothing, filter, list);
});
}
}
protected static ListTransaction<ItemStackTransaction> internal_addItemStacks(@Nonnull ItemContainer itemContainer, @Nullable List<ItemStack> itemStacks, boolean allOrNothing, boolean fullStacks, boolean filter) {
return itemStacks != null && !itemStacks.isEmpty() ? (ListTransaction)itemContainer.writeAction(() -> {
if (allOrNothing) {
for(ItemStack itemStack : itemStacks) {
int itemMaxStack = itemStack.getItem().getMaxStack();
int testQuantityRemaining = itemStack.getQuantity();
if (!fullStacks) {
testQuantityRemaining = testAddToExistingItemStacks(itemContainer, itemStack, itemMaxStack, testQuantityRemaining, filter);
}
testQuantityRemaining = testAddToEmptySlots(itemContainer, itemStack, itemMaxStack, testQuantityRemaining, filter);
if (testQuantityRemaining > 0) {
return new ListTransaction(false, (List)itemStacks.stream().map((i) -> new ItemStackTransaction(false, ActionType.ADD, itemStack, itemStack, allOrNothing, filter, Collections.emptyList())).collect(Collectors.toList()));
}
}
}
List<ItemStackTransaction> remainingItemStacks = new ObjectArrayList<ItemStackTransaction>();
for(ItemStack itemStack : itemStacks) {
remainingItemStacks.add(internal_addItemStack(itemContainer, itemStack, allOrNothing, fullStacks, filter));
}
return new ListTransaction(true, remainingItemStacks);
}) : ListTransaction.getEmptyTransaction(true);
}
protected static ListTransaction<ItemStackSlotTransaction> internal_addItemStacksOrdered(@Nonnull ItemContainer itemContainer, short offset, @Nullable List<ItemStack> itemStacks, boolean allOrNothing, boolean filter) {
if (itemStacks != null && !itemStacks.isEmpty()) {
ItemContainer.validateSlotIndex(offset, itemContainer.getCapacity());
ItemContainer.validateSlotIndex((short)(offset + itemStacks.size()), itemContainer.getCapacity());
return (ListTransaction)itemContainer.writeAction(() -> {
if (allOrNothing) {
for(short i = 0; i < itemStacks.size(); ++i) {
short slot = (short)(offset + i);
ItemStack itemStack = (ItemStack)itemStacks.get(i);
int itemMaxStack = itemStack.getItem().getMaxStack();
int testQuantityRemaining = itemStack.getQuantity();
testQuantityRemaining = testAddToExistingSlot(itemContainer, slot, itemStack, itemMaxStack, testQuantityRemaining, filter);
if (testQuantityRemaining > 0) {
List<ItemStackSlotTransaction> list = new ObjectArrayList<ItemStackSlotTransaction>();
for(short i1 = 0; i1 < itemStacks.size(); ++i1) {
short islot = (short)(offset + i1);
list.add(new ItemStackSlotTransaction(false, ActionType.ADD, islot, (ItemStack)null, (ItemStack)null, (ItemStack)null, allOrNothing, false, filter, false, itemStack, itemStack));
}
return new ListTransaction(false, list);
}
}
}
List<ItemStackSlotTransaction> remainingItemStacks = new ObjectArrayList<ItemStackSlotTransaction>();
for(short i = 0; i < itemStacks.size(); ++i) {
short slot = (short)(offset + i);
remainingItemStacks.add(internal_addItemStackToSlot(itemContainer, slot, (ItemStack)itemStacks.get(i), allOrNothing, filter));
}
return new ListTransaction(true, remainingItemStacks);
});
} else {
return ListTransaction.<ItemStackSlotTransaction>getEmptyTransaction(true);
}
}
protected static int testAddToExistingItemStacks(@Nonnull ItemContainer container, ItemStack itemStack, int itemMaxStack, int testQuantityRemaining, boolean filter) {
for(short i = 0; i < container.getCapacity() && testQuantityRemaining > 0; ++i) {
testQuantityRemaining = testAddToExistingSlot(container, i, itemStack, itemMaxStack, testQuantityRemaining, filter);
}
return testQuantityRemaining;
}
protected static ItemStackTransaction internal_removeItemStack(@Nonnull ItemContainer itemContainer, @Nonnull ItemStack itemStack, boolean allOrNothing, boolean filter) {
Item item = itemStack.getItem();
if (item == null) {
throw new IllegalArgumentException(itemStack.getItemId() + " is an invalid item!");
} else {
return (ItemStackTransaction)itemContainer.writeAction(() -> {
if (allOrNothing) {
int testQuantityRemaining = testRemoveItemStackFromItems(itemContainer, itemStack, itemStack.getQuantity(), filter);
if (testQuantityRemaining > 0) {
return new ItemStackTransaction(false, ActionType.REMOVE, itemStack, itemStack, allOrNothing, filter, Collections.emptyList());
}
}
List<ItemStackSlotTransaction> transactions = new ObjectArrayList<ItemStackSlotTransaction>();
int quantityRemaining = itemStack.getQuantity();
for(short i = 0; i < itemContainer.getCapacity() && quantityRemaining > 0; ++i) {
ItemStack slotItemStack = itemContainer.internal_getSlot(i);
if (!ItemStack.isEmpty(slotItemStack) && slotItemStack.isStackableWith(itemStack)) {
ItemStackSlotTransaction transaction = internal_removeItemStackFromSlot(itemContainer, i, quantityRemaining, false, filter);
transactions.add(transaction);
quantityRemaining = transaction.getRemainder() != null ? transaction.getRemainder().getQuantity() : 0;
}
}
ItemStack remainder = quantityRemaining > 0 ? itemStack.withQuantity(quantityRemaining) : null;
return new ItemStackTransaction(true, ActionType.REMOVE, itemStack, remainder, allOrNothing, filter, transactions);
});
}
}
protected static ListTransaction<ItemStackTransaction> internal_removeItemStacks(@Nonnull ItemContainer itemContainer, @Nullable List<ItemStack> itemStacks, boolean allOrNothing, boolean filter) {
if (itemStacks != null && !itemStacks.isEmpty()) {
for(ItemStack itemStack : itemStacks) {
Item item = itemStack.getItem();
if (item == null) {
throw new IllegalArgumentException(itemStack.getItemId() + " is an invalid item!");
}
}
return (ListTransaction)itemContainer.writeAction(() -> {
if (allOrNothing) {
for(ItemStack itemStack : itemStacks) {
int testQuantityRemaining = testRemoveItemStackFromItems(itemContainer, itemStack, itemStack.getQuantity(), filter);
if (testQuantityRemaining > 0) {
return new ListTransaction(false, (List)itemStacks.stream().map((ix) -> new ItemStackTransaction(false, ActionType.ADD, itemStack, itemStack, allOrNothing, filter, Collections.emptyList())).collect(Collectors.toList()));
}
}
}
List<ItemStackTransaction> transactions = new ObjectArrayList<ItemStackTransaction>();
for(short i = 0; i < itemStacks.size(); ++i) {
transactions.add(internal_removeItemStack(itemContainer, (ItemStack)itemStacks.get(i), allOrNothing, filter));
}
return new ListTransaction(true, transactions);
});
} else {
return ListTransaction.<ItemStackTransaction>getEmptyTransaction(true);
}
}
protected static int testRemoveItemStackFromItems(@Nonnull ItemContainer container, ItemStack itemStack, int testQuantityRemaining, boolean filter) {
for(short i = 0; i < container.getCapacity() && testQuantityRemaining > 0; ++i) {
if (!filter || !container.cantRemoveFromSlot(i)) {
ItemStack slotItemStack = container.internal_getSlot(i);
if (!ItemStack.isEmpty(slotItemStack) && slotItemStack.isStackableWith(itemStack)) {
int quantity = slotItemStack.getQuantity();
int quantityAdjustment = Math.min(quantity, testQuantityRemaining);
testQuantityRemaining -= quantityAdjustment;
}
}
}
return testQuantityRemaining;
}
protected static TestRemoveItemSlotResult testRemoveItemStackSlotFromItems(@Nonnull ItemContainer container, ItemStack itemStack, int testQuantityRemaining, boolean filter) {
return testRemoveItemStackSlotFromItems(container, itemStack, testQuantityRemaining, filter, (a, b) -> ItemStack.isStackableWith(a, b));
}
protected static TestRemoveItemSlotResult testRemoveItemStackSlotFromItems(@Nonnull ItemContainer container, ItemStack itemStack, int testQuantityRemaining, boolean filter, BiPredicate<ItemStack, ItemStack> predicate) {
TestRemoveItemSlotResult result = new TestRemoveItemSlotResult(testQuantityRemaining);
for(short i = 0; i < container.getCapacity() && result.quantityRemaining > 0; ++i) {
if (!filter || !container.cantRemoveFromSlot(i)) {
ItemStack slotItemStack = container.internal_getSlot(i);
if (!ItemStack.isEmpty(slotItemStack) && predicate.test(slotItemStack, itemStack)) {
int quantity = slotItemStack.getQuantity();
int quantityAdjustment = Math.min(quantity, result.quantityRemaining);
result.quantityRemaining -= quantityAdjustment;
result.picked.put(i, quantityAdjustment);
}
}
}
return result;
}
}