diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index c3af28a..1f822f6 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -284,7 +284,7 @@ public class PipeNetwork extends SavedData implements GraphListener craftIngredientRequests = new LinkedList<>(); - public final List> craftResultRequests = new ArrayList<>(); + // crafting module slot, ingredient request network lock + public final Queue> craftIngredientRequests = new LinkedList<>(); + // crafting module slot, destination pipe for the result, result item + public final List> craftResultRequests = new ArrayList<>(); public PressurizerBlockEntity pressurizer; public BlockState cover; public int moduleDropCheck; @@ -97,13 +101,21 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC super.saveAdditional(compound, provider); compound.put("modules", this.modules.serializeNBT(provider)); compound.putInt("module_drop_check", this.moduleDropCheck); - compound.put("requests", Utility.serializeAll(provider, this.craftIngredientRequests)); + var requests = new ListTag(); + for (var tuple : this.craftIngredientRequests) { + var nbt = new CompoundTag(); + nbt.putInt("module_slot", tuple.getLeft()); + nbt.put("lock", tuple.getRight().serializeNBT(provider)); + requests.add(nbt); + } + compound.put("craft_requests", requests); if (this.cover != null) compound.put("cover", NbtUtils.writeBlockState(this.cover)); var results = new ListTag(); for (var triple : this.craftResultRequests) { var nbt = new CompoundTag(); - nbt.putLong("dest_pipe", triple.getLeft().asLong()); + nbt.putInt("module_slot", triple.getLeft()); + nbt.putLong("dest_pipe", triple.getMiddle().asLong()); nbt.put("item", triple.getRight().save(provider)); results.add(nbt); } @@ -116,12 +128,19 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC this.moduleDropCheck = compound.getInt("module_drop_check"); this.cover = compound.contains("cover") ? NbtUtils.readBlockState(this.level != null ? this.level.holderLookup(Registries.BLOCK) : BuiltInRegistries.BLOCK.asLookup(), compound.getCompound("cover")) : null; this.craftIngredientRequests.clear(); - this.craftIngredientRequests.addAll(Utility.deserializeAll(compound.getList("requests", Tag.TAG_COMPOUND), l -> new NetworkLock(provider, l))); + var requests = compound.getList("craft_requests", Tag.TAG_COMPOUND); + for (var i = 0; i < requests.size(); i++) { + var nbt = requests.getCompound(i); + this.craftIngredientRequests.add(Pair.of( + nbt.getInt("module_slot"), + new NetworkLock(provider, nbt.getCompound("lock")))); + } this.craftResultRequests.clear(); var results = compound.getList("craft_results", Tag.TAG_COMPOUND); for (var i = 0; i < results.size(); i++) { var nbt = results.getCompound(i); - this.craftResultRequests.add(Pair.of( + this.craftResultRequests.add(Triple.of( + nbt.getInt("module_slot"), BlockPos.of(nbt.getLong("dest_pipe")), ItemStack.parseOptional(provider, nbt.getCompound("item")))); } @@ -359,6 +378,14 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC return builder.build(); } + public int getModuleSlot(ItemStack module) { + for (var i = 0; i < this.modules.getSlots(); i++) { + if (this.modules.getStackInSlot(i) == module) + return i; + } + return -1; + } + public void removeCover(Player player, InteractionHand hand) { if (this.level.isClientSide) return; diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java index da8c7e3..d63f2d8 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java @@ -25,6 +25,7 @@ import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.items.IItemHandler; import net.neoforged.neoforge.items.ItemStackHandler; import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; import java.util.ArrayList; import java.util.List; @@ -69,25 +70,29 @@ public class CraftingModuleItem extends ModuleItem { public void tick(ItemStack module, PipeBlockEntity tile) { if (!tile.shouldWorkNow(this.speed) || !tile.canWork()) return; + var slot = tile.getModuleSlot(module); var network = PipeNetwork.get(tile.getLevel()); // process crafting ingredient requests if (!tile.craftIngredientRequests.isEmpty()) { network.startProfile("crafting_ingredients"); var request = tile.craftIngredientRequests.peek(); - var equalityTypes = ItemFilter.getEqualityTypes(tile); - var dest = tile.getAvailableDestination(Direction.values(), request.stack, true, true); - if (dest != null) { - var requestRemain = network.requestExistingItem(request.location, tile.getBlockPos(), dest.getLeft(), request, dest.getRight(), equalityTypes); - network.resolveNetworkLock(request); - tile.craftIngredientRequests.remove(); + if (request.getLeft() == slot) { + var lock = request.getRight(); + var equalityTypes = ItemFilter.getEqualityTypes(tile); + var dest = tile.getAvailableDestination(Direction.values(), lock.stack, true, true); + if (dest != null) { + var requestRemain = network.requestExistingItem(lock.location, tile.getBlockPos(), dest.getLeft(), lock, dest.getRight(), equalityTypes); + network.resolveNetworkLock(lock); + tile.craftIngredientRequests.remove(); - // if we couldn't fit all items into the destination, create another request for the rest - var remain = request.stack.copy(); - remain.shrink(dest.getRight().getCount() - requestRemain.getCount()); - if (!remain.isEmpty()) { - var remainRequest = new NetworkLock(request.location, remain); - tile.craftIngredientRequests.add(remainRequest); - network.createNetworkLock(remainRequest); + // if we couldn't fit all items into the destination, create another request for the rest + var remain = lock.stack.copy(); + remain.shrink(dest.getRight().getCount() - requestRemain.getCount()); + if (!remain.isEmpty()) { + var remainRequest = new NetworkLock(lock.location, remain); + tile.craftIngredientRequests.add(Pair.of(slot, remainRequest)); + network.createNetworkLock(remainRequest); + } } } network.endProfile(); @@ -98,25 +103,27 @@ public class CraftingModuleItem extends ModuleItem { var items = network.getOrderedNetworkItems(tile.getBlockPos()); var equalityTypes = ItemFilter.getEqualityTypes(tile); for (var request : tile.craftResultRequests) { - var remain = request.getRight().copy(); - var destPipe = network.getPipe(request.getLeft()); - if (destPipe != null) { - var dest = destPipe.getAvailableDestinationOrConnectable(remain, true, true); - if (dest == null) - continue; - for (var item : items) { - var requestRemain = network.requestExistingItem(item, request.getLeft(), dest.getLeft(), null, dest.getRight(), equalityTypes); - remain.shrink(dest.getRight().getCount() - requestRemain.getCount()); - if (remain.isEmpty()) - break; - } - if (remain.getCount() != request.getRight().getCount()) { - tile.craftResultRequests.remove(request); - // if we couldn't pull everything, log a new request - if (!remain.isEmpty()) - tile.craftResultRequests.add(Pair.of(request.getLeft(), remain)); - network.endProfile(); - return; + if (request.getLeft() == slot) { + var remain = request.getRight().copy(); + var destPipe = network.getPipe(request.getMiddle()); + if (destPipe != null) { + var dest = destPipe.getAvailableDestinationOrConnectable(remain, true, true); + if (dest == null) + continue; + for (var item : items) { + var requestRemain = network.requestExistingItem(item, request.getMiddle(), dest.getLeft(), null, dest.getRight(), equalityTypes); + remain.shrink(dest.getRight().getCount() - requestRemain.getCount()); + if (remain.isEmpty()) + break; + } + if (remain.getCount() != request.getRight().getCount()) { + tile.craftResultRequests.remove(request); + // if we couldn't pull everything, log a new request + if (!remain.isEmpty()) + tile.craftResultRequests.add(Triple.of(slot, request.getMiddle(), remain)); + network.endProfile(); + return; + } } } } @@ -162,6 +169,7 @@ public class CraftingModuleItem extends ModuleItem { var craftableAmount = this.getCraftableAmount(module, tile, unavailableConsumer, stack, dependencyChain); if (craftableAmount <= 0) return stack; + var slot = tile.getModuleSlot(module); var network = PipeNetwork.get(tile.getLevel()); var items = network.getOrderedNetworkItems(tile.getBlockPos()); @@ -181,7 +189,8 @@ public class CraftingModuleItem extends ModuleItem { var copy = in.copy(); copy.setCount(in.getCount() * toCraft); var ret = ItemTerminalBlockEntity.requestItemLater(tile.getLevel(), tile.getBlockPos(), items, unavailableConsumer, copy, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes); - tile.craftIngredientRequests.addAll(ret.getLeft()); + for (var lock : ret.getLeft()) + tile.craftIngredientRequests.add(Pair.of(slot, lock)); } var remain = stack.copy(); @@ -189,7 +198,7 @@ public class CraftingModuleItem extends ModuleItem { var result = stack.copy(); result.shrink(remain.getCount()); - tile.craftResultRequests.add(Pair.of(destPipe, result)); + tile.craftResultRequests.add(Triple.of(slot, destPipe, result)); return remain; } diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlockEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlockEntity.java index 8877d9d..c02ceea 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlockEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlockEntity.java @@ -218,7 +218,7 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect var otherPipe = network.getPipe(craftable.getLeft()); if (otherPipe != null) { for (var lock : otherPipe.craftIngredientRequests) - network.resolveNetworkLock(lock); + network.resolveNetworkLock(lock.getRight()); otherPipe.craftIngredientRequests.clear(); otherPipe.craftResultRequests.clear(); }