package appeng.crafting; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import net.minecraft.nbt.NBTTagCompound; import appeng.api.AEApi; import appeng.api.config.Actionable; import appeng.api.networking.crafting.ICraftingPatternDetails; import appeng.api.networking.storage.IStorageGrid; import appeng.api.storage.IMEInventory; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IItemList; import appeng.me.cache.CraftingCache; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; public class CraftingJob implements ICraftingParent { IAEItemStack output; IItemList storage; HashSet prophecies; Multimap bottom; CraftingTask top; ICraftingHost jobHost; public CraftingJob(ICraftingHost host, NBTTagCompound data) { jobHost = host; storage = AEApi.instance().storage().createItemList(); prophecies = new HashSet(); bottom = ArrayListMultimap.create(); } public CraftingJob(ICraftingHost host, IAEItemStack what, Actionable mode) throws CraftingMissingItemsException { jobHost = host; output = what.copy(); storage = AEApi.instance().storage().createItemList(); prophecies = new HashSet(); bottom = ArrayListMultimap.create(); CraftingCache cc = host.getGrid().getCache( CraftingCache.class ); IStorageGrid sg = host.getGrid().getCache( IStorageGrid.class ); IItemList missing = AEApi.instance().storage().createItemList(); MECraftingInventory meci = new MECraftingInventory( sg.getItemInventory() ); calculateCrafting( cc, this, meci, missing, what, mode ); if ( !missing.isEmpty() ) { if ( mode == Actionable.MODULATE ) { IMEInventory netStorage = sg.getItemInventory(); Iterator i = storage.iterator(); while (i.hasNext()) { IAEItemStack item = i.next(); netStorage.injectItems( item, mode, host.getActionSrc() ); } } throw new CraftingMissingItemsException( missing ); } if ( mode == Actionable.MODULATE ) meci.moveItemsToStorage( storage ); } public void calculateCrafting(CraftingCache cc, ICraftingParent parent, IMEInventory inv, IItemList missing, IAEItemStack what, Actionable mode) { Set patterns = cc.getCraftingFor( what ); for (ICraftingPatternDetails details : patterns) { IAEItemStack[] requirements = details.getCondencedInputs(); if ( canMake( requirements, inv ) ) { extractItems( requirements, inv, storage, missing ); return; } } for (ICraftingPatternDetails details : patterns) { IAEItemStack[] requirements = details.getCondencedInputs(); extractItems( requirements, inv, storage, missing ); return; } } private void extractItems(IAEItemStack[] requirements, IMEInventory inv, IItemList dest, IItemList missing) { for (IAEItemStack is : requirements) { IAEItemStack avail = inv.extractItems( is, Actionable.MODULATE, jobHost.getActionSrc() ); if ( avail == null ) { missing.add( is ); continue; } if ( avail.getStackSize() != is.getStackSize() ) { IAEItemStack ais = avail.copy(); ais.setStackSize( is.getStackSize() - avail.getStackSize() ); missing.add( ais ); } dest.add( avail ); } } private boolean canMake(IAEItemStack[] requirements, IMEInventory inv) { for (IAEItemStack is : requirements) { IAEItemStack avail = inv.extractItems( is, Actionable.SIMULATE, jobHost.getActionSrc() ); if ( avail == null ) return false; if ( avail.getStackSize() != is.getStackSize() ) return false; } return true; } public Collection getBottom() { return bottom.values(); } public IAEItemStack addProgress(IAEItemStack progress) { Collection task = bottom.get( progress ); if ( task == null ) return progress; Iterator i = task.iterator(); while (i.hasNext()) { // adding to the first item.. progress = i.next().addProgress( progress ); // if nothing remains return if ( progress == null ) return null; // if something remains continue.. i = task.iterator(); } return null; } @Override public void writeToNBT(NBTTagCompound out) { } @Override public void removeChild(CraftingTask craftingTask) { // TODO Auto-generated method stub } public ICraftingHost getHost() { // TODO Auto-generated method stub return null; } @Override public Collection getSubJobs() { return Collections.singleton( top ); } }