Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d1c502b41 | |||
| 63653c1833 | |||
| 6cadfbdcdc | |||
| d054c6ab91 | |||
| 234b1c5dc6 | |||
| 8cc29734a2 |
+1
-1
@@ -4,7 +4,7 @@ aebuild=7
|
|||||||
aegroup=appeng
|
aegroup=appeng
|
||||||
aebasename=appliedenergistics2
|
aebasename=appliedenergistics2
|
||||||
extended=extended_life
|
extended=extended_life
|
||||||
extendedversion=v51g
|
extendedversion=v52b
|
||||||
#########################################################
|
#########################################################
|
||||||
# Versions #
|
# Versions #
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|||||||
@@ -24,34 +24,9 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import appeng.core.sync.packets.*;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
import appeng.core.sync.packets.PacketAssemblerAnimation;
|
|
||||||
import appeng.core.sync.packets.PacketClick;
|
|
||||||
import appeng.core.sync.packets.PacketCompassRequest;
|
|
||||||
import appeng.core.sync.packets.PacketCompassResponse;
|
|
||||||
import appeng.core.sync.packets.PacketCompressedNBT;
|
|
||||||
import appeng.core.sync.packets.PacketConfigButton;
|
|
||||||
import appeng.core.sync.packets.PacketCraftRequest;
|
|
||||||
import appeng.core.sync.packets.PacketFluidSlot;
|
|
||||||
import appeng.core.sync.packets.PacketInventoryAction;
|
|
||||||
import appeng.core.sync.packets.PacketJEIRecipe;
|
|
||||||
import appeng.core.sync.packets.PacketLightning;
|
|
||||||
import appeng.core.sync.packets.PacketMEFluidInventoryUpdate;
|
|
||||||
import appeng.core.sync.packets.PacketMEInventoryUpdate;
|
|
||||||
import appeng.core.sync.packets.PacketMatterCannon;
|
|
||||||
import appeng.core.sync.packets.PacketMockExplosion;
|
|
||||||
import appeng.core.sync.packets.PacketPaintedEntity;
|
|
||||||
import appeng.core.sync.packets.PacketPartPlacement;
|
|
||||||
import appeng.core.sync.packets.PacketPatternSlot;
|
|
||||||
import appeng.core.sync.packets.PacketProgressBar;
|
|
||||||
import appeng.core.sync.packets.PacketSwapSlots;
|
|
||||||
import appeng.core.sync.packets.PacketSwitchGuis;
|
|
||||||
import appeng.core.sync.packets.PacketTargetFluidStack;
|
|
||||||
import appeng.core.sync.packets.PacketTargetItemStack;
|
|
||||||
import appeng.core.sync.packets.PacketTransitionEffect;
|
|
||||||
import appeng.core.sync.packets.PacketValueConfig;
|
|
||||||
|
|
||||||
|
|
||||||
public class AppEngPacketHandlerBase
|
public class AppEngPacketHandlerBase
|
||||||
{
|
{
|
||||||
@@ -107,7 +82,10 @@ public class AppEngPacketHandlerBase
|
|||||||
|
|
||||||
PACKET_PAINTED_ENTITY( PacketPaintedEntity.class ),
|
PACKET_PAINTED_ENTITY( PacketPaintedEntity.class ),
|
||||||
|
|
||||||
PACKET_FLUID_TANK( PacketFluidSlot.class );
|
PACKET_FLUID_TANK( PacketFluidSlot.class ),
|
||||||
|
|
||||||
|
PACKET_INFORM_PLAYER( PacketInformPlayer.class );
|
||||||
|
|
||||||
|
|
||||||
private final Class<? extends AppEngPacket> packetClass;
|
private final Class<? extends AppEngPacket> packetClass;
|
||||||
private final Constructor<? extends AppEngPacket> packetConstructor;
|
private final Constructor<? extends AppEngPacket> packetConstructor;
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package appeng.core.sync.packets;
|
||||||
|
|
||||||
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
|
import appeng.core.AppEng;
|
||||||
|
import appeng.core.sync.AppEngPacket;
|
||||||
|
import appeng.core.sync.network.INetworkInfo;
|
||||||
|
import appeng.util.item.AEItemStack;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.util.text.TextComponentString;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class PacketInformPlayer extends AppEngPacket
|
||||||
|
{
|
||||||
|
private IAEItemStack actualItem = null;
|
||||||
|
private IAEItemStack reportedItem = null;
|
||||||
|
private final InfoType type;
|
||||||
|
|
||||||
|
public PacketInformPlayer( ByteBuf stream ) throws IOException
|
||||||
|
{
|
||||||
|
this.type = InfoType.values()[stream.readInt()];
|
||||||
|
if( type == InfoType.PARTIAL_ITEM_EXTRACTION )
|
||||||
|
{
|
||||||
|
this.reportedItem = AEItemStack.fromPacket( stream );
|
||||||
|
this.actualItem = AEItemStack.fromPacket( stream );
|
||||||
|
}
|
||||||
|
else if( type == InfoType.NO_ITEMS_EXTRACTED )
|
||||||
|
{
|
||||||
|
this.reportedItem = AEItemStack.fromPacket( stream );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketInformPlayer( final IAEItemStack iaeItemStack ) throws IOException
|
||||||
|
{
|
||||||
|
this( iaeItemStack, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketInformPlayer( IAEItemStack extra, IAEItemStack result ) throws IOException
|
||||||
|
{
|
||||||
|
this.reportedItem = extra;
|
||||||
|
this.actualItem = result;
|
||||||
|
if( actualItem == null )
|
||||||
|
{
|
||||||
|
this.type = InfoType.NO_ITEMS_EXTRACTED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.type = InfoType.PARTIAL_ITEM_EXTRACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ByteBuf data = Unpooled.buffer();
|
||||||
|
|
||||||
|
data.writeInt( this.getPacketID() );
|
||||||
|
|
||||||
|
data.writeInt( type.ordinal() );
|
||||||
|
|
||||||
|
reportedItem.writeToPacket( data );
|
||||||
|
if( actualItem != null )
|
||||||
|
{
|
||||||
|
actualItem.writeToPacket( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configureWrite( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clientPacketData( final INetworkInfo network, final AppEngPacket packet, final EntityPlayer player )
|
||||||
|
{
|
||||||
|
TextComponentString msg = null;
|
||||||
|
|
||||||
|
if( this.type == InfoType.PARTIAL_ITEM_EXTRACTION )
|
||||||
|
{
|
||||||
|
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could only extract" + actualItem.getStackSize() ), false );
|
||||||
|
}
|
||||||
|
else if( this.type == InfoType.NO_ITEMS_EXTRACTED )
|
||||||
|
{
|
||||||
|
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could not extract anything" ), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum InfoType
|
||||||
|
{
|
||||||
|
PARTIAL_ITEM_EXTRACTION,
|
||||||
|
NO_ITEMS_EXTRACTED
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,16 +19,6 @@
|
|||||||
package appeng.crafting;
|
package appeng.crafting;
|
||||||
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import appeng.me.cache.GridStorageCache;
|
|
||||||
import com.google.common.base.Stopwatch;
|
|
||||||
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
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.networking.IGrid;
|
import appeng.api.networking.IGrid;
|
||||||
@@ -37,7 +27,6 @@ import appeng.api.networking.IGridNode;
|
|||||||
import appeng.api.networking.crafting.ICraftingCallback;
|
import appeng.api.networking.crafting.ICraftingCallback;
|
||||||
import appeng.api.networking.crafting.ICraftingGrid;
|
import appeng.api.networking.crafting.ICraftingGrid;
|
||||||
import appeng.api.networking.crafting.ICraftingJob;
|
import appeng.api.networking.crafting.ICraftingJob;
|
||||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
|
||||||
import appeng.api.networking.security.IActionHost;
|
import appeng.api.networking.security.IActionHost;
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
import appeng.api.networking.storage.IStorageGrid;
|
import appeng.api.networking.storage.IStorageGrid;
|
||||||
@@ -47,6 +36,14 @@ import appeng.api.storage.data.IItemList;
|
|||||||
import appeng.api.util.DimensionalCoord;
|
import appeng.api.util.DimensionalCoord;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import appeng.hooks.TickHandler;
|
import appeng.hooks.TickHandler;
|
||||||
|
import appeng.me.cache.GridStorageCache;
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
public class CraftingJob implements Runnable, ICraftingJob
|
public class CraftingJob implements Runnable, ICraftingJob
|
||||||
@@ -58,48 +55,45 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
private final World world;
|
private final World world;
|
||||||
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> neededForLoop = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
private final Object2ObjectOpenHashMap<CraftingTreeNode, IAEItemStack> reserved = new Object2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
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();
|
||||||
private final Stopwatch tickSpreadingWatch = Stopwatch.createUnstarted();
|
private final Stopwatch tickSpreadingWatch = Stopwatch.createUnstarted();
|
||||||
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
|
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
|
||||||
private final ICraftingGrid cc;
|
|
||||||
private CraftingTreeNode tree;
|
|
||||||
private final IAEItemStack output;
|
private final IAEItemStack output;
|
||||||
|
private final IActionSource actionSrc;
|
||||||
|
private final ICraftingCallback callback;
|
||||||
|
private CraftingTreeNode tree;
|
||||||
private boolean simulate = false;
|
private boolean simulate = false;
|
||||||
private MECraftingInventory availableCheck;
|
private MECraftingInventory availableCheck;
|
||||||
private long bytes = 0;
|
private long bytes = 0;
|
||||||
private final IActionSource actionSrc;
|
|
||||||
private final ICraftingCallback callback;
|
|
||||||
private boolean running = false;
|
private boolean running = false;
|
||||||
private boolean done = false;
|
private boolean done = false;
|
||||||
private int time;
|
private int time;
|
||||||
private int incTime;
|
private int incTime;
|
||||||
|
|
||||||
private World wrapWorld( final World w )
|
|
||||||
{
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CraftingJob( final World w, final IGrid grid, final IActionSource actionSrc, final IAEItemStack what, final ICraftingCallback callback )
|
public CraftingJob( final World w, final IGrid grid, final IActionSource actionSrc, final IAEItemStack what, final ICraftingCallback callback )
|
||||||
{
|
{
|
||||||
this.world = this.wrapWorld( w );
|
this.world = w;
|
||||||
this.output = what.copy();
|
this.output = what.copy();
|
||||||
this.actionSrc = actionSrc;
|
this.actionSrc = actionSrc;
|
||||||
|
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
|
||||||
this.cc = grid.getCache( ICraftingGrid.class );
|
ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
||||||
final GridStorageCache sg = grid.getCache( IStorageGrid.class );
|
final GridStorageCache sg = grid.getCache( IStorageGrid.class );
|
||||||
this.original = sg.getExtractableList( actionSrc );
|
this.original = sg.getExtractableList( actionSrc );
|
||||||
|
|
||||||
|
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
||||||
this.setTree( this.getCraftingTree( cc, what ) );
|
this.setTree( this.getCraftingTree( cc, what ) );
|
||||||
this.availableCheck = null;
|
this.availableCheck = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, what.getStackSize(), null, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void refund( final IAEItemStack o )
|
void refund( final IAEItemStack o )
|
||||||
@@ -117,7 +111,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
return this.availableCheck.extractItems( available, Actionable.SIMULATE, this.actionSrc );
|
return this.availableCheck.extractItems( available, Actionable.SIMULATE, this.actionSrc );
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTask( IAEItemStack what, final long crafts, final ICraftingPatternDetails details, final int depth )
|
void addTask( IAEItemStack what, final long crafts )
|
||||||
{
|
{
|
||||||
if( crafts > 0 )
|
if( crafts > 0 )
|
||||||
{
|
{
|
||||||
@@ -133,6 +127,22 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
this.missing.add( what );
|
this.missing.add( what );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reserve( CraftingTreeNode node, IAEItemStack stack )
|
||||||
|
{
|
||||||
|
this.checkUse( stack );
|
||||||
|
reserved.put( node, stack );
|
||||||
|
}
|
||||||
|
|
||||||
|
public IItemList<IAEItemStack> getNeededForLoop()
|
||||||
|
{
|
||||||
|
return neededForLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object2ObjectOpenHashMap<CraftingTreeNode, IAEItemStack> getReserved()
|
||||||
|
{
|
||||||
|
return reserved;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
@@ -144,9 +154,11 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
this.handlePausing();
|
this.handlePausing();
|
||||||
|
|
||||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||||
craftingInventory.ignore( this.output );
|
|
||||||
|
|
||||||
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
||||||
|
this.reserved.values().forEach( availableCheck::reserve );
|
||||||
|
this.reserved.values().forEach( craftingInventory::reserve );
|
||||||
|
|
||||||
craftingTreeWatch.start();
|
craftingTreeWatch.start();
|
||||||
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
||||||
craftingTreeWatch.stop();
|
craftingTreeWatch.stop();
|
||||||
@@ -176,10 +188,12 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
if( actionSrc.player().isPresent() )
|
if( actionSrc.player().isPresent() )
|
||||||
{
|
{
|
||||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||||
craftingInventory.ignore( this.output );
|
|
||||||
|
|
||||||
this.getTree().setSimulate();
|
this.getTree().setSimulate();
|
||||||
|
|
||||||
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
||||||
|
this.reserved.values().forEach( availableCheck::reserve );
|
||||||
|
this.reserved.values().forEach( craftingInventory::reserve );
|
||||||
|
|
||||||
craftingTreeWatch.reset().start();
|
craftingTreeWatch.reset().start();
|
||||||
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
||||||
craftingTreeWatch.stop();
|
craftingTreeWatch.stop();
|
||||||
|
|||||||
@@ -19,26 +19,29 @@
|
|||||||
package appeng.crafting;
|
package appeng.crafting;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import appeng.api.config.FuzzyMode;
|
|
||||||
import appeng.util.Platform;
|
|
||||||
import net.minecraft.util.text.TextComponentString;
|
|
||||||
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;
|
||||||
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.core.sync.network.NetworkHandler;
|
||||||
|
import appeng.core.sync.packets.PacketInformPlayer;
|
||||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||||
|
import appeng.util.Platform;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.fml.common.Optional;
|
import net.minecraftforge.fml.common.Optional;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@Optional.Interface( iface = "gregtech.api.items.IToolItem", modid = "gregtech" )
|
@Optional.Interface( iface = "gregtech.api.items.IToolItem", modid = "gregtech" )
|
||||||
public class CraftingTreeNode
|
public class CraftingTreeNode
|
||||||
@@ -55,33 +58,22 @@ public class CraftingTreeNode
|
|||||||
private final IAEItemStack what;
|
private final IAEItemStack what;
|
||||||
// what are the crafting patterns for this?
|
// what are the crafting patterns for this?
|
||||||
private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<>();
|
private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<>();
|
||||||
private final ICraftingGrid cc;
|
private final boolean canEmit;
|
||||||
private final int depth;
|
private CraftingTreeNode loopHead;
|
||||||
private int bytes = 0;
|
private int bytes = 0;
|
||||||
private boolean canEmit = false;
|
|
||||||
private long missing = 0;
|
private long missing = 0;
|
||||||
private long howManyEmitted = 0;
|
private long howManyEmitted = 0;
|
||||||
private boolean exhausted = false;
|
private boolean exhausted = false;
|
||||||
|
|
||||||
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth )
|
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, long amount, final CraftingTreeProcess par, final int slot )
|
||||||
{
|
{
|
||||||
this.what = wat;
|
this.what = wat;
|
||||||
this.parent = par;
|
this.parent = par;
|
||||||
this.slot = slot;
|
this.slot = slot;
|
||||||
this.world = job.getWorld();
|
this.world = job.getWorld();
|
||||||
this.job = job;
|
this.job = job;
|
||||||
this.cc = cc;
|
|
||||||
this.depth = depth;
|
|
||||||
|
|
||||||
this.canEmit = cc.canEmitFor( this.what );
|
this.canEmit = cc.canEmitFor( this.what );
|
||||||
}
|
|
||||||
|
|
||||||
public void addNode()
|
|
||||||
{
|
|
||||||
if( !nodes.isEmpty() )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this.canEmit )
|
if( this.canEmit )
|
||||||
{
|
{
|
||||||
@@ -91,16 +83,55 @@ 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 || notRecursive( details ) && this.parent.details != details )
|
int times = 1;
|
||||||
|
for( IAEItemStack o : details.getCondensedOutputs() )
|
||||||
{
|
{
|
||||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
if( what.equals( o ) )
|
||||||
|
{
|
||||||
|
times = (int) ( amount / o.getStackSize() + ( amount % o.getStackSize() != 0 ? 1 : 0 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( this.parent == null )
|
||||||
|
{
|
||||||
|
this.nodes.add( new CraftingTreeProcess( cc, job, details, times, this ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( details == parent.details )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CraftingTreeNode recursive = recursiveNode( this );
|
||||||
|
if( recursive == null )
|
||||||
|
{
|
||||||
|
this.nodes.add( new CraftingTreeProcess( cc, job, details, times, this ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reserveForNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserveForNode()
|
||||||
|
{
|
||||||
|
if( this.equals( loopHead ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IAEItemStack available = job.checkAvailable( this.what );
|
||||||
|
if( available != null && available.getStackSize() >= this.what.getStackSize() )
|
||||||
|
{
|
||||||
|
this.job.reserve( this, this.what.copy() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parent.reserveForNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
addNode();
|
|
||||||
this.job.handlePausing();
|
this.job.handlePausing();
|
||||||
if( this.canEmit )
|
if( this.canEmit )
|
||||||
{
|
{
|
||||||
@@ -114,13 +145,16 @@ public class CraftingTreeNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
||||||
|
|
||||||
|
IAEItemStack reserved = job.getReserved().get( this );
|
||||||
|
|
||||||
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() )
|
||||||
{
|
{
|
||||||
Collection<IAEItemStack> itemList = new ArrayList<>();
|
Collection<IAEItemStack> itemList = new HashSet<>();
|
||||||
|
|
||||||
if( this.what.getItem().isDamageable() || Platform.isGTDamageableItem( this.what.getItem() ) )
|
if( this.what.getItem().isDamageable() || Platform.isGTDamageableItem( this.what.getItem() ) )
|
||||||
{
|
{
|
||||||
@@ -146,18 +180,39 @@ public class CraftingTreeNode
|
|||||||
}
|
}
|
||||||
if( this.parent.details.canSubstitute() )
|
if( this.parent.details.canSubstitute() )
|
||||||
{
|
{
|
||||||
itemList.addAll( inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) );
|
for( IAEItemStack s : parent.details.getSubstituteInputs( this.slot ) )
|
||||||
|
{
|
||||||
|
if( s != null )
|
||||||
|
{
|
||||||
|
for( IAEItemStack ss : inventoryList.findFuzzy( s, FuzzyMode.IGNORE_ALL ) )
|
||||||
|
{
|
||||||
|
if( ss != null )
|
||||||
|
{
|
||||||
|
itemList.add( ss );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( IAEItemStack fuzz : itemList )
|
for( IAEItemStack fuzz : itemList )
|
||||||
{
|
{
|
||||||
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().getCachedItemStack( 1 ), this.world ) )
|
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.getDefinition(), this.world ) )
|
||||||
{
|
{
|
||||||
fuzz = fuzz.copy();
|
fuzz = fuzz.copy();
|
||||||
fuzz.setStackSize( l );
|
fuzz.setStackSize( l );
|
||||||
|
|
||||||
final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
final IAEItemStack available;
|
||||||
|
|
||||||
|
if( reserved != null )
|
||||||
|
{
|
||||||
|
available = reserved;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||||
|
}
|
||||||
|
|
||||||
if( available != null )
|
if( available != null )
|
||||||
{
|
{
|
||||||
@@ -170,6 +225,11 @@ public class CraftingTreeNode
|
|||||||
thingsUsed.add( is.copy() );
|
thingsUsed.add( is.copy() );
|
||||||
this.used.add( is );
|
this.used.add( is );
|
||||||
}
|
}
|
||||||
|
else if( reserved != null )
|
||||||
|
{
|
||||||
|
thingsUsed.add( reserved.copy() );
|
||||||
|
this.used.add( reserved );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bytes += available.getStackSize();
|
this.bytes += available.getStackSize();
|
||||||
@@ -185,7 +245,20 @@ public class CraftingTreeNode
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
final IAEItemStack available;
|
||||||
|
|
||||||
|
if( parent == null && this.what.equals( job.getOutput() ) )
|
||||||
|
{
|
||||||
|
available = null;
|
||||||
|
}
|
||||||
|
else if( reserved != null )
|
||||||
|
{
|
||||||
|
available = reserved;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||||
|
}
|
||||||
|
|
||||||
if( available != null )
|
if( available != null )
|
||||||
{
|
{
|
||||||
@@ -198,6 +271,11 @@ public class CraftingTreeNode
|
|||||||
thingsUsed.add( is.copy() );
|
thingsUsed.add( is.copy() );
|
||||||
this.used.add( is );
|
this.used.add( is );
|
||||||
}
|
}
|
||||||
|
else if( reserved != null )
|
||||||
|
{
|
||||||
|
thingsUsed.add( reserved.copy() );
|
||||||
|
this.used.add( reserved );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bytes += available.getStackSize();
|
this.bytes += available.getStackSize();
|
||||||
@@ -219,6 +297,7 @@ public class CraftingTreeNode
|
|||||||
while ( pro.possible && l > 0 )
|
while ( pro.possible && l > 0 )
|
||||||
{
|
{
|
||||||
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
|
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
|
||||||
|
|
||||||
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
|
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
|
||||||
|
|
||||||
madeWhat.setStackSize( l );
|
madeWhat.setStackSize( l );
|
||||||
@@ -249,7 +328,9 @@ public class CraftingTreeNode
|
|||||||
while ( pro.possible && l > 0 )
|
while ( pro.possible && l > 0 )
|
||||||
{
|
{
|
||||||
final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true );
|
final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true );
|
||||||
pro.request( subInv, 1, src );
|
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
|
||||||
|
|
||||||
|
pro.request( subInv, pro.getTimes( l, madeWhat.getStackSize() ), src );
|
||||||
|
|
||||||
this.what.setStackSize( l );
|
this.what.setStackSize( l );
|
||||||
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src );
|
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src );
|
||||||
@@ -301,17 +382,24 @@ public class CraftingTreeNode
|
|||||||
throw new CraftBranchFailure( this.what, l );
|
throw new CraftBranchFailure( this.what, l );
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean notRecursive( ICraftingPatternDetails details )
|
CraftingTreeNode recursiveNode( CraftingTreeNode node )
|
||||||
{
|
{
|
||||||
if( this.parent == null )
|
if( this.parent == null )
|
||||||
{
|
{
|
||||||
return true;
|
return null;
|
||||||
}
|
}
|
||||||
if( this.parent.details == details )
|
if( node != this )
|
||||||
{
|
{
|
||||||
return false;
|
if( node.what.equals( this.what ) )
|
||||||
|
{
|
||||||
|
if( node.what.getStackSize() == this.what.getStackSize() )
|
||||||
|
{
|
||||||
|
loopHead = this;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.parent.notRecursive( details );
|
return this.parent.notRecursive( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
void dive( final CraftingJob job )
|
void dive( final CraftingJob job )
|
||||||
@@ -360,7 +448,21 @@ public class CraftingTreeNode
|
|||||||
{
|
{
|
||||||
if( src.player().isPresent() )
|
if( src.player().isPresent() )
|
||||||
{
|
{
|
||||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + i.getStackSize() + " " + i.getDefinition().getItem().getItemStackDisplayName( i.getDefinition() ) + " available but could not extract anything" ), false );
|
try
|
||||||
|
{
|
||||||
|
if( ex == null )
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendTo( new PacketInformPlayer( i ), (EntityPlayerMP) src.player().get() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendTo( new PacketInformPlayer( ex, i ), (EntityPlayerMP) src.player().get() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( IOException e )
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new CraftBranchFailure( i, i.getStackSize() );
|
throw new CraftBranchFailure( i, i.getStackSize() );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,18 +19,8 @@
|
|||||||
package appeng.crafting;
|
package appeng.crafting;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import appeng.api.config.FuzzyMode;
|
|
||||||
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.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;
|
||||||
@@ -38,37 +28,34 @@ import appeng.api.storage.data.IAEItemStack;
|
|||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
|
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 java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
|
||||||
public class CraftingTreeProcess
|
public class CraftingTreeProcess
|
||||||
{
|
{
|
||||||
private final CraftingTreeNode parent;
|
|
||||||
final ICraftingPatternDetails details;
|
final ICraftingPatternDetails details;
|
||||||
|
private final CraftingTreeNode parent;
|
||||||
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 ICraftingGrid cc;
|
|
||||||
private final World world;
|
|
||||||
boolean possible = true;
|
boolean possible = true;
|
||||||
private long crafts = 0;
|
private long crafts = 0;
|
||||||
private long bytes = 0;
|
private long bytes = 0;
|
||||||
|
private boolean hasContainerItem = false;
|
||||||
|
|
||||||
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, int times, final CraftingTreeNode craftingTreeNode )
|
||||||
{
|
{
|
||||||
this.parent = craftingTreeNode;
|
this.parent = craftingTreeNode;
|
||||||
this.details = details;
|
this.details = details;
|
||||||
this.job = job;
|
this.job = job;
|
||||||
this.depth = depth;
|
World world = job.getWorld();
|
||||||
this.cc = cc;
|
|
||||||
this.world = job.getWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addProcess()
|
|
||||||
{
|
|
||||||
if( !nodes.isEmpty() )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IAEItemStack[] list = details.getInputs();
|
final IAEItemStack[] list = details.getInputs();
|
||||||
|
|
||||||
@@ -89,131 +76,61 @@ public class CraftingTreeProcess
|
|||||||
{
|
{
|
||||||
part = list[x];
|
part = list[x];
|
||||||
isPartContainer = true;
|
isPartContainer = true;
|
||||||
|
this.hasContainerItem = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
long wantedSize = part.getStackSize();
|
long wantedSize = isPartContainer ? part.getStackSize() : part.getStackSize() * times;
|
||||||
IAEItemStack found;
|
|
||||||
long remaining = 0;
|
|
||||||
long requestAmount = 0;
|
|
||||||
|
|
||||||
if( wantedSize > 0 )
|
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||||
{
|
{
|
||||||
if( details.canSubstitute() )
|
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||||
{
|
{
|
||||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
if( subs.fuzzyComparison( part, FuzzyMode.IGNORE_ALL ) )
|
||||||
{
|
{
|
||||||
found = job.checkAvailable( subs );
|
this.nodes.put( new CraftingTreeNode( cc, job, subs.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
||||||
|
wantedSize = 0;
|
||||||
if( found != null )
|
break;
|
||||||
{
|
|
||||||
remaining = found.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 );
|
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, subs, this, x, depth + 1 ), requestAmount );
|
|
||||||
if( wantedSize == 0 )
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
//try to order the crafting of a substitute
|
||||||
|
ICraftingPatternDetails prioritizedPattern = null;
|
||||||
|
IAEItemStack prioritizedIAE = null;
|
||||||
|
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||||
{
|
{
|
||||||
found = job.checkAvailable( part );
|
if( subs.equals( part ) )
|
||||||
|
|
||||||
if( found != null )
|
|
||||||
{
|
{
|
||||||
remaining = found.getStackSize();
|
continue;
|
||||||
}
|
}
|
||||||
|
ImmutableCollection<ICraftingPatternDetails> detailCollection = cc.getCraftingFor( subs, details, x, world );
|
||||||
|
|
||||||
if( remaining > 0 )
|
for( ICraftingPatternDetails sp : detailCollection )
|
||||||
{
|
{
|
||||||
if( remaining >= wantedSize )
|
if( prioritizedPattern == null )
|
||||||
{
|
{
|
||||||
requestAmount = wantedSize;
|
prioritizedPattern = sp;
|
||||||
wantedSize = 0;
|
prioritizedIAE = subs;
|
||||||
//we have the items
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
requestAmount = remaining;
|
if( sp.getPriority() > prioritizedPattern.getPriority() )
|
||||||
wantedSize -= remaining;
|
|
||||||
}
|
|
||||||
part = part.copy().setStackSize( requestAmount );
|
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), requestAmount );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( wantedSize > 0 )
|
|
||||||
{
|
|
||||||
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
|
||||||
{
|
|
||||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
|
||||||
{
|
|
||||||
if( subs.fuzzyComparison( part, FuzzyMode.IGNORE_ALL ) )
|
|
||||||
{
|
|
||||||
wantedSize -= 1;
|
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, subs.copy().setStackSize( 1 ), this, x, depth + 1 ), 1 );
|
|
||||||
if( wantedSize == 0 )
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//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;
|
prioritizedPattern = sp;
|
||||||
prioritizedIAE = subs;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( sp.getPriority() > prioritizedPattern.getPriority() )
|
|
||||||
{
|
|
||||||
prioritizedPattern = sp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( prioritizedIAE != null )
|
}
|
||||||
{
|
if( prioritizedIAE != null )
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), this, x, depth + 1 ), wantedSize );
|
{
|
||||||
wantedSize = 0;
|
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
||||||
break;
|
wantedSize = 0;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( wantedSize > 0 )
|
if( wantedSize > 0 )
|
||||||
{
|
{
|
||||||
part = part.copy();
|
part = part.copy().setStackSize( wantedSize );
|
||||||
// use the first slot...
|
// use the first slot...
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), wantedSize );
|
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
||||||
wantedSize = 0;
|
wantedSize = 0;
|
||||||
}
|
}
|
||||||
if( !isPartContainer && wantedSize == 0 )
|
if( !isPartContainer && wantedSize == 0 )
|
||||||
@@ -225,38 +142,40 @@ public class CraftingTreeProcess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean notRecursive( ICraftingPatternDetails details )
|
CraftingTreeNode notRecursive( CraftingTreeNode node )
|
||||||
{
|
{
|
||||||
return this.parent == null || this.parent.notRecursive( details );
|
if( parent == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.parent.recursiveNode( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
long getTimes( final long remaining, final long stackSize )
|
long getTimes( final long remaining, final long stackSize )
|
||||||
{
|
{
|
||||||
for( final IAEItemStack part : details.getCondensedOutputs() )
|
if( hasContainerItem )
|
||||||
{
|
{
|
||||||
for( final IAEItemStack o : details.getCondensedInputs() )
|
return 1;
|
||||||
{
|
|
||||||
if( part.equals( o ) || o.getItem().hasContainerItem( part.getDefinition() ) )
|
|
||||||
{
|
|
||||||
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 amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
void request( final MECraftingInventory inv, final long amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||||
{
|
{
|
||||||
addProcess();
|
|
||||||
this.job.handlePausing();
|
this.job.handlePausing();
|
||||||
List<IAEItemStack> containerItems = null;
|
List<IAEItemStack> containerItems = null;
|
||||||
|
|
||||||
// request and remove inputs...
|
// request and remove inputs...
|
||||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||||
{
|
{
|
||||||
final IAEItemStack stack = entry.getKey().request( inv, entry.getValue() * amountOfTimes, src );
|
final IAEItemStack stack = entry.getKey().request( inv, details.isCraftable() && hasContainerItem ? 1 : entry.getValue() * amountOfTimes, src );
|
||||||
|
|
||||||
if( stack.getItem().hasContainerItem( stack.getDefinition() ) )
|
if( stack.equals( job.getOutput() ) )
|
||||||
|
{
|
||||||
|
job.getNeededForLoop().add( stack.copy() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( details.isCraftable() && stack.getItem().hasContainerItem( stack.getDefinition() ) )
|
||||||
{
|
{
|
||||||
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
|
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
|
||||||
final IAEItemStack o = AEItemStack.fromItemStack( is );
|
final IAEItemStack o = AEItemStack.fromItemStack( is );
|
||||||
@@ -270,16 +189,16 @@ public class CraftingTreeProcess
|
|||||||
o.setCachedItemStack( is );
|
o.setCachedItemStack( is );
|
||||||
containerItems.add( o );
|
containerItems.add( o );
|
||||||
}
|
}
|
||||||
|
if( containerItems != null )
|
||||||
|
{
|
||||||
|
for( IAEItemStack i : containerItems )
|
||||||
|
{
|
||||||
|
inv.injectItems( i, Actionable.MODULATE, src );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( containerItems != null )
|
|
||||||
{
|
|
||||||
for( IAEItemStack i : containerItems )
|
|
||||||
{
|
|
||||||
inv.injectItems( i, Actionable.MODULATE, src );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// assume its possible.
|
// assume its possible.
|
||||||
|
|
||||||
@@ -295,7 +214,7 @@ public class CraftingTreeProcess
|
|||||||
|
|
||||||
void dive( final CraftingJob job )
|
void dive( final CraftingJob job )
|
||||||
{
|
{
|
||||||
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts, this.details, this.depth );
|
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts );
|
||||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||||
{
|
{
|
||||||
entry.getKey().dive( job );
|
entry.getKey().dive( job );
|
||||||
@@ -365,4 +284,9 @@ public class CraftingTreeProcess
|
|||||||
entry.getKey().getPlan( plan );
|
entry.getKey().getPlan( plan );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reserveForNode()
|
||||||
|
{
|
||||||
|
parent.reserveForNode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,14 @@ 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.core.sync.network.NetworkHandler;
|
||||||
|
import appeng.core.sync.packets.PacketInformPlayer;
|
||||||
import appeng.util.inv.ItemListIgnoreCrafting;
|
import appeng.util.inv.ItemListIgnoreCrafting;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.util.text.TextComponentString;
|
import net.minecraft.util.text.TextComponentString;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||||
{
|
{
|
||||||
@@ -309,13 +314,20 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
|||||||
{
|
{
|
||||||
if( src.player().isPresent() )
|
if( src.player().isPresent() )
|
||||||
{
|
{
|
||||||
if( result == null )
|
try
|
||||||
{
|
{
|
||||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false );
|
if( result == null )
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra ), (EntityPlayerMP) src.player().get() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra, result ), (EntityPlayerMP) src.player().get() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
catch( IOException e )
|
||||||
{
|
{
|
||||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false );
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failed = true;
|
failed = true;
|
||||||
@@ -349,11 +361,6 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMissing( final IAEItemStack extra )
|
|
||||||
{
|
|
||||||
this.missingCache.add( extra );
|
|
||||||
}
|
|
||||||
|
|
||||||
void ignore( final IAEItemStack what )
|
void ignore( final IAEItemStack what )
|
||||||
{
|
{
|
||||||
final IAEItemStack list = this.localCache.findPrecise( what );
|
final IAEItemStack list = this.localCache.findPrecise( what );
|
||||||
@@ -362,4 +369,18 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
|||||||
list.setStackSize( 0 );
|
list.setStackSize( 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reserve( final IAEItemStack what )
|
||||||
|
{
|
||||||
|
final IAEItemStack list = this.localCache.findPrecise( what );
|
||||||
|
if( list != null )
|
||||||
|
{
|
||||||
|
list.decStackSize( what.getStackSize() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMissing( final IAEItemStack extra )
|
||||||
|
{
|
||||||
|
this.missingCache.add( extra );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,22 +19,6 @@
|
|||||||
package appeng.me.cluster.implementations;
|
package appeng.me.cluster.implementations;
|
||||||
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import appeng.api.config.Upgrades;
|
|
||||||
import appeng.helpers.DualityInterface;
|
|
||||||
import appeng.helpers.PatternHelper;
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
|
|
||||||
import net.minecraft.inventory.InventoryCrafting;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
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.config.FuzzyMode;
|
||||||
@@ -43,14 +27,7 @@ import appeng.api.implementations.ICraftingPatternItem;
|
|||||||
import appeng.api.networking.IGrid;
|
import appeng.api.networking.IGrid;
|
||||||
import appeng.api.networking.IGridHost;
|
import appeng.api.networking.IGridHost;
|
||||||
import appeng.api.networking.IGridNode;
|
import appeng.api.networking.IGridNode;
|
||||||
import appeng.api.networking.crafting.CraftingItemList;
|
import appeng.api.networking.crafting.*;
|
||||||
import appeng.api.networking.crafting.ICraftingCPU;
|
|
||||||
import appeng.api.networking.crafting.ICraftingGrid;
|
|
||||||
import appeng.api.networking.crafting.ICraftingJob;
|
|
||||||
import appeng.api.networking.crafting.ICraftingLink;
|
|
||||||
import appeng.api.networking.crafting.ICraftingMedium;
|
|
||||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
|
||||||
import appeng.api.networking.crafting.ICraftingRequester;
|
|
||||||
import appeng.api.networking.energy.IEnergyGrid;
|
import appeng.api.networking.energy.IEnergyGrid;
|
||||||
import appeng.api.networking.events.MENetworkCraftingCpuChange;
|
import appeng.api.networking.events.MENetworkCraftingCpuChange;
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
@@ -63,11 +40,8 @@ import appeng.api.storage.data.IItemList;
|
|||||||
import appeng.api.util.WorldCoord;
|
import appeng.api.util.WorldCoord;
|
||||||
import appeng.container.ContainerNull;
|
import appeng.container.ContainerNull;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import appeng.crafting.CraftBranchFailure;
|
import appeng.crafting.*;
|
||||||
import appeng.crafting.CraftingJob;
|
import appeng.helpers.PatternHelper;
|
||||||
import appeng.crafting.CraftingLink;
|
|
||||||
import appeng.crafting.CraftingWatcher;
|
|
||||||
import appeng.crafting.MECraftingInventory;
|
|
||||||
import appeng.me.cache.CraftingGridCache;
|
import appeng.me.cache.CraftingGridCache;
|
||||||
import appeng.me.cluster.IAECluster;
|
import appeng.me.cluster.IAECluster;
|
||||||
import appeng.me.helpers.MachineSource;
|
import appeng.me.helpers.MachineSource;
|
||||||
@@ -75,6 +49,17 @@ import appeng.tile.crafting.TileCraftingMonitorTile;
|
|||||||
import appeng.tile.crafting.TileCraftingTile;
|
import appeng.tile.crafting.TileCraftingTile;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import net.minecraft.inventory.InventoryCrafting;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.nbt.NBTTagList;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||||
@@ -102,6 +87,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
private IAEItemStack finalOutput;
|
private IAEItemStack finalOutput;
|
||||||
private boolean waiting = false;
|
private boolean waiting = false;
|
||||||
private IItemList<IAEItemStack> waitingFor = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
private IItemList<IAEItemStack> waitingFor = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
private IItemList<IAEItemStack> neededForLoop = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
private long availableStorage = 0;
|
private long availableStorage = 0;
|
||||||
private MachineSource machineSrc = null;
|
private MachineSource machineSrc = null;
|
||||||
private int accelerator = 0;
|
private int accelerator = 0;
|
||||||
@@ -224,13 +210,10 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
public boolean canAccept( final IAEItemStack input )
|
public boolean canAccept( final IAEItemStack input )
|
||||||
{
|
{
|
||||||
if( input instanceof IAEItemStack )
|
if( input != null )
|
||||||
{
|
{
|
||||||
final IAEItemStack is = this.waitingFor.findPrecise( input );
|
final IAEItemStack is = this.waitingFor.findPrecise( input );
|
||||||
if( is != null && is.getStackSize() > 0 )
|
return is != null && is.getStackSize() > 0;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -304,9 +287,28 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
if( this.finalOutput.equals( what ) )
|
if( this.finalOutput.equals( what ) )
|
||||||
{
|
{
|
||||||
|
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
|
||||||
IAEItemStack leftover = what;
|
IAEItemStack leftover = what;
|
||||||
|
|
||||||
this.finalOutput.decStackSize( what.getStackSize() );
|
if( isLoop != null && isLoop.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
if( isLoop.getStackSize() >= what.getStackSize() )
|
||||||
|
{
|
||||||
|
leftover = this.inventory.injectItems( what.copy(), type, src );
|
||||||
|
isLoop.decStackSize( what.getStackSize() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftover = this.inventory.injectItems( what.copy().setStackSize( what.getStackSize() - isLoop.getStackSize() ), type, src );
|
||||||
|
isLoop.decStackSize( what.getStackSize() - isLoop.getStackSize() );
|
||||||
|
}
|
||||||
|
if( leftover == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finalOutput.decStackSize( leftover.getStackSize() );
|
||||||
|
|
||||||
if( this.myLastLink != null )
|
if( this.myLastLink != null )
|
||||||
{
|
{
|
||||||
@@ -336,9 +338,28 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
if( this.finalOutput.equals( insert ) )
|
if( this.finalOutput.equals( insert ) )
|
||||||
{
|
{
|
||||||
|
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
|
||||||
IAEItemStack leftover = input;
|
IAEItemStack leftover = input;
|
||||||
|
|
||||||
this.finalOutput.decStackSize( insert.getStackSize() );
|
if( isLoop != null && isLoop.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
if( isLoop.getStackSize() >= insert.getStackSize() )
|
||||||
|
{
|
||||||
|
leftover = this.inventory.injectItems( insert.copy(), type, src );
|
||||||
|
isLoop.decStackSize( insert.getStackSize() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftover = this.inventory.injectItems( insert.copy().setStackSize( insert.getStackSize() - isLoop.getStackSize() ), type, src );
|
||||||
|
isLoop.decStackSize( insert.getStackSize() - isLoop.getStackSize() );
|
||||||
|
}
|
||||||
|
if( leftover == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finalOutput.decStackSize( leftover.getStackSize() );
|
||||||
|
|
||||||
if( this.myLastLink != null )
|
if( this.myLastLink != null )
|
||||||
{
|
{
|
||||||
@@ -966,10 +987,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.waitingFor.resetStatus();
|
this.waitingFor.resetStatus();
|
||||||
|
this.neededForLoop.resetStatus();
|
||||||
( (CraftingJob) job ).getTree().setJob( ci, this, src );
|
( (CraftingJob) job ).getTree().setJob( ci, this, src );
|
||||||
if( ci.commit( src ) )
|
if( ci.commit( src ) )
|
||||||
{
|
{
|
||||||
this.finalOutput = job.getOutput();
|
this.finalOutput = job.getOutput();
|
||||||
|
this.neededForLoop = ( (CraftingJob) job ).getNeededForLoop();
|
||||||
this.waiting = false;
|
this.waiting = false;
|
||||||
this.isComplete = false;
|
this.isComplete = false;
|
||||||
this.markDirty();
|
this.markDirty();
|
||||||
|
|||||||
@@ -283,16 +283,15 @@ public class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
|
|||||||
{
|
{
|
||||||
if( this.cachedItemStack != null )
|
if( this.cachedItemStack != null )
|
||||||
{
|
{
|
||||||
ItemStack currentCached = this.cachedItemStack;
|
if( Platform.itemComparisons().isSameItem( this.getDefinition(), this.cachedItemStack ) )
|
||||||
this.cachedItemStack = null;
|
{
|
||||||
currentCached.setCount( Ints.saturatedCast( stackSize ) );
|
ItemStack currentCached = this.cachedItemStack;
|
||||||
return currentCached;
|
this.cachedItemStack = null;
|
||||||
|
currentCached.setCount( Ints.saturatedCast( stackSize ) );
|
||||||
|
return currentCached;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return ItemHandlerHelper.copyStackWithSize( this.getDefinition(), Ints.saturatedCast( stackSize ) );
|
||||||
ItemStack itemStack = this.createItemStack();
|
|
||||||
itemStack.setCount( Ints.saturatedCast( stackSize ) );
|
|
||||||
|
|
||||||
return itemStack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user