Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c532b9c839 |
+1
-2
@@ -4,7 +4,7 @@ aebuild=7
|
|||||||
aegroup=appeng
|
aegroup=appeng
|
||||||
aebasename=appliedenergistics2
|
aebasename=appliedenergistics2
|
||||||
extended=extended_life
|
extended=extended_life
|
||||||
extendedversion=v52b
|
extendedversion=v50j
|
||||||
#########################################################
|
#########################################################
|
||||||
# Versions #
|
# Versions #
|
||||||
#########################################################
|
#########################################################
|
||||||
@@ -26,7 +26,6 @@ cofhcore_version=1.12.2-4.5.2.19
|
|||||||
crafttweaker_version=4.1.8.9
|
crafttweaker_version=4.1.8.9
|
||||||
inventorytweaks_version=1.63
|
inventorytweaks_version=1.63
|
||||||
ctm_version=MC1.12.2-0.3.1.16
|
ctm_version=MC1.12.2-0.3.1.16
|
||||||
forestry_version=5.8.2.387
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# Deployment #
|
# Deployment #
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|||||||
@@ -97,8 +97,6 @@ dependencies {
|
|||||||
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
|
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
|
||||||
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
|
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
|
||||||
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
|
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
|
||||||
deobfCompile "net.sengir.forestry:forestry_${minecraft_version}:$forestry_version"
|
|
||||||
|
|
||||||
|
|
||||||
// at runtime, use the full JEI jar
|
// at runtime, use the full JEI jar
|
||||||
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
|
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import appeng.container.slot.*;
|
import appeng.container.slot.*;
|
||||||
import appeng.util.Platform;
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@@ -160,7 +159,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
|
|
||||||
final List<Slot> slots = this.getInventorySlots();
|
final List<Slot> slots = this.getInventorySlots();
|
||||||
final Iterator<Slot> i = slots.iterator();
|
final Iterator<Slot> i = slots.iterator();
|
||||||
while ( i.hasNext() )
|
while( i.hasNext() )
|
||||||
{
|
{
|
||||||
if( i.next() instanceof SlotME )
|
if( i.next() instanceof SlotME )
|
||||||
{
|
{
|
||||||
@@ -209,17 +208,13 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlStateManager.enableDepth();
|
GlStateManager.enableDepth();
|
||||||
if( Platform.isModLoaded( "jei" ) )
|
bookmarkedJEIghostItem(mouseX,mouseY);
|
||||||
{
|
|
||||||
bookmarkedJEIghostItem( mouseX, mouseY );
|
|
||||||
}
|
|
||||||
GlStateManager.disableDepth();
|
GlStateManager.disableDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Optional.Method( modid = "jei" )
|
void bookmarkedJEIghostItem(final int mouseX, final int mouseY) {
|
||||||
void bookmarkedJEIghostItem( final int mouseX, final int mouseY )
|
|
||||||
{
|
if (!isJeiGhostItem)
|
||||||
if( !isJeiGhostItem )
|
|
||||||
{
|
{
|
||||||
bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse();
|
bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse();
|
||||||
}
|
}
|
||||||
@@ -253,9 +248,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void drawTargets(int mouseX, int mouseY) {
|
||||||
private void drawTargets( int mouseX, int mouseY )
|
|
||||||
{
|
|
||||||
GlStateManager.disableLighting();
|
GlStateManager.disableLighting();
|
||||||
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
|
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
|
||||||
{
|
{
|
||||||
@@ -384,13 +377,17 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
final AppEngSlot aeSlot = (AppEngSlot) slot;
|
final AppEngSlot aeSlot = (AppEngSlot) slot;
|
||||||
if( aeSlot.isSlotEnabled() )
|
if( aeSlot.isSlotEnabled() )
|
||||||
{
|
{
|
||||||
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 );
|
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
|
||||||
|
18,
|
||||||
|
18 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 0.4F );
|
GlStateManager.color( 1.0F, 1.0F, 1.0F, 0.4F );
|
||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 );
|
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
|
||||||
|
18,
|
||||||
|
18 );
|
||||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -509,7 +506,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
{
|
{
|
||||||
final EntityPlayer player = Minecraft.getMinecraft().player;
|
final EntityPlayer player = Minecraft.getMinecraft().player;
|
||||||
|
|
||||||
if( this.isJeiGhostItem && isDraggingJeiGhostItem )
|
if( this.isJeiGhostItem && isDraggingJeiGhostItem)
|
||||||
{
|
{
|
||||||
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
|
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
|
||||||
{
|
{
|
||||||
@@ -762,8 +759,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
this.disableShiftClick = false;
|
this.disableShiftClick = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem )
|
if (clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem) {
|
||||||
{
|
|
||||||
this.isDraggingJeiGhostItem = true;
|
this.isDraggingJeiGhostItem = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -883,7 +879,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
if( stack != ItemStack.EMPTY )
|
if( stack != ItemStack.EMPTY )
|
||||||
{
|
{
|
||||||
InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE;
|
InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE;
|
||||||
final PacketInventoryAction p = new PacketInventoryAction( direction, slot.slotNumber, 0 );
|
final PacketInventoryAction p = new PacketInventoryAction( direction , slot.slotNumber , 0);
|
||||||
NetworkHandler.instance().sendToServer( p );
|
NetworkHandler.instance().sendToServer( p );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1036,11 +1032,27 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
final float f1 = 0.00390625F;
|
final float f1 = 0.00390625F;
|
||||||
final float f = 0.00390625F;
|
final float f = 0.00390625F;
|
||||||
final float par6 = 16;
|
final float par6 = 16;
|
||||||
vb.pos( par1 + 0, par2 + par6, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
vb.pos( par1 + 0, par2 + par6, this.zLevel )
|
||||||
|
.tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 )
|
||||||
|
.color( 1.0f, 1.0f, 1.0f,
|
||||||
|
aes.getOpacityOfIcon() )
|
||||||
|
.endVertex();
|
||||||
final float par5 = 16;
|
final float par5 = 16;
|
||||||
vb.pos( par1 + par5, par2 + par6, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
vb.pos( par1 + par5, par2 + par6, this.zLevel )
|
||||||
vb.pos( par1 + par5, par2 + 0, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
.tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 )
|
||||||
vb.pos( par1 + 0, par2 + 0, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
.color( 1.0f, 1.0f, 1.0f,
|
||||||
|
aes.getOpacityOfIcon() )
|
||||||
|
.endVertex();
|
||||||
|
vb.pos( par1 + par5, par2 + 0, this.zLevel )
|
||||||
|
.tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 )
|
||||||
|
.color( 1.0f, 1.0f, 1.0f,
|
||||||
|
aes.getOpacityOfIcon() )
|
||||||
|
.endVertex();
|
||||||
|
vb.pos( par1 + 0, par2 + 0, this.zLevel )
|
||||||
|
.tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 )
|
||||||
|
.color( 1.0f, 1.0f, 1.0f,
|
||||||
|
aes.getOpacityOfIcon() )
|
||||||
|
.endVertex();
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1054,7 +1066,8 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
|||||||
{
|
{
|
||||||
if( ( (AppEngSlot) s ).getIsValid() == hasCalculatedValidness.NotAvailable )
|
if( ( (AppEngSlot) s ).getIsValid() == hasCalculatedValidness.NotAvailable )
|
||||||
{
|
{
|
||||||
boolean isValid = s.isItemValid( is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected;
|
boolean isValid = s.isItemValid(
|
||||||
|
is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected;
|
||||||
if( isValid && s instanceof SlotRestrictedInput )
|
if( isValid && s instanceof SlotRestrictedInput )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import appeng.helpers.NonBlockingItems;
|
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
@@ -239,8 +238,6 @@ public final class AppEng
|
|||||||
AppEng.proxy.postInit();
|
AppEng.proxy.postInit();
|
||||||
AEConfig.instance().save();
|
AEConfig.instance().save();
|
||||||
|
|
||||||
NonBlockingItems.INSTANCE.init();
|
|
||||||
|
|
||||||
NetworkRegistry.INSTANCE.registerGuiHandler( this, GuiBridge.GUI_Handler );
|
NetworkRegistry.INSTANCE.registerGuiHandler( this, GuiBridge.GUI_Handler );
|
||||||
NetworkHandler.init( "AE2" );
|
NetworkHandler.init( "AE2" );
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,34 @@ 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
|
||||||
{
|
{
|
||||||
@@ -82,10 +107,7 @@ 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;
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -30,6 +30,7 @@ import java.util.List;
|
|||||||
import appeng.api.config.FuzzyMode;
|
import appeng.api.config.FuzzyMode;
|
||||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||||
import appeng.container.implementations.ContainerPatternTerm;
|
import appeng.container.implementations.ContainerPatternTerm;
|
||||||
|
import gregtech.common.items.MetaTool;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
@@ -40,7 +41,6 @@ import net.minecraft.item.ItemStack;
|
|||||||
import net.minecraft.nbt.CompressedStreamTools;
|
import net.minecraft.nbt.CompressedStreamTools;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraftforge.fml.common.Optional;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
@@ -175,8 +175,7 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
{
|
{
|
||||||
ItemStack currentItem = craftMatrix.getStackInSlot( x );
|
ItemStack currentItem = craftMatrix.getStackInSlot( x );
|
||||||
|
|
||||||
if( x >= this.recipe.size() )
|
if (x >= this.recipe.size()) {
|
||||||
{
|
|
||||||
currentItem = ItemStack.EMPTY;
|
currentItem = ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +228,7 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
||||||
if( out == null )
|
if( out == null )
|
||||||
{
|
{
|
||||||
if( request.getItem().isDamageable() || Platform.isGTDamageableItem( request.getItem() ) )
|
if( request.getItem().isDamageable() || ( Platform.isModLoaded( "gregtech" ) && request.getItem() instanceof MetaTool ) )
|
||||||
{
|
{
|
||||||
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
|
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
|
||||||
for( IAEItemStack is : outList )
|
for( IAEItemStack is : outList )
|
||||||
@@ -262,7 +261,7 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
|
|
||||||
if( out != null )
|
if( out != null )
|
||||||
{
|
{
|
||||||
if( !cct.useRealItems() )
|
if (!cct.useRealItems())
|
||||||
{
|
{
|
||||||
out.setStackSize( recipe.get( x )[y].getCount() );
|
out.setStackSize( recipe.get( x )[y].getCount() );
|
||||||
}
|
}
|
||||||
@@ -286,7 +285,7 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !cct.useRealItems() )
|
if (!cct.useRealItems())
|
||||||
{
|
{
|
||||||
if( currentItem.isEmpty() && recipe.size() > x && this.recipe.get( x ) != null )
|
if( currentItem.isEmpty() && recipe.size() > x && this.recipe.get( x ) != null )
|
||||||
{
|
{
|
||||||
@@ -299,28 +298,25 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
|
|
||||||
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
|
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
|
||||||
|
|
||||||
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) )
|
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) ) {
|
||||||
{
|
IItemHandler outputSlots = cct.getInventoryByName("output");
|
||||||
IItemHandler outputSlots = cct.getInventoryByName( "output" );
|
for (int i = 0; i < outputSlots.getSlots(); ++i) {
|
||||||
for( int i = 0; i < outputSlots.getSlots(); ++i )
|
ItemHandlerUtil.setStackInSlot(outputSlots, i, ItemStack.EMPTY);
|
||||||
{
|
}
|
||||||
ItemHandlerUtil.setStackInSlot( outputSlots, i, ItemStack.EMPTY );
|
for (int i = 0; i < this.output.size() && i < outputSlots.getSlots(); ++i) {
|
||||||
}
|
if (this.output.get(i) == null || this.output.get(i) == ItemStack.EMPTY) {
|
||||||
for( int i = 0; i < this.output.size() && i < outputSlots.getSlots(); ++i )
|
continue;
|
||||||
{
|
}
|
||||||
if( this.output.get( i ) == null || this.output.get( i ) == ItemStack.EMPTY )
|
ItemHandlerUtil.setStackInSlot(outputSlots, i, this.output.get(i));
|
||||||
{
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output.get( i ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
* @param slot
|
* @param slot
|
||||||
* @param is itemstack
|
* @param is itemstack
|
||||||
* @return is if it can be used, else EMPTY
|
* @return is if it can be used, else EMPTY
|
||||||
*/
|
*/
|
||||||
private ItemStack canUseInSlot( int slot, ItemStack is )
|
private ItemStack canUseInSlot( int slot, ItemStack is )
|
||||||
|
|||||||
@@ -19,6 +19,16 @@
|
|||||||
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;
|
||||||
@@ -27,6 +37,7 @@ 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;
|
||||||
@@ -36,14 +47,6 @@ 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
|
||||||
@@ -55,45 +58,60 @@ 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 IItemList<IAEItemStack> usedWhileBuilding = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
private final Object2ObjectOpenHashMap<CraftingTreeNode, IAEItemStack> reserved = new Object2ObjectOpenHashMap<>();
|
private final IItemList<IAEItemStack> uniques = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
|
||||||
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 IAEItemStack output;
|
|
||||||
private final IActionSource actionSrc;
|
|
||||||
private final ICraftingCallback callback;
|
|
||||||
private CraftingTreeNode tree;
|
private CraftingTreeNode tree;
|
||||||
|
private final IAEItemStack output;
|
||||||
|
private long expectedOutput;
|
||||||
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 = w;
|
this.world = this.wrapWorld( w );
|
||||||
this.output = what.copy();
|
this.output = what.copy();
|
||||||
this.actionSrc = actionSrc;
|
this.actionSrc = actionSrc;
|
||||||
|
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
|
||||||
ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
final 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 = new MECraftingInventory( 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getExpectedOutput()
|
||||||
|
{
|
||||||
|
return expectedOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incExpectedOutput( long amount )
|
||||||
|
{
|
||||||
|
this.expectedOutput += amount;
|
||||||
|
}
|
||||||
|
|
||||||
private CraftingTreeNode getCraftingTree( final ICraftingGrid cc, final IAEItemStack what )
|
private CraftingTreeNode getCraftingTree( final ICraftingGrid cc, final IAEItemStack what )
|
||||||
{
|
{
|
||||||
return new CraftingTreeNode( cc, this, what, what.getStackSize(), null, -1 );
|
return new CraftingTreeNode( cc, this, what, null, -1, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void refund( final IAEItemStack o )
|
void refund( final IAEItemStack o )
|
||||||
@@ -101,6 +119,16 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
this.availableCheck.injectItems( o, Actionable.MODULATE, this.actionSrc );
|
this.availableCheck.injectItems( o, Actionable.MODULATE, this.actionSrc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IItemList<IAEItemStack> getUsedWhileBuilding()
|
||||||
|
{
|
||||||
|
return usedWhileBuilding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IItemList<IAEItemStack> getUniques()
|
||||||
|
{
|
||||||
|
return uniques;
|
||||||
|
}
|
||||||
|
|
||||||
IAEItemStack checkUse( final IAEItemStack available )
|
IAEItemStack checkUse( final IAEItemStack available )
|
||||||
{
|
{
|
||||||
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
|
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
|
||||||
@@ -108,10 +136,15 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
|
|
||||||
IAEItemStack checkAvailable( final IAEItemStack available )
|
IAEItemStack checkAvailable( final IAEItemStack available )
|
||||||
{
|
{
|
||||||
return this.availableCheck.extractItems( available, Actionable.SIMULATE, this.actionSrc );
|
return this.original.extractItems( available.copy().setStackSize( Long.MAX_VALUE ), Actionable.SIMULATE, this.actionSrc );
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTask( IAEItemStack what, final long crafts )
|
public void writeToNBT( final NBTTagCompound out )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTask( IAEItemStack what, final long crafts, final ICraftingPatternDetails details, final int depth )
|
||||||
{
|
{
|
||||||
if( crafts > 0 )
|
if( crafts > 0 )
|
||||||
{
|
{
|
||||||
@@ -127,22 +160,6 @@ 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()
|
||||||
{
|
{
|
||||||
@@ -153,15 +170,13 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
|
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
|
||||||
this.handlePausing();
|
this.handlePausing();
|
||||||
|
|
||||||
|
craftingTreeWatch.start();
|
||||||
|
|
||||||
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();
|
|
||||||
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
||||||
craftingTreeWatch.stop();
|
|
||||||
this.getTree().dive( this );
|
this.getTree().dive( this );
|
||||||
|
|
||||||
for( final String s : this.opsAndMultiplier.keySet() )
|
for( final String s : this.opsAndMultiplier.keySet() )
|
||||||
@@ -170,14 +185,8 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( actionSrc.player().isPresent() )
|
craftingTreeWatch.stop();
|
||||||
{
|
this.logCraftingJob( "real, success", craftingTreeWatch );
|
||||||
this.logCraftingJob( "simulated, success", craftingTreeWatch );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.logCraftingJob( "real, success", craftingTreeWatch );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch( final CraftBranchFailure e )
|
catch( final CraftBranchFailure e )
|
||||||
{
|
{
|
||||||
@@ -187,16 +196,14 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
{
|
{
|
||||||
if( actionSrc.player().isPresent() )
|
if( actionSrc.player().isPresent() )
|
||||||
{
|
{
|
||||||
|
craftingTreeWatch.reset().start();
|
||||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||||
this.getTree().setSimulate();
|
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.reset().start();
|
this.getTree().setSimulate();
|
||||||
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
||||||
craftingTreeWatch.stop();
|
|
||||||
this.getTree().dive( this );
|
this.getTree().dive( this );
|
||||||
|
|
||||||
for( final String s : this.opsAndMultiplier.keySet() )
|
for( final String s : this.opsAndMultiplier.keySet() )
|
||||||
@@ -205,10 +212,12 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logCraftingJob( "simulated, failed", craftingTreeWatch );
|
craftingTreeWatch.stop();
|
||||||
|
this.logCraftingJob( "simulate", craftingTreeWatch );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
craftingTreeWatch.stop();
|
||||||
this.logCraftingJob( "real, failed", craftingTreeWatch );
|
this.logCraftingJob( "real, failed", craftingTreeWatch );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,31 +19,25 @@
|
|||||||
package appeng.crafting;
|
package appeng.crafting;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import appeng.api.config.FuzzyMode;
|
||||||
|
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 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
|
public class CraftingTreeNode
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -58,20 +52,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 boolean canEmit;
|
|
||||||
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, long amount, final CraftingTreeProcess par, final int slot )
|
private boolean sim;
|
||||||
|
|
||||||
|
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth )
|
||||||
{
|
{
|
||||||
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.sim = false;
|
||||||
|
|
||||||
this.canEmit = cc.canEmitFor( this.what );
|
this.canEmit = cc.canEmitFor( this.what );
|
||||||
|
|
||||||
@@ -83,93 +79,28 @@ 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.
|
||||||
{
|
{
|
||||||
int times = 1;
|
if( this.parent == null || job.getExpectedOutput() < job.getOutput().getStackSize() )
|
||||||
for( IAEItemStack o : details.getCondensedOutputs() )
|
|
||||||
{
|
{
|
||||||
if( what.equals( o ) )
|
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
||||||
{
|
|
||||||
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
|
||||||
{
|
{
|
||||||
this.job.handlePausing();
|
this.job.handlePausing();
|
||||||
if( this.canEmit )
|
|
||||||
{
|
|
||||||
final IAEItemStack wat = this.what.copy();
|
|
||||||
wat.setStackSize( l );
|
|
||||||
|
|
||||||
this.howManyEmitted = wat.getStackSize();
|
|
||||||
this.bytes += wat.getStackSize();
|
|
||||||
|
|
||||||
return wat;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 HashSet<>();
|
Collection<IAEItemStack> itemList = new ArrayList<>();
|
||||||
|
|
||||||
if( this.what.getItem().isDamageable() || Platform.isGTDamageableItem( this.what.getItem() ) )
|
if( this.parent.getContainerItems() != null && !this.parent.getContainerItems().findFuzzy( this.what, FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||||
{
|
{
|
||||||
itemList.addAll( inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) );
|
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
|
||||||
|
|
||||||
if( this.parent.details.canSubstitute() )
|
|
||||||
{
|
|
||||||
for( IAEItemStack is : inventoryList )
|
|
||||||
{
|
|
||||||
if( is.fuzzyComparison( this.what, FuzzyMode.IGNORE_ALL ) )
|
|
||||||
{
|
|
||||||
itemList.add( is );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -178,41 +109,16 @@ public class CraftingTreeNode
|
|||||||
{
|
{
|
||||||
itemList.add( item );
|
itemList.add( item );
|
||||||
}
|
}
|
||||||
if( this.parent.details.canSubstitute() )
|
|
||||||
{
|
|
||||||
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.getDefinition(), this.world ) )
|
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().getCachedItemStack( 1 ), this.world ) )
|
||||||
{
|
{
|
||||||
fuzz = fuzz.copy();
|
fuzz = fuzz.copy();
|
||||||
fuzz.setStackSize( l );
|
fuzz.setStackSize( l );
|
||||||
|
|
||||||
final IAEItemStack available;
|
final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||||
|
|
||||||
if( reserved != null )
|
|
||||||
{
|
|
||||||
available = reserved;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( available != null )
|
if( available != null )
|
||||||
{
|
{
|
||||||
@@ -225,11 +131,6 @@ 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();
|
||||||
@@ -245,20 +146,7 @@ public class CraftingTreeNode
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final IAEItemStack available;
|
final IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||||
|
|
||||||
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 )
|
||||||
{
|
{
|
||||||
@@ -271,11 +159,6 @@ 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();
|
||||||
@@ -288,6 +171,17 @@ public class CraftingTreeNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( this.canEmit )
|
||||||
|
{
|
||||||
|
final IAEItemStack wat = this.what.copy();
|
||||||
|
wat.setStackSize( l );
|
||||||
|
|
||||||
|
this.howManyEmitted = wat.getStackSize();
|
||||||
|
this.bytes += wat.getStackSize();
|
||||||
|
|
||||||
|
return wat;
|
||||||
|
}
|
||||||
|
|
||||||
this.exhausted = true;
|
this.exhausted = true;
|
||||||
|
|
||||||
if( this.nodes.size() == 1 )
|
if( this.nodes.size() == 1 )
|
||||||
@@ -301,6 +195,7 @@ public class CraftingTreeNode
|
|||||||
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
|
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
|
||||||
|
|
||||||
madeWhat.setStackSize( l );
|
madeWhat.setStackSize( l );
|
||||||
|
|
||||||
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
|
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
|
||||||
|
|
||||||
if( available != null )
|
if( available != null )
|
||||||
@@ -328,9 +223,7 @@ 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 );
|
||||||
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
|
pro.request( subInv, 1, src );
|
||||||
|
|
||||||
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 );
|
||||||
@@ -363,10 +256,10 @@ public class CraftingTreeNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( job.isSimulation() )
|
if( this.sim )
|
||||||
{
|
{
|
||||||
this.bytes += l;
|
|
||||||
this.missing += l;
|
this.missing += l;
|
||||||
|
this.bytes += l;
|
||||||
final IAEItemStack rv = this.what.copy();
|
final IAEItemStack rv = this.what.copy();
|
||||||
rv.setStackSize( l );
|
rv.setStackSize( l );
|
||||||
return rv;
|
return rv;
|
||||||
@@ -382,26 +275,6 @@ public class CraftingTreeNode
|
|||||||
throw new CraftBranchFailure( this.what, l );
|
throw new CraftBranchFailure( this.what, l );
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftingTreeNode recursiveNode( CraftingTreeNode node )
|
|
||||||
{
|
|
||||||
if( this.parent == null )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if( node != this )
|
|
||||||
{
|
|
||||||
if( node.what.equals( this.what ) )
|
|
||||||
{
|
|
||||||
if( node.what.getStackSize() == this.what.getStackSize() )
|
|
||||||
{
|
|
||||||
loopHead = this;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.parent.notRecursive( node );
|
|
||||||
}
|
|
||||||
|
|
||||||
void dive( final CraftingJob job )
|
void dive( final CraftingJob job )
|
||||||
{
|
{
|
||||||
if( this.missing > 0 )
|
if( this.missing > 0 )
|
||||||
@@ -427,6 +300,7 @@ public class CraftingTreeNode
|
|||||||
|
|
||||||
void setSimulate()
|
void setSimulate()
|
||||||
{
|
{
|
||||||
|
this.sim = true;
|
||||||
this.missing = 0;
|
this.missing = 0;
|
||||||
this.bytes = 0;
|
this.bytes = 0;
|
||||||
this.used.resetStatus();
|
this.used.resetStatus();
|
||||||
@@ -448,21 +322,7 @@ public class CraftingTreeNode
|
|||||||
{
|
{
|
||||||
if( src.player().isPresent() )
|
if( src.player().isPresent() )
|
||||||
{
|
{
|
||||||
try
|
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + i.getStackSize() + " " + i.getDefinition().getItem().getItemStackDisplayName( i.getDefinition() ) + " available but could not extract anything" ), false );
|
||||||
{
|
|
||||||
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,46 +19,82 @@
|
|||||||
package appeng.crafting;
|
package appeng.crafting;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.config.FuzzyMode;
|
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.data.IAEItemStack;
|
|
||||||
import appeng.api.storage.data.IItemList;
|
|
||||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
|
||||||
import appeng.util.Platform;
|
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
import com.google.common.collect.ImmutableCollection;
|
import com.google.common.collect.ImmutableCollection;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
|
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import appeng.api.AEApi;
|
||||||
import java.util.List;
|
import appeng.api.networking.crafting.ICraftingGrid;
|
||||||
import java.util.Map.Entry;
|
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.me.cluster.implementations.CraftingCPUCluster;
|
||||||
|
import appeng.util.Platform;
|
||||||
|
|
||||||
|
|
||||||
public class CraftingTreeProcess
|
public class CraftingTreeProcess
|
||||||
{
|
{
|
||||||
final ICraftingPatternDetails details;
|
|
||||||
private final CraftingTreeNode parent;
|
private final CraftingTreeNode parent;
|
||||||
|
final ICraftingPatternDetails details;
|
||||||
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;
|
||||||
boolean possible = true;
|
boolean possible = true;
|
||||||
private long crafts = 0;
|
private long crafts = 0;
|
||||||
|
private IItemList<IAEItemStack> containerItems;
|
||||||
|
private boolean limitQty;
|
||||||
|
private final List<IAEItemStack> craftingResultList = new ArrayList<>();
|
||||||
private long bytes = 0;
|
private long bytes = 0;
|
||||||
private boolean hasContainerItem = false;
|
|
||||||
|
|
||||||
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, int times, final CraftingTreeNode craftingTreeNode )
|
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth )
|
||||||
{
|
{
|
||||||
this.parent = craftingTreeNode;
|
this.parent = craftingTreeNode;
|
||||||
this.details = details;
|
this.details = details;
|
||||||
this.job = job;
|
this.job = job;
|
||||||
World world = job.getWorld();
|
this.depth = depth;
|
||||||
|
final World world = job.getWorld();
|
||||||
|
|
||||||
final IAEItemStack[] list = details.getInputs();
|
final IAEItemStack[] list = details.getInputs();
|
||||||
|
|
||||||
|
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||||
|
{
|
||||||
|
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
||||||
|
{
|
||||||
|
if( containerItems == null )
|
||||||
|
{
|
||||||
|
containerItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
}
|
||||||
|
containerItems.add( part );
|
||||||
|
this.limitQty = true;
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||||
|
{
|
||||||
|
if( part.equals( job.getOutput() ) )
|
||||||
|
{
|
||||||
|
job.incExpectedOutput( part.getStackSize() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||||
|
{
|
||||||
|
if( part.equals( job.getOutput() ) )
|
||||||
|
{
|
||||||
|
job.incExpectedOutput( -part.getStackSize() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
||||||
for( IAEItemStack part : details.getCondensedInputs() )
|
for( IAEItemStack part : details.getCondensedInputs() )
|
||||||
{
|
{
|
||||||
@@ -72,65 +108,157 @@ public class CraftingTreeProcess
|
|||||||
if( part.equals( comparePart ) )
|
if( part.equals( comparePart ) )
|
||||||
{
|
{
|
||||||
boolean isPartContainer = false;
|
boolean isPartContainer = false;
|
||||||
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
if( containerItems != null && !containerItems.findFuzzy( list[x], FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||||
{
|
{
|
||||||
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;
|
if( !isPartContainer )
|
||||||
|
|
||||||
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
|
||||||
{
|
{
|
||||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
IAEItemStack found = job.checkAvailable( part );
|
||||||
{
|
IAEItemStack used;
|
||||||
if( subs.fuzzyComparison( part, FuzzyMode.IGNORE_ALL ) )
|
long requestAmount;
|
||||||
{
|
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, subs.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
|
||||||
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 )
|
long remaining = 0;
|
||||||
|
if( found != null )
|
||||||
|
{
|
||||||
|
used = job.getUsedWhileBuilding().findPrecise( part );
|
||||||
|
remaining = found.getStackSize();
|
||||||
|
if( used != null )
|
||||||
{
|
{
|
||||||
if( prioritizedPattern == null )
|
if( used.getStackSize() >= found.getStackSize() )
|
||||||
{
|
{
|
||||||
prioritizedPattern = sp;
|
remaining = 0;
|
||||||
prioritizedIAE = subs;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( sp.getPriority() > prioritizedPattern.getPriority() )
|
remaining -= used.getStackSize();
|
||||||
{
|
|
||||||
prioritizedPattern = sp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( prioritizedIAE != null )
|
}
|
||||||
|
|
||||||
|
if( remaining > 0 )
|
||||||
|
{
|
||||||
|
if( remaining >= wantedSize )
|
||||||
{
|
{
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
requestAmount = wantedSize;
|
||||||
wantedSize = 0;
|
wantedSize = 0;
|
||||||
|
//we have the items
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requestAmount = remaining;
|
||||||
|
wantedSize -= remaining;
|
||||||
|
}
|
||||||
|
part = part.copy().setStackSize( requestAmount );
|
||||||
|
job.getUsedWhileBuilding().addStorage( part );
|
||||||
|
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), requestAmount );
|
||||||
|
if( wantedSize == 0 )
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if( wantedSize > 0 )
|
||||||
|
{
|
||||||
|
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||||
|
{
|
||||||
|
//try to extract substitutes
|
||||||
|
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||||
|
{
|
||||||
|
if( subs.equals( part ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found = job.checkAvailable( subs );
|
||||||
|
remaining = 0;
|
||||||
|
|
||||||
|
if( found != null )
|
||||||
|
{
|
||||||
|
used = job.getUsedWhileBuilding().findPrecise( subs );
|
||||||
|
remaining = found.getStackSize();
|
||||||
|
if( used != null )
|
||||||
|
{
|
||||||
|
if( used.getStackSize() >= found.getStackSize() )
|
||||||
|
{
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
remaining -= used.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 );
|
||||||
|
job.getUsedWhileBuilding().addStorage( subs );
|
||||||
|
this.nodes.put( new CraftingTreeNode( cc, job, subs, this, x, depth + 1 ), requestAmount );
|
||||||
|
}
|
||||||
|
if( wantedSize == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( wantedSize > 0 )
|
||||||
|
{
|
||||||
|
//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;
|
||||||
|
prioritizedIAE = subs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( sp.getPriority() > prioritizedPattern.getPriority() )
|
||||||
|
{
|
||||||
|
prioritizedPattern = sp;
|
||||||
|
prioritizedIAE = subs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), this, x, depth + 1 ), wantedSize );
|
||||||
|
wantedSize = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( wantedSize == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( wantedSize > 0 )
|
if( wantedSize > 0 )
|
||||||
{
|
{
|
||||||
part = part.copy().setStackSize( wantedSize );
|
part = part.copy();
|
||||||
// use the first slot...
|
// use the first slot...
|
||||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), wantedSize );
|
||||||
wantedSize = 0;
|
wantedSize = 0;
|
||||||
}
|
}
|
||||||
if( !isPartContainer && wantedSize == 0 )
|
if( !isPartContainer && wantedSize == 0 )
|
||||||
@@ -140,20 +268,28 @@ public class CraftingTreeProcess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||||
|
{
|
||||||
|
for( final IAEItemStack o : details.getCondensedInputs() )
|
||||||
|
{
|
||||||
|
if( part.equals( o ) )
|
||||||
|
{
|
||||||
|
this.limitQty = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftingTreeNode notRecursive( CraftingTreeNode node )
|
IItemList<IAEItemStack> getContainerItems()
|
||||||
{
|
{
|
||||||
if( parent == null )
|
return this.containerItems;
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this.parent.recursiveNode( node );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long getTimes( final long remaining, final long stackSize )
|
long getTimes( final long remaining, final long stackSize )
|
||||||
{
|
{
|
||||||
if( hasContainerItem )
|
if( this.limitQty )
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -163,43 +299,25 @@ public class CraftingTreeProcess
|
|||||||
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
|
||||||
{
|
{
|
||||||
this.job.handlePausing();
|
this.job.handlePausing();
|
||||||
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, details.isCraftable() && hasContainerItem ? 1 : entry.getValue() * amountOfTimes, src );
|
final IAEItemStack craftableStack = entry.getKey().getStack( entry.getValue() );
|
||||||
|
final IAEItemStack stack = entry.getKey().request( inv, craftableStack.getStackSize() * amountOfTimes, src );
|
||||||
|
|
||||||
if( stack.equals( job.getOutput() ) )
|
if( containerItems != null && !this.containerItems.findFuzzy( stack, FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||||
{
|
|
||||||
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 );
|
||||||
if( o != null )
|
if( o != null )
|
||||||
{
|
{
|
||||||
if( containerItems == null )
|
|
||||||
{
|
|
||||||
containerItems = new ArrayList<>();
|
|
||||||
}
|
|
||||||
this.bytes++;
|
this.bytes++;
|
||||||
o.setCachedItemStack( is );
|
craftingResultList.add( o );
|
||||||
containerItems.add( o );
|
|
||||||
}
|
|
||||||
if( containerItems != null )
|
|
||||||
{
|
|
||||||
for( IAEItemStack i : containerItems )
|
|
||||||
{
|
|
||||||
inv.injectItems( i, Actionable.MODULATE, src );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// assume its possible.
|
// assume its possible.
|
||||||
|
|
||||||
// add crafting results..
|
// add crafting results..
|
||||||
@@ -207,14 +325,25 @@ public class CraftingTreeProcess
|
|||||||
{
|
{
|
||||||
final IAEItemStack o = out.copy();
|
final IAEItemStack o = out.copy();
|
||||||
o.setStackSize( o.getStackSize() * amountOfTimes );
|
o.setStackSize( o.getStackSize() * amountOfTimes );
|
||||||
inv.injectItems( o, Actionable.MODULATE, src );
|
craftingResultList.add( o );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( IAEItemStack i : craftingResultList )
|
||||||
|
{
|
||||||
|
inv.injectItems( i, Actionable.MODULATE, src );
|
||||||
|
}
|
||||||
|
|
||||||
this.crafts += amountOfTimes;
|
this.crafts += amountOfTimes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IAEItemStack> getCraftingResultList()
|
||||||
|
{
|
||||||
|
return craftingResultList;
|
||||||
|
}
|
||||||
|
|
||||||
void dive( final CraftingJob job )
|
void dive( final CraftingJob job )
|
||||||
{
|
{
|
||||||
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts );
|
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts, this.details, this.depth );
|
||||||
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 );
|
||||||
@@ -284,9 +413,4 @@ public class CraftingTreeProcess
|
|||||||
entry.getKey().getPlan( plan );
|
entry.getKey().getPlan( plan );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reserveForNode()
|
|
||||||
{
|
|
||||||
parent.reserveForNode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,14 +28,9 @@ 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>
|
||||||
{
|
{
|
||||||
@@ -314,20 +309,13 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
|||||||
{
|
{
|
||||||
if( src.player().isPresent() )
|
if( src.player().isPresent() )
|
||||||
{
|
{
|
||||||
try
|
if( result == null )
|
||||||
{
|
{
|
||||||
if( result == null )
|
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false );
|
||||||
{
|
|
||||||
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra ), (EntityPlayerMP) src.player().get() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra, result ), (EntityPlayerMP) src.player().get() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch( IOException e )
|
else
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failed = true;
|
failed = true;
|
||||||
@@ -361,6 +349,11 @@ 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 );
|
||||||
@@ -369,18 +362,4 @@ 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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( notInserted == null || notInserted.getStackSize() == 0 )
|
if( notInserted == null )
|
||||||
{
|
{
|
||||||
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,58 +19,15 @@
|
|||||||
package appeng.helpers;
|
package appeng.helpers;
|
||||||
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import java.util.*;
|
||||||
import appeng.api.config.Actionable;
|
|
||||||
import appeng.api.config.Settings;
|
import javax.annotation.Nullable;
|
||||||
import appeng.api.config.Upgrades;
|
|
||||||
import appeng.api.config.YesNo;
|
import appeng.util.inv.BlockingInventoryAdaptor;
|
||||||
import appeng.api.implementations.ICraftingPatternItem;
|
import appeng.util.*;
|
||||||
import appeng.api.implementations.IUpgradeableHost;
|
|
||||||
import appeng.api.implementations.tiles.ICraftingMachine;
|
|
||||||
import appeng.api.networking.GridFlags;
|
|
||||||
import appeng.api.networking.IGrid;
|
|
||||||
import appeng.api.networking.IGridNode;
|
|
||||||
import appeng.api.networking.crafting.ICraftingLink;
|
|
||||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
|
||||||
import appeng.api.networking.crafting.ICraftingProvider;
|
|
||||||
import appeng.api.networking.crafting.ICraftingProviderHelper;
|
|
||||||
import appeng.api.networking.energy.IEnergySource;
|
|
||||||
import appeng.api.networking.events.MENetworkCraftingPatternChange;
|
|
||||||
import appeng.api.networking.security.IActionHost;
|
|
||||||
import appeng.api.networking.security.IActionSource;
|
|
||||||
import appeng.api.networking.ticking.IGridTickable;
|
|
||||||
import appeng.api.networking.ticking.TickRateModulation;
|
|
||||||
import appeng.api.networking.ticking.TickingRequest;
|
|
||||||
import appeng.api.parts.IPart;
|
|
||||||
import appeng.api.storage.*;
|
|
||||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
|
||||||
import appeng.api.storage.channels.IItemStorageChannel;
|
|
||||||
import appeng.api.storage.data.IAEFluidStack;
|
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
|
||||||
import appeng.api.storage.data.IAEStack;
|
|
||||||
import appeng.api.util.AECableType;
|
|
||||||
import appeng.api.util.AEPartLocation;
|
|
||||||
import appeng.api.util.DimensionalCoord;
|
|
||||||
import appeng.api.util.IConfigManager;
|
|
||||||
import appeng.capabilities.Capabilities;
|
|
||||||
import appeng.core.settings.TickRates;
|
|
||||||
import appeng.me.GridAccessException;
|
|
||||||
import appeng.me.helpers.AENetworkProxy;
|
|
||||||
import appeng.me.helpers.MachineSource;
|
|
||||||
import appeng.me.storage.MEMonitorIInventory;
|
|
||||||
import appeng.me.storage.MEMonitorPassThrough;
|
|
||||||
import appeng.me.storage.NullInventory;
|
|
||||||
import appeng.parts.automation.StackUpgradeInventory;
|
|
||||||
import appeng.parts.automation.UpgradeInventory;
|
|
||||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
|
||||||
import appeng.tile.inventory.AppEngInternalInventory;
|
|
||||||
import appeng.util.ConfigManager;
|
|
||||||
import appeng.util.IConfigManagerHost;
|
|
||||||
import appeng.util.InventoryAdaptor;
|
|
||||||
import appeng.util.Platform;
|
|
||||||
import appeng.util.inv.*;
|
import appeng.util.inv.*;
|
||||||
import appeng.util.item.AEItemStack;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
|
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
|
||||||
import gregtech.api.block.machines.BlockMachine;
|
import gregtech.api.block.machines.BlockMachine;
|
||||||
@@ -95,8 +52,56 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
|||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import net.minecraftforge.items.wrapper.RangedWrapper;
|
import net.minecraftforge.items.wrapper.RangedWrapper;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import appeng.api.AEApi;
|
||||||
import java.util.*;
|
import appeng.api.config.Actionable;
|
||||||
|
import appeng.api.config.Settings;
|
||||||
|
import appeng.api.config.Upgrades;
|
||||||
|
import appeng.api.config.YesNo;
|
||||||
|
import appeng.api.implementations.ICraftingPatternItem;
|
||||||
|
import appeng.api.implementations.IUpgradeableHost;
|
||||||
|
import appeng.api.implementations.tiles.ICraftingMachine;
|
||||||
|
import appeng.api.networking.GridFlags;
|
||||||
|
import appeng.api.networking.IGrid;
|
||||||
|
import appeng.api.networking.IGridNode;
|
||||||
|
import appeng.api.networking.crafting.ICraftingLink;
|
||||||
|
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||||
|
import appeng.api.networking.crafting.ICraftingProvider;
|
||||||
|
import appeng.api.networking.crafting.ICraftingProviderHelper;
|
||||||
|
import appeng.api.networking.energy.IEnergySource;
|
||||||
|
import appeng.api.networking.events.MENetworkCraftingPatternChange;
|
||||||
|
import appeng.api.networking.security.IActionHost;
|
||||||
|
import appeng.api.networking.security.IActionSource;
|
||||||
|
import appeng.api.networking.ticking.IGridTickable;
|
||||||
|
import appeng.api.networking.ticking.TickRateModulation;
|
||||||
|
import appeng.api.networking.ticking.TickingRequest;
|
||||||
|
import appeng.api.parts.IPart;
|
||||||
|
import appeng.api.storage.IMEInventory;
|
||||||
|
import appeng.api.storage.IMEMonitor;
|
||||||
|
import appeng.api.storage.IStorageChannel;
|
||||||
|
import appeng.api.storage.IStorageMonitorable;
|
||||||
|
import appeng.api.storage.IStorageMonitorableAccessor;
|
||||||
|
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||||
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
|
import appeng.api.storage.data.IAEFluidStack;
|
||||||
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
|
import appeng.api.storage.data.IAEStack;
|
||||||
|
import appeng.api.util.AECableType;
|
||||||
|
import appeng.api.util.AEPartLocation;
|
||||||
|
import appeng.api.util.DimensionalCoord;
|
||||||
|
import appeng.api.util.IConfigManager;
|
||||||
|
import appeng.capabilities.Capabilities;
|
||||||
|
import appeng.core.settings.TickRates;
|
||||||
|
import appeng.me.GridAccessException;
|
||||||
|
import appeng.me.helpers.AENetworkProxy;
|
||||||
|
import appeng.me.helpers.MachineSource;
|
||||||
|
import appeng.me.storage.MEMonitorIInventory;
|
||||||
|
import appeng.me.storage.MEMonitorPassThrough;
|
||||||
|
import appeng.me.storage.NullInventory;
|
||||||
|
import appeng.parts.automation.StackUpgradeInventory;
|
||||||
|
import appeng.parts.automation.UpgradeInventory;
|
||||||
|
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||||
|
import appeng.tile.inventory.AppEngInternalInventory;
|
||||||
|
import appeng.util.item.AEItemStack;
|
||||||
|
|
||||||
import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
||||||
|
|
||||||
@@ -108,7 +113,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
public static final int NUMBER_OF_PATTERN_SLOTS = 36;
|
public static final int NUMBER_OF_PATTERN_SLOTS = 36;
|
||||||
|
|
||||||
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
|
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
|
||||||
private final IAEItemStack[] requireWork = {null, null, null, null, null, null, null, null, null};
|
private final IAEItemStack[] requireWork = {
|
||||||
|
null, null, null, null, null, null, null, null, null
|
||||||
|
};
|
||||||
private final MultiCraftingTracker craftingTracker;
|
private final MultiCraftingTracker craftingTracker;
|
||||||
private final AENetworkProxy gridProxy;
|
private final AENetworkProxy gridProxy;
|
||||||
private final IInterfaceHost iHost;
|
private final IInterfaceHost iHost;
|
||||||
@@ -121,13 +128,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
|
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
|
||||||
private final UpgradeInventory upgrades;
|
private final UpgradeInventory upgrades;
|
||||||
private final Accessor accessor = new Accessor();
|
|
||||||
private boolean hasConfig = false;
|
private boolean hasConfig = false;
|
||||||
private int priority;
|
private int priority;
|
||||||
private List<ICraftingPatternDetails> craftingList = null;
|
private List<ICraftingPatternDetails> craftingList = null;
|
||||||
private List<ItemStack> waitingToSend = null;
|
private List<ItemStack> waitingToSend = null;
|
||||||
private IMEInventory<IAEItemStack> destination;
|
private IMEInventory<IAEItemStack> destination;
|
||||||
private int isWorking = -1;
|
private int isWorking = -1;
|
||||||
|
private final Accessor accessor = new Accessor();
|
||||||
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
|
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
|
||||||
private EnumMap<EnumFacing, List<ItemStack>> waitingToSendFacing = new EnumMap<>( EnumFacing.class );
|
private EnumMap<EnumFacing, List<ItemStack>> waitingToSendFacing = new EnumMap<>( EnumFacing.class );
|
||||||
private boolean resetConfigCache = true;
|
private boolean resetConfigCache = true;
|
||||||
@@ -153,11 +160,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
this.interfaceRequestSource = new InterfaceRequestSource( this.iHost );
|
this.interfaceRequestSource = new InterfaceRequestSource( this.iHost );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean invIsCustomBlocking( BlockingInventoryAdaptor inv )
|
|
||||||
{
|
|
||||||
return ( inv.containsBlockingItems() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveChanges()
|
public void saveChanges()
|
||||||
{
|
{
|
||||||
@@ -279,7 +281,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
|
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
|
||||||
|
|
||||||
for( EnumFacing s : EnumFacing.values() )
|
for( EnumFacing s : EnumFacing.values() )
|
||||||
{
|
|
||||||
if( waitingListSided.hasKey( s.name() ) )
|
if( waitingListSided.hasKey( s.name() ) )
|
||||||
{
|
{
|
||||||
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
|
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
|
||||||
@@ -293,7 +294,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.craftingTracker.readFromNBT( data );
|
this.craftingTracker.readFromNBT( data );
|
||||||
|
|
||||||
@@ -464,7 +464,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
|
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
|
||||||
}
|
}
|
||||||
catch( GridAccessException e )
|
catch( GridAccessException e )
|
||||||
{
|
{
|
||||||
@@ -909,6 +909,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
changed = true;
|
changed = true;
|
||||||
throw new GridAccessException();
|
throw new GridAccessException();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemStack.setCachedItemStack( inputStack );
|
||||||
|
}
|
||||||
|
|
||||||
IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
|
IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
|
||||||
if( storedStack != null )
|
if( storedStack != null )
|
||||||
@@ -926,13 +930,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
else if( storedStack.isCraftable() )
|
else if( storedStack.isCraftable() )
|
||||||
{
|
{
|
||||||
itemStack.setCachedItemStack( inputStack );
|
|
||||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||||
}
|
}
|
||||||
if( acquired == null )
|
|
||||||
{
|
|
||||||
itemStack.setCachedItemStack( inputStack );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else wtf?
|
// else wtf?
|
||||||
@@ -1105,6 +1104,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
return ( inv.containsItems() );
|
return ( inv.containsItems() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean invIsCustomBlocking( BlockingInventoryAdaptor inv )
|
||||||
|
{
|
||||||
|
return ( inv.containsBlockingItems() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table )
|
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table )
|
||||||
{
|
{
|
||||||
@@ -1154,7 +1158,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||||
if( ad != null )
|
if( ad != null )
|
||||||
{
|
{
|
||||||
if( this.isBlocking() )
|
if( this.isBlocking() )
|
||||||
@@ -1166,7 +1170,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
if( phantomTE.hasBoundPosition() )
|
if( phantomTE.hasBoundPosition() )
|
||||||
{
|
{
|
||||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||||
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
|
if( NonBlockingItems.INSTANCE.getMap().containsKey( phantom.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||||
{
|
{
|
||||||
if( isCustomInvBlocking( phantom, s ) )
|
if( isCustomInvBlocking( phantom, s ) )
|
||||||
{
|
{
|
||||||
@@ -1176,7 +1180,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
|
else if( NonBlockingItems.INSTANCE.getMap().containsKey( te.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||||
{
|
{
|
||||||
if( isCustomInvBlocking( te, s ) )
|
if( isCustomInvBlocking( te, s ) )
|
||||||
{
|
{
|
||||||
@@ -1184,6 +1188,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( invIsBlocked( ad ) )
|
else if( invIsBlocked( ad ) )
|
||||||
{
|
{
|
||||||
visitedFaces.remove( s );
|
visitedFaces.remove( s );
|
||||||
@@ -1243,7 +1248,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
if( phantomTE.hasBoundPosition() )
|
if( phantomTE.hasBoundPosition() )
|
||||||
{
|
{
|
||||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||||
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
|
if( NonBlockingItems.INSTANCE.getMap().containsKey( phantom.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||||
{
|
{
|
||||||
if( !isCustomInvBlocking( phantom, s ) )
|
if( !isCustomInvBlocking( phantom, s ) )
|
||||||
{
|
{
|
||||||
@@ -1253,7 +1258,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
|
|
||||||
|
else if( NonBlockingItems.INSTANCE.getMap().containsKey( te.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||||
{
|
{
|
||||||
if( !isCustomInvBlocking( te, s ) )
|
if( !isCustomInvBlocking( te, s ) )
|
||||||
{
|
{
|
||||||
@@ -1261,13 +1267,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
else if( !invIsBlocked( ad ) )
|
||||||
{
|
{
|
||||||
if( !invIsBlocked( ad ) )
|
allAreBusy = false;
|
||||||
{
|
break;
|
||||||
allAreBusy = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1593,7 +1597,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class InterfaceRequestContext implements Comparable<Integer>
|
private class InterfaceRequestContext implements Comparable<Integer>
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1604,7 +1607,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class InterfaceInventory extends MEMonitorIInventory
|
private class InterfaceInventory extends MEMonitorIInventory
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1642,7 +1644,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class Accessor implements IStorageMonitorableAccessor
|
private class Accessor implements IStorageMonitorableAccessor
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package appeng.helpers;
|
|||||||
|
|
||||||
import appeng.core.AEConfig;
|
import appeng.core.AEConfig;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import appeng.util.Platform;
|
|
||||||
import gregtech.api.items.metaitem.MetaItem;
|
import gregtech.api.items.metaitem.MetaItem;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
@@ -51,19 +50,16 @@ public class NonBlockingItems
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ModItemMeta[0].equals( "gregtech" ) && Platform.isModLoaded( "gregtech" ) )
|
if( ModItemMeta[0].equals( "gregtech" ) )
|
||||||
{
|
{
|
||||||
boolean found = false;
|
|
||||||
for( MetaItem<?> metaItem : MetaItem.getMetaItems() )
|
for( MetaItem<?> metaItem : MetaItem.getMetaItems() )
|
||||||
{
|
{
|
||||||
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem( ModItemMeta[1] );
|
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem( ModItemMeta[1] );
|
||||||
if( metaItem.getItem( ModItemMeta[1] ) != null )
|
if( metaItem.getItem( ModItemMeta[1] ) != null )
|
||||||
{
|
{
|
||||||
found = true;
|
|
||||||
ItemStack itemStack = metaItem2.getStackForm();
|
ItemStack itemStack = metaItem2.getStackForm();
|
||||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) -> {
|
||||||
{
|
|
||||||
intSet.add( itemStack.getItemDamage() );
|
intSet.add( itemStack.getItemDamage() );
|
||||||
return intSet;
|
return intSet;
|
||||||
} );
|
} );
|
||||||
@@ -74,30 +70,28 @@ public class NonBlockingItems
|
|||||||
if( !itemStack.isEmpty() )
|
if( !itemStack.isEmpty() )
|
||||||
{
|
{
|
||||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) -> {
|
||||||
{
|
|
||||||
intSet.add( itemStack.getItemDamage() );
|
intSet.add( itemStack.getItemDamage() );
|
||||||
return intSet;
|
return intSet;
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AELog.error( "Item not found on nonBlocking config: " + s );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
if( !found )
|
|
||||||
{
|
|
||||||
AELog.error( "Item not found on nonBlocking config: " + s );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( ModItemMeta[0].equals( "ore" ) )
|
else if( ModItemMeta[0].equals( "ore" ) )
|
||||||
{
|
{
|
||||||
OreDictionary.getOres( ModItemMeta[1] ).forEach( itemStack ->
|
OreDictionary.getOres( ModItemMeta[1] ).forEach( itemStack -> {
|
||||||
{
|
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) -> {
|
||||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
intSet.add( itemStack.getItemDamage() );
|
||||||
{
|
return intSet;
|
||||||
intSet.add( itemStack.getItemDamage() );
|
} );
|
||||||
return intSet;
|
} );
|
||||||
} );
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -105,8 +99,7 @@ public class NonBlockingItems
|
|||||||
if( !itemStack.isEmpty() )
|
if( !itemStack.isEmpty() )
|
||||||
{
|
{
|
||||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) -> {
|
||||||
{
|
|
||||||
intSet.add( itemStack.getItemDamage() );
|
intSet.add( itemStack.getItemDamage() );
|
||||||
return intSet;
|
return intSet;
|
||||||
} );
|
} );
|
||||||
@@ -126,8 +119,4 @@ public class NonBlockingItems
|
|||||||
{
|
{
|
||||||
return NON_BLOCKING_MAP;
|
return NON_BLOCKING_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import appeng.container.ContainerNull;
|
|||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
import net.minecraftforge.common.crafting.IShapedRecipe;
|
import net.minecraftforge.common.crafting.IShapedRecipe;
|
||||||
import net.minecraftforge.fml.common.Optional;
|
|
||||||
|
|
||||||
|
|
||||||
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
|
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
|
||||||
@@ -248,7 +247,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
|
|
||||||
final TestStatus result = this.getStatus( slotIndex, i );
|
final TestStatus result = this.getStatus( slotIndex, i );
|
||||||
|
|
||||||
switch ( result )
|
switch( result )
|
||||||
{
|
{
|
||||||
case ACCEPT:
|
case ACCEPT:
|
||||||
return true;
|
return true;
|
||||||
@@ -267,11 +266,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
this.testFrame.setInventorySlotContents( slotIndex, i );
|
this.testFrame.setInventorySlotContents( slotIndex, i );
|
||||||
|
|
||||||
// If we cannot substitute, the items must match exactly
|
// If we cannot substitute, the items must match exactly
|
||||||
if( ( !( i.getItem().isDamageable() || Platform.isGTDamageableItem( i.getItem() ) ) && !canSubstitute ) && slotIndex < inputs.length )
|
if (!canSubstitute && slotIndex < inputs.length) {
|
||||||
{
|
if (!inputs[slotIndex].isSameType(i)) {
|
||||||
if( !inputs[slotIndex].isSameType( i ) )
|
this.markItemAs(slotIndex, i, TestStatus.DECLINE);
|
||||||
{
|
|
||||||
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,26 +326,23 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IAEItemStack> getSubstituteInputs( int slot )
|
public List<IAEItemStack> getSubstituteInputs(int slot) {
|
||||||
{
|
if (this.inputs[slot] == null) {
|
||||||
if( this.inputs[slot] == null )
|
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.substituteInputs.computeIfAbsent( slot, value -> {
|
return this.substituteInputs.computeIfAbsent(slot, value -> {
|
||||||
ItemStack[] matchingStacks = getRecipeIngredient( slot ).getMatchingStacks();
|
ItemStack[] matchingStacks = getRecipeIngredient(slot).getMatchingStacks();
|
||||||
List<IAEItemStack> itemList = new ArrayList<>( matchingStacks.length + 1 );
|
List<IAEItemStack> itemList = new ArrayList<>(matchingStacks.length + 1);
|
||||||
for( ItemStack matchingStack : matchingStacks )
|
for (ItemStack matchingStack : matchingStacks) {
|
||||||
{
|
itemList.add(AEItemStack.fromItemStack(matchingStack));
|
||||||
itemList.add( AEItemStack.fromItemStack( matchingStack ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the specific item put in by the user is at the beginning,
|
// Ensure that the specific item put in by the user is at the beginning,
|
||||||
// so that it takes precedence over substitutions
|
// so that it takes precedence over substitutions
|
||||||
itemList.add( 0, this.inputs[slot] );
|
itemList.add(0, this.inputs[slot]);
|
||||||
return itemList;
|
return itemList;
|
||||||
} );
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -358,40 +352,31 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
* ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can
|
* ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can
|
||||||
* shift the actual recipe input to the right and down.
|
* shift the actual recipe input to the right and down.
|
||||||
*/
|
*/
|
||||||
private Ingredient getRecipeIngredient( int slot )
|
private Ingredient getRecipeIngredient(int slot) {
|
||||||
{
|
|
||||||
|
|
||||||
if( standardRecipe instanceof IShapedRecipe )
|
if (standardRecipe instanceof IShapedRecipe ) {
|
||||||
{
|
|
||||||
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
|
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
|
||||||
|
|
||||||
return getShapedRecipeIngredient( slot, shapedRecipe.getRecipeWidth() );
|
return getShapedRecipeIngredient(slot, shapedRecipe.getRecipeWidth());
|
||||||
}
|
} else {
|
||||||
else
|
return getShapelessRecipeIngredient(slot);
|
||||||
{
|
|
||||||
return getShapelessRecipeIngredient( slot );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Ingredient getShapedRecipeIngredient( int slot, int recipeWidth )
|
private Ingredient getShapedRecipeIngredient(int slot, int recipeWidth) {
|
||||||
{
|
|
||||||
// Compute the offset of the user's input vs. crafting grid origin
|
// Compute the offset of the user's input vs. crafting grid origin
|
||||||
// Which is >0 if they have empty rows above or to the left of their input
|
// Which is >0 if they have empty rows above or to the left of their input
|
||||||
int topOffset = 0;
|
int topOffset = 0;
|
||||||
if( inputs[0] == null && inputs[1] == null && inputs[2] == null )
|
if (inputs[0] == null && inputs[1] == null && inputs[2] == null) {
|
||||||
{
|
|
||||||
topOffset++; // First row is fully empty
|
topOffset++; // First row is fully empty
|
||||||
if( inputs[3] == null && inputs[4] == null && inputs[5] == null )
|
if (inputs[3] == null && inputs[4] == null && inputs[5] == null) {
|
||||||
{
|
|
||||||
topOffset++; // Second row is fully empty
|
topOffset++; // Second row is fully empty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int leftOffset = 0;
|
int leftOffset = 0;
|
||||||
if( inputs[0] == null && inputs[3] == null && inputs[6] == null )
|
if (inputs[0] == null && inputs[3] == null && inputs[6] == null) {
|
||||||
{
|
|
||||||
leftOffset++; // First column is fully empty
|
leftOffset++; // First column is fully empty
|
||||||
if( inputs[1] == null && inputs[4] == null && inputs[7] == null )
|
if (inputs[1] == null && inputs[4] == null && inputs[7] == null) {
|
||||||
{
|
|
||||||
leftOffset++; // Second column is fully empty
|
leftOffset++; // Second column is fully empty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,32 +390,27 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
|
|
||||||
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
||||||
|
|
||||||
if( ingredientIndex < 0 || ingredientIndex > ingredients.size() )
|
if (ingredientIndex < 0 || ingredientIndex > ingredients.size()) {
|
||||||
{
|
|
||||||
return Ingredient.EMPTY;
|
return Ingredient.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ingredients.get( ingredientIndex );
|
return ingredients.get(ingredientIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Ingredient getShapelessRecipeIngredient( int slot )
|
private Ingredient getShapelessRecipeIngredient(int slot) {
|
||||||
{
|
|
||||||
// We map the list of *filled* sparse inputs to the shapeless (ergo unordered)
|
// We map the list of *filled* sparse inputs to the shapeless (ergo unordered)
|
||||||
// ingredients. While these do not actually correspond to each other,
|
// ingredients. While these do not actually correspond to each other,
|
||||||
// since both lists have the same length, the mapping is at least stable.
|
// since both lists have the same length, the mapping is at least stable.
|
||||||
int ingredientIndex = 0;
|
int ingredientIndex = 0;
|
||||||
for( int i = 0; i < slot; i++ )
|
for (int i = 0; i < slot; i++) {
|
||||||
{
|
if (inputs[i] != null) {
|
||||||
if( inputs[i] != null )
|
|
||||||
{
|
|
||||||
ingredientIndex++;
|
ingredientIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
||||||
if( ingredientIndex < ingredients.size() )
|
if (ingredientIndex < ingredients.size()) {
|
||||||
{
|
return ingredients.get(ingredientIndex);
|
||||||
return ingredients.get( ingredientIndex );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ingredient.EMPTY;
|
return Ingredient.EMPTY;
|
||||||
@@ -537,9 +517,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
|
|
||||||
private enum TestStatus
|
private enum TestStatus
|
||||||
{
|
{
|
||||||
ACCEPT,
|
ACCEPT, DECLINE, TEST
|
||||||
DECLINE,
|
|
||||||
TEST
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class TestLookup
|
private static final class TestLookup
|
||||||
|
|||||||
@@ -19,6 +19,22 @@
|
|||||||
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;
|
||||||
@@ -27,7 +43,14 @@ 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.*;
|
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.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;
|
||||||
@@ -40,8 +63,11 @@ 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.*;
|
import appeng.crafting.CraftBranchFailure;
|
||||||
import appeng.helpers.PatternHelper;
|
import appeng.crafting.CraftingJob;
|
||||||
|
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;
|
||||||
@@ -49,17 +75,6 @@ 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
|
||||||
@@ -87,7 +102,6 @@ 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;
|
||||||
@@ -210,10 +224,13 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
public boolean canAccept( final IAEItemStack input )
|
public boolean canAccept( final IAEItemStack input )
|
||||||
{
|
{
|
||||||
if( input != null )
|
if( input instanceof IAEItemStack )
|
||||||
{
|
{
|
||||||
final IAEItemStack is = this.waitingFor.findPrecise( input );
|
final IAEItemStack is = this.waitingFor.findPrecise( input );
|
||||||
return is != null && is.getStackSize() > 0;
|
if( is != null && is.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -287,28 +304,9 @@ 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;
|
||||||
|
|
||||||
if( isLoop != null && isLoop.getStackSize() > 0 )
|
this.finalOutput.decStackSize( what.getStackSize() );
|
||||||
{
|
|
||||||
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 )
|
||||||
{
|
{
|
||||||
@@ -338,28 +336,9 @@ 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;
|
||||||
|
|
||||||
if( isLoop != null && isLoop.getStackSize() > 0 )
|
this.finalOutput.decStackSize( insert.getStackSize() );
|
||||||
{
|
|
||||||
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 )
|
||||||
{
|
{
|
||||||
@@ -987,12 +966,10 @@ 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();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package appeng.parts.misc;
|
package appeng.parts.misc;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.config.AccessRestriction;
|
import appeng.api.config.AccessRestriction;
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
@@ -146,7 +147,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
}
|
}
|
||||||
|
|
||||||
ItemStack extracted;
|
ItemStack extracted;
|
||||||
|
|
||||||
int stackSizeCurrentSlot = stackInInventorySlot.getCount();
|
int stackSizeCurrentSlot = stackInInventorySlot.getCount();
|
||||||
int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot );
|
int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot );
|
||||||
|
|
||||||
@@ -155,17 +155,9 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
|
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
|
||||||
|
|
||||||
if( !extracted.isEmpty() )
|
if( !extracted.isEmpty() )
|
||||||
{
|
{
|
||||||
// In order to guard against broken IItemHandler implementations, we'll try to guess if the returned
|
|
||||||
// stack (especially in simulate mode) is the same that was returned by getStackInSlot. This is
|
|
||||||
// obviously not a precise science, but it would catch the previous Forge bug:
|
|
||||||
// https://github.com/MinecraftForge/MinecraftForge/pull/6580
|
|
||||||
if( extracted == stackInInventorySlot )
|
|
||||||
{
|
|
||||||
extracted = extracted.copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( extracted.getCount() > remainingCurrentSlot )
|
if( extracted.getCount() > remainingCurrentSlot )
|
||||||
{
|
{
|
||||||
// Something broke. It should never return more than we requested...
|
// Something broke. It should never return more than we requested...
|
||||||
@@ -174,17 +166,12 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
extracted.setCount( remainingCurrentSlot );
|
extracted.setCount( remainingCurrentSlot );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heuristic for simulation: looping in case of simulations is pointless, since the state of the
|
// We're just gonna use the first stack we get our hands on as the template for the rest.
|
||||||
// underlying inventory does not change after a simulated extraction. To still support inventories
|
// In case some stupid itemhandler (aka forge) returns an internal state we have to do a second
|
||||||
// that report stacks that are larger than maxStackSize, we use this heuristic
|
// expensive copy again.
|
||||||
if( simulate && extracted.getCount() == extracted.getMaxStackSize() && remainingCurrentSlot > extracted.getMaxStackSize() )
|
|
||||||
{
|
|
||||||
extracted.setCount( remainingCurrentSlot );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( gathered.isEmpty() )
|
if( gathered.isEmpty() )
|
||||||
{
|
{
|
||||||
gathered = extracted;
|
gathered = extracted.copy();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -192,9 +179,11 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
}
|
}
|
||||||
remainingCurrentSlot -= extracted.getCount();
|
remainingCurrentSlot -= extracted.getCount();
|
||||||
}
|
}
|
||||||
} while ( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
} while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
||||||
|
|
||||||
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
|
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
|
||||||
|
|
||||||
|
// Done?
|
||||||
if( remainingSize <= 0 )
|
if( remainingSize <= 0 )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
|||||||
|
|
||||||
public TileChest()
|
public TileChest()
|
||||||
{
|
{
|
||||||
this.setInternalMaxPower( PowerMultiplier.CONFIG.multiply( 128 ) );
|
this.setInternalMaxPower( PowerMultiplier.CONFIG.multiply( 40 ) );
|
||||||
this.getProxy().setFlags( GridFlags.REQUIRE_CHANNEL );
|
this.getProxy().setFlags( GridFlags.REQUIRE_CHANNEL );
|
||||||
this.config.registerSetting( Settings.SORT_BY, SortOrder.NAME );
|
this.config.registerSetting( Settings.SORT_BY, SortOrder.NAME );
|
||||||
this.config.registerSetting( Settings.VIEW_MODE, ViewItems.ALL );
|
this.config.registerSetting( Settings.VIEW_MODE, ViewItems.ALL );
|
||||||
@@ -541,7 +541,7 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
|||||||
if( this.cellHandler != null && this.cellHandler.getChannel() == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
if( this.cellHandler != null && this.cellHandler.getChannel() == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||||
{
|
{
|
||||||
final IAEItemStack returns = Platform.poweredInsert( this, this.cellHandler,
|
final IAEItemStack returns = Platform.poweredInsert( this, this.cellHandler,
|
||||||
AEItemStack.fromItemStack( this.inputInventory.getStackInSlot( 0 ) ), this.mySrc );
|
AEItemStack.fromItemStack( this.inputInventory.getStackInSlot( 0 ) ), this.mySrc );
|
||||||
|
|
||||||
if( returns == null )
|
if( returns == null )
|
||||||
{
|
{
|
||||||
@@ -698,8 +698,7 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
|||||||
{
|
{
|
||||||
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
|
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
|
||||||
}
|
}
|
||||||
}
|
} catch ( final GridAccessException e )
|
||||||
catch( final GridAccessException e )
|
|
||||||
{
|
{
|
||||||
// :(
|
// :(
|
||||||
}
|
}
|
||||||
@@ -739,11 +738,11 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
T injected = super.injectItems( input, mode, src );
|
T injected = super.injectItems( input, mode, src );
|
||||||
if( mode == Actionable.MODULATE && ( injected == null || injected.getStackSize() != input.getStackSize() ) )
|
if (mode == Actionable.MODULATE && ( injected == null || injected.getStackSize() != input.getStackSize() ))
|
||||||
{
|
{
|
||||||
if( TileChest.this.isPowered() && this.getInternalHandler().getCellInv() != null )
|
if( TileChest.this.getProxy().isActive() && this.getInternalHandler().getCellInv() != null )
|
||||||
{
|
{
|
||||||
TileChest.this.cellHandler.postChangesToListeners( Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( injected == null ? 0 : injected.getStackSize() ) ) ), TileChest.this.mySrc );
|
TileChest.this.cellHandler.postChangesToListeners(Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( injected == null ? 0 : injected.getStackSize() ) ) ), TileChest.this.mySrc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return injected;
|
return injected;
|
||||||
@@ -793,9 +792,9 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
|||||||
T extracted = super.extractItems( request, mode, src );
|
T extracted = super.extractItems( request, mode, src );
|
||||||
if( mode == Actionable.MODULATE && extracted != null )
|
if( mode == Actionable.MODULATE && extracted != null )
|
||||||
{
|
{
|
||||||
if( TileChest.this.isPowered() && this.getInternalHandler().getCellInv() != null )
|
if( TileChest.this.getProxy().isActive() && this.getInternalHandler().getCellInv() != null )
|
||||||
{
|
{
|
||||||
TileChest.this.cellHandler.postChangesToListeners( Collections.singletonList( request.copy().setStackSize( -extracted.getStackSize() ) ), TileChest.this.mySrc );
|
TileChest.this.cellHandler.postChangesToListeners(Collections.singletonList( request.copy().setStackSize( -extracted.getStackSize() ) ), TileChest.this.mySrc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extracted;
|
return extracted;
|
||||||
@@ -849,7 +848,7 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
|||||||
|
|
||||||
private class FluidHandler implements IFluidHandler
|
private class FluidHandler implements IFluidHandler
|
||||||
{
|
{
|
||||||
private final IFluidTankProperties[] TANK_PROPS = new IFluidTankProperties[]{new FluidTankProperties( null, Fluid.BUCKET_VOLUME )};
|
private final IFluidTankProperties[] TANK_PROPS = new IFluidTankProperties[] { new FluidTankProperties( null, Fluid.BUCKET_VOLUME ) };
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int fill( final FluidStack resource, final boolean doFill )
|
public int fill( final FluidStack resource, final boolean doFill )
|
||||||
@@ -859,7 +858,7 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
|||||||
.getChannel() == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
.getChannel() == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||||
{
|
{
|
||||||
final IAEFluidStack results = Platform.poweredInsert( TileChest.this, TileChest.this.cellHandler, AEFluidStack.fromFluidStack( resource ),
|
final IAEFluidStack results = Platform.poweredInsert( TileChest.this, TileChest.this.cellHandler, AEFluidStack.fromFluidStack( resource ),
|
||||||
TileChest.this.mySrc, doFill ? Actionable.MODULATE : Actionable.SIMULATE );
|
TileChest.this.mySrc, doFill ? Actionable.MODULATE : Actionable.SIMULATE );
|
||||||
|
|
||||||
if( results == null )
|
if( results == null )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import gregtech.api.items.IToolItem;
|
|
||||||
import ic2.api.item.IC2Items;
|
|
||||||
import ic2.api.item.ICustomDamageItem;
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -76,7 +73,6 @@ import net.minecraftforge.fluids.FluidStack;
|
|||||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||||
import net.minecraftforge.fml.common.Loader;
|
import net.minecraftforge.fml.common.Loader;
|
||||||
import net.minecraftforge.fml.common.ModContainer;
|
import net.minecraftforge.fml.common.ModContainer;
|
||||||
import net.minecraftforge.fml.common.Optional;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
import net.minecraftforge.oredict.OreDictionary;
|
import net.minecraftforge.oredict.OreDictionary;
|
||||||
@@ -138,8 +134,6 @@ import appeng.util.prioritylist.IPartitionList;
|
|||||||
* @version rv2
|
* @version rv2
|
||||||
* @since rv0
|
* @since rv0
|
||||||
*/
|
*/
|
||||||
@Optional.Interface( iface = "gregtech.api.items.IToolItem", modid = "gregtech" )
|
|
||||||
@Optional.Interface( iface = "ic2.api.item.ICustomDamageItem", modid = "IC2" )
|
|
||||||
public class Platform
|
public class Platform
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -182,8 +176,9 @@ public class Platform
|
|||||||
/**
|
/**
|
||||||
* This displays the value for encoded longs ( double *100 )
|
* This displays the value for encoded longs ( double *100 )
|
||||||
*
|
*
|
||||||
* @param n to be formatted long value
|
* @param n to be formatted long value
|
||||||
* @param isRate if true it adds a /t to the formatted string
|
* @param isRate if true it adds a /t to the formatted string
|
||||||
|
*
|
||||||
* @return formatted long value
|
* @return formatted long value
|
||||||
*/
|
*/
|
||||||
public static String formatPowerLong( final long n, final boolean isRate )
|
public static String formatPowerLong( final long n, final boolean isRate )
|
||||||
@@ -193,14 +188,12 @@ public class Platform
|
|||||||
final PowerUnits displayUnits = AEConfig.instance().selectedPowerUnit();
|
final PowerUnits displayUnits = AEConfig.instance().selectedPowerUnit();
|
||||||
p = PowerUnits.AE.convertTo( displayUnits, p );
|
p = PowerUnits.AE.convertTo( displayUnits, p );
|
||||||
|
|
||||||
final String[] preFixes = {
|
final String[] preFixes = { "k", "M", "G", "T", "P", "T", "P", "E", "Z", "Y" };
|
||||||
"k", "M", "G", "T", "P", "T", "P", "E", "Z", "Y"
|
|
||||||
};
|
|
||||||
String unitName = displayUnits.name();
|
String unitName = displayUnits.name();
|
||||||
|
|
||||||
String level = "";
|
String level = "";
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
while ( p > 1000 && offset < preFixes.length )
|
while( p > 1000 && offset < preFixes.length )
|
||||||
{
|
{
|
||||||
p /= 1000;
|
p /= 1000;
|
||||||
level = preFixes[offset];
|
level = preFixes[offset];
|
||||||
@@ -217,7 +210,7 @@ public class Platform
|
|||||||
final int west_y = forward.zOffset * up.xOffset - forward.xOffset * up.zOffset;
|
final int west_y = forward.zOffset * up.xOffset - forward.xOffset * up.zOffset;
|
||||||
final int west_z = forward.xOffset * up.yOffset - forward.yOffset * up.xOffset;
|
final int west_z = forward.xOffset * up.yOffset - forward.yOffset * up.xOffset;
|
||||||
|
|
||||||
switch ( west_x + west_y * 2 + west_z * 3 )
|
switch( west_x + west_y * 2 + west_z * 3 )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return AEPartLocation.EAST;
|
return AEPartLocation.EAST;
|
||||||
@@ -244,7 +237,7 @@ public class Platform
|
|||||||
final int west_y = forward.getFrontOffsetZ() * up.getFrontOffsetX() - forward.getFrontOffsetX() * up.getFrontOffsetZ();
|
final int west_y = forward.getFrontOffsetZ() * up.getFrontOffsetX() - forward.getFrontOffsetX() * up.getFrontOffsetZ();
|
||||||
final int west_z = forward.getFrontOffsetX() * up.getFrontOffsetY() - forward.getFrontOffsetY() * up.getFrontOffsetX();
|
final int west_z = forward.getFrontOffsetX() * up.getFrontOffsetY() - forward.getFrontOffsetY() * up.getFrontOffsetX();
|
||||||
|
|
||||||
switch ( west_x + west_y * 2 + west_z * 3 )
|
switch( west_x + west_y * 2 + west_z * 3 )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return EnumFacing.EAST;
|
return EnumFacing.EAST;
|
||||||
@@ -278,7 +271,8 @@ public class Platform
|
|||||||
{
|
{
|
||||||
ce = nextEnum( ce );
|
ce = nextEnum( ce );
|
||||||
}
|
}
|
||||||
} while ( !validOptions.contains( ce ) || isNotValidSetting( ce ) );
|
}
|
||||||
|
while( !validOptions.contains( ce ) || isNotValidSetting( ce ) );
|
||||||
|
|
||||||
return ce;
|
return ce;
|
||||||
}
|
}
|
||||||
@@ -452,7 +446,7 @@ public class Platform
|
|||||||
{
|
{
|
||||||
if( upAndDown )
|
if( upAndDown )
|
||||||
{
|
{
|
||||||
switch ( dir )
|
switch( dir )
|
||||||
{
|
{
|
||||||
case NORTH:
|
case NORTH:
|
||||||
return AEPartLocation.SOUTH;
|
return AEPartLocation.SOUTH;
|
||||||
@@ -472,7 +466,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch ( dir )
|
switch( dir )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return AEPartLocation.DOWN;
|
return AEPartLocation.DOWN;
|
||||||
@@ -525,7 +519,8 @@ public class Platform
|
|||||||
final double offset_x = ( getRandomInt() % 32 - 16 ) / 82;
|
final double offset_x = ( getRandomInt() % 32 - 16 ) / 82;
|
||||||
final double offset_y = ( getRandomInt() % 32 - 16 ) / 82;
|
final double offset_y = ( getRandomInt() % 32 - 16 ) / 82;
|
||||||
final double offset_z = ( getRandomInt() % 32 - 16 ) / 82;
|
final double offset_z = ( getRandomInt() % 32 - 16 ) / 82;
|
||||||
final EntityItem ei = new EntityItem( w, 0.5 + offset_x + pos.getX(), 0.5 + offset_y + pos.getY(), 0.2 + offset_z + pos.getZ(), i.copy() );
|
final EntityItem ei = new EntityItem( w, 0.5 + offset_x + pos.getX(), 0.5 + offset_y + pos.getY(), 0.2 + offset_z + pos.getZ(), i
|
||||||
|
.copy() );
|
||||||
w.spawnEntity( ei );
|
w.spawnEntity( ei );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -597,7 +592,8 @@ public class Platform
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ITooltipFlag.TooltipFlags tooltipFlag = Minecraft.getMinecraft().gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL;
|
ITooltipFlag.TooltipFlags tooltipFlag = Minecraft
|
||||||
|
.getMinecraft().gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL;
|
||||||
return itemStack.getTooltip( Minecraft.getMinecraft().player, tooltipFlag );
|
return itemStack.getTooltip( Minecraft.getMinecraft().player, tooltipFlag );
|
||||||
}
|
}
|
||||||
catch( final Exception errB )
|
catch( final Exception errB )
|
||||||
@@ -768,7 +764,7 @@ public class Platform
|
|||||||
|
|
||||||
public static int MC2MEColor( final int color )
|
public static int MC2MEColor( final int color )
|
||||||
{
|
{
|
||||||
switch ( color )
|
switch( color )
|
||||||
{
|
{
|
||||||
case 4: // "blue"
|
case 4: // "blue"
|
||||||
return 0;
|
return 0;
|
||||||
@@ -846,10 +842,10 @@ public class Platform
|
|||||||
return forward;
|
return forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( forward )
|
switch( forward )
|
||||||
{
|
{
|
||||||
case DOWN:
|
case DOWN:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case DOWN:
|
case DOWN:
|
||||||
return forward;
|
return forward;
|
||||||
@@ -868,7 +864,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UP:
|
case UP:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case NORTH:
|
case NORTH:
|
||||||
return AEPartLocation.WEST;
|
return AEPartLocation.WEST;
|
||||||
@@ -883,7 +879,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NORTH:
|
case NORTH:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return AEPartLocation.WEST;
|
return AEPartLocation.WEST;
|
||||||
@@ -898,7 +894,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SOUTH:
|
case SOUTH:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return AEPartLocation.EAST;
|
return AEPartLocation.EAST;
|
||||||
@@ -913,7 +909,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EAST:
|
case EAST:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return AEPartLocation.NORTH;
|
return AEPartLocation.NORTH;
|
||||||
@@ -927,7 +923,7 @@ public class Platform
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WEST:
|
case WEST:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return AEPartLocation.SOUTH;
|
return AEPartLocation.SOUTH;
|
||||||
@@ -948,10 +944,10 @@ public class Platform
|
|||||||
|
|
||||||
public static EnumFacing rotateAround( final EnumFacing forward, final EnumFacing axis )
|
public static EnumFacing rotateAround( final EnumFacing forward, final EnumFacing axis )
|
||||||
{
|
{
|
||||||
switch ( forward )
|
switch( forward )
|
||||||
{
|
{
|
||||||
case DOWN:
|
case DOWN:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case DOWN:
|
case DOWN:
|
||||||
return forward;
|
return forward;
|
||||||
@@ -970,7 +966,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UP:
|
case UP:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case NORTH:
|
case NORTH:
|
||||||
return EnumFacing.WEST;
|
return EnumFacing.WEST;
|
||||||
@@ -985,7 +981,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NORTH:
|
case NORTH:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return EnumFacing.WEST;
|
return EnumFacing.WEST;
|
||||||
@@ -1000,7 +996,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SOUTH:
|
case SOUTH:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return EnumFacing.EAST;
|
return EnumFacing.EAST;
|
||||||
@@ -1015,7 +1011,7 @@ public class Platform
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EAST:
|
case EAST:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return EnumFacing.NORTH;
|
return EnumFacing.NORTH;
|
||||||
@@ -1029,7 +1025,7 @@ public class Platform
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WEST:
|
case WEST:
|
||||||
switch ( axis )
|
switch( axis )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
return EnumFacing.SOUTH;
|
return EnumFacing.SOUTH;
|
||||||
@@ -1105,7 +1101,9 @@ public class Platform
|
|||||||
|
|
||||||
final Vec3d vec31 = vec3.addVector( f7 * d3, f6 * d3, f8 * d3 );
|
final Vec3d vec31 = vec3.addVector( f7 * d3, f6 * d3, f8 * d3 );
|
||||||
|
|
||||||
final AxisAlignedBB bb = new AxisAlignedBB( Math.min( vec3.x, vec31.x ), Math.min( vec3.y, vec31.y ), Math.min( vec3.z, vec31.z ), Math.max( vec3.x, vec31.x ), Math.max( vec3.y, vec31.y ), Math.max( vec3.z, vec31.z ) ).grow( 16, 16, 16 );
|
final AxisAlignedBB bb = new AxisAlignedBB( Math.min( vec3.x, vec31.x ), Math.min( vec3.y, vec31.y ), Math.min( vec3.z,
|
||||||
|
vec31.z ), Math.max( vec3.x, vec31.x ), Math.max( vec3.y, vec31.y ), Math.max( vec3.z, vec31.z ) ).grow(
|
||||||
|
16, 16, 16 );
|
||||||
|
|
||||||
Entity entity = null;
|
Entity entity = null;
|
||||||
double closest = 9999999.0D;
|
double closest = 9999999.0D;
|
||||||
@@ -1251,15 +1249,15 @@ public class Platform
|
|||||||
final T leftover = input.copy();
|
final T leftover = input.copy();
|
||||||
final T split = input.copy();
|
final T split = input.copy();
|
||||||
|
|
||||||
leftover.decStackSize( itemToAdd );
|
leftover.decStackSize(itemToAdd);
|
||||||
split.setStackSize( itemToAdd );
|
split.setStackSize(itemToAdd);
|
||||||
leftover.add( cell.injectItems( split, Actionable.MODULATE, src ) );
|
leftover.add(cell.injectItems(split, Actionable.MODULATE, src));
|
||||||
|
|
||||||
src.player().ifPresent( player ->
|
src.player().ifPresent( player ->
|
||||||
{
|
{
|
||||||
final long diff = original - leftover.getStackSize();
|
final long diff = original - leftover.getStackSize();
|
||||||
Stats.ItemsInserted.addToPlayer( player, (int) diff );
|
Stats.ItemsInserted.addToPlayer( player, (int) diff );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
return leftover;
|
return leftover;
|
||||||
}
|
}
|
||||||
@@ -1267,10 +1265,10 @@ public class Platform
|
|||||||
final T ret = cell.injectItems( input, Actionable.MODULATE, src );
|
final T ret = cell.injectItems( input, Actionable.MODULATE, src );
|
||||||
|
|
||||||
src.player().ifPresent( player ->
|
src.player().ifPresent( player ->
|
||||||
{
|
{
|
||||||
final long diff = ret == null ? input.getStackSize() : input.getStackSize() - ret.getStackSize();
|
final long diff = ret == null ? input.getStackSize() : input.getStackSize() - ret.getStackSize();
|
||||||
Stats.ItemsInserted.addToPlayer( player, (int) diff );
|
Stats.ItemsInserted.addToPlayer( player, (int) diff );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1284,7 +1282,7 @@ public class Platform
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( {"rawtypes", "unchecked"} )
|
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||||
public static void postChanges( final IStorageGrid gs, final ItemStack removed, final ItemStack added, final IActionSource src )
|
public static void postChanges( final IStorageGrid gs, final ItemStack removed, final ItemStack added, final IActionSource src )
|
||||||
{
|
{
|
||||||
for( final IStorageChannel<?> chan : AEApi.instance().storage().storageChannels() )
|
for( final IStorageChannel<?> chan : AEApi.instance().storage().storageChannels() )
|
||||||
@@ -1363,7 +1361,8 @@ public class Platform
|
|||||||
final String locationA = a.getGridBlock().isWorldAccessible() ? a.getGridBlock().getLocation().toString() : "notInWorld";
|
final String locationA = a.getGridBlock().isWorldAccessible() ? a.getGridBlock().getLocation().toString() : "notInWorld";
|
||||||
final String locationB = b.getGridBlock().isWorldAccessible() ? b.getGridBlock().getLocation().toString() : "notInWorld";
|
final String locationB = b.getGridBlock().isWorldAccessible() ? b.getGridBlock().getLocation().toString() : "notInWorld";
|
||||||
|
|
||||||
AELog.info( "Audit: Node A [isSecure=%b, key=%d, playerID=%d, location={%s}] vs Node B[isSecure=%b, key=%d, playerID=%d, location={%s}]", a_isSecure, a.getLastSecurityKey(), a.getPlayerID(), locationA, b_isSecure, b.getLastSecurityKey(), b.getPlayerID(), locationB );
|
AELog.info( "Audit: Node A [isSecure=%b, key=%d, playerID=%d, location={%s}] vs Node B[isSecure=%b, key=%d, playerID=%d, location={%s}]",
|
||||||
|
a_isSecure, a.getLastSecurityKey(), a.getPlayerID(), locationA, b_isSecure, b.getLastSecurityKey(), b.getPlayerID(), locationB );
|
||||||
}
|
}
|
||||||
|
|
||||||
// can't do that son...
|
// can't do that son...
|
||||||
@@ -1424,7 +1423,7 @@ public class Platform
|
|||||||
float yaw = 0.0f;
|
float yaw = 0.0f;
|
||||||
// player.yOffset = 1.8f;
|
// player.yOffset = 1.8f;
|
||||||
|
|
||||||
switch ( side )
|
switch( side )
|
||||||
{
|
{
|
||||||
case DOWN:
|
case DOWN:
|
||||||
pitch = 90.0f;
|
pitch = 90.0f;
|
||||||
@@ -1514,14 +1513,16 @@ public class Platform
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean checkFuzzy = ae_req.getOre().isPresent() || providedTemplate.getItemDamage() == OreDictionary.WILDCARD_VALUE || providedTemplate.hasTagCompound() || providedTemplate.isItemStackDamageable();
|
final boolean checkFuzzy = ae_req.getOre().isPresent() || providedTemplate.getItemDamage() == OreDictionary.WILDCARD_VALUE || providedTemplate
|
||||||
|
.hasTagCompound() || providedTemplate.isItemStackDamageable();
|
||||||
|
|
||||||
if( items != null && checkFuzzy )
|
if( items != null && checkFuzzy )
|
||||||
{
|
{
|
||||||
for( final IAEItemStack x : items )
|
for( final IAEItemStack x : items )
|
||||||
{
|
{
|
||||||
final ItemStack sh = x.getDefinition();
|
final ItemStack sh = x.getDefinition();
|
||||||
if( ( Platform.itemComparisons().isEqualItemType( providedTemplate, sh ) || ae_req.sameOre( x ) ) && !ItemStack.areItemsEqual( sh, output ) )
|
if( ( Platform.itemComparisons().isEqualItemType( providedTemplate, sh ) || ae_req.sameOre( x ) ) && !ItemStack.areItemsEqual( sh,
|
||||||
|
output ) )
|
||||||
{ // Platform.isSameItemType( sh, providedTemplate )
|
{ // Platform.isSameItemType( sh, providedTemplate )
|
||||||
final ItemStack cp = sh.copy();
|
final ItemStack cp = sh.copy();
|
||||||
cp.setCount( 1 );
|
cp.setCount( 1 );
|
||||||
@@ -1680,14 +1681,4 @@ public class Platform
|
|||||||
|
|
||||||
return isPurified;
|
return isPurified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isGTDamageableItem( Item item )
|
|
||||||
{
|
|
||||||
return ( isModLoaded( "gregtech" ) && item instanceof IToolItem );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isIC2DamageableItem( Item item )
|
|
||||||
{
|
|
||||||
return ( isModLoaded( "IC2" ) && item instanceof ICustomDamageItem );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
package appeng.util.inv;
|
package appeng.util.inv;
|
||||||
|
|
||||||
|
import appeng.api.config.FuzzyMode;
|
||||||
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.helpers.NonBlockingItems;
|
import appeng.helpers.NonBlockingItems;
|
||||||
|
import appeng.util.Platform;
|
||||||
|
import appeng.util.item.AEItemStack;
|
||||||
|
import gregtech.common.items.MetaTool;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package appeng.util.item;
|
package appeng.util.item;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -26,8 +27,6 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import gregtech.api.items.IToolItem;
|
|
||||||
import ic2.api.item.ICustomDamageItem;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -45,7 +44,7 @@ import appeng.core.Api;
|
|||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
|
|
||||||
|
|
||||||
public class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
|
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
|
||||||
{
|
{
|
||||||
private static final String NBT_STACKSIZE = "Cnt";
|
private static final String NBT_STACKSIZE = "Cnt";
|
||||||
private static final String NBT_REQUESTABLE = "Req";
|
private static final String NBT_REQUESTABLE = "Req";
|
||||||
@@ -281,17 +280,26 @@ public class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
|
|||||||
@Override
|
@Override
|
||||||
public ItemStack getCachedItemStack( long stackSize )
|
public ItemStack getCachedItemStack( long stackSize )
|
||||||
{
|
{
|
||||||
|
ItemStack currentCached = null;
|
||||||
if( this.cachedItemStack != null )
|
if( this.cachedItemStack != null )
|
||||||
{
|
{
|
||||||
if( Platform.itemComparisons().isSameItem( this.getDefinition(), this.cachedItemStack ) )
|
currentCached = this.cachedItemStack;
|
||||||
{
|
|
||||||
ItemStack currentCached = this.cachedItemStack;
|
|
||||||
this.cachedItemStack = null;
|
|
||||||
currentCached.setCount( Ints.saturatedCast( stackSize ) );
|
|
||||||
return currentCached;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ItemHandlerHelper.copyStackWithSize( this.getDefinition(), Ints.saturatedCast( stackSize ) );
|
|
||||||
|
ItemStack itemStack;
|
||||||
|
|
||||||
|
if( currentCached != null )
|
||||||
|
{
|
||||||
|
// Cache is suitable, just update the count
|
||||||
|
itemStack = currentCached;
|
||||||
|
currentCached.setCount( Ints.saturatedCast( stackSize ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We need a new stack :-(
|
||||||
|
itemStack = this.createItemStack();
|
||||||
|
}
|
||||||
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -362,53 +370,20 @@ public class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
|
|||||||
|
|
||||||
private boolean fuzzyItemStackComparison( ItemStack a, ItemStack b, FuzzyMode mode )
|
private boolean fuzzyItemStackComparison( ItemStack a, ItemStack b, FuzzyMode mode )
|
||||||
{
|
{
|
||||||
if( a.getItem() == b.getItem() && ( a.getItem().isDamageable() || Platform.isGTDamageableItem( a.getItem() ) ) )
|
if( a.getItem() == b.getItem() && a.getItem().isDamageable() )
|
||||||
{
|
{
|
||||||
if( mode == FuzzyMode.IGNORE_ALL )
|
if( mode == FuzzyMode.IGNORE_ALL )
|
||||||
{
|
{
|
||||||
if( a.getItem().isDamageable() )
|
return true;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if( Platform.isGTDamageableItem( a.getItem() ) )
|
|
||||||
{
|
|
||||||
return a.getItemDamage() == b.getItemDamage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if( mode == FuzzyMode.PERCENT_99 )
|
else if( mode == FuzzyMode.PERCENT_99 )
|
||||||
{
|
{
|
||||||
if( Platform.isIC2DamageableItem( a.getItem() ) )
|
return a.getItemDamage() > 1 == b.getItemDamage() > 1;
|
||||||
{
|
|
||||||
return ( (ICustomDamageItem) a.getItem() ).getCustomDamage( a ) > 1 == ( (ICustomDamageItem) b.getItem() ).getCustomDamage( b ) > 1;
|
|
||||||
}
|
|
||||||
else if( a.getItem().isDamageable() )
|
|
||||||
{
|
|
||||||
return a.getItemDamage() > 1 == b.getItemDamage() > 1;
|
|
||||||
}
|
|
||||||
else if( Platform.isGTDamageableItem( a.getItem() ) )
|
|
||||||
{
|
|
||||||
return ( (IToolItem) a.getItem() ).getItemDamage( a ) > 1 == ( (IToolItem) b.getItem() ).getItemDamage( b ) > 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float percentDamageOfA = 0;
|
final float percentDamageOfA = (float) a.getItemDamage() / a.getMaxDamage();
|
||||||
float percentDamageOfB = 0;
|
final float percentDamageOfB = (float) b.getItemDamage() / b.getMaxDamage();
|
||||||
if( Platform.isIC2DamageableItem( a.getItem() ) )
|
|
||||||
{
|
|
||||||
percentDamageOfA = (float) ( (ICustomDamageItem) a.getItem() ).getCustomDamage( a ) / ( (ICustomDamageItem) a.getItem() ).getMaxCustomDamage( a );
|
|
||||||
percentDamageOfB = (float) ( (ICustomDamageItem) b.getItem() ).getCustomDamage( b ) / ( (ICustomDamageItem) b.getItem() ).getMaxCustomDamage( b );
|
|
||||||
}
|
|
||||||
else if( a.getItem().isDamageable() )
|
|
||||||
{
|
|
||||||
percentDamageOfA = (float) a.getItemDamage() / a.getMaxDamage();
|
|
||||||
percentDamageOfB = (float) b.getItemDamage() / b.getMaxDamage();
|
|
||||||
}
|
|
||||||
else if( Platform.isGTDamageableItem( a.getItem() ) )
|
|
||||||
{
|
|
||||||
percentDamageOfA = (float) ( (IToolItem) a.getItem() ).getItemDamage( a ) / ( (IToolItem) a.getItem() ).getMaxItemDamage( a );
|
|
||||||
percentDamageOfB = (float) ( (IToolItem) b.getItem() ).getItemDamage( b ) / ( (IToolItem) b.getItem() ).getMaxItemDamage( b );
|
|
||||||
}
|
|
||||||
|
|
||||||
return percentDamageOfA > mode.breakPoint == percentDamageOfB > mode.breakPoint;
|
return percentDamageOfA > mode.breakPoint == percentDamageOfB > mode.breakPoint;
|
||||||
}
|
}
|
||||||
@@ -416,5 +391,4 @@ public class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ import java.util.Map;
|
|||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
import gregtech.api.items.IToolItem;
|
import gregtech.common.items.MetaTool;
|
||||||
import ic2.api.item.ICustomDamageItem;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap;
|
||||||
@@ -35,210 +34,159 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectSortedMap;
|
|||||||
import appeng.api.config.FuzzyMode;
|
import appeng.api.config.FuzzyMode;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This variant list is optimized for damageable items, and supports selecting durability ranges with
|
* This variant list is optimized for damageable items, and supports selecting durability ranges with
|
||||||
* {@link #findFuzzy(IAEItemStack, FuzzyMode)}.
|
* {@link #findFuzzy(IAEItemStack, FuzzyMode)}.
|
||||||
*/
|
*/
|
||||||
class FuzzyItemVariantList extends ItemVariantList
|
class FuzzyItemVariantList extends ItemVariantList {
|
||||||
{
|
|
||||||
|
|
||||||
static final SharedStackComparator COMPARATOR = new SharedStackComparator();
|
static final SharedStackComparator COMPARATOR = new SharedStackComparator();
|
||||||
|
|
||||||
// NOTE: We only use Object as they key here so we can pass our special DamageBounds to the subMap method.
|
// NOTE: We only use Object as they key here so we can pass our special DamageBounds to the subMap method.
|
||||||
// We NEVER put any keys in this map that are not AESharedItemStacks.
|
// We NEVER put any keys in this map that are not AESharedItemStacks.
|
||||||
private final Object2ObjectSortedMap<Object, IAEItemStack> records = new Object2ObjectAVLTreeMap<>( COMPARATOR );
|
private final Object2ObjectSortedMap<Object, IAEItemStack> records = new Object2ObjectAVLTreeMap<>(COMPARATOR);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<IAEItemStack> findFuzzy( final IAEItemStack filter, final FuzzyMode fuzzy )
|
public Collection<IAEItemStack> findFuzzy(final IAEItemStack filter, final FuzzyMode fuzzy) {
|
||||||
{
|
ItemStack itemStack = filter.getDefinition();
|
||||||
ItemStack itemStack = filter.getDefinition();
|
|
||||||
|
|
||||||
ItemDamageBound lowerBound = makeLowerBound( itemStack, fuzzy );
|
ItemDamageBound lowerBound = makeLowerBound(itemStack, fuzzy);
|
||||||
ItemDamageBound upperBound = makeUpperBound( itemStack, fuzzy );
|
ItemDamageBound upperBound = makeUpperBound(itemStack, fuzzy);
|
||||||
Preconditions.checkState( lowerBound.itemDamage > upperBound.itemDamage );
|
Preconditions.checkState(lowerBound.itemDamage > upperBound.itemDamage);
|
||||||
|
|
||||||
return this.records.subMap( lowerBound, upperBound ).values();
|
return this.records.subMap(lowerBound, upperBound).values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
Map<AESharedItemStack, IAEItemStack> getRecords()
|
Map<AESharedItemStack, IAEItemStack> getRecords() {
|
||||||
{
|
// We ensure on our end that we NEVER use anything but AESharedItemStack as the key in this map
|
||||||
// We ensure on our end that we NEVER use anything but AESharedItemStack as the key in this map
|
return (Map<AESharedItemStack, IAEItemStack>) (Object) this.records;
|
||||||
return (Map<AESharedItemStack, IAEItemStack>) (Object) this.records;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static class ItemDamageBound
|
static class ItemDamageBound {
|
||||||
{
|
final int itemDamage;
|
||||||
final int itemDamage;
|
|
||||||
|
|
||||||
public ItemDamageBound( int itemDamage )
|
public ItemDamageBound(int itemDamage) {
|
||||||
{
|
this.itemDamage = itemDamage;
|
||||||
this.itemDamage = itemDamage;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This comparator creates a strict and total ordering over all {@link AESharedItemStack} of the same item. To
|
* This comparator creates a strict and total ordering over all {@link AESharedItemStack} of the same item. To
|
||||||
* support selecting ranges of durability, it is defined for type {@link Object} and also accepts
|
* support selecting ranges of durability, it is defined for type {@link Object} and also accepts
|
||||||
* {@link ItemDamageBound} as an argument to compare against.
|
* {@link ItemDamageBound} as an argument to compare against.
|
||||||
*/
|
*/
|
||||||
static class SharedStackComparator implements Comparator<Object>
|
static class SharedStackComparator implements Comparator<Object> {
|
||||||
{
|
@Override
|
||||||
@Override
|
public int compare(Object a, Object b) {
|
||||||
public int compare( Object a, Object b )
|
// Either argument can either be a damage bound or a shared item stack
|
||||||
{
|
// Since we never put damage bounds into the map as keys, only one
|
||||||
// Either argument can either be a damage bound or a shared item stack
|
// of the two arguments can possibly be a bound
|
||||||
// Since we never put damage bounds into the map as keys, only one
|
ItemDamageBound boundA = null;
|
||||||
// of the two arguments can possibly be a bound
|
AESharedItemStack stackA = null;
|
||||||
ItemDamageBound boundA = null;
|
int itemDamageA;
|
||||||
AESharedItemStack stackA = null;
|
if (a instanceof ItemDamageBound) {
|
||||||
int itemDamageA;
|
boundA = (ItemDamageBound) a;
|
||||||
if( a instanceof ItemDamageBound )
|
itemDamageA = boundA.itemDamage;
|
||||||
{
|
} else {
|
||||||
boundA = (ItemDamageBound) a;
|
stackA = (AESharedItemStack) a;
|
||||||
itemDamageA = boundA.itemDamage;
|
itemDamageA = stackA.getItemDamage();
|
||||||
}
|
}
|
||||||
else
|
ItemDamageBound boundB = null;
|
||||||
{
|
AESharedItemStack stackB = null;
|
||||||
stackA = (AESharedItemStack) a;
|
int itemDamageB;
|
||||||
itemDamageA = stackA.getItemDamage();
|
if (b instanceof ItemDamageBound) {
|
||||||
}
|
boundB = (ItemDamageBound) b;
|
||||||
ItemDamageBound boundB = null;
|
itemDamageB = boundB.itemDamage;
|
||||||
AESharedItemStack stackB = null;
|
} else {
|
||||||
int itemDamageB;
|
stackB = (AESharedItemStack) b;
|
||||||
if( b instanceof ItemDamageBound )
|
itemDamageB = stackB.getItemDamage();
|
||||||
{
|
}
|
||||||
boundB = (ItemDamageBound) b;
|
|
||||||
itemDamageB = boundB.itemDamage;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stackB = (AESharedItemStack) b;
|
|
||||||
itemDamageB = stackB.getItemDamage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// When either argument is a damage bound, we just compare the damage values because it is used
|
// When either argument is a damage bound, we just compare the damage values because it is used
|
||||||
// only to get a certain damage range out of the map.
|
// only to get a certain damage range out of the map.
|
||||||
if( boundA != null || boundB != null )
|
if (boundA != null || boundB != null) {
|
||||||
{
|
return Integer.compare(itemDamageB, itemDamageA);
|
||||||
return Integer.compare( itemDamageB, itemDamageA );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ItemStack itemStackA = stackA.getDefinition();
|
ItemStack itemStackA = stackA.getDefinition();
|
||||||
ItemStack itemStackB = stackB.getDefinition();
|
ItemStack itemStackB = stackB.getDefinition();
|
||||||
Preconditions.checkState( itemStackA.getCount() == 1, "ItemStack#getCount() has to be 1" );
|
Preconditions.checkState(itemStackA.getCount() == 1, "ItemStack#getCount() has to be 1");
|
||||||
Preconditions.checkArgument( itemStackB.getCount() == 1, "ItemStack#getCount() has to be 1" );
|
Preconditions.checkArgument(itemStackB.getCount() == 1, "ItemStack#getCount() has to be 1");
|
||||||
|
|
||||||
if( itemStackA == itemStackB )
|
if (itemStackA == itemStackB) {
|
||||||
{
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Damaged items are sorted before undamaged items
|
// Damaged items are sorted before undamaged items
|
||||||
final int damageValue = Integer.compare( itemDamageB, itemDamageA );
|
final int damageValue = Integer.compare(itemDamageB, itemDamageA);
|
||||||
if( damageValue != 0 )
|
if (damageValue != 0) {
|
||||||
{
|
return damageValue;
|
||||||
return damageValue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// As a final tie breaker, order by the object identity of the item stack
|
// As a final tie breaker, order by the object identity of the item stack
|
||||||
// While this will order seemingly at random, we only need the order of
|
// While this will order seemingly at random, we only need the order of
|
||||||
// damage values to be predictable, while still having to satisfy the
|
// damage values to be predictable, while still having to satisfy the
|
||||||
// complete order requirements of the sorted map
|
// complete order requirements of the sorted map
|
||||||
return Long.compare( System.identityHashCode( itemStackA ), System.identityHashCode( itemStackB ) );
|
return Long.compare(System.identityHashCode(itemStackA), System.identityHashCode(itemStackB));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minecraft reverses the damage values. So anything with a damage of 0 is undamaged and increases the more damaged
|
* Minecraft reverses the damage values. So anything with a damage of 0 is undamaged and increases the more damaged
|
||||||
* the item is.
|
* the item is.
|
||||||
* <p>
|
* <p>
|
||||||
* Further the used subMap follows [MAX_DAMAGE, MIN_DAMAGE), so to include undamaged items, we have to start with a
|
* Further the used subMap follows [MAX_DAMAGE, MIN_DAMAGE), so to include undamaged items, we have to start with a
|
||||||
* lower damage value than 0, while it is fine to use {@link ItemStack#getMaxDamage()} for the upper bound.
|
* lower damage value than 0, while it is fine to use {@link ItemStack#getMaxDamage()} for the upper bound.
|
||||||
*/
|
*/
|
||||||
private static final int MIN_DAMAGE_VALUE = -1;
|
private static final int MIN_DAMAGE_VALUE = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep in mind that the stack order is from most damaged to least damaged, so this lower bound will actually be a
|
* Keep in mind that the stack order is from most damaged to least damaged, so this lower bound will actually be a
|
||||||
* higher number than the upper bound.
|
* higher number than the upper bound.
|
||||||
*/
|
*/
|
||||||
static ItemDamageBound makeLowerBound( final ItemStack stack, final FuzzyMode fuzzy )
|
static ItemDamageBound makeLowerBound(final ItemStack stack, final FuzzyMode fuzzy)
|
||||||
{
|
{
|
||||||
Preconditions.checkState( stack.getItem().isDamageable() || ( Platform.isGTDamageableItem( stack.getItem() ) ), "Item#isDamageable() has to be true" );
|
Preconditions.checkState( stack.getItem().isDamageable() , "Item#isDamageable() has to be true" );
|
||||||
|
|
||||||
int damage;
|
int damage;
|
||||||
int maxDamage;
|
if( fuzzy == FuzzyMode.IGNORE_ALL )
|
||||||
if( Platform.isIC2DamageableItem( stack.getItem() ) )
|
{
|
||||||
{
|
if( stack.getMaxDamage() == 0 )
|
||||||
maxDamage = ( (ICustomDamageItem) stack.getItem() ).getMaxCustomDamage( stack );
|
{
|
||||||
damage = ( (ICustomDamageItem) stack.getItem() ).getCustomDamage( stack );
|
damage = stack.getItemDamage();
|
||||||
}
|
}
|
||||||
else if( Platform.isGTDamageableItem( stack.getItem() ) )
|
else
|
||||||
{
|
{
|
||||||
maxDamage = ( (IToolItem) stack.getItem() ).getMaxItemDamage( stack );
|
damage = stack.getMaxDamage();
|
||||||
damage = ( (IToolItem) stack.getItem() ).getItemDamage( stack );
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
maxDamage = stack.getMaxDamage();
|
final int breakpoint = fuzzy.calculateBreakPoint( stack.getMaxDamage() );
|
||||||
damage = stack.getItemDamage();
|
damage = stack.getItemDamage() <= breakpoint ? breakpoint : stack.getMaxDamage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fuzzy == FuzzyMode.IGNORE_ALL )
|
return new ItemDamageBound( damage );
|
||||||
{
|
}
|
||||||
if( maxDamage != 0 )
|
|
||||||
{
|
|
||||||
damage = maxDamage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final int breakpoint = fuzzy.calculateBreakPoint( maxDamage );
|
|
||||||
damage = damage <= breakpoint ? breakpoint : maxDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ItemDamageBound( damage );
|
/*
|
||||||
}
|
* Keep in mind that the stack order is from most damaged to least damaged, so this upper bound will actually be a
|
||||||
|
* lower number than the lower bound. It also is exclusive.
|
||||||
|
*/
|
||||||
|
static ItemDamageBound makeUpperBound(final ItemStack stack, final FuzzyMode fuzzy) {
|
||||||
|
Preconditions.checkState(stack.getItem().isDamageable() , "Item#isDamageable() has to be true");
|
||||||
|
|
||||||
/*
|
int damage;
|
||||||
* Keep in mind that the stack order is from most damaged to least damaged, so this upper bound will actually be a
|
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
||||||
* lower number than the lower bound. It also is exclusive.
|
damage = MIN_DAMAGE_VALUE;
|
||||||
*/
|
} else {
|
||||||
static ItemDamageBound makeUpperBound( final ItemStack stack, final FuzzyMode fuzzy )
|
final int breakpoint = fuzzy.calculateBreakPoint(stack.getMaxDamage());
|
||||||
{
|
damage = stack.getItemDamage() <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint;
|
||||||
Preconditions.checkState( stack.getItem().isDamageable() || ( Platform.isGTDamageableItem( stack.getItem() ) ), "Item#isDamageable() has to be true" );
|
}
|
||||||
|
|
||||||
int damage;
|
return new ItemDamageBound(damage);
|
||||||
if( fuzzy == FuzzyMode.IGNORE_ALL )
|
}
|
||||||
{
|
|
||||||
damage = MIN_DAMAGE_VALUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int maxDamage;
|
|
||||||
if( Platform.isIC2DamageableItem( stack.getItem() ) )
|
|
||||||
{
|
|
||||||
maxDamage = ( (ICustomDamageItem) stack.getItem() ).getMaxCustomDamage( stack );
|
|
||||||
damage = ( (ICustomDamageItem) stack.getItem() ).getCustomDamage( stack );
|
|
||||||
}
|
|
||||||
else if( Platform.isGTDamageableItem( stack.getItem() ) )
|
|
||||||
{
|
|
||||||
maxDamage = ( (IToolItem) stack.getItem() ).getMaxItemDamage( stack );
|
|
||||||
damage = ( (IToolItem) stack.getItem() ).getItemDamage( stack );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxDamage = stack.getMaxDamage();
|
|
||||||
damage = stack.getItemDamage();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int breakpoint = fuzzy.calculateBreakPoint( maxDamage );
|
|
||||||
damage = damage <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ItemDamageBound( damage );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.util.NoSuchElementException;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
|
import gregtech.common.items.MetaTool;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
||||||
@@ -35,217 +36,180 @@ import appeng.api.config.FuzzyMode;
|
|||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
|
|
||||||
|
public final class ItemList implements IItemList<IAEItemStack> {
|
||||||
|
|
||||||
public final class ItemList implements IItemList<IAEItemStack>
|
private final Reference2ObjectMap<Item, ItemVariantList> records = new Reference2ObjectOpenHashMap<>();
|
||||||
{
|
/**
|
||||||
|
* We increment this version field everytime an attempt to mutate this item list (or potentially one of its
|
||||||
|
* sub-lists) is made. Iterators will copy the version when they are created and compare it against the current
|
||||||
|
* version whenever they advance to trigger a {@link ConcurrentModificationException}.
|
||||||
|
*/
|
||||||
|
private final AtomicInteger version = new AtomicInteger(0);
|
||||||
|
|
||||||
private final Reference2ObjectMap<Item, ItemVariantList> records = new Reference2ObjectOpenHashMap<>();
|
@Override
|
||||||
/**
|
public IAEItemStack findPrecise(final IAEItemStack itemStack) {
|
||||||
* We increment this version field everytime an attempt to mutate this item list (or potentially one of its
|
if (itemStack == null) {
|
||||||
* sub-lists) is made. Iterators will copy the version when they are created and compare it against the current
|
return null;
|
||||||
* version whenever they advance to trigger a {@link ConcurrentModificationException}.
|
}
|
||||||
*/
|
|
||||||
private final AtomicInteger version = new AtomicInteger( 0 );
|
|
||||||
|
|
||||||
@Override
|
ItemVariantList record = this.records.get(itemStack.getItem());
|
||||||
public IAEItemStack findPrecise( final IAEItemStack itemStack )
|
return record != null ? record.findPrecise(itemStack) : null;
|
||||||
{
|
}
|
||||||
if( itemStack == null )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemVariantList record = this.records.get( itemStack.getItem() );
|
@Override
|
||||||
return record != null ? record.findPrecise( itemStack ) : null;
|
public Collection<IAEItemStack> findFuzzy(final IAEItemStack filter, final FuzzyMode fuzzy) {
|
||||||
}
|
if (filter == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
ItemVariantList record = this.records.get(filter.getItem());
|
||||||
public Collection<IAEItemStack> findFuzzy( final IAEItemStack filter, final FuzzyMode fuzzy )
|
return record != null ? record.findFuzzy(filter, fuzzy) : Collections.emptyList();
|
||||||
{
|
}
|
||||||
if( filter == null )
|
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemVariantList record = this.records.get( filter.getItem() );
|
@Override
|
||||||
return record != null ? record.findFuzzy( filter, fuzzy ) : Collections.emptyList();
|
public boolean isEmpty() {
|
||||||
}
|
return !this.iterator().hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty()
|
public void add(final IAEItemStack itemStack) {
|
||||||
{
|
version.incrementAndGet();
|
||||||
return !this.iterator().hasNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (itemStack == null) {
|
||||||
public void add( final IAEItemStack itemStack )
|
return;
|
||||||
{
|
}
|
||||||
version.incrementAndGet();
|
|
||||||
|
|
||||||
if( itemStack == null )
|
this.getOrCreateRecord(itemStack.getItem()).add(itemStack);
|
||||||
{
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getOrCreateRecord( itemStack.getItem() ).add( itemStack );
|
@Override
|
||||||
}
|
public void addStorage(final IAEItemStack itemStack) {
|
||||||
|
version.incrementAndGet();
|
||||||
|
|
||||||
@Override
|
if (itemStack == null) {
|
||||||
public void addStorage( final IAEItemStack itemStack )
|
return;
|
||||||
{
|
}
|
||||||
version.incrementAndGet();
|
|
||||||
|
|
||||||
if( itemStack == null )
|
this.getOrCreateRecord(itemStack.getItem()).addStorage(itemStack);
|
||||||
{
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getOrCreateRecord( itemStack.getItem() ).addStorage( itemStack );
|
@Override
|
||||||
}
|
public void addCrafting(final IAEItemStack itemStack) {
|
||||||
|
version.incrementAndGet();
|
||||||
|
|
||||||
@Override
|
if (itemStack == null) {
|
||||||
public void addCrafting( final IAEItemStack itemStack )
|
return;
|
||||||
{
|
}
|
||||||
version.incrementAndGet();
|
|
||||||
|
|
||||||
if( itemStack == null )
|
this.getOrCreateRecord(itemStack.getItem()).addCrafting(itemStack);
|
||||||
{
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getOrCreateRecord( itemStack.getItem() ).addCrafting( itemStack );
|
@Override
|
||||||
}
|
public void addRequestable(final IAEItemStack itemStack) {
|
||||||
|
version.incrementAndGet();
|
||||||
|
|
||||||
@Override
|
if (itemStack == null) {
|
||||||
public void addRequestable( final IAEItemStack itemStack )
|
return;
|
||||||
{
|
}
|
||||||
version.incrementAndGet();
|
|
||||||
|
|
||||||
if( itemStack == null )
|
this.getOrCreateRecord(itemStack.getItem()).addRequestable(itemStack);
|
||||||
{
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getOrCreateRecord( itemStack.getItem() ).addRequestable( itemStack );
|
@Override
|
||||||
}
|
public IAEItemStack getFirstItem() {
|
||||||
|
for (final IAEItemStack stackType : this) {
|
||||||
|
return stackType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
return null;
|
||||||
public IAEItemStack getFirstItem()
|
}
|
||||||
{
|
|
||||||
for( final IAEItemStack stackType : this )
|
|
||||||
{
|
|
||||||
return stackType;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
@Override
|
||||||
}
|
public int size() {
|
||||||
|
int size = 0;
|
||||||
|
for (ItemVariantList entry : records.values()) {
|
||||||
|
size += entry.size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
return size;
|
||||||
public int size()
|
}
|
||||||
{
|
|
||||||
int size = 0;
|
|
||||||
for( ItemVariantList entry : records.values() )
|
|
||||||
{
|
|
||||||
size += entry.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
@Override
|
||||||
}
|
public Iterator<IAEItemStack> iterator() {
|
||||||
|
return new ChainedIterator(this.records.values().iterator(), version);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<IAEItemStack> iterator()
|
public void resetStatus() {
|
||||||
{
|
for (final IAEItemStack i : this) {
|
||||||
return new ChainedIterator( this.records.values().iterator(), version );
|
i.reset();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
private ItemVariantList getOrCreateRecord(Item item) {
|
||||||
public void resetStatus()
|
return this.records.computeIfAbsent(item, this::makeRecordMap);
|
||||||
{
|
}
|
||||||
for( final IAEItemStack i : this )
|
|
||||||
{
|
|
||||||
i.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemVariantList getOrCreateRecord( Item item )
|
private ItemVariantList makeRecordMap(Item item) {
|
||||||
{
|
if (item.isDamageable() ) {
|
||||||
return this.records.computeIfAbsent( item, this::makeRecordMap );
|
return new FuzzyItemVariantList();
|
||||||
}
|
} else {
|
||||||
|
return new NormalItemVariantList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ItemVariantList makeRecordMap( Item item )
|
/**
|
||||||
{
|
* Iterates over multiple item lists as if they were one list.
|
||||||
if( item.isDamageable() || Platform.isGTDamageableItem( item ) )
|
*/
|
||||||
{
|
private static class ChainedIterator implements Iterator<IAEItemStack> {
|
||||||
return new FuzzyItemVariantList();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new NormalItemVariantList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private final AtomicInteger parentVersion;
|
||||||
* Iterates over multiple item lists as if they were one list.
|
private final int version;
|
||||||
*/
|
private final Iterator<ItemVariantList> parent;
|
||||||
private static class ChainedIterator implements Iterator<IAEItemStack>
|
private Iterator<IAEItemStack> next;
|
||||||
{
|
|
||||||
|
|
||||||
private final AtomicInteger parentVersion;
|
public ChainedIterator(Iterator<ItemVariantList> iterator, AtomicInteger parentVersion) {
|
||||||
private final int version;
|
this.parent = iterator;
|
||||||
private final Iterator<ItemVariantList> parent;
|
this.parentVersion = parentVersion;
|
||||||
private Iterator<IAEItemStack> next;
|
this.version = parentVersion.get();
|
||||||
|
this.ensureItems();
|
||||||
|
}
|
||||||
|
|
||||||
public ChainedIterator( Iterator<ItemVariantList> iterator, AtomicInteger parentVersion )
|
@Override
|
||||||
{
|
public boolean hasNext() {
|
||||||
this.parent = iterator;
|
return next != null && next.hasNext();
|
||||||
this.parentVersion = parentVersion;
|
}
|
||||||
this.version = parentVersion.get();
|
|
||||||
this.ensureItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext()
|
public IAEItemStack next() {
|
||||||
{
|
if (this.next == null) {
|
||||||
return next != null && next.hasNext();
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
|
if (this.version != this.parentVersion.get()) {
|
||||||
|
throw new ConcurrentModificationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
IAEItemStack result = this.next.next();
|
||||||
public IAEItemStack next()
|
this.ensureItems();
|
||||||
{
|
return result;
|
||||||
if( this.next == null )
|
}
|
||||||
{
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
if( this.version != this.parentVersion.get() )
|
|
||||||
{
|
|
||||||
throw new ConcurrentModificationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
IAEItemStack result = this.next.next();
|
private void ensureItems() {
|
||||||
this.ensureItems();
|
if (hasNext()) {
|
||||||
return result;
|
return; // Still items left in the current one
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureItems()
|
// Find the next iterator willing to return some items...
|
||||||
{
|
while (this.parent.hasNext()) {
|
||||||
if( hasNext() )
|
this.next = this.parent.next().iterator();
|
||||||
{
|
|
||||||
return; // Still items left in the current one
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the next iterator willing to return some items...
|
if (this.next.hasNext()) {
|
||||||
while ( this.parent.hasNext() )
|
return; // Found one!
|
||||||
{
|
}
|
||||||
this.next = this.parent.next().iterator();
|
}
|
||||||
|
|
||||||
if( this.next.hasNext() )
|
// No more items
|
||||||
{
|
this.next = null;
|
||||||
return; // Found one!
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// No more items
|
|
||||||
this.next = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user