Recursive crafting works.

MA's can accept pushes.
Interfaces no alter pushing behavior depending on ICraftingMachine settings.
Fixed bug where crafting would record items that don't exist as available for the initial pull.
This commit is contained in:
AlgorithmX2 2014-06-20 02:12:39 -05:00
parent fea125a993
commit 6cbc5aa953
6 changed files with 64 additions and 28 deletions

View file

@ -1,6 +1,7 @@
package appeng.crafting; package appeng.crafting;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.util.Platform;
public class CraftBranchFailure extends Exception public class CraftBranchFailure extends Exception
{ {
@ -10,7 +11,7 @@ public class CraftBranchFailure extends Exception
IAEItemStack missing; IAEItemStack missing;
public CraftBranchFailure(IAEItemStack what, long howMany) { public CraftBranchFailure(IAEItemStack what, long howMany) {
super( "this should have been caught!" ); super( "Failed: " + Platform.getItemDisplayName( what ) + " x " + howMany );
missing = what.copy(); missing = what.copy();
missing.setStackSize( howMany ); missing.setStackSize( howMany );
} }

View file

@ -31,6 +31,7 @@ public class CraftingJob implements Runnable
boolean simulate = false; boolean simulate = false;
final MECraftingInventory original; final MECraftingInventory original;
final MECraftingInventory availableCheck;
public CraftingTreeNode tree; public CraftingTreeNode tree;
private BaseActionSource actionSrc; private BaseActionSource actionSrc;
@ -45,6 +46,12 @@ public class CraftingJob implements Runnable
storage = AEApi.instance().storage().createItemList(); storage = AEApi.instance().storage().createItemList();
prophecies = new HashSet(); prophecies = new HashSet();
original = null; original = null;
availableCheck = null;
}
public IAEItemStack checkUse(IAEItemStack available)
{
return availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
} }
public CraftingJob(ICraftingHost host, IAEItemStack what, Actionable mode) { public CraftingJob(ICraftingHost host, IAEItemStack what, Actionable mode) {
@ -57,7 +64,7 @@ public class CraftingJob implements Runnable
CraftingCache cc = host.getGrid().getCache( CraftingCache.class ); CraftingCache cc = host.getGrid().getCache( CraftingCache.class );
IStorageGrid sg = host.getGrid().getCache( IStorageGrid.class ); IStorageGrid sg = host.getGrid().getCache( IStorageGrid.class );
original = new MECraftingInventory( sg.getItemInventory(), false, false, false ); original = new MECraftingInventory( sg.getItemInventory(), false, false, false );
availableCheck = new MECraftingInventory( sg.getItemInventory(), false, false, false );
tree = getCraftingTree( cc, what ); tree = getCraftingTree( cc, what );
} }

View file

