clean-up
This commit is contained in:
@@ -59,7 +59,6 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
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> 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 Object monitor = new Object();
|
||||
@@ -114,11 +113,6 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
return usedWhileBuilding;
|
||||
}
|
||||
|
||||
public IItemList<IAEItemStack> getUniques()
|
||||
{
|
||||
return uniques;
|
||||
}
|
||||
|
||||
IAEItemStack checkUse( final IAEItemStack available )
|
||||
{
|
||||
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
|
||||
|
||||
@@ -88,7 +88,7 @@ public class CraftingTreeNode
|
||||
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() )
|
||||
if( this.parent == null || notRecursive( details ) && this.parent.details != details )
|
||||
{
|
||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class CraftingTreeNode
|
||||
{
|
||||
Collection<IAEItemStack> itemList = new ArrayList<>();
|
||||
|
||||
if( this.what.getItem().hasContainerItem( this.what.getDefinition() ) )
|
||||
if( this.what.getItem().hasContainerItem( this.what.getDefinition() ) || this.what.getItem().isDamageable() )
|
||||
{
|
||||
itemList.addAll( inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) );
|
||||
|
||||
@@ -298,9 +298,17 @@ public class CraftingTreeNode
|
||||
throw new CraftBranchFailure( this.what, l );
|
||||
}
|
||||
|
||||
boolean notRecursive()
|
||||
boolean notRecursive( ICraftingPatternDetails details )
|
||||
{
|
||||
return this.parent == null || job.getUniques().findPrecise( this.what ) == null;
|
||||
if( this.parent == null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if( this.parent.details == details )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.parent.notRecursive( details );
|
||||
}
|
||||
|
||||
void dive( final CraftingJob job )
|
||||
|
||||
@@ -24,19 +24,16 @@ import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
@@ -75,14 +72,18 @@ public class CraftingTreeProcess
|
||||
}
|
||||
final IAEItemStack[] list = details.getInputs();
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||
{
|
||||
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
||||
for( final IAEItemStack o : details.getCondensedInputs() )
|
||||
{
|
||||
this.limitQty = true;
|
||||
//break;
|
||||
if( part.equals( o ) )
|
||||
{
|
||||
this.limitQty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
||||
for( IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
@@ -99,21 +100,57 @@ public class CraftingTreeProcess
|
||||
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
||||
{
|
||||
part = list[x];
|
||||
this.limitQty = true;
|
||||
isPartContainer = true;
|
||||
}
|
||||
long wantedSize = part.getStackSize();
|
||||
|
||||
if( isPartContainer && wantedSize > 0 )
|
||||
long wantedSize = part.getStackSize();
|
||||
IAEItemStack found;
|
||||
IAEItemStack used;
|
||||
long remaining = 0;
|
||||
long requestAmount = 0;
|
||||
|
||||
if( wantedSize > 0 )
|
||||
{
|
||||
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||
if( details.canSubstitute() )
|
||||
{
|
||||
IItemList<IAEItemStack> aa = ( (CraftingGridCache) cc ).getAvailableItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() );
|
||||
for( IAEItemStack is : aa )
|
||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||
{
|
||||
if( is.fuzzyComparison( part, FuzzyMode.IGNORE_ALL ) )
|
||||
found = job.checkAvailable( subs );
|
||||
|
||||
if( found != null )
|
||||
{
|
||||
wantedSize -= 1;
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, is.copy().setStackSize( 1 ), this, x, depth + 1 ), 1 );
|
||||
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;
|
||||
@@ -121,144 +158,98 @@ public class CraftingTreeProcess
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !isPartContainer )
|
||||
{
|
||||
IAEItemStack found = job.checkAvailable( part );
|
||||
IAEItemStack used;
|
||||
long requestAmount;
|
||||
|
||||
long remaining = 0;
|
||||
if( found != null )
|
||||
else
|
||||
{
|
||||
used = job.getUsedWhileBuilding().findPrecise( part );
|
||||
remaining = found.getStackSize();
|
||||
if( used != null )
|
||||
found = job.checkAvailable( part );
|
||||
|
||||
if( found != null )
|
||||
{
|
||||
if( used.getStackSize() >= found.getStackSize() )
|
||||
used = job.getUsedWhileBuilding().findPrecise( part );
|
||||
remaining = found.getStackSize();
|
||||
if( used != null )
|
||||
{
|
||||
remaining = 0;
|
||||
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
|
||||
{
|
||||
remaining -= used.getStackSize();
|
||||
requestAmount = remaining;
|
||||
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( remaining > 0 )
|
||||
{
|
||||
if( remaining >= wantedSize )
|
||||
{
|
||||
requestAmount = wantedSize;
|
||||
wantedSize = 0;
|
||||
//we have the items
|
||||
}
|
||||
else
|
||||
{
|
||||
requestAmount = remaining;
|
||||
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;
|
||||
}
|
||||
}
|
||||
if( wantedSize > 0 )
|
||||
|
||||
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||
{
|
||||
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||
{
|
||||
//try to extract substitutes
|
||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||
if( subs.fuzzyComparison( part, FuzzyMode.IGNORE_ALL ) )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
wantedSize -= 1;
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, subs.copy().setStackSize( 1 ), this, x, depth + 1 ), 1 );
|
||||
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 ) )
|
||||
{
|
||||
//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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,23 +267,11 @@ public class CraftingTreeProcess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||
{
|
||||
for( final IAEItemStack o : details.getCondensedInputs() )
|
||||
{
|
||||
if( part.equals( o ) )
|
||||
{
|
||||
this.limitQty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean notRecursive()
|
||||
boolean notRecursive( ICraftingPatternDetails details )
|
||||
{
|
||||
return this.parent == null || this.parent.notRecursive();
|
||||
return this.parent == null || this.parent.notRecursive( details );
|
||||
}
|
||||
|
||||
long getTimes( final long remaining, final long stackSize )
|
||||
|
||||
@@ -147,52 +147,41 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
|
||||
ItemStack extracted;
|
||||
|
||||
if( !simulate )
|
||||
int stackSizeCurrentSlot = stackInInventorySlot.getCount();
|
||||
int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot );
|
||||
|
||||
// We have to loop here because according to the docs, the handler shouldn't return a stack with size >
|
||||
// maxSize, even if we request more. So even if it returns a valid stack, it might have more stuff.
|
||||
do
|
||||
{
|
||||
int stackSizeCurrentSlot = stackInInventorySlot.getCount();
|
||||
int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot );
|
||||
|
||||
// We have to loop here because according to the docs, the handler shouldn't return a stack with size >
|
||||
// maxSize, even if we request more. So even if it returns a valid stack, it might have more stuff.
|
||||
|
||||
do
|
||||
{
|
||||
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, false );
|
||||
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
if( extracted.getCount() > remainingCurrentSlot )
|
||||
{
|
||||
// Something broke. It should never return more than we requested...
|
||||
// We're going to silently eat the remainder
|
||||
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.", this.itemHandler.getClass().getName(), extracted.toString(), remainingCurrentSlot );
|
||||
extracted.setCount( remainingCurrentSlot );
|
||||
}
|
||||
|
||||
// We're just gonna use the first stack we get our hands on as the template for the rest.
|
||||
// In case some stupid itemhandler (aka forge) returns an internal state we have to do a second
|
||||
// expensive copy again.
|
||||
if( gathered.isEmpty() )
|
||||
{
|
||||
gathered = extracted;
|
||||
}
|
||||
else
|
||||
{
|
||||
gathered.grow( extracted.getCount() );
|
||||
}
|
||||
remainingCurrentSlot -= extracted.getCount();
|
||||
}
|
||||
} while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
||||
|
||||
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
|
||||
}
|
||||
else
|
||||
{
|
||||
extracted = this.itemHandler.extractItem( i, remainingSize, true );
|
||||
|
||||
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
extracted.setCount( Math.min( stackInInventorySlot.getCount(), remainingSize ) );
|
||||
// In order to guard against broken IItemHandler implementations, we'll try to guess if the returned
|
||||
// stack (especially in simulate mode) is the same that was returned by getStackInSlot. This is
|
||||
// obviously not a precise science, but it would catch the previous Forge bug:
|
||||
// https://github.com/MinecraftForge/MinecraftForge/pull/6580
|
||||
if( extracted == stackInInventorySlot )
|
||||
{
|
||||
extracted = extracted.copy();
|
||||
}
|
||||
|
||||
if( extracted.getCount() > remainingCurrentSlot )
|
||||
{
|
||||
// Something broke. It should never return more than we requested...
|
||||
// We're going to silently eat the remainder
|
||||
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.", this.itemHandler.getClass().getName(), extracted.toString(), remainingCurrentSlot );
|
||||
extracted.setCount( remainingCurrentSlot );
|
||||
}
|
||||
|
||||
// Heuristic for simulation: looping in case of simulations is pointless, since the state of the
|
||||
// underlying inventory does not change after a simulated extraction. To still support inventories
|
||||
// that report stacks that are larger than maxStackSize, we use this heuristic
|
||||
if( simulate && extracted.getCount() == extracted.getMaxStackSize() && remainingCurrentSlot > extracted.getMaxStackSize() )
|
||||
{
|
||||
extracted.setCount( remainingCurrentSlot );
|
||||
}
|
||||
|
||||
if( gathered.isEmpty() )
|
||||
{
|
||||
gathered = extracted;
|
||||
@@ -201,9 +190,11 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
{
|
||||
gathered.grow( extracted.getCount() );
|
||||
}
|
||||
remainingSize -= extracted.getCount();
|
||||
remainingCurrentSlot -= extracted.getCount();
|
||||
}
|
||||
}
|
||||
} while ( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
||||
|
||||
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
|
||||
if( remainingSize <= 0 )
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -299,6 +299,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
|
||||
{
|
||||
// We need a new stack :-(
|
||||
itemStack = this.createItemStack();
|
||||
itemStack.setCount( Ints.saturatedCast( stackSize ) );
|
||||
}
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user