diff --git a/src/main/java/appeng/core/features/AEFeature.java b/src/main/java/appeng/core/features/AEFeature.java index f7e1e707c..edfe86917 100644 --- a/src/main/java/appeng/core/features/AEFeature.java +++ b/src/main/java/appeng/core/features/AEFeature.java @@ -164,6 +164,7 @@ public enum AEFeature PATTERNS( "Patterns", Constants.CATEGORY_CRAFTING_FEATURES ), CRAFTING_CPU( "CraftingCPU", Constants.CATEGORY_CRAFTING_FEATURES ), CRAFTING_MANAGER_FALLBACK( "CraftingManagerFallback", Constants.CATEGORY_CRAFTING_FEATURES, "Use CraftingManager to find an alternative recipe, after a pattern rejected an ingredient. Should be enabled to avoid issues, but can have a minor performance impact." ), + INSANE_BLOCKING_MODE( "InsaneBlockingMode", Constants.CATEGORY_CRAFTING_FEATURES, "Use the default AE2 blocking mode that doesn't work on any machines" ), BASIC_CARDS( "BasicCards", Constants.CATEGORY_UPGRADES ), ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ), diff --git a/src/main/java/appeng/helpers/DualityInterface.java b/src/main/java/appeng/helpers/DualityInterface.java index 17588c934..bb9d15a70 100644 --- a/src/main/java/appeng/helpers/DualityInterface.java +++ b/src/main/java/appeng/helpers/DualityInterface.java @@ -88,6 +88,8 @@ import appeng.api.util.AEPartLocation; import appeng.api.util.DimensionalCoord; import appeng.api.util.IConfigManager; import appeng.capabilities.Capabilities; +import appeng.core.AEConfig; +import appeng.core.features.AEFeature; import appeng.core.settings.TickRates; import appeng.me.GridAccessException; import appeng.me.helpers.AENetworkProxy; @@ -897,6 +899,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn }; } + private static boolean invIsBlocked(InventoryAdaptor inv) { + if (AEConfig.instance().isFeatureEnabled(AEFeature.INSANE_BLOCKING_MODE)) + return !inv.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty(); + else + return inv.containsItems(); + } + @Override public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table ) { @@ -945,7 +954,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn { if( this.isBlocking() ) { - if( !ad.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty() ) + if( invIsBlocked(ad) ) { continue; } @@ -996,7 +1005,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() ); if( ad != null ) { - if( ad.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty() ) + if( !invIsBlocked(ad) ) { allAreBusy = false; break; diff --git a/src/main/java/appeng/helpers/MultiCraftingTracker.java b/src/main/java/appeng/helpers/MultiCraftingTracker.java index 8d8d4e2b6..bf75da380 100644 --- a/src/main/java/appeng/helpers/MultiCraftingTracker.java +++ b/src/main/java/appeng/helpers/MultiCraftingTracker.java @@ -131,14 +131,14 @@ public class MultiCraftingTracker if( this.getLink( x ) == null ) { final IAEItemStack aisC = ais.copy(); - if (this.failedCraftTriesSlot[x] == 0) { + if (this.failedCraftTriesSlot[x] <= 0) { aisC.setStackSize(itemToCraft); this.setJob(x, cg.beginCraftingJob(w, g, mySrc, aisC, null)); } if (getJob(x) != null) this.failedCraftTriesSlot[x] = 0; - else this.failedCraftTriesSlot[x] += 2; + else this.failedCraftTriesSlot[x] += 20; } - this.failedCraftTriesSlot[x] += 2; + this.failedCraftTriesSlot[x] -= 1; } } return false; diff --git a/src/main/java/appeng/me/Grid.java b/src/main/java/appeng/me/Grid.java index daab0dbd5..4762d4937 100644 --- a/src/main/java/appeng/me/Grid.java +++ b/src/main/java/appeng/me/Grid.java @@ -39,6 +39,7 @@ import appeng.api.util.IReadOnlyCollection; import appeng.core.worlddata.WorldData; import appeng.hooks.TickHandler; import appeng.util.ReadOnlyCollection; +import appeng.me.cache.CraftingGridCache; public class Grid implements IGrid @@ -219,7 +220,10 @@ public class Grid implements IGrid @Override public MENetworkEvent postEvent( final MENetworkEvent ev ) { - return this.eventBus.postEvent( this, ev ); + CraftingGridCache.pauseRebuilds(); + final MENetworkEvent ret = this.eventBus.postEvent( this, ev ); + CraftingGridCache.unpauseRebuilds(); + return ret; } @Override diff --git a/src/main/java/appeng/me/GridNode.java b/src/main/java/appeng/me/GridNode.java index 6dc863a48..958685b8f 100644 --- a/src/main/java/appeng/me/GridNode.java +++ b/src/main/java/appeng/me/GridNode.java @@ -55,6 +55,7 @@ import appeng.api.util.IReadOnlyCollection; import appeng.core.AELog; import appeng.core.worlddata.WorldData; import appeng.hooks.TickHandler; +import appeng.me.cache.CraftingGridCache; import appeng.me.pathfinding.IPathItem; import appeng.util.IWorldCallable; import appeng.util.ReadOnlyCollection; @@ -164,6 +165,8 @@ public class GridNode implements IGridNode, IPathItem { final Object tracker = new Object(); + CraftingGridCache.pauseRebuilds(); + Deque nextRun = new ArrayDeque<>(); nextRun.add( this ); @@ -203,6 +206,7 @@ public class GridNode implements IGridNode, IPathItem } } } + CraftingGridCache.unpauseRebuilds(); } @Override diff --git a/src/main/java/appeng/me/cache/CraftingGridCache.java b/src/main/java/appeng/me/cache/CraftingGridCache.java index 7bd105ade..30ecf13b0 100644 --- a/src/main/java/appeng/me/cache/CraftingGridCache.java +++ b/src/main/java/appeng/me/cache/CraftingGridCache.java @@ -114,6 +114,8 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper private IStorageGrid storageGrid; private IEnergyGrid energyGrid; private boolean updateList = false; + private static int pauseRebuilds = 0; + private static Set rebuildNeeded = new HashSet<>(); public CraftingGridCache( final IGrid grid ) { @@ -240,8 +242,34 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper // nothing! } + public static void pauseRebuilds() + { + pauseRebuilds++; + } + + public static void unpauseRebuilds() + { + pauseRebuilds--; + if (pauseRebuilds == 0 && rebuildNeeded.size() > 0) + { + ImmutableSet needed = ImmutableSet.copyOf(rebuildNeeded); + rebuildNeeded.clear(); + for ( CraftingGridCache cache: needed ) + { + cache.updatePatterns(); + } + } + } + private void updatePatterns() { + // coalesce change events during a grid traversal to a single rebuild + if (pauseRebuilds != 0) + { + rebuildNeeded.add(this); + return; + } + final Map> oldItems = this.craftableItems; // erase list.