aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/interfaces/metatileentity
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api/interfaces/metatileentity')
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IConnectable.java34
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IFluidLockable.java27
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java539
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityCable.java19
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityItemPipe.java123
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityPipe.java24
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IMetricsExporter.java28
7 files changed, 794 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IConnectable.java b/src/main/java/gregtech/api/interfaces/metatileentity/IConnectable.java
new file mode 100644
index 0000000000..0ca519d40b
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IConnectable.java
@@ -0,0 +1,34 @@
+package gregtech.api.interfaces.metatileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+/**
+ * For pipes, wires, and other MetaTiles which need to be decided whether they should connect to the block at each side.
+ */
+public interface IConnectable {
+
+ int NO_CONNECTION = 0b00000000;
+ int CONNECTED_DOWN = 0b00000001;
+ int CONNECTED_UP = 0b00000010;
+ int CONNECTED_NORTH = 0b00000100;
+ int CONNECTED_SOUTH = 0b00001000;
+ int CONNECTED_WEST = 0b00010000;
+ int CONNECTED_EAST = 0b00100000;
+ int CONNECTED_ALL = 0b00111111;
+ int HAS_FRESHFOAM = 0b01000000;
+ int HAS_HARDENEDFOAM = 0b10000000;
+ int HAS_FOAM = 0b11000000;
+
+ /**
+ * Try to connect to the Block at the specified side returns the connection state. Non-positive values for failed,
+ * others for succeeded.
+ */
+ int connect(ForgeDirection side);
+
+ /**
+ * Try to disconnect to the Block at the specified side
+ */
+ void disconnect(ForgeDirection side);
+
+ boolean isConnectedAtSide(ForgeDirection side);
+}
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IFluidLockable.java b/src/main/java/gregtech/api/interfaces/metatileentity/IFluidLockable.java
new file mode 100644
index 0000000000..f7f6112680
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IFluidLockable.java
@@ -0,0 +1,27 @@
+package gregtech.api.interfaces.metatileentity;
+
+import net.minecraftforge.fluids.Fluid;
+
+/**
+ * Implement this interface if your MetaTileEntity supports fluid lock mechanism.
+ */
+@SuppressWarnings({ "BooleanMethodIsAlwaysInverted" })
+public interface IFluidLockable {
+
+ /**
+ * Use {@link Fluid#getName()} instead of {@link Fluid#getUnlocalizedName()} for fluid name
+ */
+ void setLockedFluidName(String name);
+
+ String getLockedFluidName();
+
+ /**
+ * Set fluid lock state. Would be useful when you don't necessarily want to change mode when locked fluid is
+ * changed.
+ */
+ void lockFluid(boolean lock);
+
+ boolean isFluidLocked();
+
+ boolean acceptsFluidLock(String name);
+}
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
new file mode 100644
index 0000000000..2c222e76a8
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
@@ -0,0 +1,539 @@
+package gregtech.api.interfaces.metatileentity;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.IFluidHandler;
+import net.minecraftforge.fluids.IFluidTank;
+
+import com.gtnewhorizons.modularui.api.forge.ItemStackHandler;
+
+import appeng.api.crafting.ICraftingIconProvider;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.enums.Dyes;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.modularui.IGetGUITextureSet;
+import gregtech.api.interfaces.tileentity.IGearEnergyTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.interfaces.tileentity.IGregtechWailaProvider;
+import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable;
+import gregtech.api.objects.GT_ItemStack;
+import gregtech.api.util.GT_Config;
+import gregtech.api.util.GT_Util;
+
+/**
+ * Warning, this Interface has just been made to be able to add multiple kinds of MetaTileEntities (Cables, Pipes,
+ * Transformers, but not the regular Blocks)
+ * <p/>
+ * Don't implement this yourself and expect it to work. Extend @MetaTileEntity itself.
+ */
+public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHandler, IGearEnergyTileEntity,
+ IMachineBlockUpdateable, IGregtechWailaProvider, IGetGUITextureSet, ICraftingIconProvider {
+
+ /**
+ * This determines the BaseMetaTileEntity belonging to this MetaTileEntity by using the Meta ID of the Block itself.
+ * <p/>
+ * 0 = BaseMetaTileEntity, Wrench lvl 0 to dismantle 1 = BaseMetaTileEntity, Wrench lvl 1 to dismantle 2 =
+ * BaseMetaTileEntity, Wrench lvl 2 to dismantle 3 = BaseMetaTileEntity, Wrench lvl 3 to dismantle 4 =
+ * BaseMetaPipeEntity, Wrench lvl 0 to dismantle 5 = BaseMetaPipeEntity, Wrench lvl 1 to dismantle 6 =
+ * BaseMetaPipeEntity, Wrench lvl 2 to dismantle 7 = BaseMetaPipeEntity, Wrench lvl 3 to dismantle 8 =
+ * BaseMetaPipeEntity, Cutter lvl 0 to dismantle 9 = BaseMetaPipeEntity, Cutter lvl 1 to dismantle 10 =
+ * BaseMetaPipeEntity, Cutter lvl 2 to dismantle 11 = BaseMetaPipeEntity, Cutter lvl 3 to dismantle 12 = GT++ 13 =
+ * GT++ 14 = GT++ 15 = GT++
+ */
+ byte getTileEntityBaseType();
+
+ /**
+ * @param aTileEntity is just because the internal Variable "mBaseMetaTileEntity" is set after this Call.
+ * @return a newly created and ready MetaTileEntity
+ */
+ IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity);
+
+ /**
+ * @return an ItemStack representing this MetaTileEntity.
+ */
+ ItemStack getStackForm(long aAmount);
+
+ /**
+ * new getter for the BaseMetaTileEntity, which restricts usage to certain Functions.
+ */
+ IGregTechTileEntity getBaseMetaTileEntity();
+
+ /**
+ * Sets the BaseMetaTileEntity of this
+ */
+ void setBaseMetaTileEntity(IGregTechTileEntity aBaseMetaTileEntity);
+
+ /**
+ * when placing a Machine in World, to initialize default Modes. aNBT can be null!
+ */
+ void initDefaultModes(NBTTagCompound aNBT);
+
+ /**
+ * ^= writeToNBT
+ */
+ void saveNBTData(NBTTagCompound aNBT);
+
+ /**
+ * ^= readFromNBT
+ */
+ void loadNBTData(NBTTagCompound aNBT);
+
+ /**
+ * Adds the NBT-Information to the ItemStack, when being dismanteled properly Used to store Machine specific Upgrade
+ * Data.
+ */
+ void setItemNBT(NBTTagCompound aNBT);
+
+ /**
+ * Called in the registered MetaTileEntity when the Server starts, to reset static variables
+ */
+ void onServerStart();
+
+ /**
+ * Called in the registered MetaTileEntity when the Server ticks a World the first time, to load things from the
+ * World Save
+ */
+ void onWorldLoad(File aSaveDirectory);
+
+ /**
+ * Called in the registered MetaTileEntity when the Server stops, to save the Game.
+ */
+ void onWorldSave(File aSaveDirectory);
+
+ /**
+ * Called to set Configuration values for this MetaTileEntity. Use aConfig.get(ConfigCategories.machineconfig,
+ * "MetaTileEntityName.Ability", DEFAULT_VALUE); to set the Values.
+ */
+ void onConfigLoad(GT_Config aConfig);
+
+ /**
+ * If a Cover of that Type can be placed on this Side. Also Called when the Facing of the Block Changes and a Cover
+ * is on said Side.
+ */
+ boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aStack);
+
+ /**
+ * When a Player right-clicks the Facing with a Screwdriver.
+ */
+ void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ,
+ ItemStack aTool);
+
+ /**
+ * When a Player right-clicks the Facing with a Wrench.
+ */
+ boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, float aX,
+ float aY, float aZ, ItemStack aTool);
+
+ /**
+ * When a Player right-clicks the Facing with a wire cutter.
+ */
+ boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer,
+ float aX, float aY, float aZ, ItemStack aTool);
+
+ /**
+ * When a Player right-clicks the Facing with a soldering iron.
+ */
+ boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer,
+ float aX, float aY, float aZ, ItemStack aTool);
+
+ /**
+ * Called right before this Machine explodes
+ */
+ void onExplosion();
+
+ /**
+ * The First processed Tick which was passed to this MetaTileEntity
+ */
+ void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity);
+
+ /**
+ * The Tick before all the generic handling happens, what gives a slightly faster reaction speed. Don't use this if
+ * you really don't need to. @onPostTick is better suited for ticks. This happens still after the Cover handling.
+ */
+ void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick);
+
+ /**
+ * The Tick after all the generic handling happened. Recommended to use this like updateEntity.
+ */
+ void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick);
+
+ /**
+ * Called when this MetaTileEntity gets (intentionally) disconnected from the BaseMetaTileEntity. Doesn't get called
+ * when this thing is moved by Frames or similar hacks.
+ */
+ void inValidate();
+
+ /**
+ * Called when the BaseMetaTileEntity gets invalidated, what happens right before the @inValidate above gets called
+ */
+ void onRemoval();
+
+ /**
+ * Called when the BaseMetaTileEntity gets unloaded (chunk or world)
+ */
+ default void onUnload() {}
+
+ /**
+ * @param facing the facing direction to check
+ * @return if aFacing would be a valid Facing for this Device. Used for wrenching.
+ */
+ boolean isFacingValid(ForgeDirection facing);
+
+ /**
+ * @return the Server Side Container
+ * @deprecated Use ModularUI
+ */
+ @Deprecated
+ default Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @return the Client Side GUI Container
+ * @deprecated Use ModularUI
+ */
+ @Deprecated
+ default Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * For back compatibility, you need to override this if this MetaTileEntity uses ModularUI.
+ */
+ default boolean useModularUI() {
+ return false;
+ }
+
+ /**
+ * From new ISidedInventory
+ */
+ boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, ItemStack aStack);
+
+ /**
+ * From new ISidedInventory
+ */
+ boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, ItemStack aStack);
+
+ /**
+ * @return if aIndex is a valid Slot. false for things like HoloSlots. Is used for determining if an Item is dropped
+ * upon Block destruction and for Inventory Access Management
+ */
+ boolean isValidSlot(int aIndex);
+
+ /**
+ * Check if the item at the specified index should be dropped
+ *
+ * @param index Index that will be checked
+ * @return True if the item at the index should be dropped, else false
+ */
+ boolean shouldDropItemAt(int index);
+
+ /**
+ * @return if aIndex can be set to Zero stackSize, when being removed.
+ */
+ boolean setStackToZeroInsteadOfNull(int aIndex);
+
+ /**
+ * If this Side can connect to inputting pipes
+ */
+ boolean isLiquidInput(ForgeDirection side);
+
+ /**
+ * If this Side can connect to outputting pipes
+ */
+ boolean isLiquidOutput(ForgeDirection side);
+
+ /**
+ * Just an Accessor for the Name variable.
+ */
+ String getMetaName();
+
+ /**
+ * @return true if the Machine can be accessed
+ */
+ boolean isAccessAllowed(EntityPlayer aPlayer);
+
+ /**
+ * a Player right-clicks the Machine Sneaky right clicks are not getting passed to this!
+ *
+ * @return mostly {@code false}. Probably is left for compatibility.
+ */
+ boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side, float aX,
+ float aY, float aZ);
+
+ /**
+ * a Player leftclicks the Machine Sneaky leftclicks are getting passed to this unlike with the rightclicks.
+ */
+ void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer);
+
+ /**
+ * Called Clientside with the Data got from @getUpdateData
+ */
+ void onValueUpdate(byte aValue);
+
+ /**
+ * return a small bit of Data, like a secondary Facing for example with this Function, for the Client. The
+ * BaseMetaTileEntity detects changes to this Value and will then send an Update. This is only for Information,
+ * which is visible as Texture to the outside.
+ * <p/>
+ * If you just want to have an Active/Redstone State then set the Active State inside the BaseMetaTileEntity
+ * instead.
+ */
+ byte getUpdateData();
+
+ /**
+ * For the rare case you need this Function
+ */
+ void receiveClientEvent(byte aEventID, byte aValue);
+
+ /**
+ * Called to actually play the sound on client side. Client/Server check is already done.
+ */
+ void doSound(byte aIndex, double aX, double aY, double aZ);
+
+ void startSoundLoop(byte aIndex, double aX, double aY, double aZ);
+
+ void stopSoundLoop(byte aValue, double aX, double aY, double aZ);
+
+ /**
+ * Sends the Event for the Sound Triggers, only usable Server Side!
+ */
+ void sendSound(byte aIndex);
+
+ /**
+ * Sends the Event for the Sound Triggers, only usable Server Side!
+ */
+ void sendLoopStart(byte aIndex);
+
+ /**
+ * Sends the Event for the Sound Triggers, only usable Server Side!
+ */
+ void sendLoopEnd(byte aIndex);
+
+ /**
+ * Called when the Machine explodes. Override the Explosion code here.
+ *
+ * @param aExplosionPower explosion power
+ */
+ void doExplosion(long aExplosionPower);
+
+ /**
+ * If this is just a simple Machine, which can be wrenched at 100%
+ */
+ boolean isSimpleMachine();
+
+ /**
+ * If there should be a Lag Warning if something laggy happens during this Tick.
+ * <p/>
+ * The Advanced Pump uses this to not cause the Lag Message, while it scans for all close Fluids. The Item Pipes and
+ * Retrievers neither send this Message, when scanning for Pipes.
+ */
+ boolean doTickProfilingMessageDuringThisTick();
+
+ /**
+ * returns the DebugLog
+ */
+ ArrayList<String> getSpecialDebugInfo(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, int aLogLevel,
+ ArrayList<String> aList);
+
+ /**
+ * get a small Description
+ */
+ String[] getDescription();
+
+ /**
+ * In case the Output Voltage varies.
+ */
+ String getSpecialVoltageToolTip();
+
+ /**
+ * Icon of the Texture. If this returns null then it falls back to getTextureIndex.
+ *
+ * @param side is the Side of the Block
+ * @param facing is the direction the Block is facing
+ * @param colorIndex The Minecraft Color the Block is having
+ * @param active if the Machine is currently active (use this instead of calling
+ * {@code mBaseMetaTileEntity.mActive)}. Note: In case of Pipes this means if this Side is
+ * connected to something or not.
+ * @param redstoneLevel if the Machine is currently outputting a RedstoneSignal (use this instead of calling
+ * {@code mBaseMetaTileEntity.mRedstone} !!!)
+ */
+ ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int colorIndex, boolean active, boolean redstoneLevel);
+
+ /**
+ * Register Icons here. This gets called when the Icons get initialized by the Base Block Best is you put your Icons
+ * in a static Array for quick and easy access without relying on the MetaTileList.
+ *
+ * @param aBlockIconRegister The Block Icon Register
+ */
+ @SideOnly(Side.CLIENT)
+ void registerIcons(IIconRegister aBlockIconRegister);
+
+ /**
+ * @return true if you override the Rendering.
+ */
+ @SideOnly(Side.CLIENT)
+ boolean renderInInventory(Block aBlock, int aMeta, RenderBlocks aRenderer);
+
+ /**
+ * @return true if you override the Rendering.
+ */
+ @SideOnly(Side.CLIENT)
+ boolean renderInWorld(IBlockAccess aWorld, int aX, int aY, int aZ, Block aBlock, RenderBlocks aRenderer);
+
+ /**
+ * Gets the Output for the comparator on the given Side
+ */
+ byte getComparatorValue(ForgeDirection side);
+
+ float getExplosionResistance(ForgeDirection side);
+
+ String[] getInfoData();
+
+ boolean isGivingInformation();
+
+ ItemStack[] getRealInventory();
+
+ boolean connectsToItemPipe(ForgeDirection side);
+
+ void onColorChangeServer(byte aColor);
+
+ void onColorChangeClient(byte aColor);
+
+ /**
+ * @return Actual color shown on GUI
+ */
+ default int getGUIColorization() {
+ if (getBaseMetaTileEntity() != null) {
+ return getBaseMetaTileEntity().getGUIColorization();
+ } else {
+ return GT_Util.getRGBInt(Dyes.MACHINE_METAL.getRGBA());
+ }
+ }
+
+ int getLightOpacity();
+
+ boolean allowGeneralRedstoneOutput();
+
+ void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB,
+ List<AxisAlignedBB> outputAABB, Entity collider);
+
+ AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ);
+
+ void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity collider);
+
+ /**
+ * The onCreated Function of the Item Class redirects here
+ */
+ void onCreated(ItemStack aStack, World aWorld, EntityPlayer aPlayer);
+
+ boolean hasAlternativeModeText();
+
+ String getAlternativeModeText();
+
+ boolean shouldJoinIc2Enet();
+
+ /**
+ * The Machine Update, which is called when the Machine needs an Update of its Parts. I suggest to wait 1-5 seconds
+ * before actually checking the Machine Parts. RP-Frames could for example cause Problems when you instacheck the
+ * Machine Parts.
+ * <p>
+ * just do stuff since we are already in meta tile...
+ */
+ @Override
+ void onMachineBlockUpdate();
+
+ /**
+ * just return in should recurse since we are already in meta tile...
+ */
+ @Override
+ default boolean isMachineBlockUpdateRecursive() {
+ return true;
+ }
+
+ /**
+ * A randomly called display update to be able to add particles or other items for display
+ *
+ * @param aBaseMetaTileEntity The entity that will handle the {@see Block#randomDisplayTick}
+ */
+ @SideOnly(Side.CLIENT)
+ default void onRandomDisplayTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ /* do nothing */
+ }
+
+ default int getGUIWidth() {
+ return 176;
+ }
+
+ default int getGUIHeight() {
+ return 166;
+ }
+
+ /*
+ * ModularUI Support
+ */
+ default ItemStackHandler getInventoryHandler() {
+ return null;
+ }
+
+ default String getLocalName() {
+ return "Unknown";
+ }
+
+ default boolean doesBindPlayerInventory() {
+ return true;
+ }
+
+ default int getTextColorOrDefault(String textType, int defaultColor) {
+ return defaultColor;
+ }
+
+ /**
+ * Called before block is destroyed. This is before inventory dropping code has executed.
+ */
+ default void onBlockDestroyed() {}
+
+ /**
+ * Allows to add additional data to the tooltip, which is specific to an instance of the machine
+ *
+ * @param stack Item stack of this MTE
+ * @param tooltip Tooltip to which can be added
+ */
+ default void addAdditionalTooltipInformation(ItemStack stack, List<String> tooltip) {}
+
+ @Override
+ default ItemStack getMachineCraftingIcon() {
+ return null;
+ }
+
+ /**
+ * Gets items to be displayed for HoloInventory mod.
+ *
+ * @return null if default implementation should be used, i.e. {@link IInventory#getStackInSlot}.
+ * Otherwise, a list of items to be displayed. Null element may be contained.
+ */
+ @Nullable
+ default List<ItemStack> getItemsForHoloGlasses() {
+ return null;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityCable.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityCable.java
new file mode 100644
index 0000000000..a2d672e765
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityCable.java
@@ -0,0 +1,19 @@
+package gregtech.api.interfaces.metatileentity;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public interface IMetaTileEntityCable extends IMetaTileEntityPipe {
+
+ @Deprecated
+ long transferElectricity(ForgeDirection side, long aVoltage, long aAmperage,
+ ArrayList<TileEntity> aAlreadyPassedTileEntityList);
+
+ default long transferElectricity(ForgeDirection side, long aVoltage, long aAmperage,
+ HashSet<TileEntity> aAlreadyPassedSet) {
+ return transferElectricity(side, aVoltage, aAmperage, new ArrayList<>(aAlreadyPassedSet));
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityItemPipe.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityItemPipe.java
new file mode 100644
index 0000000000..5daf895c20
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityItemPipe.java
@@ -0,0 +1,123 @@
+package gregtech.api.interfaces.metatileentity;
+
+import java.util.Map;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+
+public interface IMetaTileEntityItemPipe extends IMetaTileEntityPipe {
+
+ /**
+ * @return if this Pipe can still be used.
+ */
+ boolean pipeCapacityCheck();
+
+ /**
+ * @return if this Pipe can still be used.
+ */
+ boolean incrementTransferCounter(int aIncrement);
+
+ /**
+ * Sends an ItemStack from aSender to the adjacent Blocks.
+ *
+ * @param aSender the BaseMetaTileEntity sending the Stack.
+ * @return if it was able to send something
+ */
+ boolean sendItemStack(Object aSender);
+
+ /**
+ * Executes the Sending Code for inserting Stacks into the TileEntities.
+ *
+ * @param aSender the BaseMetaTileEntity sending the Stack.
+ * @param side the Side of the PIPE facing the TileEntity.
+ * @return if this Side was allowed to Output into the Block.
+ */
+ boolean insertItemStackIntoTileEntity(Object aSender, ForgeDirection side);
+
+ /**
+ * Can be used to make flow control Pipes, like Redpowers Restriction Tubes. Every normal Pipe returns a Value of
+ * 32768, so you can easily insert lower Numbers to set Routing priorities. Negative Numbers to "suck" Items into a
+ * certain direction are also possible.
+ */
+ int getStepSize();
+
+ /**
+ * Utility for the Item Network
+ */
+ class Util {
+
+ /**
+ * @return connected Item Pipes
+ */
+ public static Map<IMetaTileEntityItemPipe, Long> scanPipes(IMetaTileEntityItemPipe aMetaTileEntity,
+ Map<IMetaTileEntityItemPipe, Long> aMap, long aStep, boolean aSuckItems, boolean aIgnoreCapacity) {
+ aStep += aMetaTileEntity.getStepSize();
+ if (aIgnoreCapacity || aMetaTileEntity.pipeCapacityCheck())
+ if (aMap.get(aMetaTileEntity) == null || aMap.get(aMetaTileEntity) > aStep) {
+ final IGregTechTileEntity aBaseMetaTileEntity = aMetaTileEntity.getBaseMetaTileEntity();
+ aMap.put(aMetaTileEntity, aStep);
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ if (aMetaTileEntity instanceof IConnectable
+ && !((IConnectable) aMetaTileEntity).isConnectedAtSide(side)) continue;
+ final ForgeDirection oppositeSide = side.getOpposite();
+ if (aSuckItems) {
+ if (aBaseMetaTileEntity.getCoverInfoAtSide(side)
+ .letsItemsIn(-2)) {
+ final IGregTechTileEntity tItemPipe = aBaseMetaTileEntity
+ .getIGregTechTileEntityAtSide(side);
+ if (aBaseMetaTileEntity.getColorization() >= 0) {
+ final byte tColor = tItemPipe.getColorization();
+ if (tColor >= 0 && tColor != aBaseMetaTileEntity.getColorization()) {
+ continue;
+ }
+ }
+ if (tItemPipe instanceof BaseMetaPipeEntity) {
+ final IMetaTileEntity tMetaTileEntity = tItemPipe.getMetaTileEntity();
+ if (tMetaTileEntity instanceof IMetaTileEntityItemPipe
+ && tItemPipe.getCoverInfoAtSide(oppositeSide)
+ .letsItemsOut(-2)) {
+ scanPipes(
+ (IMetaTileEntityItemPipe) tMetaTileEntity,
+ aMap,
+ aStep,
+ aSuckItems,
+ aIgnoreCapacity);
+ }
+ }
+ }
+ } else {
+ if (aBaseMetaTileEntity.getCoverInfoAtSide(side)
+ .letsItemsOut(-2)) {
+ final IGregTechTileEntity tItemPipe = aBaseMetaTileEntity
+ .getIGregTechTileEntityAtSide(side);
+ if (tItemPipe != null) {
+ if (aBaseMetaTileEntity.getColorization() >= 0) {
+ final byte tColor = tItemPipe.getColorization();
+ if (tColor >= 0 && tColor != aBaseMetaTileEntity.getColorization()) {
+ continue;
+ }
+ }
+ if (tItemPipe instanceof BaseMetaPipeEntity) {
+ final IMetaTileEntity tMetaTileEntity = tItemPipe.getMetaTileEntity();
+ if (tMetaTileEntity instanceof IMetaTileEntityItemPipe
+ && tItemPipe.getCoverInfoAtSide(oppositeSide)
+ .letsItemsIn(-2)) {
+ scanPipes(
+ (IMetaTileEntityItemPipe) tMetaTileEntity,
+ aMap,
+ aStep,
+ aSuckItems,
+ aIgnoreCapacity);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return aMap;
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityPipe.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityPipe.java
new file mode 100644
index 0000000000..0ac29b2e45
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntityPipe.java
@@ -0,0 +1,24 @@
+package gregtech.api.interfaces.metatileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+
+public interface IMetaTileEntityPipe extends IMetaTileEntity {
+
+ /**
+ * Icon of the Texture. If this returns null then it falls back to getTextureIndex.
+ *
+ * @param side is the Side of the Block
+ * @param facingBitMask is the Bitmask of all Connections
+ * @param colorIndex The Minecraft Color the Block is having
+ * @param active if the Machine is currently active (use this instead of calling
+ * mBaseMetaTileEntity.mActive!!!). Note: In case of Pipes this means if this Side is connected
+ * to something or not.
+ * @param redstoneLevel if the Machine is currently outputting a RedstoneSignal (use this instead of calling
+ * mBaseMetaTileEntity.mRedstone!!!)
+ */
+ ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection side, int facingBitMask,
+ int colorIndex, boolean active, boolean redstoneLevel);
+}
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetricsExporter.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetricsExporter.java
new file mode 100644
index 0000000000..f97cd79ed6
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetricsExporter.java
@@ -0,0 +1,28 @@
+package gregtech.api.interfaces.metatileentity;
+
+import java.util.List;
+
+import org.jetbrains.annotations.NotNull;
+
+import gregtech.api.metatileentity.BaseMetaTileEntity;
+
+/**
+ * Metrics Transmitter covers look for this interface for retrieving custom metrics for a machine. If this interface is
+ * not present on the machine housing the cover, it will use {@link BaseMetaTileEntity#getInfoData()} to retrieve info
+ * instead.
+ */
+public interface IMetricsExporter {
+
+ /**
+ * Attached metrics covers will call this method to receive reported metrics.
+ * <p>
+ * When reporting metrics, try to keep the number of entries small, and ordering of entries consistent. Advanced
+ * Sensor Cards allow the user to selectively turn off individual lines using the panel's UI, and doing so is
+ * aggravated by a metrics set that is inconsistent and/or large.
+ *
+ * @return A list of strings to print on the information panel the advanced sensor card is utilizing. Each item in
+ * the list will be printed on its own line.
+ */
+ @NotNull
+ List<String> reportMetrics();
+}