Compare commits
6 Commits
ctree-tweak
...
wip
| Author | SHA1 | Date | |
|---|---|---|---|
| c532b9c839 | |||
| 447c6debab | |||
| 50470ae3cf | |||
| 993be652c9 | |||
| b3bfbd0b58 | |||
| 49b3dc8b60 |
+1
-1
@@ -4,7 +4,7 @@ aebuild=7
|
|||||||
aegroup=appeng
|
aegroup=appeng
|
||||||
aebasename=appliedenergistics2
|
aebasename=appliedenergistics2
|
||||||
extended=extended_life
|
extended=extended_life
|
||||||
extendedversion=v50g
|
extendedversion=v50j
|
||||||
#########################################################
|
#########################################################
|
||||||
# Versions #
|
# Versions #
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ package appeng.crafting;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import appeng.me.cache.GridStorageCache;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@@ -58,6 +59,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
private final IItemList<IAEItemStack> crafting = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
private final IItemList<IAEItemStack> crafting = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
private final IItemList<IAEItemStack> usedWhileBuilding = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
private final IItemList<IAEItemStack> usedWhileBuilding = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
private final IItemList<IAEItemStack> uniques = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
|
||||||
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
|
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
|
||||||
private final Object monitor = new Object();
|
private final Object monitor = new Object();
|
||||||
@@ -65,6 +67,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
|
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
|
||||||
private CraftingTreeNode tree;
|
private CraftingTreeNode tree;
|
||||||
private final IAEItemStack output;
|
private final IAEItemStack output;
|
||||||
|
private long expectedOutput;
|
||||||
private boolean simulate = false;
|
private boolean simulate = false;
|
||||||
private MECraftingInventory availableCheck;
|
private MECraftingInventory availableCheck;
|
||||||
private long bytes = 0;
|
private long bytes = 0;
|
||||||
@@ -87,14 +90,25 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
this.actionSrc = actionSrc;
|
this.actionSrc = actionSrc;
|
||||||
|
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
|
||||||
final ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
final ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
||||||
final IStorageGrid sg = grid.getCache( IStorageGrid.class );
|
final GridStorageCache sg = grid.getCache( IStorageGrid.class );
|
||||||
this.original = new MECraftingInventory( sg.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), actionSrc, false, false, false );
|
this.original = new MECraftingInventory( sg.getExtractableList( actionSrc ) );
|
||||||
|
|
||||||
this.setTree( this.getCraftingTree( cc, what ) );
|
this.setTree( this.getCraftingTree( cc, what ) );
|
||||||
this.availableCheck = null;
|
this.availableCheck = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getExpectedOutput()
|
||||||
|
{
|
||||||
|
return expectedOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incExpectedOutput( long amount )
|
||||||
|
{
|
||||||
|
this.expectedOutput += amount;
|
||||||
|
}
|
||||||
|
|
||||||
private CraftingTreeNode getCraftingTree( final ICraftingGrid cc, final IAEItemStack what )
|
private CraftingTreeNode getCraftingTree( final ICraftingGrid cc, final IAEItemStack what )
|
||||||
{
|
{
|
||||||
return new CraftingTreeNode( cc, this, what, null, -1, 0 );
|
return new CraftingTreeNode( cc, this, what, null, -1, 0 );
|
||||||
@@ -110,9 +124,9 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
return usedWhileBuilding;
|
return usedWhileBuilding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAEItemStack getOriginal( IAEItemStack request )
|
public IItemList<IAEItemStack> getUniques()
|
||||||
{
|
{
|
||||||
return original.getItemList().findPrecise( request );
|
return uniques;
|
||||||
}
|
}
|
||||||
|
|
||||||
IAEItemStack checkUse( final IAEItemStack available )
|
IAEItemStack checkUse( final IAEItemStack available )
|
||||||
@@ -120,6 +134,11 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
|
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IAEItemStack checkAvailable( final IAEItemStack available )
|
||||||
|
{
|
||||||
|
return this.original.extractItems( available.copy().setStackSize( Long.MAX_VALUE ), Actionable.SIMULATE, this.actionSrc );
|
||||||
|
}
|
||||||
|
|
||||||
public void writeToNBT( final NBTTagCompound out )
|
public void writeToNBT( final NBTTagCompound out )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import appeng.api.config.FuzzyMode;
|
||||||
|
|
||||||
import net.minecraft.util.text.TextComponentString;
|
import net.minecraft.util.text.TextComponentString;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.config.FuzzyMode;
|
|
||||||
import appeng.api.networking.crafting.ICraftingGrid;
|
import appeng.api.networking.crafting.ICraftingGrid;
|
||||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
@@ -81,100 +79,32 @@ public class CraftingTreeNode
|
|||||||
for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in
|
for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in
|
||||||
// order.
|
// order.
|
||||||
{
|
{
|
||||||
if( this.parent == null || this.parent.notRecursive( details ) )
|
if( this.parent == null || job.getExpectedOutput() < job.getOutput().getStackSize() )
|
||||||
{
|
{
|
||||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth, boolean available )
|
|
||||||
{
|
|
||||||
this.what = wat;
|
|
||||||
this.parent = par;
|
|
||||||
this.slot = slot;
|
|
||||||
this.world = job.getWorld();
|
|
||||||
this.job = job;
|
|
||||||
this.sim = false;
|
|
||||||
|
|
||||||
this.canEmit = cc.canEmitFor( this.what );
|
|
||||||
|
|
||||||
if( this.canEmit )
|
|
||||||
{
|
|
||||||
return; // if you can emit for something, you can't make it with patterns.
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !available )
|
|
||||||
{
|
|
||||||
for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in
|
|
||||||
// order.
|
|
||||||
{
|
|
||||||
if( this.parent == null || this.parent.notRecursive( details ) )
|
|
||||||
{
|
|
||||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean notRecursive( final ICraftingPatternDetails details )
|
|
||||||
{
|
|
||||||
IAEItemStack[] o = details.getCondensedOutputs();
|
|
||||||
|
|
||||||
for( final IAEItemStack i : o )
|
|
||||||
{
|
|
||||||
if( i.equals( this.what ) )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
o = details.getCondensedInputs();
|
|
||||||
|
|
||||||
for( final IAEItemStack i : o )
|
|
||||||
{
|
|
||||||
if( i.equals( this.what ) )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this.parent == null )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.parent.notRecursive( details );
|
|
||||||
}
|
|
||||||
|
|
||||||
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||||
{
|
{
|
||||||
this.job.handlePausing();
|
this.job.handlePausing();
|
||||||
|
|
||||||
|
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
||||||
final List<IAEItemStack> thingsUsed = new ArrayList<>();
|
final List<IAEItemStack> thingsUsed = new ArrayList<>();
|
||||||
|
|
||||||
this.what.setStackSize( l );
|
this.what.setStackSize( l );
|
||||||
|
|
||||||
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
|
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
|
||||||
{
|
{
|
||||||
final Collection<IAEItemStack> itemList;
|
Collection<IAEItemStack> itemList = new ArrayList<>();
|
||||||
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
|
||||||
|
|
||||||
if( this.parent.details.canSubstitute() )
|
if( this.parent.getContainerItems() != null && !this.parent.getContainerItems().findFuzzy( this.what, FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||||
{
|
{
|
||||||
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs( this.slot );
|
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
|
||||||
itemList = new ArrayList<>( substitutes.size() );
|
|
||||||
|
|
||||||
for( IAEItemStack stack : substitutes )
|
|
||||||
{
|
|
||||||
itemList.addAll( inventoryList.findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
itemList = Lists.newArrayList();
|
|
||||||
|
|
||||||
final IAEItemStack item = inventoryList.findPrecise( this.what );
|
final IAEItemStack item = inventoryList.findPrecise( this.what );
|
||||||
|
|
||||||
if( item != null )
|
if( item != null )
|
||||||
{
|
{
|
||||||
itemList.add( item );
|
itemList.add( item );
|
||||||
|
|||||||
@@ -20,45 +20,40 @@ package appeng.crafting;
|
|||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import appeng.api.config.Actionable;
|
||||||
|
import appeng.api.config.FuzzyMode;
|
||||||
|
import appeng.util.item.AEItemStack;
|
||||||
|
import com.google.common.collect.ImmutableCollection;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
|
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
|
||||||
import net.minecraft.inventory.InventoryCrafting;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldServer;
|
|
||||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.config.Actionable;
|
|
||||||
import appeng.api.networking.crafting.ICraftingGrid;
|
import appeng.api.networking.crafting.ICraftingGrid;
|
||||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
import appeng.api.storage.channels.IItemStorageChannel;
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.container.ContainerNull;
|
|
||||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
|
|
||||||
public class CraftingTreeProcess
|
public class CraftingTreeProcess
|
||||||
{
|
{
|
||||||
|
|
||||||
private final CraftingTreeNode parent;
|
private final CraftingTreeNode parent;
|
||||||
final ICraftingPatternDetails details;
|
final ICraftingPatternDetails details;
|
||||||
private final CraftingJob job;
|
private final CraftingJob job;
|
||||||
private final Object2LongArrayMap<CraftingTreeNode> nodes = new Object2LongArrayMap<>();
|
private final Object2LongArrayMap<CraftingTreeNode> nodes = new Object2LongArrayMap<>();
|
||||||
private final int depth;
|
private final int depth;
|
||||||
boolean possible = true;
|
boolean possible = true;
|
||||||
private World world;
|
|
||||||
private long crafts = 0;
|
private long crafts = 0;
|
||||||
private boolean containerItems;
|
private IItemList<IAEItemStack> containerItems;
|
||||||
private boolean limitQty;
|
private boolean limitQty;
|
||||||
private boolean fullSimulation;
|
private final List<IAEItemStack> craftingResultList = new ArrayList<>();
|
||||||
private long bytes = 0;
|
private long bytes = 0;
|
||||||
|
|
||||||
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth )
|
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth )
|
||||||
@@ -69,167 +64,256 @@ public class CraftingTreeProcess
|
|||||||
this.depth = depth;
|
this.depth = depth;
|
||||||
final World world = job.getWorld();
|
final World world = job.getWorld();
|
||||||
|
|
||||||
if( details.isCraftable() )
|
final IAEItemStack[] list = details.getInputs();
|
||||||
|
|
||||||
|
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||||
{
|
{
|
||||||
final IAEItemStack[] list = details.getInputs();
|
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
||||||
|
|
||||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
|
||||||
{
|
{
|
||||||
boolean isAnInput = false;
|
if( containerItems == null )
|
||||||
for( final IAEItemStack a : details.getCondensedOutputs() )
|
|
||||||
{
|
{
|
||||||
if( a != null && a.equals( part ) )
|
containerItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
{
|
|
||||||
isAnInput = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isAnInput )
|
|
||||||
{
|
|
||||||
this.limitQty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
|
||||||
{
|
|
||||||
this.limitQty = this.containerItems = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
containerItems.add( part );
|
||||||
|
this.limitQty = true;
|
||||||
|
//break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( this.containerItems )
|
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||||
|
{
|
||||||
|
if( part.equals( job.getOutput() ) )
|
||||||
{
|
{
|
||||||
for( int x = 0; x < list.length; x++ )
|
job.incExpectedOutput( part.getStackSize() );
|
||||||
{
|
|
||||||
final IAEItemStack part = list[x];
|
|
||||||
if( part != null )
|
|
||||||
{
|
|
||||||
job.getUsedWhileBuilding().addStorage( part );
|
|
||||||
IAEItemStack used = job.getUsedWhileBuilding().findPrecise( part );
|
|
||||||
if( job.getOriginal( part ) != null && used.getStackSize() <= job.getOriginal( part ).getStackSize() )
|
|
||||||
{
|
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1, true ), part.getStackSize() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||||
|
{
|
||||||
|
if( part.equals( job.getOutput() ) )
|
||||||
{
|
{
|
||||||
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
job.incExpectedOutput( -part.getStackSize() );
|
||||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
||||||
|
for( IAEItemStack part : details.getCondensedInputs() )
|
||||||
|
{
|
||||||
|
if( part == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for( int x = 0; x < list.length; x++ )
|
||||||
|
{
|
||||||
|
final IAEItemStack comparePart = list[x];
|
||||||
|
if( part.equals( comparePart ) )
|
||||||
{
|
{
|
||||||
for( int x = 0; x < list.length; x++ )
|
boolean isPartContainer = false;
|
||||||
|
if( containerItems != null && !containerItems.findFuzzy( list[x], FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||||
{
|
{
|
||||||
final IAEItemStack comparePart = list[x];
|
part = list[x];
|
||||||
if( part != null && part.equals( comparePart ) )
|
isPartContainer = true;
|
||||||
|
}
|
||||||
|
long wantedSize = part.getStackSize();
|
||||||
|
|
||||||
|
if( !isPartContainer )
|
||||||
|
{
|
||||||
|
IAEItemStack found = job.checkAvailable( part );
|
||||||
|
IAEItemStack used;
|
||||||
|
long requestAmount;
|
||||||
|
|
||||||
|
long remaining = 0;
|
||||||
|
if( found != null )
|
||||||
{
|
{
|
||||||
job.getUsedWhileBuilding().addStorage( part );
|
used = job.getUsedWhileBuilding().findPrecise( part );
|
||||||
IAEItemStack used = job.getUsedWhileBuilding().findPrecise( part );
|
remaining = found.getStackSize();
|
||||||
if( job.getOriginal( part ) != null && used.getStackSize() <= job.getOriginal( part ).getStackSize() )
|
if( used != null )
|
||||||
{
|
{
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1, true ), part.getStackSize() );
|
if( used.getStackSize() >= found.getStackSize() )
|
||||||
|
{
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
remaining -= used.getStackSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( remaining > 0 )
|
||||||
|
{
|
||||||
|
if( remaining >= wantedSize )
|
||||||
|
{
|
||||||
|
requestAmount = wantedSize;
|
||||||
|
wantedSize = 0;
|
||||||
|
//we have the items
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// use the first slot...
|
requestAmount = remaining;
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
|
wantedSize -= remaining;
|
||||||
|
}
|
||||||
|
part = part.copy().setStackSize( requestAmount );
|
||||||
|
job.getUsedWhileBuilding().addStorage( part );
|
||||||
|
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), requestAmount );
|
||||||
|
if( wantedSize == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if( wantedSize > 0 )
|
||||||
|
{
|
||||||
|
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||||
|
{
|
||||||
|
//try to extract substitutes
|
||||||
|
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||||
|
{
|
||||||
|
if( subs.equals( part ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found = job.checkAvailable( subs );
|
||||||
|
remaining = 0;
|
||||||
|
|
||||||
|
if( found != null )
|
||||||
|
{
|
||||||
|
used = job.getUsedWhileBuilding().findPrecise( subs );
|
||||||
|
remaining = found.getStackSize();
|
||||||
|
if( used != null )
|
||||||
|
{
|
||||||
|
if( used.getStackSize() >= found.getStackSize() )
|
||||||
|
{
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
remaining -= used.getStackSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( remaining > 0 )
|
||||||
|
{
|
||||||
|
if( remaining >= wantedSize )
|
||||||
|
{
|
||||||
|
requestAmount = wantedSize;
|
||||||
|
wantedSize = 0;
|
||||||
|
//we have the items
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requestAmount = remaining;
|
||||||
|
wantedSize -= remaining;
|
||||||
|
}
|
||||||
|
subs = subs.copy().setStackSize( requestAmount );
|
||||||
|
job.getUsedWhileBuilding().addStorage( subs );
|
||||||
|
this.nodes.put( new CraftingTreeNode( cc, job, subs, this, x, depth + 1 ), requestAmount );
|
||||||
|
}
|
||||||
|
if( wantedSize == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( wantedSize > 0 )
|
||||||
|
{
|
||||||
|
//try to order the crafting of a substitute
|
||||||
|
ICraftingPatternDetails prioritizedPattern = null;
|
||||||
|
IAEItemStack prioritizedIAE = null;
|
||||||
|
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||||
|
{
|
||||||
|
if( subs.equals( part ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ImmutableCollection<ICraftingPatternDetails> detailCollection = cc.getCraftingFor( subs, details, x, world );
|
||||||
|
|
||||||
|
for( ICraftingPatternDetails sp : detailCollection )
|
||||||
|
{
|
||||||
|
if( prioritizedPattern == null )
|
||||||
|
{
|
||||||
|
prioritizedPattern = sp;
|
||||||
|
prioritizedIAE = subs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( sp.getPriority() > prioritizedPattern.getPriority() )
|
||||||
|
{
|
||||||
|
prioritizedPattern = sp;
|
||||||
|
prioritizedIAE = subs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), this, x, depth + 1 ), wantedSize );
|
||||||
|
wantedSize = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( wantedSize == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( wantedSize > 0 )
|
||||||
|
{
|
||||||
|
part = part.copy();
|
||||||
|
// use the first slot...
|
||||||
|
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), wantedSize );
|
||||||
|
wantedSize = 0;
|
||||||
|
}
|
||||||
|
if( !isPartContainer && wantedSize == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
|
||||||
{
|
|
||||||
boolean isAnInput = false;
|
|
||||||
for( final IAEItemStack a : details.getCondensedOutputs() )
|
|
||||||
{
|
|
||||||
if( a != null && a.equals( part ) )
|
|
||||||
{
|
|
||||||
isAnInput = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isAnInput )
|
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||||
|
{
|
||||||
|
for( final IAEItemStack o : details.getCondensedInputs() )
|
||||||
|
{
|
||||||
|
if( part.equals( o ) )
|
||||||
{
|
{
|
||||||
this.limitQty = true;
|
this.limitQty = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
|
||||||
{
|
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, -1, depth + 1 ), part.getStackSize() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean notRecursive( final ICraftingPatternDetails details )
|
IItemList<IAEItemStack> getContainerItems()
|
||||||
{
|
{
|
||||||
return this.parent == null || this.parent.notRecursive( details );
|
return this.containerItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getTimes( final long remaining, final long stackSize )
|
long getTimes( final long remaining, final long stackSize )
|
||||||
{
|
{
|
||||||
if( this.limitQty || this.fullSimulation )
|
if( this.limitQty )
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 );
|
return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
void request( final MECraftingInventory inv, final long amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||||
{
|
{
|
||||||
this.job.handlePausing();
|
this.job.handlePausing();
|
||||||
if( this.fullSimulation )
|
|
||||||
|
// request and remove inputs...
|
||||||
|
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||||
{
|
{
|
||||||
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
final IAEItemStack craftableStack = entry.getKey().getStack( entry.getValue() );
|
||||||
|
final IAEItemStack stack = entry.getKey().request( inv, craftableStack.getStackSize() * amountOfTimes, src );
|
||||||
|
|
||||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
if( containerItems != null && !this.containerItems.findFuzzy( stack, FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||||
{
|
{
|
||||||
final IAEItemStack item = entry.getKey().getStack( entry.getValue() );
|
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
|
||||||
final IAEItemStack stack = entry.getKey().request( inv, item.getStackSize(), src );
|
final IAEItemStack o = AEItemStack.fromItemStack( is );
|
||||||
|
|
||||||
ic.setInventorySlotContents( entry.getKey().getSlot(), stack.createItemStack() );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
|
||||||
{
|
|
||||||
ItemStack is = ic.getStackInSlot( x );
|
|
||||||
is = Platform.getContainerItem( is );
|
|
||||||
|
|
||||||
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
|
|
||||||
if( o != null )
|
if( o != null )
|
||||||
{
|
{
|
||||||
this.bytes++;
|
this.bytes++;
|
||||||
inv.injectItems( o, Actionable.MODULATE, src );
|
craftingResultList.add( o );
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// request and remove inputs...
|
|
||||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
|
||||||
{
|
|
||||||
final IAEItemStack item = entry.getKey().getStack( entry.getValue() );
|
|
||||||
final IAEItemStack stack = entry.getKey().request( inv, item.getStackSize() * i, src );
|
|
||||||
|
|
||||||
if( this.containerItems )
|
|
||||||
{
|
|
||||||
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
|
|
||||||
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
|
|
||||||
if( o != null )
|
|
||||||
{
|
|
||||||
this.bytes++;
|
|
||||||
inv.injectItems( o, Actionable.MODULATE, src );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,10 +324,21 @@ public class CraftingTreeProcess
|
|||||||
for( final IAEItemStack out : this.details.getCondensedOutputs() )
|
for( final IAEItemStack out : this.details.getCondensedOutputs() )
|
||||||
{
|
{
|
||||||
final IAEItemStack o = out.copy();
|
final IAEItemStack o = out.copy();
|
||||||
o.setStackSize( o.getStackSize() * i );
|
o.setStackSize( o.getStackSize() * amountOfTimes );
|
||||||
inv.injectItems( o, Actionable.MODULATE, src );
|
craftingResultList.add( o );
|
||||||
}
|
}
|
||||||
this.crafts += i;
|
|
||||||
|
for( IAEItemStack i : craftingResultList )
|
||||||
|
{
|
||||||
|
inv.injectItems( i, Actionable.MODULATE, src );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.crafts += amountOfTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IAEItemStack> getCraftingResultList()
|
||||||
|
{
|
||||||
|
return craftingResultList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dive( final CraftingJob job )
|
void dive( final CraftingJob job )
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import appeng.api.storage.IStorageChannel;
|
|||||||
import appeng.api.storage.channels.IItemStorageChannel;
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.me.helpers.PlayerSource;
|
|
||||||
import appeng.util.inv.ItemListIgnoreCrafting;
|
import appeng.util.inv.ItemListIgnoreCrafting;
|
||||||
import net.minecraft.util.text.TextComponentString;
|
import net.minecraft.util.text.TextComponentString;
|
||||||
|
|
||||||
@@ -312,11 +311,11 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
|||||||
{
|
{
|
||||||
if( result == null )
|
if( result == null )
|
||||||
{
|
{
|
||||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could not extract anything" ), false );
|
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could only extract " + result.getStackSize() ), false );
|
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failed = true;
|
failed = true;
|
||||||
|
|||||||
@@ -464,14 +464,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( removed )
|
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
|
||||||
{
|
|
||||||
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
|
|
||||||
}
|
|
||||||
else if( newPattern )
|
|
||||||
{
|
|
||||||
this.provideCrafting( (ICraftingProviderHelper) this.gridProxy.getCrafting() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch( GridAccessException e )
|
catch( GridAccessException e )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -411,27 +411,6 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
|||||||
{
|
{
|
||||||
details.add( medium );
|
details.add( medium );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !updatePatterns )
|
|
||||||
{
|
|
||||||
List<IAEItemStack> newCraftables = new ArrayList<>();
|
|
||||||
|
|
||||||
ObjectSet<ICraftingPatternDetails> b = new ObjectRBTreeSet<>( COMPARATOR );
|
|
||||||
ImmutableList<ICraftingPatternDetails> a = this.craftableItems.get( api.getCondensedOutputs()[0] );
|
|
||||||
if( a != null )
|
|
||||||
{
|
|
||||||
b.addAll( this.craftableItems.get( api.getOutputs()[0] ) );
|
|
||||||
}
|
|
||||||
b.add( api );
|
|
||||||
|
|
||||||
for( IAEItemStack stack : api.getCondensedOutputs() )
|
|
||||||
{
|
|
||||||
IAEItemStack i = stack.copy().reset().setCraftable( true );
|
|
||||||
this.craftableItems.put( i, ImmutableList.copyOf( b ) );
|
|
||||||
newCraftables.add( i );
|
|
||||||
}
|
|
||||||
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), newCraftables, new BaseActionSource() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+34
-8
@@ -19,13 +19,12 @@
|
|||||||
package appeng.me.cache;
|
package appeng.me.cache;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
|
import appeng.crafting.MECraftingInventory;
|
||||||
|
import appeng.helpers.IInterfaceHost;
|
||||||
|
import appeng.helpers.IPriorityHost;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.SetMultimap;
|
import com.google.common.collect.SetMultimap;
|
||||||
|
|
||||||
@@ -55,6 +54,8 @@ import appeng.me.helpers.GenericInterestManager;
|
|||||||
import appeng.me.helpers.MachineSource;
|
import appeng.me.helpers.MachineSource;
|
||||||
import appeng.me.storage.ItemWatcher;
|
import appeng.me.storage.ItemWatcher;
|
||||||
import appeng.me.storage.NetworkInventoryHandler;
|
import appeng.me.storage.NetworkInventoryHandler;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
|
||||||
|
|
||||||
public class GridStorageCache implements IStorageGrid
|
public class GridStorageCache implements IStorageGrid
|
||||||
@@ -68,6 +69,8 @@ public class GridStorageCache implements IStorageGrid
|
|||||||
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
|
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
|
||||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
private final Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
private final Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||||
|
private MECraftingInventory localCache = null;
|
||||||
|
private final Int2ObjectMap<MECraftingInventory> extractableItemPriorityMap = new Int2ObjectOpenHashMap<>();
|
||||||
private int localDepth;
|
private int localDepth;
|
||||||
|
|
||||||
public GridStorageCache( final IGrid g )
|
public GridStorageCache( final IGrid g )
|
||||||
@@ -82,6 +85,8 @@ public class GridStorageCache implements IStorageGrid
|
|||||||
@Override
|
@Override
|
||||||
public void onUpdateTick()
|
public void onUpdateTick()
|
||||||
{
|
{
|
||||||
|
this.localCache = null;
|
||||||
|
this.extractableItemPriorityMap.clear();
|
||||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() );
|
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +174,28 @@ public class GridStorageCache implements IStorageGrid
|
|||||||
return (IMEMonitor<T>) this.storageMonitors.get( channel );
|
return (IMEMonitor<T>) this.storageMonitors.get( channel );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MECraftingInventory getExtractableList( IActionSource src )
|
||||||
|
{
|
||||||
|
if( src instanceof MachineSource )
|
||||||
|
{
|
||||||
|
if( src.machine().isPresent() )
|
||||||
|
{
|
||||||
|
IActionHost machine = src.machine().get();
|
||||||
|
if( machine instanceof IInterfaceHost )
|
||||||
|
{
|
||||||
|
extractableItemPriorityMap.putIfAbsent( ( (IPriorityHost) machine ).getPriority(), new MECraftingInventory( getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), src, false, false, false ) );
|
||||||
|
return extractableItemPriorityMap.get( ( (IPriorityHost) machine ).getPriority() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( localCache == null )
|
||||||
|
{
|
||||||
|
localCache = new MECraftingInventory( getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), src, false, false, false );
|
||||||
|
}
|
||||||
|
return localCache;
|
||||||
|
}
|
||||||
|
|
||||||
private CellChangeTracker addCellProvider( final ICellProvider cc, final CellChangeTracker tracker )
|
private CellChangeTracker addCellProvider( final ICellProvider cc, final CellChangeTracker tracker )
|
||||||
{
|
{
|
||||||
if( this.inactiveCellProviders.contains( cc ) )
|
if( this.inactiveCellProviders.contains( cc ) )
|
||||||
@@ -198,8 +225,7 @@ public class GridStorageCache implements IStorageGrid
|
|||||||
|
|
||||||
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
|
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
|
||||||
|
|
||||||
this.storageMonitors.forEach( ( channel, monitor ) ->
|
this.storageMonitors.forEach( ( channel, monitor ) -> {
|
||||||
{
|
|
||||||
for( final IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( channel ) )
|
for( final IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( channel ) )
|
||||||
{
|
{
|
||||||
tracker.postChanges( channel, -1, h, actionSrc );
|
tracker.postChanges( channel, -1, h, actionSrc );
|
||||||
|
|||||||
@@ -239,7 +239,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
// also stop accepting items when the job is complete, i.e. to prevent re-insertion when pushing out
|
// also stop accepting items when the job is complete, i.e. to prevent re-insertion when pushing out
|
||||||
// items during storeItems
|
// items during storeItems
|
||||||
if (input == null || isComplete) {
|
if( input == null || isComplete )
|
||||||
|
{
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +376,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
final ImmutableList<IAEItemStack> single = ImmutableList.of( diff.copy() );
|
final ImmutableList<IAEItemStack> single = ImmutableList.of( diff.copy() );
|
||||||
|
|
||||||
while( i.hasNext() )
|
while ( i.hasNext() )
|
||||||
{
|
{
|
||||||
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> o = i.next();
|
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> o = i.next();
|
||||||
final IMEMonitorHandlerReceiver<IAEItemStack> receiver = o.getKey();
|
final IMEMonitorHandlerReceiver<IAEItemStack> receiver = o.getKey();
|
||||||
@@ -495,15 +496,14 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canCraft(final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs)
|
private boolean canCraft( final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs )
|
||||||
{
|
{
|
||||||
if( !details.isCraftable() )
|
if( !details.isCraftable() )
|
||||||
{
|
{
|
||||||
// Processing patterns are relatively easy
|
// Processing patterns are relatively easy
|
||||||
for ( IAEItemStack input : condensedInputs )
|
for( IAEItemStack input : condensedInputs )
|
||||||
{
|
{
|
||||||
final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE,
|
final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE, this.machineSrc );
|
||||||
this.machineSrc );
|
|
||||||
|
|
||||||
if( ais == null || ais.getStackSize() < input.getStackSize() )
|
if( ais == null || ais.getStackSize() < input.getStackSize() )
|
||||||
{
|
{
|
||||||
@@ -516,7 +516,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
// When substitutions are allowed, we have to keep track of which items we've reserved
|
// When substitutions are allowed, we have to keep track of which items we've reserved
|
||||||
IAEItemStack[] inputs = details.getInputs();
|
IAEItemStack[] inputs = details.getInputs();
|
||||||
Map<IAEItemStack, Integer> consumedCount = new HashMap<>();
|
Map<IAEItemStack, Integer> consumedCount = new HashMap<>();
|
||||||
for ( int i = 0; i < inputs.length; i++ )
|
for( int i = 0; i < inputs.length; i++ )
|
||||||
{
|
{
|
||||||
List<IAEItemStack> substitutes = details.getSubstituteInputs( i );
|
List<IAEItemStack> substitutes = details.getSubstituteInputs( i );
|
||||||
if( substitutes.isEmpty() )
|
if( substitutes.isEmpty() )
|
||||||
@@ -525,9 +525,9 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for ( IAEItemStack substitute : substitutes )
|
for( IAEItemStack substitute : substitutes )
|
||||||
{
|
{
|
||||||
for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) )
|
for( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) )
|
||||||
{
|
{
|
||||||
int alreadyConsumed = consumedCount.getOrDefault( fuzz, 0 );
|
int alreadyConsumed = consumedCount.getOrDefault( fuzz, 0 );
|
||||||
if( fuzz.getStackSize() - alreadyConsumed <= 0 )
|
if( fuzz.getStackSize() - alreadyConsumed <= 0 )
|
||||||
@@ -537,8 +537,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
fuzz = fuzz.copy();
|
fuzz = fuzz.copy();
|
||||||
fuzz.setStackSize( 1 ); // We're iterating over non condensed inputs which means there's 1 of each needed
|
fuzz.setStackSize( 1 ); // We're iterating over non condensed inputs which means there's 1 of each needed
|
||||||
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE,
|
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE, this.machineSrc );
|
||||||
this.machineSrc );
|
|
||||||
|
|
||||||
if( ais != null && ais.getStackSize() > 0 )
|
if( ais != null && ais.getStackSize() > 0 )
|
||||||
{
|
{
|
||||||
@@ -565,11 +564,11 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
// When no substitutions can occur, we can simply check that all items are accounted since
|
// When no substitutions can occur, we can simply check that all items are accounted since
|
||||||
// each type of item should only occur once
|
// each type of item should only occur once
|
||||||
for ( IAEItemStack g : condensedInputs )
|
for( IAEItemStack g : condensedInputs )
|
||||||
{
|
{
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
||||||
for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) )
|
for( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) )
|
||||||
{
|
{
|
||||||
fuzz = fuzz.copy();
|
fuzz = fuzz.copy();
|
||||||
fuzz.setStackSize( g.getStackSize() );
|
fuzz.setStackSize( g.getStackSize() );
|
||||||
@@ -675,8 +674,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
this.somethingChanged = false;
|
this.somethingChanged = false;
|
||||||
this.executeCrafting( eg, cc );
|
this.executeCrafting( eg, cc );
|
||||||
}
|
} while ( this.somethingChanged && this.remainingOperations > 0 );
|
||||||
while( this.somethingChanged && this.remainingOperations > 0 );
|
|
||||||
}
|
}
|
||||||
this.usedOps[2] = this.usedOps[1];
|
this.usedOps[2] = this.usedOps[1];
|
||||||
this.usedOps[1] = this.usedOps[0];
|
this.usedOps[1] = this.usedOps[0];
|
||||||
@@ -692,7 +690,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator();
|
final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator();
|
||||||
|
|
||||||
while( i.hasNext() )
|
while ( i.hasNext() )
|
||||||
{
|
{
|
||||||
final Entry<ICraftingPatternDetails, TaskProgress> e = i.next();
|
final Entry<ICraftingPatternDetails, TaskProgress> e = i.next();
|
||||||
|
|
||||||
@@ -708,12 +706,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
InventoryCrafting ic = null;
|
InventoryCrafting ic = null;
|
||||||
|
|
||||||
if (!visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty())
|
if( !visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty() )
|
||||||
{
|
{
|
||||||
visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList()) ) );
|
visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList() ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!visitedMediums.get( details ).isEmpty())
|
while ( !visitedMediums.get( details ).isEmpty() )
|
||||||
{
|
{
|
||||||
|
|
||||||
ICraftingMedium m = visitedMediums.get( details ).poll();
|
ICraftingMedium m = visitedMediums.get( details ).poll();
|
||||||
@@ -773,52 +771,58 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
itemList = new ArrayList<>(1);
|
else
|
||||||
|
{
|
||||||
|
itemList = new ArrayList<>( 1 );
|
||||||
|
|
||||||
final IAEItemStack item = this.inventory.getItemList()
|
final IAEItemStack item = this.inventory.getItemList().findPrecise( input[x] );
|
||||||
.findPrecise(input[x]);
|
|
||||||
|
|
||||||
if (item != null) {
|
if( item != null )
|
||||||
itemList.add(item);
|
{
|
||||||
|
itemList.add( item );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IAEItemStack fuzz : itemList) {
|
for( IAEItemStack fuzz : itemList )
|
||||||
|
{
|
||||||
fuzz = fuzz.copy();
|
fuzz = fuzz.copy();
|
||||||
fuzz.setStackSize(input[x].getStackSize());
|
fuzz.setStackSize( input[x].getStackSize() );
|
||||||
|
|
||||||
if (details.isValidItemForSlot(x, fuzz.createItemStack(),
|
if( details.isValidItemForSlot( x, fuzz.createItemStack(), this.getWorld() ) )
|
||||||
this.getWorld())) {
|
{
|
||||||
final IAEItemStack ais = this.inventory.extractItems(fuzz,
|
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.MODULATE, this.machineSrc );
|
||||||
Actionable.MODULATE, this.machineSrc);
|
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
||||||
final ItemStack is = ais == null ? ItemStack.EMPTY
|
|
||||||
: ais.createItemStack();
|
|
||||||
|
|
||||||
if (!is.isEmpty()) {
|
if( !is.isEmpty() )
|
||||||
this.postChange(AEItemStack.fromItemStack(is), this.machineSrc);
|
{
|
||||||
ic.setInventorySlotContents(x, is);
|
this.postChange( AEItemStack.fromItemStack( is ), this.machineSrc );
|
||||||
|
ic.setInventorySlotContents( x, is );
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
final IAEItemStack ais = this.inventory.extractItems(input[x].copy(),
|
else
|
||||||
Actionable.MODULATE, this.machineSrc);
|
{
|
||||||
|
final IAEItemStack ais = this.inventory.extractItems( input[x].copy(), Actionable.MODULATE, this.machineSrc );
|
||||||
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
||||||
|
|
||||||
if (!is.isEmpty()) {
|
if( !is.isEmpty() )
|
||||||
this.postChange(input[x], this.machineSrc);
|
{
|
||||||
ic.setInventorySlotContents(x, is);
|
this.postChange( input[x], this.machineSrc );
|
||||||
if (is.getCount() == input[x].getStackSize()) {
|
ic.setInventorySlotContents( x, is );
|
||||||
|
if( is.getCount() == input[x].getStackSize() )
|
||||||
|
{
|
||||||
found = true;
|
found = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if( !found )
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -902,7 +906,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
private void storeItems()
|
private void storeItems()
|
||||||
{
|
{
|
||||||
Preconditions.checkState(isComplete, "CPU should be complete to prevent re-insertion when dumping items");
|
Preconditions.checkState( isComplete, "CPU should be complete to prevent re-insertion when dumping items" );
|
||||||
final IGrid g = this.getGrid();
|
final IGrid g = this.getGrid();
|
||||||
|
|
||||||
if( g == null )
|
if( g == null )
|
||||||
@@ -1016,8 +1020,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
public boolean isBusy()
|
public boolean isBusy()
|
||||||
{
|
{
|
||||||
|
|
||||||
this.tasks.entrySet().removeIf(
|
this.tasks.entrySet().removeIf( taskProgressEntry -> taskProgressEntry.getValue().value <= 0 );
|
||||||
taskProgressEntry -> taskProgressEntry.getValue().value <= 0 );
|
|
||||||
|
|
||||||
if( !this.waitingFor.isEmpty() || !this.tasks.isEmpty() )
|
if( !this.waitingFor.isEmpty() || !this.tasks.isEmpty() )
|
||||||
{
|
{
|
||||||
@@ -1075,8 +1078,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
final int hash = System.identityHashCode( this );
|
final int hash = System.identityHashCode( this );
|
||||||
final int hmm = this.finalOutput == null ? 0 : this.finalOutput.hashCode();
|
final int hmm = this.finalOutput == null ? 0 : this.finalOutput.hashCode();
|
||||||
|
|
||||||
return Long.toString( now, Character.MAX_RADIX ) + '-' + Integer.toString( hash, Character.MAX_RADIX ) + '-' + Integer.toString( hmm,
|
return Long.toString( now, Character.MAX_RADIX ) + '-' + Integer.toString( hash, Character.MAX_RADIX ) + '-' + Integer.toString( hmm, Character.MAX_RADIX );
|
||||||
Character.MAX_RADIX );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private NBTTagCompound generateLinkData( final String craftingID, final boolean standalone, final boolean req )
|
private NBTTagCompound generateLinkData( final String craftingID, final boolean standalone, final boolean req )
|
||||||
@@ -1103,7 +1105,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
public void getListOfItem( final IItemList<IAEItemStack> list, final CraftingItemList whichList )
|
public void getListOfItem( final IItemList<IAEItemStack> list, final CraftingItemList whichList )
|
||||||
{
|
{
|
||||||
switch( whichList )
|
switch ( whichList )
|
||||||
{
|
{
|
||||||
case ACTIVE:
|
case ACTIVE:
|
||||||
for( final IAEItemStack ais : this.waitingFor )
|
for( final IAEItemStack ais : this.waitingFor )
|
||||||
@@ -1174,7 +1176,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
IAEItemStack is;
|
IAEItemStack is;
|
||||||
|
|
||||||
switch( storage2 )
|
switch ( storage2 )
|
||||||
{
|
{
|
||||||
case STORAGE:
|
case STORAGE:
|
||||||
is = this.inventory.getItemList().findPrecise( what );
|
is = this.inventory.getItemList().findPrecise( what );
|
||||||
|
|||||||
Reference in New Issue
Block a user