Compare commits

...

6 Commits

Author SHA1 Message Date
PrototypeTrousers 7d1c502b41 workss 2022-04-04 15:44:22 -03:00
PrototypeTrousers 63653c1833 added packets for missing items report 2022-04-04 03:55:51 -03:00
PrototypeTrousers 6cadfbdcdc 3 2022-04-01 19:30:18 -03:00
PrototypeTrousers d054c6ab91 2 2022-04-01 19:30:18 -03:00
PrototypeTrousers 234b1c5dc6 meh. crafting gets stuck if the output loops 2022-04-01 19:30:18 -03:00
PrototypeTrousers 8cc29734a2 positive loop support 2022-04-01 19:30:18 -03:00
9 changed files with 443 additions and 293 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
extended=extended_life
extendedversion=v51g
extendedversion=v52b
#########################################################
# Versions #
#########################################################
@@ -24,34 +24,9 @@ import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import appeng.core.sync.packets.*;
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
{
@@ -107,7 +82,10 @@ public class AppEngPacketHandlerBase
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 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
}
}
+41 -27
View File
@@ -19,16 +19,6 @@
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.config.Actionable;
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.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStorageGrid;
@@ -47,6 +36,14 @@ import appeng.api.storage.data.IItemList;
import appeng.api.util.DimensionalCoord;
import appeng.core.AELog;
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
@@ -58,48 +55,45 @@ public class CraftingJob implements Runnable, ICraftingJob
private final World world;
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> 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 Object monitor = new Object();
private final Stopwatch tickSpreadingWatch = Stopwatch.createUnstarted();
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
private final ICraftingGrid cc;
private CraftingTreeNode tree;
private final IAEItemStack output;
private final IActionSource actionSrc;
private final ICraftingCallback callback;
private CraftingTreeNode tree;
private boolean simulate = false;
private MECraftingInventory availableCheck;
private long bytes = 0;
private final IActionSource actionSrc;
private final ICraftingCallback callback;
private boolean running = false;
private boolean done = false;
private int time;
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 )
{
this.world = this.wrapWorld( w );
this.world = w;
this.output = what.copy();
this.actionSrc = actionSrc;
this.callback = callback;
this.cc = grid.getCache( ICraftingGrid.class );
ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
final GridStorageCache sg = grid.getCache( IStorageGrid.class );
this.original = sg.getExtractableList( actionSrc );
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.setTree( this.getCraftingTree( cc, what ) );
this.availableCheck = null;
}
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 )
@@ -117,7 +111,7 @@ public class CraftingJob implements Runnable, ICraftingJob
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 )
{
@@ -133,6 +127,22 @@ public class CraftingJob implements Runnable, ICraftingJob
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
public void run()
{
@@ -144,9 +154,11 @@ public class CraftingJob implements Runnable, ICraftingJob
this.handlePausing();
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
craftingInventory.ignore( this.output );
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.reserved.values().forEach( availableCheck::reserve );
this.reserved.values().forEach( craftingInventory::reserve );
craftingTreeWatch.start();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
craftingTreeWatch.stop();
@@ -176,10 +188,12 @@ public class CraftingJob implements Runnable, ICraftingJob
if( actionSrc.player().isPresent() )
{
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
craftingInventory.ignore( this.output );
this.getTree().setSimulate();
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.reserved.values().forEach( availableCheck::reserve );
this.reserved.values().forEach( craftingInventory::reserve );
craftingTreeWatch.reset().start();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
craftingTreeWatch.stop();
@@ -19,26 +19,29 @@
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.config.Actionable;
import appeng.api.config.FuzzyMode;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInformPlayer;
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 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" )
public class CraftingTreeNode
@@ -55,33 +58,22 @@ public class CraftingTreeNode
private final IAEItemStack what;
// what are the crafting patterns for this?
private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<>();
private final ICraftingGrid cc;
private final int depth;
private final boolean canEmit;
private CraftingTreeNode loopHead;
private int bytes = 0;
private boolean canEmit = false;
private long missing = 0;
private long howManyEmitted = 0;
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.parent = par;
this.slot = slot;
this.world = job.getWorld();
this.job = job;
this.cc = cc;
this.depth = depth;
this.canEmit = cc.canEmitFor( this.what );
}
public void addNode()
{
if( !nodes.isEmpty() )
{
return;
}
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
// 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
{
addNode();
this.job.handlePausing();
if( this.canEmit )
{
@@ -114,13 +145,16 @@ public class CraftingTreeNode
}
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
IAEItemStack reserved = job.getReserved().get( this );
final List<IAEItemStack> thingsUsed = new ArrayList<>();
this.what.setStackSize( l );
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() ) )
{
@@ -146,18 +180,39 @@ public class CraftingTreeNode
}
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 )
{
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.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 )
{
@@ -170,6 +225,11 @@ public class CraftingTreeNode
thingsUsed.add( is.copy() );
this.used.add( is );
}
else if( reserved != null )
{
thingsUsed.add( reserved.copy() );
this.used.add( reserved );
}
}
this.bytes += available.getStackSize();
@@ -185,7 +245,20 @@ public class CraftingTreeNode
}
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 )
{
@@ -198,6 +271,11 @@ public class CraftingTreeNode
thingsUsed.add( is.copy() );
this.used.add( is );
}
else if( reserved != null )
{
thingsUsed.add( reserved.copy() );
this.used.add( reserved );
}
}
this.bytes += available.getStackSize();
@@ -219,6 +297,7 @@ public class CraftingTreeNode
while ( pro.possible && l > 0 )
{
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
madeWhat.setStackSize( l );
@@ -249,7 +328,9 @@ public class CraftingTreeNode
while ( pro.possible && l > 0 )
{
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 );
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src );
@@ -301,17 +382,24 @@ public class CraftingTreeNode
throw new CraftBranchFailure( this.what, l );
}
boolean notRecursive( ICraftingPatternDetails details )
CraftingTreeNode recursiveNode( CraftingTreeNode node )
{
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 )
@@ -360,7 +448,21 @@ public class CraftingTreeNode
{
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() );
}
@@ -19,18 +19,8 @@
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.FuzzyMode;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.security.IActionSource;
@@ -38,37 +28,34 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.me.cluster.implementations.CraftingCPUCluster;
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
{
private final CraftingTreeNode parent;
final ICraftingPatternDetails details;
private final CraftingTreeNode parent;
private final CraftingJob job;
private final Object2LongArrayMap<CraftingTreeNode> nodes = new Object2LongArrayMap<>();
private final int depth;
private final ICraftingGrid cc;
private final World world;
boolean possible = true;
private long crafts = 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.details = details;
this.job = job;
this.depth = depth;
this.cc = cc;
this.world = job.getWorld();
}
public void addProcess()
{
if( !nodes.isEmpty() )
{
return;
}
World world = job.getWorld();
final IAEItemStack[] list = details.getInputs();
@@ -89,131 +76,61 @@ public class CraftingTreeProcess
{
part = list[x];
isPartContainer = true;
this.hasContainerItem = true;
}
long wantedSize = part.getStackSize();
IAEItemStack found;
long remaining = 0;
long requestAmount = 0;
long wantedSize = isPartContainer ? part.getStackSize() : part.getStackSize() * times;
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 );
if( found != null )
{
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;
}
}
this.nodes.put( new CraftingTreeNode( cc, job, subs.copy(), wantedSize, this, x ), part.getStackSize() / times );
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( found != null )
if( subs.equals( part ) )
{
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;
wantedSize = 0;
//we have the items
prioritizedPattern = sp;
prioritizedIAE = subs;
}
else
{
requestAmount = remaining;
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 )
if( sp.getPriority() > prioritizedPattern.getPriority() )
{
prioritizedPattern = sp;
prioritizedIAE = subs;
}
else
{
if( sp.getPriority() > prioritizedPattern.getPriority() )
{
prioritizedPattern = sp;
}
}
}
if( prioritizedIAE != null )
{
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), this, x, depth + 1 ), wantedSize );
wantedSize = 0;
break;
}
}
if( prioritizedIAE != null )
{
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), wantedSize, this, x ), part.getStackSize() / times );
wantedSize = 0;
break;
}
}
}
if( wantedSize > 0 )
{
part = part.copy();
part = part.copy().setStackSize( wantedSize );
// 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;
}
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 )
{
for( final IAEItemStack part : details.getCondensedOutputs() )
if( hasContainerItem )
{
for( final IAEItemStack o : details.getCondensedInputs() )
{
if( part.equals( o ) || o.getItem().hasContainerItem( part.getDefinition() ) )
{
return 1;
}
}
return 1;
}
return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 );
}
void request( final MECraftingInventory inv, final long amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
addProcess();
this.job.handlePausing();
List<IAEItemStack> containerItems = null;
// request and remove inputs...
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 IAEItemStack o = AEItemStack.fromItemStack( is );
@@ -270,16 +189,16 @@ public class CraftingTreeProcess
o.setCachedItemStack( is );
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.
@@ -295,7 +214,7 @@ public class CraftingTreeProcess
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() )
{
entry.getKey().dive( job );
@@ -365,4 +284,9 @@ public class CraftingTreeProcess
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.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInformPlayer;
import appeng.util.inv.ItemListIgnoreCrafting;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.text.TextComponentString;
import java.io.IOException;
public class MECraftingInventory implements IMEInventory<IAEItemStack>
{
@@ -309,13 +314,20 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
{
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;
@@ -349,11 +361,6 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
return true;
}
private void addMissing( final IAEItemStack extra )
{
this.missingCache.add( extra );
}
void ignore( final IAEItemStack what )
{
final IAEItemStack list = this.localCache.findPrecise( what );
@@ -362,4 +369,18 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
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;
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.config.Actionable;
import appeng.api.config.FuzzyMode;
@@ -43,14 +27,7 @@ import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.CraftingItemList;
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.crafting.*;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.MENetworkCraftingCpuChange;
import appeng.api.networking.security.IActionSource;
@@ -63,11 +40,8 @@ import appeng.api.storage.data.IItemList;
import appeng.api.util.WorldCoord;
import appeng.container.ContainerNull;
import appeng.core.AELog;
import appeng.crafting.CraftBranchFailure;
import appeng.crafting.CraftingJob;
import appeng.crafting.CraftingLink;
import appeng.crafting.CraftingWatcher;
import appeng.crafting.MECraftingInventory;
import appeng.crafting.*;
import appeng.helpers.PatternHelper;
import appeng.me.cache.CraftingGridCache;
import appeng.me.cluster.IAECluster;
import appeng.me.helpers.MachineSource;
@@ -75,6 +49,17 @@ import appeng.tile.crafting.TileCraftingMonitorTile;
import appeng.tile.crafting.TileCraftingTile;
import appeng.util.Platform;
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
@@ -102,6 +87,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private IAEItemStack finalOutput;
private boolean waiting = false;
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 MachineSource machineSrc = null;
private int accelerator = 0;
@@ -224,13 +210,10 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public boolean canAccept( final IAEItemStack input )
{
if( input instanceof IAEItemStack )
if( input != null )
{
final IAEItemStack is = this.waitingFor.findPrecise( input );
if( is != null && is.getStackSize() > 0 )
{
return true;
}
return is != null && is.getStackSize() > 0;
}
return false;
}
@@ -304,9 +287,28 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
if( this.finalOutput.equals( what ) )
{
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
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 )
{
@@ -336,9 +338,28 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
if( this.finalOutput.equals( insert ) )
{
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
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 )
{
@@ -966,10 +987,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
try
{
this.waitingFor.resetStatus();
this.neededForLoop.resetStatus();
( (CraftingJob) job ).getTree().setJob( ci, this, src );
if( ci.commit( src ) )
{
this.finalOutput = job.getOutput();
this.neededForLoop = ( (CraftingJob) job ).getNeededForLoop();
this.waiting = false;
this.isComplete = false;
this.markDirty();
@@ -283,16 +283,15 @@ public class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
{
if( this.cachedItemStack != null )
{
ItemStack currentCached = this.cachedItemStack;
this.cachedItemStack = null;
currentCached.setCount( Ints.saturatedCast( stackSize ) );
return currentCached;
if( Platform.itemComparisons().isSameItem( this.getDefinition(), this.cachedItemStack ) )
{
ItemStack currentCached = this.cachedItemStack;
this.cachedItemStack = null;
currentCached.setCount( Ints.saturatedCast( stackSize ) );
return currentCached;
}
}
ItemStack itemStack = this.createItemStack();
itemStack.setCount( Ints.saturatedCast( stackSize ) );
return itemStack;
return ItemHandlerHelper.copyStackWithSize( this.getDefinition(), Ints.saturatedCast( stackSize ) );
}
@Override