Processing patterns now use the order of items/fluids specified in the pattern.

Cherry picked from bb44bf1633f4986a9400a7eaa55e5d0e96e9989d
This commit is contained in:
Darkere
2021-12-31 16:55:31 +01:00
committed by raoulvdberge
parent 6827b12f4a
commit aa1777d5dc
7 changed files with 67 additions and 47 deletions

View File

@@ -10,6 +10,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Fixed ### Fixed
- Fixed multiple bugs related to transferring recipes into the Crafting Grid. - Fixed multiple bugs related to transferring recipes into the Crafting Grid.
- Processing patterns now use the order of items/fluids specified in the pattern
by [@necauqua](https://github.com/necauqua) and [@Darkere](https://github.com/Darkere).
## [v1.10.0-beta.4] - 2021-12-28 ## [v1.10.0-beta.4] - 2021-12-28

View File

@@ -1,7 +1,6 @@
package com.refinedmods.refinedstorage.api.autocrafting; package com.refinedmods.refinedstorage.api.autocrafting;
import com.refinedmods.refinedstorage.api.util.Action; import com.refinedmods.refinedstorage.api.util.Action;
import com.refinedmods.refinedstorage.api.util.StackListEntry;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@@ -152,7 +151,7 @@ public interface ICraftingPatternContainer {
* @param action action to perform * @param action action to perform
* @return whether insertion was successful * @return whether insertion was successful
*/ */
default boolean insertItemsIntoInventory(Collection<StackListEntry<ItemStack>> toInsert, Action action) { default boolean insertItemsIntoInventory(Collection<ItemStack> toInsert, Action action) {
IItemHandler dest = getConnectedInventory(); IItemHandler dest = getConnectedInventory();
@@ -164,11 +163,10 @@ public interface ICraftingPatternContainer {
return false; return false;
} }
Deque<StackListEntry<ItemStack>> stacks = new ArrayDeque<>(toInsert); Deque<ItemStack> stacks = new ArrayDeque<>(toInsert);
StackListEntry<ItemStack> currentEntry = stacks.poll();
ItemStack current = currentEntry != null ? currentEntry.getStack() : null; ItemStack current = stacks.poll();
List<Integer> availableSlots = IntStream.range(0, dest.getSlots()).boxed().collect(Collectors.toList()); List<Integer> availableSlots = IntStream.range(0, dest.getSlots()).boxed().collect(Collectors.toList());
@@ -189,9 +187,8 @@ public interface ICraftingPatternContainer {
} }
if (remainder.isEmpty()) { // If we inserted successfully, get a next stack. if (remainder.isEmpty()) { // If we inserted successfully, get a next stack.
currentEntry = stacks.poll(); current = stacks.poll();
current = currentEntry != null ? currentEntry.getStack() : null;
} else if (current.getCount() == remainder.getCount()) { // If we didn't insert anything over ALL these slots, stop here. } else if (current.getCount() == remainder.getCount()) { // If we didn't insert anything over ALL these slots, stop here.
break; break;
} else { // If we didn't insert all, continue with other slots and use our remainder. } else { // If we didn't insert all, continue with other slots and use our remainder.
@@ -215,7 +212,7 @@ public interface ICraftingPatternContainer {
* @param action action to perform * @param action action to perform
* @return whether insertion was successful * @return whether insertion was successful
*/ */
default boolean insertFluidsIntoInventory(Collection<StackListEntry<FluidStack>> toInsert, Action action) { default boolean insertFluidsIntoInventory(Collection<FluidStack> toInsert, Action action) {
IFluidHandler dest = getConnectedFluidInventory(); IFluidHandler dest = getConnectedFluidInventory();
if (toInsert.isEmpty()) { if (toInsert.isEmpty()) {
@@ -226,12 +223,12 @@ public interface ICraftingPatternContainer {
return false; return false;
} }
for (StackListEntry<FluidStack> entry : toInsert) { for (FluidStack stack : toInsert) {
int filled = dest.fill(entry.getStack(), action == Action.SIMULATE ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE); int filled = dest.fill(stack, action == Action.SIMULATE ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE);
if (filled != entry.getStack().getAmount()) { if (filled != stack.getAmount()) {
if (action == Action.PERFORM) { if (action == Action.PERFORM) {
LogManager.getLogger().warn("Inventory unexpectedly didn't accept all of {}, the remainder has been voided!", entry.getStack().getTranslationKey()); LogManager.getLogger().warn("Inventory unexpectedly didn't accept all of {}, the remainder has been voided!", stack.getTranslationKey());
} }
return false; return false;

View File

@@ -6,7 +6,6 @@ import com.refinedmods.refinedstorage.api.util.Action;
import com.refinedmods.refinedstorage.api.util.IComparer; import com.refinedmods.refinedstorage.api.util.IComparer;
import com.refinedmods.refinedstorage.api.util.IStackList; import com.refinedmods.refinedstorage.api.util.IStackList;
import com.refinedmods.refinedstorage.api.util.StackListEntry; import com.refinedmods.refinedstorage.api.util.StackListEntry;
import com.refinedmods.refinedstorage.apiimpl.API;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
@@ -19,15 +18,15 @@ public final class IoUtil {
private IoUtil() { private IoUtil() {
} }
public static IStackList<ItemStack> extractFromInternalItemStorage(IStackList<ItemStack> list, IStorageDisk<ItemStack> storage, Action action) { public static List<ItemStack> extractFromInternalItemStorage(List<ItemStack> list, IStorageDisk<ItemStack> storage, Action action) {
IStackList<ItemStack> extracted = API.instance().createItemStackList(); List<ItemStack> extracted = new ArrayList<>();
for (StackListEntry<ItemStack> entry : list.getStacks()) { for (ItemStack stack : list) {
ItemStack result = storage.extract(entry.getStack(), entry.getStack().getCount(), DEFAULT_EXTRACT_FLAGS, action); ItemStack result = storage.extract(stack, stack.getCount(), DEFAULT_EXTRACT_FLAGS, action);
if (result.isEmpty() || result.getCount() != entry.getStack().getCount()) { if (result.isEmpty() || result.getCount() != stack.getCount()) {
if (action == Action.PERFORM) { if (action == Action.PERFORM) {
throw new IllegalStateException("The internal crafting inventory reported that " + entry.getStack() + " was available but we got " + result); throw new IllegalStateException("The internal crafting inventory reported that " + stack + " was available but we got " + result);
} }
return null; return null;
@@ -39,15 +38,15 @@ public final class IoUtil {
return extracted; return extracted;
} }
public static IStackList<FluidStack> extractFromInternalFluidStorage(IStackList<FluidStack> list, IStorageDisk<FluidStack> storage, Action action) { public static List<FluidStack> extractFromInternalFluidStorage(List<FluidStack> list, IStorageDisk<FluidStack> storage, Action action) {
IStackList<FluidStack> extracted = API.instance().createFluidStackList(); List<FluidStack> extracted = new ArrayList<>();
for (StackListEntry<FluidStack> entry : list.getStacks()) { for (FluidStack stack : list) {
FluidStack result = storage.extract(entry.getStack(), entry.getStack().getAmount(), DEFAULT_EXTRACT_FLAGS, action); FluidStack result = storage.extract(stack, stack.getAmount(), DEFAULT_EXTRACT_FLAGS, action);
if (result.isEmpty() || result.getAmount() != entry.getStack().getAmount()) { if (result.isEmpty() || result.getAmount() != stack.getAmount()) {
if (action == Action.PERFORM) { if (action == Action.PERFORM) {
throw new IllegalStateException("The internal crafting inventory reported that " + entry.getStack() + " was available but we got " + result); throw new IllegalStateException("The internal crafting inventory reported that " + stack + " was available but we got " + result);
} }
return null; return null;

View File

@@ -11,12 +11,10 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Iterator; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class NodeRequirements { public class NodeRequirements {
private static final String NBT_ITEMS_TO_USE = "ItemsToUse"; private static final String NBT_ITEMS_TO_USE = "ItemsToUse";
@@ -32,9 +30,9 @@ public class NodeRequirements {
private final Map<Integer, Integer> fluidsNeededPerCraft = new LinkedHashMap<>(); private final Map<Integer, Integer> fluidsNeededPerCraft = new LinkedHashMap<>();
@Nullable @Nullable
private IStackList<ItemStack> cachedSimulatedItemRequirementSet = null; private List<ItemStack> cachedSimulatedItemRequirementSet = null;
@Nullable @Nullable
private IStackList<FluidStack> cachedSimulatedFluidRequirementSet = null; private List<FluidStack> cachedSimulatedFluidRequirementSet = null;
public void addItemRequirement(int ingredientNumber, ItemStack stack, int size, int perCraft) { public void addItemRequirement(int ingredientNumber, ItemStack stack, int size, int perCraft) {
if (!itemsNeededPerCraft.containsKey(ingredientNumber)) { if (!itemsNeededPerCraft.containsKey(ingredientNumber)) {
@@ -56,13 +54,13 @@ public class NodeRequirements {
cachedSimulatedFluidRequirementSet = null; cachedSimulatedFluidRequirementSet = null;
} }
public IStackList<ItemStack> getSingleItemRequirementSet(boolean simulate) { public List<ItemStack> getSingleItemRequirementSet(boolean simulate) {
IStackList<ItemStack> cached = cachedSimulatedItemRequirementSet; List<ItemStack> cached = cachedSimulatedItemRequirementSet;
if (simulate && cached != null) { if (simulate && cached != null) {
return cached; return cached;
} }
IStackList<ItemStack> toReturn = API.instance().createItemStackList(); List<ItemStack> toReturn = new ArrayList<>();
for (int i = 0; i < itemRequirements.size(); i++) { for (int i = 0; i < itemRequirements.size(); i++) {
int needed = itemsNeededPerCraft.get(i); int needed = itemsNeededPerCraft.get(i);
@@ -78,7 +76,7 @@ public class NodeRequirements {
itemRequirements.get(i).remove(toUse, needed); itemRequirements.get(i).remove(toUse, needed);
} }
toReturn.add(toUse, needed); toReturn.add(ItemHandlerHelper.copyStackWithSize(toUse, needed));
needed = 0; needed = 0;
} else { } else {
@@ -101,13 +99,13 @@ public class NodeRequirements {
return toReturn; return toReturn;
} }
public IStackList<FluidStack> getSingleFluidRequirementSet(boolean simulate) { public List<FluidStack> getSingleFluidRequirementSet(boolean simulate) {
IStackList<FluidStack> cached = cachedSimulatedFluidRequirementSet; List<FluidStack> cached = cachedSimulatedFluidRequirementSet;
if (simulate && cached != null) { if (simulate && cached != null) {
return cached; return cached;
} }
IStackList<FluidStack> toReturn = API.instance().createFluidStackList(); List<FluidStack> toReturn = new ArrayList<>();
for (int i = 0; i < fluidRequirements.size(); i++) { for (int i = 0; i < fluidRequirements.size(); i++) {
int needed = fluidsNeededPerCraft.get(i); int needed = fluidsNeededPerCraft.get(i);
@@ -123,7 +121,9 @@ public class NodeRequirements {
fluidRequirements.get(i).remove(toUse, needed); fluidRequirements.get(i).remove(toUse, needed);
} }
toReturn.add(toUse, needed); FluidStack stack = toUse.copy();
stack.setAmount(needed);
toReturn.add(stack);
needed = 0; needed = 0;
} else { } else {

View File

@@ -11,11 +11,15 @@ import com.refinedmods.refinedstorage.api.util.StackListEntry;
import com.refinedmods.refinedstorage.apiimpl.API; import com.refinedmods.refinedstorage.apiimpl.API;
import com.refinedmods.refinedstorage.apiimpl.autocrafting.task.v6.IoUtil; import com.refinedmods.refinedstorage.apiimpl.autocrafting.task.v6.IoUtil;
import com.refinedmods.refinedstorage.apiimpl.autocrafting.task.v6.SerializationUtil; import com.refinedmods.refinedstorage.apiimpl.autocrafting.task.v6.SerializationUtil;
import com.refinedmods.refinedstorage.apiimpl.util.FluidStackList;
import com.refinedmods.refinedstorage.apiimpl.util.ItemStackList;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import java.util.List;
public class ProcessingNode extends Node { public class ProcessingNode extends Node {
private static final String NBT_ITEMS_RECEIVED = "ItemsReceived"; private static final String NBT_ITEMS_RECEIVED = "ItemsReceived";
private static final String NBT_FLUIDS_RECEIVED = "FluidsReceived"; private static final String NBT_FLUIDS_RECEIVED = "FluidsReceived";
@@ -117,8 +121,8 @@ public class ProcessingNode extends Node {
boolean hasAllRequirements = false; boolean hasAllRequirements = false;
IStackList<ItemStack> extractedItems = IoUtil.extractFromInternalItemStorage(requirements.getSingleItemRequirementSet(true), internalStorage, Action.SIMULATE); List<ItemStack> extractedItems = IoUtil.extractFromInternalItemStorage(requirements.getSingleItemRequirementSet(true), internalStorage, Action.SIMULATE);
IStackList<FluidStack> extractedFluids = null; List<FluidStack> extractedFluids = null;
if (extractedItems != null) { if (extractedItems != null) {
extractedFluids = IoUtil.extractFromInternalFluidStorage(requirements.getSingleFluidRequirementSet(true), internalFluidStorage, Action.SIMULATE); extractedFluids = IoUtil.extractFromInternalFluidStorage(requirements.getSingleFluidRequirementSet(true), internalFluidStorage, Action.SIMULATE);
if (extractedFluids != null) { if (extractedFluids != null) {
@@ -128,9 +132,9 @@ public class ProcessingNode extends Node {
boolean canInsertFullAmount = false; boolean canInsertFullAmount = false;
if (hasAllRequirements) { if (hasAllRequirements) {
canInsertFullAmount = container.insertItemsIntoInventory(extractedItems.getStacks(), Action.SIMULATE); canInsertFullAmount = container.insertItemsIntoInventory(extractedItems, Action.SIMULATE);
if (canInsertFullAmount) { if (canInsertFullAmount) {
canInsertFullAmount = container.insertFluidsIntoInventory(extractedFluids.getStacks(), Action.SIMULATE); canInsertFullAmount = container.insertFluidsIntoInventory(extractedFluids, Action.SIMULATE);
} }
} else { } else {
break; break;
@@ -151,8 +155,8 @@ public class ProcessingNode extends Node {
extractedItems = IoUtil.extractFromInternalItemStorage(requirements.getSingleItemRequirementSet(false), internalStorage, Action.PERFORM); extractedItems = IoUtil.extractFromInternalItemStorage(requirements.getSingleItemRequirementSet(false), internalStorage, Action.PERFORM);
extractedFluids = IoUtil.extractFromInternalFluidStorage(requirements.getSingleFluidRequirementSet(false), internalFluidStorage, Action.PERFORM); extractedFluids = IoUtil.extractFromInternalFluidStorage(requirements.getSingleFluidRequirementSet(false), internalFluidStorage, Action.PERFORM);
container.insertItemsIntoInventory(extractedItems.getStacks(), Action.PERFORM); container.insertItemsIntoInventory(extractedItems, Action.PERFORM);
container.insertFluidsIntoInventory(extractedFluids.getStacks(), Action.PERFORM); container.insertFluidsIntoInventory(extractedFluids, Action.PERFORM);
next(); next();
@@ -249,8 +253,8 @@ public class ProcessingNode extends Node {
public void onCalculationFinished() { public void onCalculationFinished() {
super.onCalculationFinished(); super.onCalculationFinished();
this.singleItemSetToRequire = requirements.getSingleItemRequirementSet(true); this.singleItemSetToRequire = new ItemStackList(requirements.getSingleItemRequirementSet(true));
this.singleFluidSetToRequire = requirements.getSingleFluidRequirementSet(true); this.singleFluidSetToRequire = new FluidStackList(requirements.getSingleFluidRequirementSet(true));
} }
@Override @Override

View File

@@ -19,6 +19,15 @@ public class FluidStackList implements IStackList<FluidStack> {
private final ArrayListMultimap<Fluid, StackListEntry<FluidStack>> stacks = ArrayListMultimap.create(); private final ArrayListMultimap<Fluid, StackListEntry<FluidStack>> stacks = ArrayListMultimap.create();
private final Map<UUID, FluidStack> index = new HashMap<>(); private final Map<UUID, FluidStack> index = new HashMap<>();
public FluidStackList() {
}
public FluidStackList(Iterable<FluidStack> stacks) {
for (FluidStack stack : stacks) {
add(stack);
}
}
@Override @Override
public StackListResult<FluidStack> add(@Nonnull FluidStack stack, int size) { public StackListResult<FluidStack> add(@Nonnull FluidStack stack, int size) {
if (stack.isEmpty() || size <= 0) { if (stack.isEmpty() || size <= 0) {

View File

@@ -20,6 +20,15 @@ public class ItemStackList implements IStackList<ItemStack> {
private final ArrayListMultimap<Item, StackListEntry<ItemStack>> stacks = ArrayListMultimap.create(); private final ArrayListMultimap<Item, StackListEntry<ItemStack>> stacks = ArrayListMultimap.create();
private final Map<UUID, ItemStack> index = new HashMap<>(); private final Map<UUID, ItemStack> index = new HashMap<>();
public ItemStackList() {
}
public ItemStackList(Iterable<ItemStack> stacks) {
for (ItemStack stack : stacks) {
add(stack);
}
}
@Override @Override
public StackListResult<ItemStack> add(@Nonnull ItemStack stack, int size) { public StackListResult<ItemStack> add(@Nonnull ItemStack stack, int size) {
if (stack.isEmpty() || size <= 0) { if (stack.isEmpty() || size <= 0) {