From 0a7ed11cc46667846594684485a664b79e5405a5 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 18:50:42 +0000 Subject: [PATCH] Keep jobs of attuned interfaces in the network when their target updates Targets such as furnaces notify their neighbours every time their contents change. Attuned crafting interfaces unregistered from the crafting network on each of these notifications, and only registered again on their next update. In between, their crafting jobs were missing from the dependency graph, so dependent jobs were reported as missing ingredients. Attuned interfaces now only re-register when their target gained or lost its recipe handler, or exposes other recipes. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01C5iUzweRYoCkKB5bvJdH8Y --- .../PartTypeInterfaceCraftingAttuned.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/cyclops/integratedcrafting/part/PartTypeInterfaceCraftingAttuned.java b/src/main/java/org/cyclops/integratedcrafting/part/PartTypeInterfaceCraftingAttuned.java index 497293d7d..ced678135 100644 --- a/src/main/java/org/cyclops/integratedcrafting/part/PartTypeInterfaceCraftingAttuned.java +++ b/src/main/java/org/cyclops/integratedcrafting/part/PartTypeInterfaceCraftingAttuned.java @@ -1,5 +1,6 @@ package org.cyclops.integratedcrafting.part; +import com.google.common.collect.Lists; import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -133,7 +134,10 @@ public boolean shouldTriggerBlockRenderUpdate(@Nullable State oldPartState, @Nul @Override public void onBlockNeighborChange(INetwork network, IPartNetwork partNetwork, PartTarget target, State state, BlockGetter world, Block neighbourBlock, BlockPos neighbourBlockPos) { - boolean isNeighbourTarget = neighbourBlockPos.equals(target.getTarget().getPos().getBlockPos()); + // Targets such as furnaces notify their neighbours on every operation, while their recipes remain the same. + // Only re-register if the target really changed, as this temporarily removes our crafting jobs from the network. + boolean isNeighbourTarget = neighbourBlockPos.equals(target.getTarget().getPos().getBlockPos()) + && state.hasTargetChanged(); boolean hadValidTarget = false; if (isNeighbourTarget) { hadValidTarget = state.hasValidTarget(); @@ -179,6 +183,21 @@ public boolean hasValidTarget() { return this.hasValidTarget; } + /** + * @return If the target gained or lost its recipe handler, or exposes other recipes than the ones that were last read. + */ + public boolean hasTargetChanged() { + if (getTarget() == null || this.recipes == null) { + return true; + } + LazyOptional recipeHandler = getTargetRecipeHandler(); + if (recipeHandler.isPresent() != this.hasValidTarget) { + return true; + } + return recipeHandler.isPresent() && !Lists.newArrayList(recipeHandler.orElseThrow(IllegalStateException::new).getRecipes()) + .equals(Lists.newArrayList(this.recipes)); + } + @Override public void writeToNBT(CompoundTag tag) { super.writeToNBT(tag);