diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEFluidHandler.java b/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEFluidHandler.java index 91c2f121b..e60b75add 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEFluidHandler.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEFluidHandler.java @@ -40,11 +40,11 @@ public int fill(FluidStack resource, FluidAction action) { @NotNull @Override - public FluidStack drain(FluidFilter filter, FluidAction simulate) { + public FluidStack drain(FluidFilter filter, int count, FluidAction simulate) { Pair fluidKey = AEApi.findAEFluidFromFilter(storageMonitor, null, filter); if (fluidKey.getRight() == null) return FluidStack.EMPTY; - long extracted = storageMonitor.extract(fluidKey.getRight(), filter.getCount(), simulate == FluidAction.SIMULATE ? Actionable.SIMULATE : Actionable.MODULATE, actionSource); + long extracted = storageMonitor.extract(fluidKey.getRight(), count, simulate == FluidAction.SIMULATE ? Actionable.SIMULATE : Actionable.MODULATE, actionSource); return new FluidStack(fluidKey.getRight().getFluid(), (int) Math.min(extracted, Integer.MAX_VALUE)); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEItemHandler.java b/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEItemHandler.java index bc34d07f4..1cac91a3e 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEItemHandler.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MEItemHandler.java @@ -45,7 +45,7 @@ public ItemStack extractItem(ItemFilter filter, int count, boolean simulate) { if (itemKey.getRight() == null) return ItemStack.EMPTY; long extracted = storageMonitor.extract(itemKey.getRight(), count, simulate ? Actionable.SIMULATE : Actionable.MODULATE, actionSource); - // Safe to cast here, the amount will never be higher than 64 + // Safe to cast here, the amount will never be higher than count ItemStack stack = itemKey.getRight().toStack(); stack.setCount((int) extracted); return stack; diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSFluidHandler.java b/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSFluidHandler.java index e0fb3362e..0d5e262ee 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSFluidHandler.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSFluidHandler.java @@ -33,13 +33,13 @@ public int fill(FluidStack resource, @NotNull FluidAction action) { @NotNull @Override - public FluidStack drain(FluidFilter filter, FluidAction simulate) { + public FluidStack drain(FluidFilter filter, int count, FluidAction simulate) { AdvancedPeripherals.debug("Trying to extract fluid from filter: " + filter); FluidResource fluid = RSApi.getFluid(network, filter); if (fluid == null) return FluidStack.EMPTY; - long amountExtracted = component.extract(fluid, filter.getCount(), simulate == FluidAction.SIMULATE ? Action.SIMULATE : Action.EXECUTE, Actor.EMPTY); + long amountExtracted = component.extract(fluid, count, simulate == FluidAction.SIMULATE ? Action.SIMULATE : Action.EXECUTE, Actor.EMPTY); FluidStack extracted = VariantUtil.toFluidStack(fluid, (int) amountExtracted); AdvancedPeripherals.debug("Extracted fluid: " + extracted + " from filter: " + filter); diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ChemicalUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ChemicalUtil.java index 962187060..20aeafeb5 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ChemicalUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ChemicalUtil.java @@ -27,61 +27,73 @@ public class ChemicalUtil { public static long moveChemical(IChemicalHandler inventoryFrom, IChemicalHandler inventoryTo, ChemicalFilter filter) { if (inventoryFrom == null) return 0; - long amount = filter.getCount(); - long transferableAmount = 0; + int fromSlot = filter.getFromSlot(); + int toSlot = filter.getToSlot(); - // The logic changes with storage systems since these systems do not have slots + long transferred = 0; + + // The logic changes when exporting from storage systems since these systems do not have slots if (inventoryFrom instanceof IStorageSystemChemicalHandler storageSystemHandler) { - ChemicalStack extracted = storageSystemHandler.extractChemical(filter, amount, Action.SIMULATE); - amount = Math.min(amount, extracted.getAmount()); - if (amount > 0) { + if (toSlot < -1 || toSlot >= inventoryTo.getChemicalTanks()) + return 0; + for (int i = toSlot == -1 ? 0 : toSlot; i < (toSlot == -1 ? inventoryTo.getChemicalTanks() : toSlot + 1); i++) { + ChemicalStack existing = inventoryTo.getChemicalInTank(i); + ChemicalStack extracted; + if (existing.isEmpty()) { + extracted = storageSystemHandler.extractChemical(filter, filter.getCount() - transferred, Action.SIMULATE); + } else { // If chemical already exists in tank, try to export same type of chemical + extracted = storageSystemHandler.extractChemical(ChemicalFilter.fromStack(existing), filter.getCount() - transferred, Action.SIMULATE); + if (!filter.test(extracted)) + extracted = ChemicalStack.EMPTY; + } + if (extracted.isEmpty()) + continue; ChemicalStack remaining; - int toSlot = filter.getToSlot(); - if (toSlot >= 0) { - remaining = inventoryTo.insertChemical(toSlot, extracted, Action.EXECUTE); - } else { + if (toSlot == -1) { // Try to use this chemical handler's distribution remaining = inventoryTo.insertChemical(extracted, Action.EXECUTE); + } else { + remaining = inventoryTo.insertChemical(i, extracted, Action.EXECUTE); } - amount -= remaining.getAmount(); + transferred += storageSystemHandler.extractChemical(ChemicalFilter.fromStack(extracted), extracted.getAmount() - remaining.getAmount(), Action.EXECUTE).getAmount(); + if (transferred >= filter.getCount()) + break; } - if (amount > 0) { - transferableAmount += storageSystemHandler.extractChemical(filter, amount, Action.EXECUTE).getAmount(); - } - return transferableAmount; + return transferred; } - if (inventoryTo instanceof IStorageSystemChemicalHandler storageSystemHandler) { - int fromSlot = filter.getFromSlot(); - if (fromSlot >= 0) { - transferableAmount = importChemical(inventoryFrom, filter, storageSystemHandler, amount, fromSlot); - } else { - int tanks = inventoryFrom.getChemicalTanks(); - for (int i = 0; amount > 0 && i < tanks; i++) { - long imported = importChemical(inventoryFrom, filter, storageSystemHandler, amount, i); - transferableAmount += imported; - amount -= imported; + if (fromSlot < -1 || fromSlot >= inventoryFrom.getChemicalTanks()) + return 0; + for (int i = fromSlot == -1 ? 0 : fromSlot; i < (fromSlot == -1 ? inventoryFrom.getChemicalTanks() : fromSlot + 1); i++) { + if (filter.test(inventoryFrom.getChemicalInTank(i))) { + ChemicalStack extracted; + if (fromSlot == -1) { // Try to use this chemical handler's distribution + ChemicalStack toExtract = inventoryFrom.getChemicalInTank(i).copyWithAmount(filter.getCount() - transferred); + extracted = inventoryFrom.extractChemical(toExtract, Action.SIMULATE); + } else { + extracted = inventoryFrom.extractChemical(i, filter.getCount() - transferred, Action.SIMULATE); } - } - return transferableAmount; - } + if (extracted.isEmpty()) + continue; - return transferableAmount; - } + ChemicalStack remaining; + if (toSlot == -1 && !(inventoryTo instanceof IStorageSystemItemHandler)) { // Try to use this chemical handler's distribution + remaining = inventoryTo.insertChemical(extracted, Action.EXECUTE); + } else { + remaining = inventoryTo.insertChemical(toSlot, extracted, Action.EXECUTE); // toSlot is ignored for storage systems + } - private static long importChemical(IChemicalHandler inventoryFrom, ChemicalFilter filter, IStorageSystemChemicalHandler storageSystemHandler, long amount, int tank) { - long transferableAmount = 0; - ChemicalStack chemicalInTank = inventoryFrom.getChemicalInTank(tank); - if (filter.test(chemicalInTank)) { - ChemicalStack extracted = inventoryFrom.extractChemical(tank, amount, Action.SIMULATE); - if (!extracted.isEmpty()) { - long remaining = storageSystemHandler.insertChemical(extracted, Action.EXECUTE).getAmount(); - long extracting = extracted.getAmount() - remaining; - if (extracting > 0) { - transferableAmount += inventoryFrom.extractChemical(tank, extracting, Action.EXECUTE).getAmount(); + if (fromSlot == -1) { // Try to use this chemical handler's distribution + extracted.setAmount(extracted.getAmount() - remaining.getAmount()); + transferred += inventoryFrom.extractChemical(extracted, Action.EXECUTE).getAmount(); + } else { + transferred += inventoryFrom.extractChemical(i, filter.getCount() - remaining.getAmount(), Action.EXECUTE).getAmount(); } + if (transferred >= filter.getCount()) + break; } } - return transferableAmount; + return transferred; + } public static IChemicalHandler extractHandler(@Nullable Object object, @Nullable Level level, @Nullable BlockPos pos, @Nullable Direction direction) { diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java index 9463c7939..b01e07a92 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java @@ -29,36 +29,44 @@ private FluidUtil() { public static int moveFluid(IFluidHandler inventoryFrom, IFluidHandler inventoryTo, FluidFilter filter) { if (inventoryFrom == null) return 0; - int amount = filter.getCount(); - int transferableAmount = 0; + int transferred = 0; - // The logic changes with storage systems since these systems do not have slots + // The logic changes when exporting from storage systems since these systems do not have slots if (inventoryFrom instanceof IStorageSystemFluidHandler storageSystemHandler) { - FluidStack extracted = storageSystemHandler.drain(filter, IFluidHandler.FluidAction.SIMULATE); - int inserted = inventoryTo.fill(extracted, IFluidHandler.FluidAction.EXECUTE); - - transferableAmount += storageSystemHandler.drain(filter.setCount(inserted), IFluidHandler.FluidAction.EXECUTE).getAmount(); - - return transferableAmount; + for (int i = 0; i < inventoryTo.getTanks(); i++) { + FluidStack existing = inventoryTo.getFluidInTank(i); + FluidStack extracted; + if (existing.isEmpty()) { + extracted = storageSystemHandler.drain(filter, filter.getCount() - transferred, IFluidHandler.FluidAction.SIMULATE); + } else { // If fluid already exists in tank, try to export same type of fluid + extracted = storageSystemHandler.drain(FluidFilter.fromStack(existing), filter.getCount() - transferred, IFluidHandler.FluidAction.SIMULATE); + if (!filter.test(extracted)) + extracted = FluidStack.EMPTY; + } + if (extracted.isEmpty()) + continue; + int inserted = inventoryTo.fill(extracted, IFluidHandler.FluidAction.EXECUTE); + transferred += storageSystemHandler.drain(FluidFilter.fromStack(extracted), inserted, IFluidHandler.FluidAction.EXECUTE).getAmount(); + if (transferred >= filter.getCount()) + break; + } + return transferred; } - if (inventoryTo instanceof IStorageSystemFluidHandler storageSystemHandler) { - if (filter.test(inventoryFrom.getFluidInTank(0))) { - FluidStack toExtract = inventoryFrom.getFluidInTank(0).copy(); - toExtract.setAmount(amount); + for (int i = 0; i < inventoryFrom.getTanks(); i++) { + if (filter.test(inventoryFrom.getFluidInTank(i))) { + FluidStack toExtract = inventoryFrom.getFluidInTank(i).copyWithAmount(filter.getCount() - transferred); FluidStack extracted = inventoryFrom.drain(toExtract, IFluidHandler.FluidAction.SIMULATE); if (extracted.isEmpty()) - return 0; - int inserted = storageSystemHandler.fill(extracted, IFluidHandler.FluidAction.EXECUTE); - + continue; + int inserted = inventoryTo.fill(extracted, IFluidHandler.FluidAction.EXECUTE); extracted.setAmount(inserted); - transferableAmount += inventoryFrom.drain(extracted, IFluidHandler.FluidAction.EXECUTE).getAmount(); + transferred += inventoryFrom.drain(extracted, IFluidHandler.FluidAction.EXECUTE).getAmount(); + if (transferred >= filter.getCount()) + break; } - - return transferableAmount; } - - return transferableAmount; + return transferred; } public static IFluidHandler extractHandler(@Nullable Object object, @Nullable Level level, @Nullable BlockPos pos, @Nullable Direction direction) { diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/IStorageSystemFluidHandler.java b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/IStorageSystemFluidHandler.java index 183f3e9fd..9dca24c4b 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/IStorageSystemFluidHandler.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/IStorageSystemFluidHandler.java @@ -17,7 +17,7 @@ public interface IStorageSystemFluidHandler extends IFluidHandler { * @return extracted from the slot, must be empty if nothing can be extracted. The returned ItemStack can be safely modified after, so item handlers should return a new or copied stack. */ @NotNull - FluidStack drain(FluidFilter filter, FluidAction simulate); + FluidStack drain(FluidFilter filter, int count, FluidAction simulate); @Override default int getTanks() { diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/InventoryUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/InventoryUtil.java index e8a6fb7a1..4fe207842 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/InventoryUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/InventoryUtil.java @@ -46,64 +46,51 @@ public static int moveItem(IItemHandler inventoryFrom, IItemHandler inventoryTo, int fromSlot = filter.getFromSlot(); int toSlot = filter.getToSlot(); - int amount = filter.getCount(); - int transferableAmount = 0; + int transferred = 0; - // The logic changes with storage systems since these systems do not have slots + // The logic changes when exporting from storage systems since these systems do not have slots if (inventoryFrom instanceof IStorageSystemItemHandler storageSystemHandler) { + if (toSlot < -1 || toSlot >= inventoryTo.getSlots()) + return 0; for (int i = toSlot == -1 ? 0 : toSlot; i < (toSlot == -1 ? inventoryTo.getSlots() : toSlot + 1); i++) { - ItemStack extracted = storageSystemHandler.extractItem(filter, filter.getCount(), true); + ItemStack existing = inventoryTo.getStackInSlot(i); + ItemStack extracted; + if (existing.isEmpty()) { + extracted = storageSystemHandler.extractItem(filter, filter.getCount() - transferred, true); + } else { // If item already exists in slot, try to export same type of item + extracted = storageSystemHandler.extractItem(ItemFilter.fromStack(existing), filter.getCount() - transferred, true); + if (!filter.test(extracted)) + extracted = ItemStack.EMPTY; + } if (extracted.isEmpty()) continue; - ItemStack inserted; - if (toSlot == -1) { - inserted = ItemHandlerHelper.insertItem(inventoryTo, extracted, false); - } else { - inserted = inventoryTo.insertItem(toSlot, extracted, false); - } - amount -= extracted.getCount() - inserted.getCount(); - transferableAmount += storageSystemHandler.extractItem(filter, extracted.getCount() - inserted.getCount(), false).getCount(); - if (transferableAmount >= filter.getCount()) + ItemStack remaining = inventoryTo.insertItem(i, extracted, false); + transferred += storageSystemHandler.extractItem(ItemFilter.fromStack(extracted), extracted.getCount() - remaining.getCount(), false).getCount(); + if (transferred >= filter.getCount()) break; } - return transferableAmount; - } - - if (inventoryTo instanceof IStorageSystemItemHandler storageSystemHandler) { - for (int i = fromSlot == -1 ? 0 : fromSlot; i < (fromSlot == -1 ? inventoryFrom.getSlots() : fromSlot + 1); i++) { - if (filter.test(inventoryFrom.getStackInSlot(i))) { - ItemStack extracted = inventoryFrom.extractItem(i, amount - transferableAmount, true); - if (extracted.isEmpty()) - continue; - ItemStack remaining = storageSystemHandler.insertItem(toSlot, extracted, false); - - amount -= remaining.getCount(); - transferableAmount += inventoryFrom.extractItem(i, extracted.getCount() - remaining.getCount(), false).getCount(); - if (transferableAmount >= filter.getCount()) - break; - } - } - return transferableAmount; + return transferred; } + if (fromSlot < -1 || fromSlot >= inventoryFrom.getSlots()) + return 0; for (int i = fromSlot == -1 ? 0 : fromSlot; i < (fromSlot == -1 ? inventoryFrom.getSlots() : fromSlot + 1); i++) { if (filter.test(inventoryFrom.getStackInSlot(i))) { - ItemStack extracted = inventoryFrom.extractItem(i, amount - transferableAmount, true); + ItemStack extracted = inventoryFrom.extractItem(i, filter.getCount() - transferred, true); if (extracted.isEmpty()) continue; - ItemStack inserted; - if (toSlot == -1) { - inserted = ItemHandlerHelper.insertItem(inventoryTo, extracted, false); + ItemStack remaining; + if (toSlot == -1 && !(inventoryTo instanceof IStorageSystemItemHandler)) { + remaining = ItemHandlerHelper.insertItem(inventoryTo, extracted, false); } else { - inserted = inventoryTo.insertItem(toSlot, extracted, false); + remaining = inventoryTo.insertItem(toSlot, extracted, false); // toSlot is ignored for storage systems } - amount -= inserted.getCount(); - transferableAmount += inventoryFrom.extractItem(i, extracted.getCount() - inserted.getCount(), false).getCount(); - if (transferableAmount >= filter.getCount()) + transferred += inventoryFrom.extractItem(i, extracted.getCount() - remaining.getCount(), false).getCount(); + if (transferred >= filter.getCount()) break; } } - return transferableAmount; + return transferred; } @Nullable