From ff9a10b926ce2d632ea218372e80aaf51a4176be Mon Sep 17 00:00:00 2001 From: AlgorithmX2 Date: Sun, 22 Jun 2014 02:00:38 -0500 Subject: [PATCH] Crafting is virtually working 100% --- .../implementations/ContainerCraftAmount.java | 1 - .../ContainerCraftConfirm.java | 12 +- core/sync/packets/PacketCraftRequest.java | 2 +- crafting/CraftingJob.java | 31 +++- crafting/CraftingTreeNode.java | 2 +- crafting/CraftingTreeProcess.java | 72 ++++++-- crafting/ICraftingHost.java | 8 - crafting/MECraftingInventory.java | 4 +- me/cache/CraftingCache.java | 10 +- .../implementations/CraftingCPUCluster.java | 166 +++++++++++++++--- parts/automation/PartFormationPlane.java | 12 +- tile/crafting/TileMolecularAssembler.java | 37 +++- util/Platform.java | 30 +++- util/item/ItemList.java | 4 +- 14 files changed, 323 insertions(+), 68 deletions(-) diff --git a/container/implementations/ContainerCraftAmount.java b/container/implementations/ContainerCraftAmount.java index c113faa6b..2115b1d06 100644 --- a/container/implementations/ContainerCraftAmount.java +++ b/container/implementations/ContainerCraftAmount.java @@ -45,7 +45,6 @@ public class ContainerCraftAmount extends AEBaseContainer implements ICraftingHo return h.getActionableNode().getGrid(); } - @Override public World getWorld() { return getPlayerInv().player.worldObj; diff --git a/container/implementations/ContainerCraftConfirm.java b/container/implementations/ContainerCraftConfirm.java index a321e829a..9c42ff42a 100644 --- a/container/implementations/ContainerCraftConfirm.java +++ b/container/implementations/ContainerCraftConfirm.java @@ -40,10 +40,13 @@ public class ContainerCraftConfirm extends AEBaseContainer implements ICraftingH try { result = job.get(); - CraftingCache cc = getGrid().getCache( CraftingCache.class ); - cc.submitJob( result, null, getActionSrc() ); - AELog.info( "Job info is ready!" ); - this.isContainerValid = false; + if ( !result.isSimulation() ) + { + CraftingCache cc = getGrid().getCache( CraftingCache.class ); + cc.submitJob( result, null, getActionSrc() ); + AELog.info( "Job info is ready!" ); + this.isContainerValid = false; + } } catch (Throwable e) { @@ -87,7 +90,6 @@ public class ContainerCraftConfirm extends AEBaseContainer implements ICraftingH return h.getActionableNode().getGrid(); } - @Override public World getWorld() { return getPlayerInv().player.worldObj; diff --git a/core/sync/packets/PacketCraftRequest.java b/core/sync/packets/PacketCraftRequest.java index b104850ec..05cde9f23 100644 --- a/core/sync/packets/PacketCraftRequest.java +++ b/core/sync/packets/PacketCraftRequest.java @@ -78,7 +78,7 @@ public class PacketCraftRequest extends AppEngPacket try { - CraftingJob cj = new CraftingJob( cca, slotItem, Actionable.SIMULATE ); + CraftingJob cj = new CraftingJob( cca.getWorld(), cca, slotItem, Actionable.SIMULATE ); ContainerOpenContext context = cca.openContext; if ( context != null ) diff --git a/crafting/CraftingJob.java b/crafting/CraftingJob.java index 1b3323a95..2f5030946 100644 --- a/crafting/CraftingJob.java +++ b/crafting/CraftingJob.java @@ -5,6 +5,7 @@ import java.util.HashSet; import java.util.concurrent.TimeUnit; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; import appeng.api.AEApi; import appeng.api.config.Actionable; import appeng.api.networking.crafting.ICraftingPatternDetails; @@ -35,14 +36,16 @@ public class CraftingJob implements Runnable public CraftingTreeNode tree; private BaseActionSource actionSrc; + World world; public IAEItemStack getOutput() { return output; } - public CraftingJob(ICraftingHost host, NBTTagCompound data) { + public CraftingJob(World w, ICraftingHost host, NBTTagCompound data) { jobHost = host; + world = wrapWorld( w ); storage = AEApi.instance().storage().createItemList(); prophecies = new HashSet(); original = null; @@ -54,8 +57,9 @@ public class CraftingJob implements Runnable return availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc ); } - public CraftingJob(ICraftingHost host, IAEItemStack what, Actionable mode) { + public CraftingJob(World w, ICraftingHost host, IAEItemStack what, Actionable mode) { jobHost = host; + world = wrapWorld( w ); output = what.copy(); storage = AEApi.instance().storage().createItemList(); prophecies = new HashSet(); @@ -68,6 +72,19 @@ public class CraftingJob implements Runnable tree = getCraftingTree( cc, what ); } + private World wrapWorld(World w) + { + return w; + /* + * -- works on interfaces.. :( try { + * + * InvocationHandler handler = new CraftingWorldSync( w ); Class proxyClass = Proxy.getProxyClass( + * World.class.getClassLoader(), new Class[] { World.class } ); return (World) proxyClass.getConstructor( new + * Class[] { InvocationHandler.class } ).newInstance( new Object[] { handler } ); } catch (Throwable t) { throw + * new RuntimeException( t ); } + */ + } + private CraftingTreeNode getCraftingTree(CraftingCache cc, IAEItemStack what) { return new CraftingTreeNode( cc, this, what, null, -1, 0 ); @@ -191,4 +208,14 @@ public class CraftingJob implements Runnable } + public boolean isSimulation() + { + return simulate; + } + + public World getWorld() + { + return world; + } + } diff --git a/crafting/CraftingTreeNode.java b/crafting/CraftingTreeNode.java index b01b61e8e..3b4861a59 100644 --- a/crafting/CraftingTreeNode.java +++ b/crafting/CraftingTreeNode.java @@ -42,7 +42,7 @@ public class CraftingTreeNode what = wat; parent = par; this.slot = slot; - this.world = job.jobHost.getWorld(); + this.world = job.getWorld(); this.job = job; sim = false; diff --git a/crafting/CraftingTreeProcess.java b/crafting/CraftingTreeProcess.java index a385efb59..9912c7014 100644 --- a/crafting/CraftingTreeProcess.java +++ b/crafting/CraftingTreeProcess.java @@ -4,25 +4,32 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; import appeng.api.AEApi; import appeng.api.config.Actionable; import appeng.api.networking.crafting.ICraftingPatternDetails; import appeng.api.networking.security.BaseActionSource; import appeng.api.storage.data.IAEItemStack; +import appeng.container.ContainerNull; import appeng.me.cache.CraftingCache; import appeng.me.cluster.implementations.CraftingCPUCluster; +import appeng.util.Platform; +import cpw.mods.fml.common.FMLCommonHandler; public class CraftingTreeProcess { + World world; CraftingTreeNode parent; ICraftingPatternDetails details; CraftingJob job; long crafts = 0; boolean damageable; + boolean fullsimulation; final private int depth; @@ -34,19 +41,36 @@ public class CraftingTreeProcess this.details = details; this.job = job; this.depth = depth; + world = job.getWorld(); if ( details.isCraftable() ) { IAEItemStack list[] = details.getInputs(); + InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 ); + IAEItemStack[] is = details.getInputs(); + for (int x = 0; x < ic.getSizeInventory(); x++) + ic.setInventorySlotContents( x, is[x] == null ? null : is[x].getItemStack() ); + + FMLCommonHandler.instance().firePlayerCraftingEvent( Platform.getPlayer( (WorldServer) world ), details.getOutput( ic, world ), ic ); + + for (int x = 0; x < ic.getSizeInventory(); x++) + { + ItemStack g = ic.getStackInSlot( x ); + if ( g != null && g.stackSize > 1 ) + fullsimulation = true; + } + for (int x = 0; x < list.length; x++) { IAEItemStack part = list[x]; if ( part != null ) { - ItemStack is = part.getItemStack(); - if ( is.getItem().hasContainerItem( is ) ) + ItemStack g = part.getItemStack(); + + if ( g.getItem().hasContainerItem( g ) ) damageable = true; + nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() ); } } @@ -67,7 +91,7 @@ public class CraftingTreeProcess long getTimes(long remaining, long stackSize) { - if ( damageable ) + if ( damageable || fullsimulation ) return 1; return (remaining / stackSize) + (remaining % stackSize != 0 ? 1 : 0); } @@ -92,21 +116,41 @@ public class CraftingTreeProcess if ( Thread.interrupted() ) throw new InterruptedException(); - // request and remove inputs... - for (Entry entry : nodes.entrySet()) + if ( fullsimulation ) { - IAEItemStack item = entry.getKey().getStack( entry.getValue() ); - IAEItemStack stack = entry.getKey().request( inv, item.getStackSize() * i, src ); + InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 ); - if ( damageable ) + for (Entry entry : nodes.entrySet()) { - ItemStack is = stack.getItemStack(); - if ( stack.getItem().hasContainerItem( is ) ) - { - is = stack.getItem().getContainerItem( is ); - if ( is.isItemStackDamageable() && is.getItemDamage() == is.getMaxDamage() ) - is = null; + IAEItemStack item = entry.getKey().getStack( entry.getValue() ); + IAEItemStack stack = entry.getKey().request( inv, item.getStackSize(), src ); + ic.setInventorySlotContents( entry.getKey().slot, stack.getItemStack() ); + } + + FMLCommonHandler.instance().firePlayerCraftingEvent( Platform.getPlayer( (WorldServer) world ), details.getOutput( ic, world ), ic ); + + for (int x = 0; x < ic.getSizeInventory(); x++) + { + ItemStack is = ic.getStackInSlot( x ); + is = Platform.getContainerItem( is ); + + IAEItemStack o = AEApi.instance().storage().createItemStack( is ); + if ( o != null ) + inv.injectItems( o, Actionable.MODULATE, src ); + } + } + else + { + // request and remove inputs... + for (Entry entry : nodes.entrySet()) + { + IAEItemStack item = entry.getKey().getStack( entry.getValue() ); + IAEItemStack stack = entry.getKey().request( inv, item.getStackSize() * i, src ); + + if ( damageable ) + { + ItemStack is = Platform.getContainerItem( stack.getItemStack() ); IAEItemStack o = AEApi.instance().storage().createItemStack( is ); if ( o != null ) inv.injectItems( o, Actionable.MODULATE, src ); diff --git a/crafting/ICraftingHost.java b/crafting/ICraftingHost.java index 880afedc8..015286a81 100644 --- a/crafting/ICraftingHost.java +++ b/crafting/ICraftingHost.java @@ -1,6 +1,5 @@ package appeng.crafting; -import net.minecraft.world.World; import appeng.api.networking.IGrid; import appeng.api.networking.security.BaseActionSource; @@ -12,13 +11,6 @@ public interface ICraftingHost */ IGrid getGrid(); - /** - * required for crafting calculations. - * - * @return world the host is located in - */ - World getWorld(); - /** * get source of moving items around. * diff --git a/crafting/MECraftingInventory.java b/crafting/MECraftingInventory.java index ab73d9ea4..eeef951bd 100644 --- a/crafting/MECraftingInventory.java +++ b/crafting/MECraftingInventory.java @@ -185,6 +185,8 @@ public class MECraftingInventory implements IMEInventory public void ignore(IAEItemStack what) { - + IAEItemStack list = localCache.findPrecise( what ); + if ( list != null ) + list.setStackSize( 0 ); } } diff --git a/me/cache/CraftingCache.java b/me/cache/CraftingCache.java index f4f775a77..5185e042a 100644 --- a/me/cache/CraftingCache.java +++ b/me/cache/CraftingCache.java @@ -261,13 +261,19 @@ public class CraftingCache implements IGridCache, ICraftingProviderHelper, ICell public boolean submitJob(CraftingJob job, CraftingCPUCluster target, BaseActionSource src) { + if ( job.isSimulation() ) + return false; + if ( target == null ) { // TODO real stuff... for (CraftingCPUCluster cpu : cpuClusters) { - target = cpu; - break; + if ( !cpu.isBusy() ) + { + target = cpu; + break; + } } } diff --git a/me/cluster/implementations/CraftingCPUCluster.java b/me/cluster/implementations/CraftingCPUCluster.java index bcb670009..591bd3482 100644 --- a/me/cluster/implementations/CraftingCPUCluster.java +++ b/me/cluster/implementations/CraftingCPUCluster.java @@ -9,6 +9,7 @@ import java.util.Map.Entry; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; import appeng.api.AEApi; import appeng.api.config.Actionable; import appeng.api.config.FuzzyMode; @@ -33,7 +34,9 @@ import appeng.crafting.MECraftingInventory; import appeng.me.cache.CraftingCache; import appeng.me.cluster.IAECluster; import appeng.tile.crafting.TileCraftingTile; +import appeng.util.Platform; import appeng.util.item.AEItemStack; +import cpw.mods.fml.common.FMLCommonHandler; public class CraftingCPUCluster implements IAECluster { @@ -41,6 +44,7 @@ public class CraftingCPUCluster implements IAECluster public WorldCoord min; public WorldCoord max; public boolean isDestroyed = false; + private boolean isComplete = true; class TaskProgress { @@ -60,6 +64,7 @@ public class CraftingCPUCluster implements IAECluster MECraftingInventory inventory = new MECraftingInventory(); IAEItemStack finalOutput; + BaseActionSource mySrc; boolean waiting = false; Map tasks = new HashMap(); @@ -149,11 +154,19 @@ public class CraftingCPUCluster implements IAECluster { is.decStackSize( input.getStackSize() ); - AELog.info( "Task: " + is.getStackSize() + " remaining : " + getRemainingTasks() + " remaining : " - + (is.getStackSize() + getRemainingTasks()) + " total left : waiting: " + (waiting ? "yes" : "no") ); + // AELog.info( "Task: " + is.getStackSize() + " remaining : " + getRemainingTasks() + + // " remaining : " + // + (is.getStackSize() + getRemainingTasks()) + " total left : waiting: " + (waiting ? "yes" : + // "no") ); if ( finalOutput.equals( input ) ) + { + finalOutput.decStackSize( input.getStackSize() ); + if ( finalOutput.getStackSize() <= 0 ) + completeJob(); + return input; // ignore it. + } // 2000 return inventory.injectItems( what, type, src ); @@ -163,13 +176,20 @@ public class CraftingCPUCluster implements IAECluster insert.setStackSize( is.getStackSize() ); what.decStackSize( is.getStackSize() ); - AELog.info( "Task: " + is.getStackSize() + " remaining : " + getRemainingTasks() + " remaining : " + (is.getStackSize() + getRemainingTasks()) - + " total left : waiting: " + (waiting ? "yes" : "no") ); + // AELog.info( "Task: " + is.getStackSize() + " remaining : " + getRemainingTasks() + " remaining : " + + // (is.getStackSize() + getRemainingTasks()) + // + " total left : waiting: " + (waiting ? "yes" : "no") ); is.setStackSize( 0 ); if ( finalOutput.equals( input ) ) + { + finalOutput.decStackSize( input.getStackSize() ); + if ( finalOutput.getStackSize() <= 0 ) + completeJob(); + return input; // ignore it. + } inventory.injectItems( insert, type, src ); @@ -180,6 +200,20 @@ public class CraftingCPUCluster implements IAECluster return input; } + public IGrid getGrid() + { + for (TileCraftingTile r : tiles) + return r.getActionableNode().getGrid(); + + throw new RuntimeException( "No tiles inside a cpu cluster." ); + } + + private void completeJob() + { + AELog.info( "marking job as complete" ); + isComplete = true; + } + private int getRemainingTasks() { int o = 0; @@ -188,19 +222,72 @@ public class CraftingCPUCluster implements IAECluster return o; } - private boolean canCraft(IAEItemStack[] condencedInputs) + private boolean canCraft(ICraftingPatternDetails details, IAEItemStack[] condencedInputs) { - for (IAEItemStack is : condencedInputs) + for (IAEItemStack g : condencedInputs) { - IAEItemStack avail = inventory.extractItems( is, Actionable.SIMULATE, null ); - if ( avail == null || avail.getStackSize() < is.getStackSize() ) - return false; + + if ( details.isCraftable() ) + { + boolean found = false; + + for (IAEItemStack fuzz : inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL )) + { + fuzz = fuzz.copy(); + fuzz.setStackSize( g.getStackSize() ); + IAEItemStack ais = inventory.extractItems( fuzz, Actionable.SIMULATE, null ); + ItemStack is = ais == null ? null : ais.getItemStack(); + + if ( is != null && is.stackSize == g.getStackSize() ) + { + found = true; + break; + } + } + + if ( !found ) + return false; + } + else + { + IAEItemStack ais = inventory.extractItems( g.copy(), Actionable.SIMULATE, null ); + ItemStack is = ais == null ? null : ais.getItemStack(); + + if ( is == null || is.stackSize < g.getStackSize() ) + return false; + } } + return true; } public void updateCraftingLogic(IGrid grid, CraftingCache cc) { + if ( isComplete ) + { + if ( inventory.getItemList().isEmpty() ) + return; + + IStorageGrid sg = grid.getCache( IStorageGrid.class ); + IMEInventory ii = sg.getItemInventory(); + + for (IAEItemStack is : inventory.getItemList()) + { + is = inventory.extractItems( is.copy(), Actionable.MODULATE, mySrc ); + + if ( is != null ) + is = ii.injectItems( is, Actionable.MODULATE, mySrc ); + + if ( is != null ) + inventory.injectItems( is, Actionable.MODULATE, mySrc ); + } + + if ( inventory.getItemList().isEmpty() ) + inventory = new MECraftingInventory(); + + return; + } + waiting = false; if ( waiting || tasks.isEmpty() ) // nothing to do here... return; @@ -214,7 +301,7 @@ public class CraftingCPUCluster implements IAECluster continue; ICraftingPatternDetails details = e.getKey(); - if ( canCraft( details.getCondencedInputs() ) ) + if ( canCraft( details, details.getCondencedInputs() ) ) { InventoryCrafting ic = null; @@ -228,21 +315,22 @@ public class CraftingCPUCluster implements IAECluster if ( ic == null ) { ic = new InventoryCrafting( new ContainerNull(), 3, 3 ); + boolean found = false; IAEItemStack[] input = details.getInputs(); for (int x = 0; x < input.length; x++) { + if ( input[x] != null ) { - boolean found = true; - + found = false; if ( details.isCraftable() ) { 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, mySrc ); ItemStack is = ais == null ? null : ais.getItemStack(); if ( is != null && details.isValidItemForSlot( x, is, getWorld() ) ) @@ -255,7 +343,7 @@ public class CraftingCPUCluster implements IAECluster } else { - IAEItemStack ais = inventory.extractItems( input[x].copy(), Actionable.MODULATE, null ); + IAEItemStack ais = inventory.extractItems( input[x].copy(), Actionable.MODULATE, mySrc ); ItemStack is = ais == null ? null : ais.getItemStack(); if ( is != null ) @@ -269,6 +357,20 @@ public class CraftingCPUCluster implements IAECluster if ( !found ) break; } + + } + + if ( !found ) + { + // put stuff back.. + for (int x = 0; x < ic.getSizeInventory(); x++) + { + ItemStack is = ic.getStackInSlot( x ); + if ( is != null ) + inventory.injectItems( AEItemStack.create( is ), Actionable.MODULATE, mySrc ); + } + ic = null; + break; } } @@ -280,6 +382,19 @@ public class CraftingCPUCluster implements IAECluster for (IAEItemStack out : details.getCondencedOutputs()) waitingFor.add( out.copy() ); + if ( details.isCraftable() ) + { + FMLCommonHandler.instance().firePlayerCraftingEvent( Platform.getPlayer( (WorldServer) getWorld() ), + details.getOutput( ic, getWorld() ), ic ); + + for (int x = 0; x < ic.getSizeInventory(); x++) + { + ItemStack output = Platform.getContainerItem( ic.getStackInSlot( x ) ); + if ( output != null ) + waitingFor.add( AEItemStack.create( output ) ); + } + } + ic = null; // hand off complete! e.getValue().value--; @@ -299,7 +414,7 @@ public class CraftingCPUCluster implements IAECluster { ItemStack is = ic.getStackInSlot( x ); if ( is != null ) - inventory.injectItems( AEItemStack.create( is ), Actionable.MODULATE, null ); + inventory.injectItems( AEItemStack.create( is ), Actionable.MODULATE, mySrc ); } } } @@ -316,13 +431,6 @@ public class CraftingCPUCluster implements IAECluster public boolean submitJob(IGrid g, CraftingJob job, BaseActionSource src) { - Iterator> i = tasks.entrySet().iterator(); - while (i.hasNext()) - { - if ( i.next().getValue().value <= 0 ) - i.remove(); - } - if ( !tasks.isEmpty() || !waitingFor.isEmpty() ) return false; @@ -337,6 +445,8 @@ public class CraftingCPUCluster implements IAECluster ci.commit( src ); finalOutput = job.getOutput(); waiting = false; + isComplete = false; + mySrc = src; return true; } catch (CraftBranchFailure e) @@ -363,4 +473,16 @@ public class CraftingCPUCluster implements IAECluster i.value += crafts; } + + public boolean isBusy() + { + Iterator> i = tasks.entrySet().iterator(); + while (i.hasNext()) + { + if ( i.next().getValue().value <= 0 ) + i.remove(); + } + + return !tasks.isEmpty() || !waitingFor.isEmpty(); + } } diff --git a/parts/automation/PartFormationPlane.java b/parts/automation/PartFormationPlane.java index c20998803..91a60401f 100644 --- a/parts/automation/PartFormationPlane.java +++ b/parts/automation/PartFormationPlane.java @@ -9,6 +9,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemFirework; import net.minecraft.item.ItemSkull; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -385,11 +386,20 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine if ( w.getBlock( x, y, z ).isReplaceable( w, x, y, z ) ) { - if ( i instanceof ItemBlock || i instanceof IPlantable || i instanceof ItemSkull || i instanceof IPartItem ) + if ( i instanceof ItemBlock || i instanceof IPlantable || i instanceof ItemSkull || i instanceof ItemFirework || i instanceof IPartItem ) { EntityPlayer player = Platform.getPlayer( (WorldServer) w ); Platform.configurePlayer( player, side, tile ); + if ( i instanceof ItemFirework ) + { + Chunk c = w.getChunkFromBlockCoords( x, z ); + int sum = 0; + for (List Z : c.entityLists) + sum += Z.size(); + if ( sum > 32 ) + return input; + } maxStorage = is.stackSize; worked = true; if ( type == Actionable.MODULATE ) diff --git a/tile/crafting/TileMolecularAssembler.java b/tile/crafting/TileMolecularAssembler.java index 00aecdf31..769a028e0 100644 --- a/tile/crafting/TileMolecularAssembler.java +++ b/tile/crafting/TileMolecularAssembler.java @@ -7,6 +7,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; import net.minecraftforge.common.util.ForgeDirection; import appeng.api.AEApi; import appeng.api.config.Actionable; @@ -38,6 +39,7 @@ import appeng.util.ConfigManager; import appeng.util.IConfigManagerHost; import appeng.util.InventoryAdaptor; import appeng.util.Platform; +import cpw.mods.fml.common.FMLCommonHandler; public class TileMolecularAssembler extends AENetworkInvTile implements IAEAppEngInventory, ISidedInventory, IUpgradeableHost, IConfigManagerHost, IGridTickable, ICraftingMachine @@ -326,7 +328,9 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IAEAppEn if ( inv.getStackInSlot( 9 ) != null ) { pushOut( inv.getStackInSlot( 9 ) ); - return inv.getStackInSlot( 9 ) == null ? TickRateModulation.SLEEP : TickRateModulation.IDLE; + ejectHeldItems(); + isAwake = inv.getStackInSlot( 9 ) != null; + return isAwake ? TickRateModulation.SLEEP : TickRateModulation.IDLE; } if ( myPlan == null ) @@ -366,18 +370,43 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IAEAppEn ItemStack output = myPlan.getOutput( craftingInv, getWorldObj() ); if ( output != null ) { + FMLCommonHandler.instance().firePlayerCraftingEvent( Platform.getPlayer( (WorldServer) getWorldObj() ), output, craftingInv ); + for (int x = 0; x < craftingInv.getSizeInventory(); x++) - inv.setInventorySlotContents( x, null ); + inv.setInventorySlotContents( x, Platform.getContainerItem( craftingInv.getStackInSlot( x ) ) ); pushOut( output.copy() ); - isAwake = false; - return inv.getStackInSlot( 9 ) == null ? TickRateModulation.SLEEP : TickRateModulation.IDLE; + + if ( inv.getStackInSlot( 10 ) == null ) + myPlan = null; + + ejectHeldItems(); + + isAwake = inv.getStackInSlot( 9 ) != null; + return isAwake ? TickRateModulation.SLEEP : TickRateModulation.IDLE; } } return TickRateModulation.FASTER; } + private void ejectHeldItems() + { + if ( myPlan == null && inv.getStackInSlot( 9 ) == null ) + { + for (int x = 0; x < 9; x++) + { + ItemStack is = inv.getStackInSlot( x ); + if ( is != null ) + { + inv.setInventorySlotContents( 9, is ); + inv.setInventorySlotContents( x, null ); + return; + } + } + } + } + private int userPower(int i) { try diff --git a/util/Platform.java b/util/Platform.java index 6b9a44959..4607d185f 100644 --- a/util/Platform.java +++ b/util/Platform.java @@ -1233,10 +1233,9 @@ public class Platform Vec3 vec31 = vec3.addVector( (double) f7 * d3, (double) f6 * d3, (double) f8 * d3 ); - AxisAlignedBB bb = AxisAlignedBB - .getBoundingBox( Math.min( vec3.xCoord, vec31.xCoord ), Math.min( vec3.yCoord, vec31.yCoord ), Math.min( vec3.zCoord, vec31.zCoord ), - Math.max( vec3.xCoord, vec31.xCoord ), Math.max( vec3.yCoord, vec31.yCoord ), Math.max( vec3.zCoord, vec31.zCoord ) ) - .expand( 16, 16, 16 ); + AxisAlignedBB bb = AxisAlignedBB.getBoundingBox( Math.min( vec3.xCoord, vec31.xCoord ), Math.min( vec3.yCoord, vec31.yCoord ), + Math.min( vec3.zCoord, vec31.zCoord ), Math.max( vec3.xCoord, vec31.xCoord ), Math.max( vec3.yCoord, vec31.yCoord ), + Math.max( vec3.zCoord, vec31.zCoord ) ).expand( 16, 16, 16 ); Entity entity = null; double Closeest = 9999999.0D; @@ -1643,4 +1642,27 @@ public class Platform return null; } + public static ItemStack getContainerItem(ItemStack stackInSlot) + { + if ( stackInSlot == null ) + return null; + + Item i = stackInSlot.getItem(); + if ( i == null || !i.hasContainerItem( stackInSlot ) ) + { + if ( stackInSlot.stackSize > 1 ) + { + stackInSlot.stackSize--; + return stackInSlot; + } + return null; + } + + ItemStack ci = i.getContainerItem( stackInSlot.copy() ); + if ( ci.isItemStackDamageable() && ci.getItemDamage() == ci.getMaxDamage() ) + ci = null; + + return ci; + } + } diff --git a/util/item/ItemList.java b/util/item/ItemList.java index 97af438b2..e74f7b624 100644 --- a/util/item/ItemList.java +++ b/util/item/ItemList.java @@ -183,14 +183,14 @@ public final class ItemList implements IItemList findFuzzyDamage(AEItemStack filter, FuzzyMode fuzzy, boolean ignoreMeta) { StackType low = (StackType) filter.getLow( fuzzy, ignoreMeta ); StackType high = (StackType) filter.getHigh( fuzzy, ignoreMeta ); - return records.subMap( low, true, high, true ).values(); + return records.subMap( low, true, high, true ).descendingMap().values(); } @Override