fixed recipes with crafting dependencies not waiting for them before emitting a redstone signal

This commit is contained in:
Ell 2024-12-03 23:59:50 +01:00
parent 1d05d1c906
commit 1d6272b574
2 changed files with 17 additions and 7 deletions

View file

@ -17,18 +17,19 @@ public class ActiveCraft implements INBTSerializable<CompoundTag> {
public BlockPos pipe;
public int moduleSlot;
public List<ItemStack> travelingIngredients = new ArrayList<>();
public List<NetworkLock> ingredientsToRequest;
public List<ItemStack> travelingIngredients;
public BlockPos resultDestPipe;
public ItemStack resultStackRemain;
public boolean inProgress;
// we only remove canceled requests from the queue once their items are fully delivered to the crafting location, so that unfinished recipes don't get stuck in crafters etc.
public boolean canceled;
public ActiveCraft(BlockPos pipe, int moduleSlot, List<NetworkLock> ingredientsToRequest, BlockPos resultDestPipe, ItemStack resultStackRemain) {
public ActiveCraft(BlockPos pipe, int moduleSlot, List<NetworkLock> ingredientsToRequest, List<ItemStack> travelingIngredients, BlockPos resultDestPipe, ItemStack resultStackRemain) {
this.pipe = pipe;
this.moduleSlot = moduleSlot;
this.ingredientsToRequest = ingredientsToRequest;
this.travelingIngredients = travelingIngredients;
this.resultDestPipe = resultDestPipe;
this.resultStackRemain = resultStackRemain;
}

View file

@ -177,23 +177,29 @@ public class CraftingModuleItem extends ModuleItem {
var allCrafts = new ArrayList<ActiveCraft>();
// if we're ensuring item order, all items for a single recipe should be sent in order first before starting on the next one!
for (var c = contents.ensureItemOrder ? toCraft : 1; c > 0; c--) {
var crafts = new ArrayList<ItemStack>();
var locks = new ArrayList<NetworkLock>();
for (var i = 0; i < contents.input.getSlots(); i++) {
var in = contents.input.getStackInSlot(i);
if (in.isEmpty())
continue;
var copy = in.copy();
var request = in.copy();
if (!contents.ensureItemOrder)
copy.setCount(in.getCount() * toCraft);
var ret = network.requestLocksAndStartCrafting(tile.getBlockPos(), items, unavailableConsumer, copy, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes);
request.setCount(in.getCount() * toCraft);
var ret = network.requestLocksAndStartCrafting(tile.getBlockPos(), items, unavailableConsumer, request, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes);
// set crafting dependencies as in progress immediately so that, when canceling, they don't leave behind half-crafted inbetween dependencies
// TODO to be more optimal, we should really do this when setting the main craft as in progress, but that would require storing references to all of the dependencies
ret.getRight().forEach(a -> a.inProgress = true);
locks.addAll(ret.getLeft());
allCrafts.addAll(ret.getRight());
// the items we started crafting are the ones we didn't request normally (ie ones we didn't create locks for)
var startedCrafting = request.copyWithCount(request.getCount() - ret.getLeft().stream().mapToInt(l -> l.stack.getCount()).sum());
if (!startedCrafting.isEmpty())
crafts.add(startedCrafting);
}
var crafted = contents.ensureItemOrder ? resultAmount : resultAmount * toCraft;
var activeCraft = new ActiveCraft(tile.getBlockPos(), slot, locks, destPipe, stack.copyWithCount(Math.min(crafted, leftOfRequest)));
// items we started craft dependencies for are ones that will be sent to us (so we're waiting for them immediately!)
var activeCraft = new ActiveCraft(tile.getBlockPos(), slot, locks, crafts, destPipe, stack.copyWithCount(Math.min(crafted, leftOfRequest)));
tile.getActiveCrafts().add(activeCraft);
allCrafts.add(activeCraft);
leftOfRequest -= crafted;
@ -211,7 +217,10 @@ public class CraftingModuleItem extends ModuleItem {
var equalityTypes = ItemFilter.getEqualityTypes(tile);
var allCrafts = tile.getActiveCrafts();
for (var craft : allCrafts.stream().filter(c -> c.moduleSlot == slot && !c.getTravelingIngredient(stack, equalityTypes).isEmpty()).toList()) {
craft.travelingIngredients.remove(craft.getTravelingIngredient(stack, equalityTypes));
var traveling = craft.getTravelingIngredient(stack, equalityTypes);
traveling.shrink(stack.getCount());
if (traveling.isEmpty())
craft.travelingIngredients.remove(traveling);
if (contents.insertSingles) {
var handler = tile.getItemHandler(direction);