@ -32,6 +32,7 @@ public class CraftingTreeNode
boolean cannotUse = false; boolean cannotUse = false;
long missing = 0; long missing = 0;
CraftingJob job;
IItemList<IAEItemStack> used = AEApi.instance().storage().createItemList(); IItemList<IAEItemStack> used = AEApi.instance().storage().createItemList();
boolean exhausted = false; boolean exhausted = false;
@ -42,6 +43,7 @@ public class CraftingTreeNode
parent = par; parent = par;
this.slot = slot; this.slot = slot;
this.world = job.jobHost.getWorld(); this.world = job.jobHost.getWorld();
this.job = job;
sim = false; sim = false;
for (ICraftingPatternDetails details : cc.getCraftingFor( what ))// in order. for (ICraftingPatternDetails details : cc.getCraftingFor( what ))// in order.
@ -90,7 +92,7 @@ public class CraftingTreeNode
if ( available != null ) if ( available != null )
{ {
if ( !exhausted ) if ( !exhausted )
used.add( available ); used.add( job.checkUse( available ) );
l -= available.getStackSize(); l -= available.getStackSize();
if ( l == 0 ) if ( l == 0 )
@ -106,7 +108,7 @@ public class CraftingTreeNode
if ( available != null ) if ( available != null )
{ {
if ( !exhausted ) if ( !exhausted )
used.add( available ); used.add( job.checkUse( available ) );
l -= available.getStackSize(); l -= available.getStackSize();
if ( l == 0 ) if ( l == 0 )

View file

@ -706,29 +706,31 @@ public class DualityInterface implements IGridTickable, ISegmentedInventory, ISt
TileEntity te = w.getTileEntity( tile.xCoord + s.offsetX, tile.yCoord + s.offsetY, tile.zCoord + s.offsetZ ); TileEntity te = w.getTileEntity( tile.xCoord + s.offsetX, tile.yCoord + s.offsetY, tile.zCoord + s.offsetZ );
if ( te instanceof ICraftingMachine ) if ( te instanceof ICraftingMachine )
{ {
if ( ((ICraftingMachine) te).pushPattern( patternDetails, table, s.getOpposite() ) ) ICraftingMachine cm = (ICraftingMachine) te;
return true; if ( cm.acceptsPlans() )
}
else
{
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if ( ad != null )
{ {
possibleDirections.remove( s ); if ( cm.pushPattern( patternDetails, table, s.getOpposite() ) )
return true;
for (int x = 0; x < table.getSizeInventory(); x++) continue;
{
ItemStack is = table.getStackInSlot( x );
if ( is != null )
{
addToSendList( ad.addItems( is ) );
}
}
pushItemsOut( possibleDirections );
return true;
} }
} }
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if ( ad != null )
{
for (int x = 0; x < table.getSizeInventory(); x++)
{
ItemStack is = table.getStackInSlot( x );
if ( is != null )
{
addToSendList( ad.addItems( is ) );
}
}
pushItemsOut( possibleDirections );
return true;
}
} }
return false; return false;

View file

@ -136,7 +136,7 @@ public class CraftingCPUCluster implements IAECluster
public IAEStack injectItems(IAEStack input, Actionable type, BaseActionSource src) public IAEStack injectItems(IAEStack input, Actionable type, BaseActionSource src)
{ {
if ( input instanceof IAEItemStack ) if ( input instanceof IAEItemStack && type == Actionable.MODULATE )
{ {
IAEItemStack what = (IAEItemStack) input; IAEItemStack what = (IAEItemStack) input;
IAEItemStack is = waitingFor.findPrecise( what ); IAEItemStack is = waitingFor.findPrecise( what );
@ -149,21 +149,29 @@ public class CraftingCPUCluster implements IAECluster
{ {
is.decStackSize( input.getStackSize() ); is.decStackSize( input.getStackSize() );
AELog.info( "Task: " + is.getStackSize() + " remaining : " + getRemainingTasks() + " remaining : "
+ (is.getStackSize() + getRemainingTasks()) + " total left : waiting: " + (waiting ? "yes" : "no") );
if ( finalOutput.equals( input ) ) if ( finalOutput.equals( input ) )
return input; // ignore it. return input; // ignore it.
return inventory.injectItems( what, Actionable.MODULATE, src ); // 2000
return inventory.injectItems( what, type, src );
} }
IAEItemStack insert = what.copy(); IAEItemStack insert = what.copy();
insert.setStackSize( is.getStackSize() ); insert.setStackSize( is.getStackSize() );
what.decStackSize( is.getStackSize() ); what.decStackSize( is.getStackSize() );
AELog.info( "Task: " + is.getStackSize() + " remaining : " + getRemainingTasks() + " remaining : " + (is.getStackSize() + getRemainingTasks())
+ " total left : waiting: " + (waiting ? "yes" : "no") );
is.setStackSize( 0 ); is.setStackSize( 0 );
if ( finalOutput.equals( input ) ) if ( finalOutput.equals( input ) )
return input; // ignore it. return input; // ignore it.
inventory.injectItems( insert, Actionable.MODULATE, src ); inventory.injectItems( insert, type, src );
return what; return what;
} }
@ -172,6 +180,14 @@ public class CraftingCPUCluster implements IAECluster
return input; return input;
} }
private int getRemainingTasks()
{
int o = 0;
for (Entry<ICraftingPatternDetails, TaskProgress> tp : tasks.entrySet())
o += tp.getValue().value * tp.getKey().getCondencedOutputs()[0].getStackSize();
return o;
}
private boolean canCraft(IAEItemStack[] condencedInputs) private boolean canCraft(IAEItemStack[] condencedInputs)
{ {
for (IAEItemStack is : condencedInputs) for (IAEItemStack is : condencedInputs)
@ -185,6 +201,7 @@ public class CraftingCPUCluster implements IAECluster
public void updateCraftingLogic(IGrid grid, CraftingCache cc) public void updateCraftingLogic(IGrid grid, CraftingCache cc)
{ {
waiting = false;
if ( waiting || tasks.isEmpty() ) // nothing to do here... if ( waiting || tasks.isEmpty() ) // nothing to do here...
return; return;
@ -203,6 +220,9 @@ public class CraftingCPUCluster implements IAECluster
for (ICraftingMedium m : cc.getMediums( e.getKey() )) for (ICraftingMedium m : cc.getMediums( e.getKey() ))
{ {
if ( e.getValue().value <= 0 )
continue;
if ( !m.isBusy() ) if ( !m.isBusy() )
{ {
if ( ic == null ) if ( ic == null )
@ -220,6 +240,8 @@ public class CraftingCPUCluster implements IAECluster
{ {
for (IAEItemStack fuzz : inventory.getItemList().findFuzzy( input[x], FuzzyMode.IGNORE_ALL )) for (IAEItemStack fuzz : inventory.getItemList().findFuzzy( input[x], FuzzyMode.IGNORE_ALL ))
{ {
fuzz = fuzz.copy();
fuzz.setStackSize( input[x].getStackSize() );
IAEItemStack ais = inventory.extractItems( fuzz, Actionable.MODULATE, null ); IAEItemStack ais = inventory.extractItems( fuzz, Actionable.MODULATE, null );
ItemStack is = ais == null ? null : ais.getItemStack(); ItemStack is = ais == null ? null : ais.getItemStack();
@ -310,6 +332,7 @@ public class CraftingCPUCluster implements IAECluster
try try
{ {
waitingFor.resetStatus();
job.tree.setJob( ci, this, src ); job.tree.setJob( ci, this, src );
ci.commit( src ); ci.commit( src );
finalOutput = job.getOutput(); finalOutput = job.getOutput();

View file

@ -15,6 +15,7 @@ import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.api.config.Upgrades; import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost; import appeng.api.implementations.IUpgradeableHost;
import appeng.api.implementations.tiles.ICraftingMachine;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingPatternDetails; import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.IGridTickable;
@ -39,7 +40,7 @@ import appeng.util.InventoryAdaptor;
import appeng.util.Platform; import appeng.util.Platform;
public class TileMolecularAssembler extends AENetworkInvTile implements IAEAppEngInventory, ISidedInventory, IUpgradeableHost, IConfigManagerHost, public class TileMolecularAssembler extends AENetworkInvTile implements IAEAppEngInventory, ISidedInventory, IUpgradeableHost, IConfigManagerHost,
IGridTickable IGridTickable, ICraftingMachine
{ {
static final int[] sides = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; static final int[] sides = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };