aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api/interfaces')
-rw-r--r--src/main/java/gregtech/api/interfaces/IBlockContainer.java10
-rw-r--r--src/main/java/gregtech/api/interfaces/IBlockOnWalkOver.java9
-rw-r--r--src/main/java/gregtech/api/interfaces/IChunkLoader.java10
-rw-r--r--src/main/java/gregtech/api/interfaces/ICleanroom.java22
-rw-r--r--src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java18
-rw-r--r--src/main/java/gregtech/api/interfaces/IColorModulationContainer.java6
-rw-r--r--src/main/java/gregtech/api/interfaces/ICondition.java116
-rw-r--r--src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java47
-rw-r--r--src/main/java/gregtech/api/interfaces/IDamagableItem.java8
-rw-r--r--src/main/java/gregtech/api/interfaces/IDebugableBlock.java24
-rw-r--r--src/main/java/gregtech/api/interfaces/IDescribable.java12
-rw-r--r--src/main/java/gregtech/api/interfaces/IDragAndDropSupport.java58
-rw-r--r--src/main/java/gregtech/api/interfaces/IFluidAccess.java26
-rw-r--r--src/main/java/gregtech/api/interfaces/IFoodStat.java37
-rw-r--r--src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java68
-rw-r--r--src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java98
-rw-r--r--src/main/java/gregtech/api/interfaces/IGuiIcon.java19
-rw-r--r--src/main/java/gregtech/api/interfaces/IGuiScreen.java45
-rw-r--r--src/main/java/gregtech/api/interfaces/IHasIndexedTexture.java17
-rw-r--r--src/main/java/gregtech/api/interfaces/IHatchElement.java198
-rw-r--r--src/main/java/gregtech/api/interfaces/IHeatingCoil.java20
-rw-r--r--src/main/java/gregtech/api/interfaces/IIconContainer.java48
-rw-r--r--src/main/java/gregtech/api/interfaces/IItemBehaviour.java47
-rw-r--r--src/main/java/gregtech/api/interfaces/IItemContainer.java40
-rw-r--r--src/main/java/gregtech/api/interfaces/IMaterialHandler.java6
-rw-r--r--src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java25
-rw-r--r--src/main/java/gregtech/api/interfaces/IOreRecipeRegistrator.java19
-rw-r--r--src/main/java/gregtech/api/interfaces/IProjectileItem.java29
-rw-r--r--src/main/java/gregtech/api/interfaces/IRecipeMap.java74
-rw-r--r--src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java69
-rw-r--r--src/main/java/gregtech/api/interfaces/ISecondaryDescribable.java30
-rw-r--r--src/main/java/gregtech/api/interfaces/ISubTagContainer.java21
-rw-r--r--src/main/java/gregtech/api/interfaces/ITexture.java55
-rw-r--r--src/main/java/gregtech/api/interfaces/ITextureBuilder.java109
-rw-r--r--src/main/java/gregtech/api/interfaces/IToolStats.java206
-rw-r--r--src/main/java/gregtech/api/interfaces/covers/IControlsWorkCover.java30
-rw-r--r--src/main/java/gregtech/api/interfaces/fluid/IFluidStore.java22
-rw-r--r--src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java14
-rw-r--r--src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java96
-rw-r--r--src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java60
-rw-r--r--src/main/java/gregtech/api/interfaces/internal/IBCTileEntity.java8
-rw-r--r--src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java8
-rw-r--r--src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java50
-rw-r--r--src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java1069
-rw-r--r--src/main/java/gregtech/api/interfaces/internal/IIC2TileEntity.java14
-rw-r--r--src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java46
-rw-r--r--src/main/java/gregtech/api/interfaces/internal/IUETileEntity.java5
-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
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java282
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/IAddGregtechLogo.java8
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/IAddInventorySlots.java15
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/IAddUIWidgets.java9
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/IBindPlayerInventoryUI.java9
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/IGetGUITextureSet.java10
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java11
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IAllSidedTexturedTileEntity.java24
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IBasicEnergyContainer.java110
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java27
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java91
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IDebugableTileEntity.java18
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IDigitalChest.java33
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IEnergyConductor.java41
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java178
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IFibreConnected.java34
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IGTEnet.java19
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IGearEnergyTileEntity.java21
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IGregTechDeviceInformation.java22
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java206
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IGregtechWailaProvider.java21
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IHasInventory.java37
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java190
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IIC2Enet.java17
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java24
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IMachineProgress.java96
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IOverclockDescriptionProvider.java15
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IPipeRenderedTileEntity.java18
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java31
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java52
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IRedstoneReceiver.java33
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IRedstoneTileEntity.java17
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/ITexturedTileEntity.java14
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/ITurnable.java46
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IUpgradableMachine.java42
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IVoidable.java89
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IWirelessEnergyHatchInformation.java17
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/RecipeMapWorkable.java49
92 files changed, 5838 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/interfaces/IBlockContainer.java b/src/main/java/gregtech/api/interfaces/IBlockContainer.java
new file mode 100644
index 0000000000..5a80655a5c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IBlockContainer.java
@@ -0,0 +1,10 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.block.Block;
+
+public interface IBlockContainer {
+
+ Block getBlock();
+
+ byte getMeta();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IBlockOnWalkOver.java b/src/main/java/gregtech/api/interfaces/IBlockOnWalkOver.java
new file mode 100644
index 0000000000..0c8fce931b
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IBlockOnWalkOver.java
@@ -0,0 +1,9 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.world.World;
+
+public interface IBlockOnWalkOver {
+
+ void onWalkOver(EntityLivingBase aEntity, World aWorld, int aX, int aY, int aZ);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IChunkLoader.java b/src/main/java/gregtech/api/interfaces/IChunkLoader.java
new file mode 100644
index 0000000000..b597d6a71f
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IChunkLoader.java
@@ -0,0 +1,10 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.world.ChunkCoordIntPair;
+
+// This interface is implemented by the machines that actively load a working chunk
+public interface IChunkLoader {
+
+ // return a working chunk coordinates, may be null
+ ChunkCoordIntPair getActiveChunk();
+}
diff --git a/src/main/java/gregtech/api/interfaces/ICleanroom.java b/src/main/java/gregtech/api/interfaces/ICleanroom.java
new file mode 100644
index 0000000000..61e339d050
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/ICleanroom.java
@@ -0,0 +1,22 @@
+package gregtech.api.interfaces;
+
+/**
+ * Classes implementing this interface can act as cleanroom, used to satisfy environment required for some recipes.
+ */
+public interface ICleanroom {
+
+ /**
+ * @return Current cleanness of this cleanroom. Max at 10000.
+ */
+ int getCleanness();
+
+ /**
+ * @return If this cleanroom is valid.
+ */
+ boolean isValidCleanroom();
+
+ /**
+ * Release pollution to this cleanroom.
+ */
+ void pollute();
+}
diff --git a/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java b/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java
new file mode 100644
index 0000000000..b0d42f9aec
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java
@@ -0,0 +1,18 @@
+package gregtech.api.interfaces;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.tileentity.TileEntity;
+
+/**
+ * Implement this interface for TileEntities that can have association to cleanroom.
+ * Calling {@link gregtech.common.GT_Pollution#addPollution(TileEntity, int)} from this machine
+ * will pollute associated cleanroom.
+ */
+public interface ICleanroomReceiver {
+
+ @Nullable
+ ICleanroom getCleanroom();
+
+ void setCleanroom(ICleanroom cleanroom);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IColorModulationContainer.java b/src/main/java/gregtech/api/interfaces/IColorModulationContainer.java
new file mode 100644
index 0000000000..55053e1d12
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IColorModulationContainer.java
@@ -0,0 +1,6 @@
+package gregtech.api.interfaces;
+
+public interface IColorModulationContainer {
+
+ short[] getRGBA();
+}
diff --git a/src/main/java/gregtech/api/interfaces/ICondition.java b/src/main/java/gregtech/api/interfaces/ICondition.java
new file mode 100644
index 0000000000..9c7033b3d7
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/ICondition.java
@@ -0,0 +1,116 @@
+package gregtech.api.interfaces;
+
+public interface ICondition<O> {
+
+ boolean isTrue(O aObject);
+
+ // Utility Classes for adding relations between Conditions.
+
+ class Not<O> implements ICondition<O> {
+
+ private final ICondition<O> mCondition;
+
+ public Not(ICondition<O> aCondition) {
+ mCondition = aCondition;
+ }
+
+ @Override
+ public boolean isTrue(O aObject) {
+ return !mCondition.isTrue(aObject);
+ }
+ }
+
+ class Or<O> implements ICondition<O> {
+
+ private final ICondition<O>[] mConditions;
+
+ @SafeVarargs
+ public Or(ICondition<O>... aConditions) {
+ mConditions = aConditions;
+ }
+
+ @Override
+ public boolean isTrue(O aObject) {
+ for (ICondition<O> tCondition : mConditions) if (tCondition.isTrue(aObject)) return true;
+ return false;
+ }
+ }
+
+ class Nor<O> implements ICondition<O> {
+
+ private final ICondition<O>[] mConditions;
+
+ @SafeVarargs
+ public Nor(ICondition<O>... aConditions) {
+ mConditions = aConditions;
+ }
+
+ @Override
+ public boolean isTrue(O aObject) {
+ for (ICondition<O> tCondition : mConditions) if (tCondition.isTrue(aObject)) return false;
+ return true;
+ }
+ }
+
+ class And<O> implements ICondition<O> {
+
+ private final ICondition<O>[] mConditions;
+
+ @SafeVarargs
+ public And(ICondition<O>... aConditions) {
+ mConditions = aConditions;
+ }
+
+ @Override
+ public boolean isTrue(O aObject) {
+ for (ICondition<O> tCondition : mConditions) if (!tCondition.isTrue(aObject)) return false;
+ return true;
+ }
+ }
+
+ class Nand<O> implements ICondition<O> {
+
+ private final ICondition<O>[] mConditions;
+
+ @SafeVarargs
+ public Nand(ICondition<O>... aConditions) {
+ mConditions = aConditions;
+ }
+
+ @Override
+ public boolean isTrue(O aObject) {
+ for (ICondition<O> tCondition : mConditions) if (!tCondition.isTrue(aObject)) return true;
+ return false;
+ }
+ }
+
+ class Xor<O> implements ICondition<O> {
+
+ private final ICondition<O> mCondition1, mCondition2;
+
+ public Xor(ICondition<O> aCondition1, ICondition<O> aCondition2) {
+ mCondition1 = aCondition1;
+ mCondition2 = aCondition2;
+ }
+
+ @Override
+ public boolean isTrue(O aObject) {
+ return mCondition1.isTrue(aObject) != mCondition2.isTrue(aObject);
+ }
+ }
+
+ class Equal<O> implements ICondition<O> {
+
+ private final ICondition<O> mCondition1, mCondition2;
+
+ public Equal(ICondition<O> aCondition1, ICondition<O> aCondition2) {
+ mCondition1 = aCondition1;
+ mCondition2 = aCondition2;
+ }
+
+ @Override
+ public boolean isTrue(O aObject) {
+ return mCondition1.isTrue(aObject) == mCondition2.isTrue(aObject);
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java b/src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java
new file mode 100644
index 0000000000..8dde8163c8
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java
@@ -0,0 +1,47 @@
+package gregtech.api.interfaces;
+
+import java.util.List;
+
+import net.minecraft.item.ItemStack;
+
+import gregtech.api.GregTech_API;
+
+/**
+ * Implement this interface if your tileentity (or metatileentity) supports configuration circuits to resolve recipe
+ * conflicts.
+ */
+public interface IConfigurationCircuitSupport {
+
+ /**
+ *
+ * @return Integrated circuit slot index in the machine inventory
+ */
+ int getCircuitSlot();
+
+ /**
+ * Return a list of possible configuration circuit this machine expects.
+ * <p>
+ * This list is unmodifiable. Its elements are not supposed to be modified in any way!
+ */
+ default List<ItemStack> getConfigurationCircuits() {
+ return GregTech_API.getConfigurationCircuitList(100);
+ }
+
+ /**
+ *
+ * @return True if that machine supports built-in configuration circuit
+ */
+ boolean allowSelectCircuit();
+
+ /**
+ *
+ * @return Circuit slot index in GUI container
+ */
+ default int getCircuitGUISlot() {
+ return getCircuitSlot();
+ }
+
+ int getCircuitSlotX();
+
+ int getCircuitSlotY();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IDamagableItem.java b/src/main/java/gregtech/api/interfaces/IDamagableItem.java
new file mode 100644
index 0000000000..5f0d53b577
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IDamagableItem.java
@@ -0,0 +1,8 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.item.ItemStack;
+
+public interface IDamagableItem {
+
+ boolean doDamageToItem(ItemStack aStack, int aVanillaDamage);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IDebugableBlock.java b/src/main/java/gregtech/api/interfaces/IDebugableBlock.java
new file mode 100644
index 0000000000..9c6ab660bd
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IDebugableBlock.java
@@ -0,0 +1,24 @@
+package gregtech.api.interfaces;
+
+import java.util.ArrayList;
+
+import net.minecraft.entity.player.EntityPlayer;
+
+/**
+ * You are allowed to include this File in your Download, as i will not change it.
+ */
+public interface IDebugableBlock {
+
+ /**
+ * Returns a Debug Message, for a generic DebugItem Blocks have to implement this interface NOT TileEntities!
+ *
+ * @param aPlayer the Player, who rightclicked with his Debug Item
+ * @param aX Block-Coordinate
+ * @param aY Block-Coordinate
+ * @param aZ Block-Coordinate
+ * @param aLogLevel the Log Level of the Debug Item. 0 = Obvious 1 = Visible for the regular Scanner 2 = Only
+ * visible to more advanced Scanners 3 = Debug ONLY
+ * @return a String-Array containing the DebugInfo, every Index is a separate line (0 = first Line)
+ */
+ ArrayList<String> getDebugInfo(EntityPlayer aPlayer, int aX, int aY, int aZ, int aLogLevel);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IDescribable.java b/src/main/java/gregtech/api/interfaces/IDescribable.java
new file mode 100644
index 0000000000..21bb520482
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IDescribable.java
@@ -0,0 +1,12 @@
+package gregtech.api.interfaces;
+
+/**
+ * To get simple things like a ToolTip Description
+ */
+public interface IDescribable {
+
+ /**
+ * The Tooltip Text
+ */
+ String[] getDescription();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IDragAndDropSupport.java b/src/main/java/gregtech/api/interfaces/IDragAndDropSupport.java
new file mode 100644
index 0000000000..b516db5bad
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IDragAndDropSupport.java
@@ -0,0 +1,58 @@
+package gregtech.api.interfaces;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.client.gui.inventory.GuiContainer;
+import net.minecraft.item.ItemStack;
+
+import codechicken.nei.NEIClientUtils;
+import codechicken.nei.VisiblityData;
+import codechicken.nei.api.INEIGuiHandler;
+import codechicken.nei.api.TaggedInventoryArea;
+import cpw.mods.fml.common.Optional;
+import gregtech.api.enums.Mods;
+
+/**
+ * Implement this interface if your GuiContainer supports Drag-And-Drop behavior on NEI.
+ */
+@Optional.Interface(modid = Mods.Names.NOT_ENOUGH_ITEMS, iface = "codechicken.nei.api.INEIGuiHandler")
+public interface IDragAndDropSupport extends INEIGuiHandler {
+
+ /**
+ * Implement this to handle Drag-And-Drop behavior. This may be invoked on normal click too
+ * ({@code isGhost==false}), so be careful if your slot supports both Drag-And-Drop and other behaviors e.g. fluid
+ * I/O with FluidDisplay click
+ *
+ * @param gui Current gui instance. Make sure to check if it is an instance of your GuiContainer.
+ * @param mousex X position of the mouse
+ * @param mousey Y position of the mouse
+ * @param draggedStack ItemStack user is holding on cursor
+ * @param button 0 = left click, 1 = right click
+ * @param isGhost Whether {@code draggedStack} is dragged from ItemPanel/BookmarkPanel, or actual item player
+ * holds
+ * @return True if success
+ */
+ boolean handleDragAndDropGT(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button,
+ boolean isGhost);
+
+ default boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button) {
+ return handleDragAndDropGT(gui, mousex, mousey, draggedStack, button, NEIClientUtils.getHeldItem() == null);
+ }
+
+ default VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility) {
+ return currentVisibility;
+ }
+
+ default Iterable<Integer> getItemSpawnSlots(GuiContainer gui, ItemStack item) {
+ return Collections.emptyList();
+ }
+
+ default List<TaggedInventoryArea> getInventoryAreas(GuiContainer gui) {
+ return null;
+ }
+
+ default boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
+ return false;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IFluidAccess.java b/src/main/java/gregtech/api/interfaces/IFluidAccess.java
new file mode 100644
index 0000000000..8fa9b3a3fa
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IFluidAccess.java
@@ -0,0 +1,26 @@
+package gregtech.api.interfaces;
+
+import net.minecraftforge.fluids.FluidStack;
+
+public interface IFluidAccess {
+
+ void set(FluidStack stack);
+
+ FluidStack get();
+
+ int getCapacity();
+
+ default int getRealCapacity() {
+ return getCapacity();
+ }
+
+ default void addAmount(int amount) {
+ if (get() != null) {
+ get().amount = Math.min(get().amount + amount, getRealCapacity());
+ }
+ }
+
+ default void verifyFluidStack() {
+ if (get() != null && get().amount <= 0) set(null);
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IFoodStat.java b/src/main/java/gregtech/api/interfaces/IFoodStat.java
new file mode 100644
index 0000000000..c768c5ca1c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IFoodStat.java
@@ -0,0 +1,37 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.EnumAction;
+import net.minecraft.item.ItemStack;
+
+import gregtech.api.items.GT_MetaBase_Item;
+
+public interface IFoodStat {
+
+ /**
+ * Warning the "aPlayer" Parameter may be null!
+ */
+ int getFoodLevel(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer);
+
+ /**
+ * Warning the "aPlayer" Parameter may be null!
+ */
+ float getSaturation(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer);
+
+ /**
+ * Warning the "aPlayer" Parameter may be null!
+ */
+ boolean alwaysEdible(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer);
+
+ /**
+ * Warning the "aPlayer" Parameter may be null!
+ */
+ boolean isRotten(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer);
+
+ /**
+ * Warning the "aPlayer" Parameter may be null!
+ */
+ EnumAction getFoodAction(GT_MetaBase_Item aItem, ItemStack aStack);
+
+ void onEaten(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java b/src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java
new file mode 100644
index 0000000000..4bf0311544
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java
@@ -0,0 +1,68 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.common.render.items.GT_GeneratedMaterial_Renderer;
+
+public interface IGT_ItemWithMaterialRenderer {
+
+ /**
+ * @return If allow using {@link gregtech.common.render.items.GT_MetaGenerated_Item_Renderer} to render item
+ */
+ boolean shouldUseCustomRenderer(int aMetaData);
+
+ /**
+ * @return Custom renderer of the Material with offset < 32000
+ */
+ GT_GeneratedMaterial_Renderer getMaterialRenderer(int aMetaData);
+
+ /**
+ * If this returns false, renderer falls back to {@link gregtech.common.render.items.GT_GeneratedItem_Renderer}
+ */
+ boolean allowMaterialRenderer(int aMetaData);
+
+ /**
+ * @return Icon the Material is going to be rendered with
+ */
+ IIcon getIcon(int aMetaData, int pass);
+
+ /**
+ * @return Icon of the Overlay (or null if there is no Icon)
+ */
+ IIcon getOverlayIcon(int aMetaData, int pass);
+
+ /**
+ * @return Color Modulation the Material is going to be rendered with.
+ */
+ short[] getRGBa(ItemStack aStack);
+
+ @SideOnly(Side.CLIENT)
+ default int getSpriteNumber() {
+ if (this instanceof Item) {
+ return ((Item) this).getSpriteNumber();
+ } else {
+ throw new RuntimeException(String.format("Class %s does not extend Item!", getClass()));
+ }
+ }
+
+ @SideOnly(Side.CLIENT)
+ default boolean requiresMultipleRenderPasses() {
+ if (this instanceof Item) {
+ return ((Item) this).requiresMultipleRenderPasses();
+ } else {
+ throw new RuntimeException(String.format("Class %s does not extend Item!", getClass()));
+ }
+ }
+
+ default int getRenderPasses(int metadata) {
+ if (this instanceof Item) {
+ return ((Item) this).getRenderPasses(metadata);
+ } else {
+ throw new RuntimeException(String.format("Class %s does not extend Item!", getClass()));
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java b/src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java
new file mode 100644
index 0000000000..b931549a07
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java
@@ -0,0 +1,98 @@
+package gregtech.api.interfaces;
+
+import java.math.BigInteger;
+import java.util.UUID;
+
+import net.minecraft.entity.player.EntityPlayer;
+
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.common.misc.WirelessNetworkManager;
+import gregtech.common.misc.spaceprojects.SpaceProjectManager;
+
+// If you are adding very late-game content feel free to tap into this interface.
+// The eventual goal is to bypass laser/dynamo stuff and have energy deposited directly from ultra-endgame
+// multi-blocks directly into the users network.
+/**
+ * Use WirelessNetworkManager instead
+ */
+@Deprecated
+public interface IGlobalWirelessEnergy {
+
+ // Adds a user to the energy map if they do not already exist. Otherwise, do
+ // nothing. Will also check if the user
+ // has changed their username and adjust the maps accordingly. This should be
+ // called infrequently. Ideally on first
+ // tick of a machine being placed only.
+
+ default void strongCheckOrAddUser(EntityPlayer user) {
+ WirelessNetworkManager.strongCheckOrAddUser(user.getUniqueID());
+ }
+
+ default void strongCheckOrAddUser(UUID user_uuid, String user_name) {
+ WirelessNetworkManager.strongCheckOrAddUser(user_uuid);
+ }
+
+ default void strongCheckOrAddUser(String user_uuid, String user_name) {
+ WirelessNetworkManager.strongCheckOrAddUser(UUID.fromString(user_uuid));
+ }
+
+ // ------------------------------------------------------------------------------------
+ // Add EU to the users global energy. You can enter a negative number to
+ // subtract it.
+ // If the value goes below 0 it will return false and not perform the operation.
+ // BigIntegers have much slower operations than longs/ints. You should call
+ // these methods
+ // as infrequently as possible and bulk store values to add to the global map.
+ default boolean addEUToGlobalEnergyMap(String userUUID, BigInteger EU) {
+ return WirelessNetworkManager.addEUToGlobalEnergyMap(UUID.fromString(userUUID), EU);
+ }
+
+ default boolean addEUToGlobalEnergyMap(UUID user_uuid, BigInteger EU) {
+ return addEUToGlobalEnergyMap(user_uuid.toString(), EU);
+ }
+
+ default boolean addEUToGlobalEnergyMap(UUID user_uuid, long EU) {
+ return addEUToGlobalEnergyMap(user_uuid.toString(), BigInteger.valueOf(EU));
+ }
+
+ default boolean addEUToGlobalEnergyMap(UUID user_uuid, int EU) {
+ return addEUToGlobalEnergyMap(user_uuid.toString(), BigInteger.valueOf(EU));
+ }
+
+ default boolean addEUToGlobalEnergyMap(String user_uuid, long EU) {
+ return addEUToGlobalEnergyMap(user_uuid, BigInteger.valueOf(EU));
+ }
+
+ default boolean addEUToGlobalEnergyMap(String user_uuid, int EU) {
+ return addEUToGlobalEnergyMap(user_uuid, BigInteger.valueOf(EU));
+ }
+
+ // ------------------------------------------------------------------------------------
+
+ default BigInteger getUserEU(String user_uuid) {
+ return WirelessNetworkManager.getUserEU(UUID.fromString(user_uuid));
+ }
+
+ // This overwrites the EU in the network. Only use this if you are absolutely
+ // sure you know what you are doing.
+ default void setUserEU(String user_uuid, BigInteger EU) {
+ WirelessNetworkManager.setUserEU(UUID.fromString(user_uuid), EU);
+ }
+
+ default String GetUsernameFromUUID(String uuid) {
+ return SpaceProjectManager.getPlayerNameFromUUID(UUID.fromString(uuid));
+ }
+
+ default String getUUIDFromUsername(String username) {
+ return SpaceProjectManager.getPlayerUUIDFromName(username)
+ .toString();
+ }
+
+ static void clearGlobalEnergyInformationMaps() {
+ WirelessNetworkManager.clearGlobalEnergyInformationMaps();
+ }
+
+ default UUID processInitialSettings(final IGregTechTileEntity machine) {
+ return WirelessNetworkManager.processInitialSettings(machine);
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IGuiIcon.java b/src/main/java/gregtech/api/interfaces/IGuiIcon.java
new file mode 100644
index 0000000000..0bc7408250
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IGuiIcon.java
@@ -0,0 +1,19 @@
+package gregtech.api.interfaces;
+
+/**
+ * To allow addons to make use of GT_GuiIcon
+ */
+public interface IGuiIcon {
+
+ int getX();
+
+ int getY();
+
+ int getWidth();
+
+ int getHeight();
+
+ int getTexId();
+
+ IGuiIcon getOverlay();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IGuiScreen.java b/src/main/java/gregtech/api/interfaces/IGuiScreen.java
new file mode 100644
index 0000000000..c33838fc7f
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IGuiScreen.java
@@ -0,0 +1,45 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.GuiButton;
+import net.minecraft.client.renderer.entity.RenderItem;
+
+import gregtech.api.gui.widgets.GT_GuiTooltip;
+
+public interface IGuiScreen {
+
+ interface IGuiElement {
+
+ void onInit();
+
+ default void onRemoved() {}
+
+ void draw(int mouseX, int mouseY, float parTicks);
+ }
+
+ void addToolTip(GT_GuiTooltip toolTip);
+
+ boolean removeToolTip(GT_GuiTooltip toolTip);
+
+ GuiButton getSelectedButton();
+
+ void clearSelectedButton();
+
+ void buttonClicked(GuiButton button);
+
+ int getGuiLeft();
+
+ int getGuiTop();
+
+ int getXSize();
+
+ int getYSize();
+
+ void addElement(IGuiElement element);
+
+ boolean removeElement(IGuiElement element);
+
+ RenderItem getItemRenderer();
+
+ FontRenderer getFontRenderer();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IHasIndexedTexture.java b/src/main/java/gregtech/api/interfaces/IHasIndexedTexture.java
new file mode 100644
index 0000000000..ed31984b6e
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IHasIndexedTexture.java
@@ -0,0 +1,17 @@
+package gregtech.api.interfaces;
+
+/**
+ * To be implemented on blocks. Usually machine casing blocks.
+ */
+public interface IHasIndexedTexture {
+
+ /**
+ * Returns the statically mapped texture for this casing. Return
+ * {@link gregtech.api.enums.Textures.BlockIcons#ERROR_TEXTURE_INDEX} if meta maps to a nonexistent block, or the
+ * block does not have a statically mapped texture.
+ *
+ * @param aMeta block meta
+ * @return texture index into {@link gregtech.api.enums.Textures.BlockIcons#casingTexturePages}
+ */
+ int getTextureIndex(int aMeta);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IHatchElement.java b/src/main/java/gregtech/api/interfaces/IHatchElement.java
new file mode 100644
index 0000000000..09f3385729
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IHatchElement.java
@@ -0,0 +1,198 @@
+package gregtech.api.interfaces;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.BiPredicate;
+import java.util.function.ToLongFunction;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.google.common.collect.ImmutableList;
+import com.gtnewhorizon.structurelib.structure.IStructureElement;
+
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.util.GT_StructureUtility;
+import gregtech.api.util.IGT_HatchAdder;
+
+public interface IHatchElement<T> {
+
+ List<? extends Class<? extends IMetaTileEntity>> mteClasses();
+
+ IGT_HatchAdder<? super T> adder();
+
+ String name();
+
+ long count(T t);
+
+ default <T2 extends T> IHatchElement<T2> withMteClass(Class<? extends IMetaTileEntity> aClass) {
+ if (aClass == null) throw new IllegalArgumentException();
+ return withMteClasses(Collections.singletonList(aClass));
+ }
+
+ @SuppressWarnings("unchecked") // can't set SafeVarargs :(
+ default <T2 extends T> IHatchElement<T2> withMteClasses(Class<? extends IMetaTileEntity>... aClasses) {
+ if (aClasses == null) throw new IllegalArgumentException();
+ return withMteClasses(Arrays.asList(aClasses));
+ }
+
+ default <T2 extends T> IHatchElement<T2> withMteClasses(List<Class<? extends IMetaTileEntity>> aClasses) {
+ if (aClasses == null) throw new IllegalArgumentException();
+ return new HatchElement<>(aClasses, null, null, null, this);
+ }
+
+ default <T2 extends T> IHatchElement<T2> withAdder(IGT_HatchAdder<T2> aAdder) {
+ if (aAdder == null) throw new IllegalArgumentException();
+ return new HatchElement<>(null, aAdder, null, null, this);
+ }
+
+ default IHatchElement<T> withName(String aName) {
+ if (aName == null) throw new IllegalArgumentException();
+ return new HatchElement<>(null, null, aName, null, this);
+ }
+
+ default <T2 extends T> IHatchElement<T2> withCount(ToLongFunction<T2> aCount) {
+ if (aCount == null) throw new IllegalArgumentException();
+ return new HatchElement<>(null, null, null, aCount, this);
+ }
+
+ default <T2 extends T> IStructureElement<T2> newAny(int aCasingIndex, int aDot) {
+ if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException();
+ return GT_StructureUtility.<T2>buildHatchAdder()
+ .anyOf(this)
+ .casingIndex(aCasingIndex)
+ .dot(aDot)
+ .continueIfSuccess()
+ .build();
+ }
+
+ default <T2 extends T> IStructureElement<T2> newAny(int aCasingIndex, int aDot, ForgeDirection... allowedFacings) {
+ if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException();
+ return GT_StructureUtility.<T2>buildHatchAdder()
+ .anyOf(this)
+ .casingIndex(aCasingIndex)
+ .dot(aDot)
+ .continueIfSuccess()
+ .allowOnly(allowedFacings)
+ .build();
+ }
+
+ default <T2 extends T> IStructureElement<T2> newAny(int aCasingIndex, int aDot,
+ BiPredicate<? super T2, ? super IGregTechTileEntity> aShouldSkip) {
+ if (aCasingIndex < 0 || aDot < 0 || aShouldSkip == null) throw new IllegalArgumentException();
+ return GT_StructureUtility.<T2>buildHatchAdder()
+ .anyOf(this)
+ .casingIndex(aCasingIndex)
+ .dot(aDot)
+ .shouldSkip(aShouldSkip)
+ .continueIfSuccess()
+ .build();
+ }
+
+ default <T2 extends T> IHatchElement<T2> or(IHatchElement<? super T2> fallback) {
+ return new HatchElementEither<>(this, fallback);
+ }
+}
+
+class HatchElementEither<T> implements IHatchElement<T> {
+
+ private final IHatchElement<? super T> first, second;
+ private ImmutableList<? extends Class<? extends IMetaTileEntity>> mMteClasses;
+ private String name;
+
+ HatchElementEither(IHatchElement<? super T> first, IHatchElement<? super T> second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ @Override
+ public List<? extends Class<? extends IMetaTileEntity>> mteClasses() {
+ if (mMteClasses == null) mMteClasses = ImmutableList.<Class<? extends IMetaTileEntity>>builder()
+ .addAll(first.mteClasses())
+ .addAll(second.mteClasses())
+ .build();
+ return mMteClasses;
+ }
+
+ @Override
+ public IGT_HatchAdder<? super T> adder() {
+ return ((t, te, i) -> first.adder()
+ .apply(t, te, i)
+ || second.adder()
+ .apply(t, te, i));
+ }
+
+ @Override
+ public String name() {
+ if (name == null) name = first.name() + " or " + second.name();
+ return name;
+ }
+
+ @Override
+ public long count(T t) {
+ return first.count(t) + second.count(t);
+ }
+}
+
+class HatchElement<T> implements IHatchElement<T> {
+
+ private final List<Class<? extends IMetaTileEntity>> mClasses;
+ private final IGT_HatchAdder<? super T> mAdder;
+ private final String mName;
+ private final IHatchElement<? super T> mBacking;
+ private final ToLongFunction<? super T> mCount;
+
+ public HatchElement(List<Class<? extends IMetaTileEntity>> aMteClasses, IGT_HatchAdder<? super T> aAdder,
+ String aName, ToLongFunction<? super T> aCount, IHatchElement<? super T> aBacking) {
+ this.mClasses = aMteClasses;
+ this.mAdder = aAdder;
+ this.mName = aName;
+ this.mCount = aCount;
+ this.mBacking = aBacking;
+ }
+
+ @Override
+ public List<? extends Class<? extends IMetaTileEntity>> mteClasses() {
+ return mClasses == null ? mBacking.mteClasses() : mClasses;
+ }
+
+ @Override
+ public IGT_HatchAdder<? super T> adder() {
+ return mAdder == null ? mBacking.adder() : mAdder;
+ }
+
+ @Override
+ public String name() {
+ return mName == null ? mBacking.name() : mName;
+ }
+
+ @Override
+ public long count(T t) {
+ return mCount == null ? mBacking.count(t) : mCount.applyAsLong(t);
+ }
+
+ @Override
+ public <T2 extends T> IHatchElement<T2> withMteClasses(List<Class<? extends IMetaTileEntity>> aClasses) {
+ if (aClasses == null) throw new IllegalArgumentException();
+ return new HatchElement<>(aClasses, mAdder, mName, mCount, mBacking);
+ }
+
+ @Override
+ public <T2 extends T> IHatchElement<T2> withAdder(IGT_HatchAdder<T2> aAdder) {
+ if (aAdder == null) throw new IllegalArgumentException();
+ return new HatchElement<>(mClasses, aAdder, mName, mCount, mBacking);
+ }
+
+ @Override
+ public IHatchElement<T> withName(String aName) {
+ if (aName == null) throw new IllegalArgumentException();
+ return new HatchElement<>(mClasses, mAdder, aName, mCount, mBacking);
+ }
+
+ @Override
+ public <T2 extends T> IHatchElement<T2> withCount(ToLongFunction<T2> aCount) {
+ if (aCount == null) throw new IllegalArgumentException();
+ return new HatchElement<>(mClasses, mAdder, mName, aCount, mBacking);
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IHeatingCoil.java b/src/main/java/gregtech/api/interfaces/IHeatingCoil.java
new file mode 100644
index 0000000000..37f7969d56
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IHeatingCoil.java
@@ -0,0 +1,20 @@
+package gregtech.api.interfaces;
+
+import java.util.function.Consumer;
+
+import net.minecraft.item.ItemStack;
+
+import gregtech.api.enums.HeatingCoilLevel;
+
+public interface IHeatingCoil {
+
+ HeatingCoilLevel getCoilHeat(int meta);
+
+ default HeatingCoilLevel getCoilHeat(ItemStack stack) {
+ return getCoilHeat(stack.getItemDamage());
+ }
+
+ void setOnCoilCheck(Consumer<IHeatingCoil> callback);
+
+ Consumer<IHeatingCoil> getOnCoilCheck();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IIconContainer.java b/src/main/java/gregtech/api/interfaces/IIconContainer.java
new file mode 100644
index 0000000000..525721bb5c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IIconContainer.java
@@ -0,0 +1,48 @@
+package gregtech.api.interfaces;
+
+import static gregtech.api.enums.GT_Values.UNCOLORED_RGBA;
+
+import net.minecraft.util.IIcon;
+import net.minecraft.util.ResourceLocation;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+public interface IIconContainer {
+
+ /**
+ * @return A regular Icon.
+ */
+ @SideOnly(Side.CLIENT)
+ IIcon getIcon();
+
+ /**
+ * @return Icon of the Overlay (or null if there is no Icon)
+ */
+ @SideOnly(Side.CLIENT)
+ IIcon getOverlayIcon();
+
+ /**
+ * @return the Amount of Render Passes for this Icon.
+ */
+ @SideOnly(Side.CLIENT)
+ default int getIconPasses() {
+ return 1;
+ }
+
+ /**
+ * @return the Default Texture File for this Icon.
+ */
+ @SideOnly(Side.CLIENT)
+ ResourceLocation getTextureFile();
+
+ @SideOnly(Side.CLIENT)
+ default short[] getIconColor(int aRenderPass) {
+ return UNCOLORED_RGBA;
+ }
+
+ @SideOnly(Side.CLIENT)
+ default boolean isUsingColorModulation(int aRenderPass) {
+ return aRenderPass == 0;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IItemBehaviour.java b/src/main/java/gregtech/api/interfaces/IItemBehaviour.java
new file mode 100644
index 0000000000..67bb505c6b
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IItemBehaviour.java
@@ -0,0 +1,47 @@
+package gregtech.api.interfaces;
+
+import java.util.List;
+
+import net.minecraft.dispenser.IBlockSource;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.projectile.EntityArrow;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.enums.SubTag;
+import gregtech.api.items.GT_MetaBase_Item;
+
+public interface IItemBehaviour<E extends Item> {
+
+ boolean onLeftClickEntity(E aItem, ItemStack aStack, EntityPlayer aPlayer, Entity aEntity);
+
+ boolean onItemUse(E aItem, ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ,
+ int ordinalSide, float hitX, float hitY, float hitZ);
+
+ boolean onItemUseFirst(E aItem, ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ,
+ ForgeDirection side, float hitX, float hitY, float hitZ);
+
+ ItemStack onItemRightClick(E aItem, ItemStack aStack, World aWorld, EntityPlayer aPlayer);
+
+ List<String> getAdditionalToolTips(E aItem, List<String> aList, ItemStack aStack);
+
+ void onUpdate(E aItem, ItemStack aStack, World aWorld, Entity aPlayer, int aTimer, boolean aIsInHand);
+
+ boolean isItemStackUsable(E aItem, ItemStack aStack);
+
+ boolean canDispense(E aItem, IBlockSource aSource, ItemStack aStack);
+
+ ItemStack onDispense(E aItem, IBlockSource aSource, ItemStack aStack);
+
+ boolean hasProjectile(GT_MetaBase_Item aItem, SubTag aProjectileType, ItemStack aStack);
+
+ EntityArrow getProjectile(E aItem, SubTag aProjectileType, ItemStack aStack, World aWorld, double aX, double aY,
+ double aZ);
+
+ EntityArrow getProjectile(E aItem, SubTag aProjectileType, ItemStack aStack, World aWorld, EntityLivingBase aEntity,
+ float aSpeed);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IItemContainer.java b/src/main/java/gregtech/api/interfaces/IItemContainer.java
new file mode 100644
index 0000000000..de94606e95
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IItemContainer.java
@@ -0,0 +1,40 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+
+public interface IItemContainer {
+
+ Item getItem();
+
+ Block getBlock();
+
+ boolean isStackEqual(Object aStack);
+
+ boolean isStackEqual(Object aStack, boolean aWildcard, boolean aIgnoreNBT);
+
+ ItemStack get(long aAmount, Object... aReplacements);
+
+ ItemStack getWildcard(long aAmount, Object... aReplacements);
+
+ ItemStack getUndamaged(long aAmount, Object... aReplacements);
+
+ ItemStack getAlmostBroken(long aAmount, Object... aReplacements);
+
+ ItemStack getWithDamage(long aAmount, long aMetaValue, Object... aReplacements);
+
+ IItemContainer set(Item aItem);
+
+ IItemContainer set(ItemStack aStack);
+
+ IItemContainer registerOre(Object... aOreNames);
+
+ IItemContainer registerWildcardAsOre(Object... aOreNames);
+
+ ItemStack getWithCharge(long aAmount, int aEnergy, Object... aReplacements);
+
+ ItemStack getWithName(long aAmount, String aDisplayName, Object... aReplacements);
+
+ boolean hasBeenSet();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IMaterialHandler.java b/src/main/java/gregtech/api/interfaces/IMaterialHandler.java
new file mode 100644
index 0000000000..ddd7e832dd
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IMaterialHandler.java
@@ -0,0 +1,6 @@
+package gregtech.api.interfaces;
+
+public interface IMaterialHandler {
+
+ void onMaterialsInit();
+}
diff --git a/src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java b/src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java
new file mode 100644
index 0000000000..1dd36d9998
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java
@@ -0,0 +1,25 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+
+/**
+ * Together with {@link gregtech.api.net.GT_Packet_UpdateItem} you can request server side to update item in hand with a
+ * NBT tag.
+ * <p>
+ * Usual NBT tag size limit applies.
+ */
+public interface INetworkUpdatableItem {
+
+ /**
+ * Receive update from client. Runs on server thread.
+ *
+ * @param stack Stack being updated
+ * @param player player holding the stack
+ * @param tag received data
+ * @return true if this stack should be kept inside the player inventory. false if this stack should vanish (i.e.
+ * slot content set to null)
+ */
+ boolean receive(ItemStack stack, EntityPlayerMP player, NBTTagCompound tag);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IOreRecipeRegistrator.java b/src/main/java/gregtech/api/interfaces/IOreRecipeRegistrator.java
new file mode 100644
index 0000000000..714342ae7e
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IOreRecipeRegistrator.java
@@ -0,0 +1,19 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.item.ItemStack;
+
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.OrePrefixes;
+
+public interface IOreRecipeRegistrator {
+
+ /**
+ * Contains a Code Fragment, used in the OrePrefix to register Recipes. Better than using a switch/case, like I did
+ * before.
+ *
+ * @param aPrefix always != null
+ * @param aMaterial always != null, and can be == _NULL if the Prefix is Self Referencing or not Material based!
+ * @param aStack always != null
+ */
+ void registerOre(OrePrefixes aPrefix, Materials aMaterial, String aOreDictName, String aModName, ItemStack aStack);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IProjectileItem.java b/src/main/java/gregtech/api/interfaces/IProjectileItem.java
new file mode 100644
index 0000000000..64782bf04c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IProjectileItem.java
@@ -0,0 +1,29 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.projectile.EntityArrow;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+
+import gregtech.api.enums.SubTag;
+
+public interface IProjectileItem {
+
+ /**
+ * @return if this Item has an Arrow Entity
+ */
+ boolean hasProjectile(SubTag aProjectileType, ItemStack aStack);
+
+ /**
+ * @return an Arrow Entity to be spawned. If null then this is not an Arrow. Note: Other Projectiles still extend
+ * EntityArrow
+ */
+ EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, double aX, double aY, double aZ);
+
+ /**
+ * @return an Arrow Entity to be spawned. If null then this is not an Arrow. Note: Other Projectiles still extend
+ * EntityArrow
+ */
+ EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, EntityLivingBase aEntity,
+ float aSpeed);
+}
diff --git a/src/main/java/gregtech/api/interfaces/IRecipeMap.java b/src/main/java/gregtech/api/interfaces/IRecipeMap.java
new file mode 100644
index 0000000000..ce48b29927
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IRecipeMap.java
@@ -0,0 +1,74 @@
+package gregtech.api.interfaces;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import gregtech.api.util.GT_Recipe;
+import gregtech.api.util.GT_RecipeBuilder;
+import gregtech.api.util.GT_Utility;
+
+/**
+ * Represents the target of a recipe adding action, usually, but not necessarily, is a recipe map itself.
+ */
+public interface IRecipeMap {
+
+ /**
+ * Add a downstream recipe map that will get to handle the original builder.
+ * <p>
+ * Downstream recipe maps got passed the recipe builder after parent recipe map is done with its business. Notice
+ * at this time the original recipe builder might be modified by the parent recipe map in some form, but it will
+ * remain as valid.
+ * <p>
+ * A downstream will only be invoked if parent recipe map added something.
+ *
+ * @param downstream the downstream recipe map to add
+ */
+ void addDownstream(IRecipeMap downstream);
+
+ /**
+ * Actually add the recipe represented by the builder. CAN modify the builder's internal states!!!
+ */
+ @Nonnull
+ Collection<GT_Recipe> doAdd(GT_RecipeBuilder builder);
+
+ /**
+ * Return a variant of this recipe map that will perform a deep copy on input recipe builder before doing anything
+ * to it.
+ * <p>
+ * The returned recipe map will not have any downstreams, but can accept new downstreams.
+ */
+ default IRecipeMap deepCopyInput() {
+ return newRecipeMap(b -> doAdd(b.copy()));
+ }
+
+ static IRecipeMap newRecipeMap(Function<? super GT_RecipeBuilder, Collection<GT_Recipe>> func) {
+ return new IRecipeMap() {
+
+ private final Collection<IRecipeMap> downstreams = new ArrayList<>();
+
+ @Override
+ public void addDownstream(IRecipeMap downstream) {
+ downstreams.add(downstream);
+ }
+
+ @Nonnull
+ @Override
+ public Collection<GT_Recipe> doAdd(GT_RecipeBuilder builder) {
+ List<Collection<GT_Recipe>> ret = new ArrayList<>();
+ Collection<GT_Recipe> out = func.apply(builder);
+ ret.add(out);
+ builder.clearInvalid();
+ if (!out.isEmpty()) {
+ for (IRecipeMap downstream : downstreams) {
+ ret.add(downstream.doAdd(builder));
+ }
+ }
+ return GT_Utility.concat(ret);
+ }
+ };
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java b/src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java
new file mode 100644
index 0000000000..0eea6ca3a4
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java
@@ -0,0 +1,69 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.block.Block;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.tileentity.ICoverable;
+import gregtech.api.util.GT_CoverBehavior;
+
+/**
+ * Implemented by the MetaTileEntity of the Redstone Circuit Block
+ */
+public interface IRedstoneCircuitBlock {
+
+ /**
+ * The Output Direction the Circuit Block is Facing
+ */
+ ForgeDirection getOutputFacing();
+
+ /**
+ * sets Output Redstone State at Side
+ */
+ boolean setRedstone(byte aStrength, ForgeDirection side);
+
+ /**
+ * returns Output Redstone State at Side Note that setRedstone checks if there is a Difference between the old and
+ * the new Setting before consuming any Energy
+ */
+ byte getOutputRedstone(ForgeDirection side);
+
+ /**
+ * returns Input Redstone Signal at Side
+ */
+ byte getInputRedstone(ForgeDirection side);
+
+ /**
+ * If this Side is Covered up and therefor not doing any Redstone
+ */
+ GT_CoverBehavior getCover(ForgeDirection side);
+
+ int getCoverID(ForgeDirection side);
+
+ int getCoverVariable(ForgeDirection side);
+
+ /**
+ * returns whatever Block-ID is adjacent to the Redstone Circuit Block
+ */
+ Block getBlockAtSide(ForgeDirection side);
+
+ /**
+ * returns whatever Meta-Value is adjacent to the Redstone Circuit Block
+ */
+ byte getMetaIDAtSide(ForgeDirection side);
+
+ /**
+ * returns whatever TileEntity is adjacent to the Redstone Circuit Block
+ */
+ TileEntity getTileEntityAtSide(ForgeDirection side);
+
+ /**
+ * returns whatever TileEntity is used by the Redstone Circuit Block
+ */
+ ICoverable getOwnTileEntity();
+
+ /**
+ * returns worldObj.rand.nextInt(aRange)
+ */
+ int getRandom(int aRange);
+}
diff --git a/src/main/java/gregtech/api/interfaces/ISecondaryDescribable.java b/src/main/java/gregtech/api/interfaces/ISecondaryDescribable.java
new file mode 100644
index 0000000000..1f480091fc
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/ISecondaryDescribable.java
@@ -0,0 +1,30 @@
+package gregtech.api.interfaces;
+
+/**
+ * To get a tooltip with a secondary description
+ */
+public interface ISecondaryDescribable extends IDescribable {
+
+ /**
+ * Convenient to call when overriding the `String[] getDescription()` method.
+ */
+ default String[] getCurrentDescription() {
+ if (isDisplaySecondaryDescription() && getSecondaryDescription() != null) {
+ return getSecondaryDescription();
+ }
+ return getPrimaryDescription();
+ }
+
+ String[] getPrimaryDescription();
+
+ String[] getSecondaryDescription();
+
+ /**
+ * This method will only be called on client side
+ *
+ * @return whether the secondary description should be display. default is false
+ */
+ default boolean isDisplaySecondaryDescription() {
+ return false;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/ISubTagContainer.java b/src/main/java/gregtech/api/interfaces/ISubTagContainer.java
new file mode 100644
index 0000000000..3e3690c67b
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/ISubTagContainer.java
@@ -0,0 +1,21 @@
+package gregtech.api.interfaces;
+
+import gregtech.api.enums.SubTag;
+
+public interface ISubTagContainer {
+
+ /**
+ * @return if the Tag is inside the List.
+ */
+ boolean contains(SubTag aTag);
+
+ /**
+ * @return The ISubTagContainer you called this Function on, for convenience.
+ */
+ ISubTagContainer add(SubTag... aTags);
+
+ /**
+ * @return if the Tag was there before it has been removed.
+ */
+ boolean remove(SubTag aTag);
+}
diff --git a/src/main/java/gregtech/api/interfaces/ITexture.java b/src/main/java/gregtech/api/interfaces/ITexture.java
new file mode 100644
index 0000000000..e97fa4539a
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/ITexture.java
@@ -0,0 +1,55 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+
+public interface ITexture {
+
+ void renderXPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ);
+
+ void renderXNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ);
+
+ void renderYPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ);
+
+ void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ);
+
+ void renderZPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ);
+
+ void renderZNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ);
+
+ boolean isValidTexture();
+
+ /**
+ * @return {@code true} if this texture is from the old package
+ */
+ default boolean isOldTexture() {
+ return true;
+ }
+
+ /**
+ * Will initialize the {@link Tessellator} if rendering off-world (Inventory)
+ *
+ * @param aRenderer The {@link RenderBlocks} Renderer
+ * @param aNormalX The X Normal for current Quad Face
+ * @param aNormalY The Y Normal for current Quad Face
+ * @param aNormalZ The Z Normal for current Quad Face
+ */
+ default void startDrawingQuads(RenderBlocks aRenderer, float aNormalX, float aNormalY, float aNormalZ) {
+ if (aRenderer.useInventoryTint && !isOldTexture()) {
+ Tessellator.instance.startDrawingQuads();
+ Tessellator.instance.setNormal(aNormalX, aNormalY, aNormalZ);
+ }
+ }
+
+ /**
+ * Will run the {@link Tessellator} to draw Quads if rendering off-world (Inventory)
+ *
+ * @param aRenderer The {@link RenderBlocks} Renderer
+ */
+ default void draw(RenderBlocks aRenderer) {
+ if (aRenderer.useInventoryTint && !isOldTexture()) {
+ Tessellator.instance.draw();
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/ITextureBuilder.java b/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
new file mode 100644
index 0000000000..7c9672d521
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
@@ -0,0 +1,109 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.block.Block;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
+
+import gregtech.api.render.TextureFactory;
+
+/**
+ * <p>
+ * This Interface defines operations to configure and build instances of the {@link ITexture} implementations
+ * </p>
+ * <p>
+ * Use the {@link TextureFactory#builder()} method to get an instance of the {@link ITextureBuilder} implementation.
+ * </p>
+ */
+public interface ITextureBuilder {
+
+ /**
+ * Build the {@link ITexture}
+ *
+ * @return The built {@link ITexture}
+ * @throws IllegalStateException if setFromBlock has never been called.
+ */
+ ITexture build();
+
+ /**
+ * @param block The {@link Block}
+ * @param meta The meta value for the Block
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder setFromBlock(final Block block, final int meta);
+
+ /**
+ * @param side
+ * <p>
+ * The {@link ForgeDirection} side providing the texture
+ * </p>
+ * <p>
+ * Default is {@link ForgeDirection#UNKNOWN} to use same side as rendered
+ * </p>
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder setFromSide(final ForgeDirection side);
+
+ /**
+ * @param iconContainers The {@link IIconContainer}s to add
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder addIcon(final IIconContainer... iconContainers);
+
+ /**
+ * @param rgba The RGBA tint for this {@link ITexture}
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder setRGBA(final short[] rgba);
+
+ /**
+ * @param iTextures The {@link ITexture} layers to add
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder addLayer(final ITexture... iTextures);
+
+ /**
+ * Set alpha blending
+ *
+ * @param allowAlpha to set
+ *
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder setAllowAlpha(final boolean allowAlpha);
+
+ /**
+ * Texture will render with same orientation as with vanilla blocks
+ *
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder stdOrient();
+
+ /**
+ * Force using world coord overload of getIcon.
+ *
+ * @return {@link ITextureBuilder} for chaining
+ * @throws IllegalStateException if setFromBlock has never been called.
+ */
+ ITextureBuilder useWorldCoord();
+
+ /**
+ * Force using meta overload of getIcon.
+ *
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder noWorldCoord();
+
+ /**
+ * Texture will orientate from block's {@link ExtendedFacing}
+ *
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder extFacing();
+
+ /**
+ * Texture always render with full brightness to glow in the dark
+ *
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder glow();
+}
diff --git a/src/main/java/gregtech/api/interfaces/IToolStats.java b/src/main/java/gregtech/api/interfaces/IToolStats.java
new file mode 100644
index 0000000000..9d8da63b6c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IToolStats.java
@@ -0,0 +1,206 @@
+package gregtech.api.interfaces;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.minecraft.block.Block;
+import net.minecraft.enchantment.Enchantment;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.DamageSource;
+import net.minecraft.world.World;
+import net.minecraftforge.event.world.BlockEvent;
+
+import gregtech.api.items.GT_MetaGenerated_Tool;
+
+/**
+ * The Stats for GT Tools. Not including any Material Modifiers.
+ * <p/>
+ * And this is supposed to not have any ItemStack Parameters as these are generic Stats.
+ */
+public interface IToolStats {
+
+ /**
+ * Called when aPlayer crafts this Tool
+ */
+ void onToolCrafted(ItemStack aStack, EntityPlayer aPlayer);
+
+ /**
+ * Called when this gets added to a Tool Item
+ */
+ void onStatsAddedToTool(GT_MetaGenerated_Tool aItem, int aID);
+
+ /**
+ * @implNote if you are only modifying drops, override
+ * {@link #convertBlockDrops(List, ItemStack, EntityPlayer, Block, int, int, int, byte, int, boolean, BlockEvent.HarvestDropsEvent)}
+ * @param player The player
+ * @param x Block pos
+ * @param y Block pos
+ * @param z Block pos
+ * @param block the block
+ * @param metadata block metadata
+ * @param tile TileEntity of the block if exist
+ * @param event the event, cancel it to prevent the block from being broken
+ */
+ default void onBreakBlock(@Nonnull EntityPlayer player, int x, int y, int z, @Nonnull Block block, byte metadata,
+ @Nullable TileEntity tile, @Nonnull BlockEvent.BreakEvent event) {}
+
+ /**
+ * @return Damage the Tool receives when breaking a Block. 100 is one Damage Point (or 100 EU).
+ */
+ int getToolDamagePerBlockBreak();
+
+ /**
+ * @return Damage the Tool receives when converting the drops of a Block. 100 is one Damage Point (or 100 EU).
+ */
+ int getToolDamagePerDropConversion();
+
+ /**
+ * @return Damage the Tool receives when being used as Container Item. 100 is one use, however it is usually 8 times
+ * more than normal.
+ */
+ int getToolDamagePerContainerCraft();
+
+ /**
+ * @return Damage the Tool receives when being used as Weapon, 200 is the normal Value, 100 for actual Weapons.
+ */
+ int getToolDamagePerEntityAttack();
+
+ /**
+ * @return Basic Quality of the Tool, 0 is normal. If increased, it will increase the general quality of all Tools
+ * of this Type. Decreasing is also possible.
+ */
+ int getBaseQuality();
+
+ /**
+ * @return The Damage Bonus for this Type of Tool against Mobs. 1.0F is normal punch.
+ */
+ float getBaseDamage();
+
+ /**
+ * @return This gets the Hurt Resistance time for Entities getting hit. (always does 1 as minimum)
+ */
+ int getHurtResistanceTime(int aOriginalHurtResistance, Entity aEntity);
+
+ /**
+ * @return This is a multiplier for the Tool Speed. 1.0F = no special Speed.
+ */
+ float getSpeedMultiplier();
+
+ /**
+ * @return This is a multiplier for the Tool Speed. 1.0F = no special Durability.
+ */
+ float getMaxDurabilityMultiplier();
+
+ DamageSource getDamageSource(EntityLivingBase aPlayer, Entity aEntity);
+
+ String getMiningSound();
+
+ String getCraftingSound();
+
+ String getEntityHitSound();
+
+ String getBreakingSound();
+
+ Enchantment[] getEnchantments(ItemStack aStack);
+
+ int[] getEnchantmentLevels(ItemStack aStack);
+
+ /**
+ * @return If this Tool can be used for blocking Damage like a Sword.
+ */
+ boolean canBlock();
+
+ /**
+ * @return If this Tool can be used as an RC Crowbar.
+ */
+ boolean isCrowbar();
+
+ /**
+ * @return If this Tool can be used as an FR Grafter.
+ */
+ boolean isGrafter();
+
+ boolean isChainsaw();
+
+ /**
+ * @return If this Tool can be used as an BC Wrench.
+ */
+ boolean isWrench();
+
+ /**
+ * @return if this Tool can be used as an PR screwdriver
+ */
+ default boolean isScrewdriver() {
+ return false;
+ }
+
+ /**
+ * @return If this Tool can be used as Weapon i.e. if that is the main purpose.
+ */
+ boolean isWeapon();
+
+ /**
+ * @return If this Tool is a Ranged Weapon. Return false at isWeapon unless you have a Blade attached to your
+ * Bow/Gun or something
+ */
+ boolean isRangedWeapon();
+
+ /**
+ * @return If this Tool can be used as Weapon i.e. if that is the main purpose.
+ */
+ boolean isMiningTool();
+
+ /**
+ * {@link Block#getHarvestTool(int)} can return the following Values for example. "axe", "pickaxe", "sword",
+ * "shovel", "hoe", "grafter", "saw", "wrench", "crowbar", "file", "hammer", "plow", "plunger", "scoop",
+ * "screwdriver", "sense", "scythe", "softhammer", "cutter", "plasmatorch"
+ *
+ * @return If this is a minable Block. Tool Quality checks (like Diamond Tier or something) are separate from this
+ * check.
+ */
+ boolean isMinableBlock(Block aBlock, byte aMetaData);
+
+ /**
+ * This lets you modify the Drop List, when this type of Tool has been used.
+ *
+ * @return the Amount of modified Items, used to determine the extra durability cost
+ */
+ int convertBlockDrops(List<ItemStack> aDrops, ItemStack aStack, EntityPlayer aPlayer, Block aBlock, int aX, int aY,
+ int aZ, byte aMetaData, int aFortune, boolean aSilkTouch, BlockEvent.HarvestDropsEvent aEvent);
+
+ /**
+ * @return Returns a broken Version of the Item.
+ */
+ ItemStack getBrokenItem(ItemStack aStack);
+
+ /**
+ * @return the Damage actually done to the Mob.
+ */
+ float getNormalDamageAgainstEntity(float aOriginalDamage, Entity aEntity, ItemStack aStack, EntityPlayer aPlayer);
+
+ /**
+ * @return the Damage actually done to the Mob.
+ */
+ float getMagicDamageAgainstEntity(float aOriginalDamage, Entity aEntity, ItemStack aStack, EntityPlayer aPlayer);
+
+ IIconContainer getIcon(boolean aIsToolHead, ItemStack aStack);
+
+ short[] getRGBa(boolean aIsToolHead, ItemStack aStack);
+
+ float getMiningSpeed(Block aBlock, byte aMetaData, float aDefault, EntityPlayer aPlayer, World worldObj, int aX,
+ int aY, int aZ);
+
+ default String getToolTypeName() {
+ return null;
+ };
+
+ default byte getMaxMode() {
+ return 1;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/covers/IControlsWorkCover.java b/src/main/java/gregtech/api/interfaces/covers/IControlsWorkCover.java
new file mode 100644
index 0000000000..d4cd1e9ec2
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/covers/IControlsWorkCover.java
@@ -0,0 +1,30 @@
+package gregtech.api.interfaces.covers;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.tileentity.ICoverable;
+import gregtech.api.interfaces.tileentity.IMachineProgress;
+
+/**
+ * Marker interface for covers that might control whether the work can start on a {@link IMachineProgress}.
+ */
+public interface IControlsWorkCover {
+
+ /**
+ * Make sure there is only one GT_Cover_ControlsWork on the aTileEntity TODO this is a migration thing. Remove this
+ * after 2.3.0 is released.
+ *
+ * @return true if the cover is the first (side) one
+ **/
+ static boolean makeSureOnlyOne(ForgeDirection aMySide, ICoverable aTileEntity) {
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ if (aTileEntity.getCoverBehaviorAtSideNew(side) instanceof IControlsWorkCover
+ && side.ordinal() < aMySide.ordinal()) {
+ aTileEntity.dropCover(side, side, true);
+ aTileEntity.markDirty();
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/fluid/IFluidStore.java b/src/main/java/gregtech/api/interfaces/fluid/IFluidStore.java
new file mode 100644
index 0000000000..047cf4df5b
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/fluid/IFluidStore.java
@@ -0,0 +1,22 @@
+package gregtech.api.interfaces.fluid;
+
+import javax.annotation.Nonnull;
+
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.IFluidTank;
+
+/**
+ * Objects implementing this interface can be used for storing certain fluid, especially for recipe output.
+ */
+public interface IFluidStore extends IFluidTank {
+
+ /**
+ * @return If this does not have partially filled fluid nor have restriction on what fluid to accept.
+ */
+ boolean isEmptyAndAcceptsAnyFluid();
+
+ /**
+ * @return Whether to allow given fluid to be inserted into this.
+ */
+ boolean canStoreFluid(@Nonnull FluidStack fluidStack);
+}
diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java b/src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java
new file mode 100644
index 0000000000..7c8b2b3f11
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java
@@ -0,0 +1,14 @@
+package gregtech.api.interfaces.fluid;
+
+import net.minecraftforge.fluids.FluidRegistry;
+
+@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope
+public interface IGT_Fluid {
+
+ /**
+ * Adds this {@link IGT_Fluid} to the {@link FluidRegistry} and internally-implemented registrations
+ *
+ * @return {@link IGT_RegisteredFluid} The GregTech registered fluid
+ */
+ IGT_RegisteredFluid addFluid();
+}
diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java b/src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java
new file mode 100644
index 0000000000..f15b148fcb
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java
@@ -0,0 +1,96 @@
+package gregtech.api.interfaces.fluid;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.block.Block;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidRegistry;
+
+import gregtech.api.enums.FluidState;
+
+@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope
+public interface IGT_FluidBuilder {
+
+ /**
+ * @param colorRGBA The {@code short[]} RGBA color of the {@link Fluid} or {@code null} for no defined RGBA color
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withColorRGBA(final short[] colorRGBA);
+
+ /**
+ * @param localizedName The localized name of this {@link IGT_FluidBuilder}
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withLocalizedName(final String localizedName);
+
+ /**
+ * @param fluidState The {@link FluidState} of this {@link IGT_FluidBuilder}
+ * @param temperature The Kelvin temperature of this {@link IGT_FluidBuilder}
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withStateAndTemperature(final FluidState fluidState, final int temperature);
+
+ /**
+ * @param stillIconResourceLocation the {@link ResourceLocation} of the still fluid icon
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withStillIconResourceLocation(final ResourceLocation stillIconResourceLocation);
+
+ /**
+ * @param flowingIconResourceLocation the {@link ResourceLocation} of the flowing fluid icon
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withFlowingIconResourceLocation(final ResourceLocation flowingIconResourceLocation);
+
+ /**
+ * @param textureName The name of the GregTech mod texture of this {@link IGT_FluidBuilder}
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withTextureName(final String textureName);
+
+ /**
+ * @param fluidBlock the {@link Block} implementation of the {@link IGT_Fluid}
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withFluidBlock(final Block fluidBlock);
+
+ /**
+ * @param fromFluid the {@link Fluid} to copy the icons from
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withIconsFrom(@Nonnull final Fluid fromFluid);
+
+ /**
+ * @param stillIconResourceLocation The {@link ResourceLocation} of the still fluid texture
+ * @param flowingIconResourceLocation The {@link ResourceLocation} of the flowing fluid texture
+ * @return {@link IGT_FluidBuilder} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_FluidBuilder withTextures(final ResourceLocation stillIconResourceLocation,
+ final ResourceLocation flowingIconResourceLocation);
+
+ /**
+ * Builds the {@link IGT_Fluid}
+ *
+ * @return the built {@link IGT_Fluid}
+ */
+ IGT_Fluid build();
+
+ /**
+ * Builds, then adds the {@link IGT_Fluid} to the {@link FluidRegistry}
+ *
+ * @return the {@link IGT_Fluid}
+ * @see #build()
+ * @see IGT_Fluid#addFluid()
+ */
+ IGT_RegisteredFluid buildAndRegister();
+}
diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java b/src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java
new file mode 100644
index 0000000000..181824874c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java
@@ -0,0 +1,60 @@
+package gregtech.api.interfaces.fluid;
+
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+
+import gregtech.api.enums.FluidState;
+import gregtech.api.enums.Materials;
+
+public interface IGT_RegisteredFluid {
+
+ /**
+ * Registers the containers in the {@link FluidContainerRegistry} for this {@link IGT_RegisteredFluid}
+ *
+ * @param fullContainer The full fluid container
+ * @param emptyContainer The empty fluid container
+ * @param containerSize The size of the container
+ * @return The {@link IGT_RegisteredFluid} for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_RegisteredFluid registerContainers(final ItemStack fullContainer, final ItemStack emptyContainer,
+ final int containerSize);
+
+ /**
+ * Registers the bucket-sized 1000L containers in the {@link FluidContainerRegistry} for this
+ * {@link IGT_RegisteredFluid}
+ *
+ * @param fullContainer The full container to associate with this {@link IGT_RegisteredFluid}
+ * @param emptyContainer The empty container associate with this {@link IGT_RegisteredFluid}
+ * @return {@link IGT_RegisteredFluid} for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_RegisteredFluid registerBContainers(final ItemStack fullContainer, final ItemStack emptyContainer);
+
+ /**
+ * Registers the potion-sized 250L containers in the {@link FluidContainerRegistry} for this
+ * {@link IGT_RegisteredFluid}
+ *
+ * @param fullContainer The full container to associate with this {@link IGT_RegisteredFluid}
+ * @param emptyContainer The empty container associate with this {@link IGT_RegisteredFluid}
+ * @return {@link IGT_RegisteredFluid} self for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_RegisteredFluid registerPContainers(final ItemStack fullContainer, final ItemStack emptyContainer);
+
+ /**
+ * Updates the {@link Materials}'s fluids from this {@link IGT_RegisteredFluid}'s state
+ *
+ * @param material the {@link Materials} to configure based on this {@link IGT_RegisteredFluid} and
+ * {@link FluidState}
+ * @return The {@link IGT_RegisteredFluid} for call chaining
+ */
+ @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value
+ IGT_RegisteredFluid configureMaterials(final Materials material);
+
+ /**
+ * @return this {@link IGT_RegisteredFluid} cast to {@link Fluid}
+ */
+ Fluid asFluid();
+}
diff --git a/src/main/java/gregtech/api/interfaces/internal/IBCTileEntity.java b/src/main/java/gregtech/api/interfaces/internal/IBCTileEntity.java
new file mode 100644
index 0000000000..4acfa62549
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/internal/IBCTileEntity.java
@@ -0,0 +1,8 @@
+package gregtech.api.interfaces.internal;
+
+/**
+ * A simple compound Interface for generic BuildCraft Code.
+ */
+public interface IBCTileEntity /* extends IPowerReceptor */ {
+ //
+}
diff --git a/src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java b/src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java
new file mode 100644
index 0000000000..3f29736470
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java
@@ -0,0 +1,8 @@
+package gregtech.api.interfaces.internal;
+
+import net.minecraft.item.crafting.IRecipe;
+
+public interface IGT_CraftingRecipe extends IRecipe {
+
+ boolean isRemovable();
+}
diff --git a/src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java b/src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java
new file mode 100644
index 0000000000..dbf888ef96
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java
@@ -0,0 +1,50 @@
+package gregtech.api.interfaces.internal;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+
+/**
+ * Interface used by the Mods Main Class to reference to internals.
+ * <p/>
+ * Don't even think about including this File in your Mod.
+ */
+public interface IGT_Mod {
+
+ /**
+ * This means that Server specific Basefiles are definitely existing! Not if the World is actually server side or
+ * not!
+ */
+ boolean isServerSide();
+
+ /**
+ * This means that Client specific Basefiles are definitely existing! Not if the World is actually client side or
+ * not!
+ */
+ boolean isClientSide();
+
+ /**
+ * This means that Bukkit specific Basefiles are definitely existing! Not if the World is actually bukkit server or
+ * not!
+ */
+ boolean isBukkitSide();
+
+ /**
+ * works only ClientSide otherwise returns null
+ */
+ EntityPlayer getThePlayer();
+
+ // ---------- Internal Usage Only ----------
+
+ /**
+ * works only ClientSide otherwise returns 0
+ *
+ * @return the Index of the added Armor
+ */
+ int addArmor(String aArmorPrefix);
+
+ /**
+ * Plays the Sonictron Sound for the ItemStack on the Client Side
+ */
+ void doSonictronSound(ItemStack aStack, World aWorld, double aX, double aY, double aZ);
+}
diff --git a/src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java b/src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java
new file mode 100644
index 0000000000..e7abfea98f
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java
@@ -0,0 +1,1069 @@
+package gregtech.api.interfaces.internal;
+
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+
+import gregtech.api.util.GT_Recipe;
+import gregtech.api.util.GT_RecipeBuilder;
+
+public interface IGT_RecipeAdder {
+
+ /**
+ * Adds a FusionreactorRecipe Does not work anymore!
+ */
+
+ @Deprecated
+ boolean addFusionReactorRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, int aFusionDurationInTicks,
+ int aFusionEnergyPerTick, int aEnergyNeededForStartingFusion);
+
+ /**
+ * Adds a FusionreactorRecipe
+ *
+ * @param aInput1 = first Input (not null, and respects StackSize)
+ * @param aInput2 = second Input (not null, and respects StackSize)
+ * @param aOutput1 = Output of the Fusion (can be null, and respects StackSize)
+ * @param aFusionDurationInTicks = How many ticks the Fusion lasts (must be > 0)
+ * @param aFusionEnergyPerTick = The EU generated per Tick (can even be negative!)
+ * @param aEnergyNeededForStartingFusion = EU needed for heating the Reactor up (must be >= 0)
+ * @return true if the Recipe got added, otherwise false.
+ */
+
+ @Deprecated
+ boolean addFusionReactorRecipe(FluidStack aInput1, FluidStack aInput2, FluidStack aOutput1,
+ int aFusionDurationInTicks, int aFusionEnergyPerTick, int aEnergyNeededForStartingFusion);
+
+ /**
+ * Adds a Fusion Reactor Recipe
+ *
+ * @param FluidInputArray Array of input fluids. Up to 16.
+ * @param FluidOutputArray Array of output fluids. Up to 16.
+ * @param aFusionDurationInTicks How many ticks the Fusion lasts (must be > 0).
+ * @param aFusionEnergyPerTick The EU consumed per tick to keep the reaction going.
+ * @param aEnergyNeededForStartingFusion EU needed to initialize the fusion reaction. (must be >= 0).
+ * @return true if the recipe got added, otherwise false.
+ */
+
+ @Deprecated
+ boolean addFusionReactorRecipe(FluidStack[] FluidInputArray, FluidStack[] FluidOutputArray,
+ int aFusionDurationInTicks, int aFusionEnergyPerTick, int aEnergyNeededForStartingFusion);
+
+ /**
+ * Adds a Centrifuge Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ * @param aOutput3 can be null
+ * @param aOutput4 can be null
+ * @param aDuration must be > 0
+ */
+
+ @Deprecated
+ boolean addCentrifugeRecipe(ItemStack aInput1, int aInput2, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, ItemStack aOutput4, ItemStack aOutput5, ItemStack aOutput6, int aDuration);
+
+ @Deprecated
+ boolean addCentrifugeRecipe(ItemStack aInput1, int aInput2, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, ItemStack aOutput4, ItemStack aOutput5, ItemStack aOutput6, int aDuration, int aEUt);
+
+ /**
+ * Adds a Centrifuge Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ * @param aOutput3 can be null
+ * @param aOutput4 can be null
+ * @param aDuration must be > 0
+ */
+ @Deprecated
+ boolean addCentrifugeRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, ItemStack aOutput5,
+ ItemStack aOutput6, int[] aChances, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addCentrifugeRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, ItemStack aOutput5,
+ ItemStack aOutput6, int[] aChances, int aDuration, int aEUt, boolean aCleanroom);
+
+ /**
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @return if the recipe was successfully added
+ */
+
+ @Deprecated
+ boolean addCompressorRecipe(ItemStack aInput1, ItemStack aOutput1, int aDuration, int aEUt);
+
+ /**
+ * Adds a Electrolyzer Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ * @param aOutput3 can be null
+ * @param aOutput4 can be null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addElectrolyzerRecipe(ItemStack aInput1, int aInput2, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, ItemStack aOutput4, ItemStack aOutput5, ItemStack aOutput6, int aDuration, int aEUt);
+
+ /**
+ * Adds a Electrolyzer Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ * @param aOutput3 can be null
+ * @param aOutput4 can be null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addElectrolyzerRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, ItemStack aOutput5,
+ ItemStack aOutput6, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds a Chemical Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 must be != null
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ */
+ @Deprecated
+ boolean addChemicalRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput, int aDuration);
+
+ @Deprecated
+ boolean addChemicalRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Chemical Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 must be != null
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ */
+ @Deprecated
+ boolean addChemicalRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput, int aDuration);
+
+ /**
+ * Adds a Chemical Recipe Only use this when the recipe conflicts in MultiBlock!
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 must be != null
+ * @param aOutput must be != null
+ * @param aOutput2 must be != null
+ * @param aDuration must be > 0
+ */
+ @Deprecated
+ boolean addChemicalRecipeForBasicMachineOnly(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput,
+ FluidStack aFluidOutput, ItemStack aOutput, ItemStack aOutput2, int aDuration, int aEUtick);
+
+ /**
+ * Adds a Chemical Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 must be != null
+ * @param aOutput must be != null
+ * @param aOutput2 must be != null
+ * @param aDuration must be > 0
+ */
+ @Deprecated
+ boolean addChemicalRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput, ItemStack aOutput2, int aDuration);
+
+ /**
+ * Adds Recipes for creating a radically polymerized polymer from a base Material (for example Ethylene ->
+ * Polyethylene)
+ *
+ * @param aBasicMaterial The basic Material
+ * @param aBasicMaterialCell The corresponding Cell basic Material
+ * @param aPolymer The polymer
+ */
+ void addDefaultPolymerizationRecipes(Fluid aBasicMaterial, ItemStack aBasicMaterialCell, Fluid aPolymer);
+
+ /**
+ * Adds a Chemical Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 must be != null
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ * @param aEUtick must be > 0
+ */
+ @Deprecated
+ boolean addChemicalRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput, int aDuration, int aEUtick);
+
+ @Deprecated
+ boolean addChemicalRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput, ItemStack aOutput2, int aDuration, int aEUtick, boolean aCleanroom);
+
+ /**
+ * Adds a Chemical Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 must be != null
+ * @param aOutput must be != null
+ * @param aOutput2 must be != null
+ * @param aDuration must be > 0
+ * @param aEUtick must be > 0
+ */
+ @Deprecated
+ boolean addChemicalRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput, ItemStack aOutput2, int aDuration, int aEUtick);
+
+ /**
+ * Adds a Chemical Recipe that only exists in the Large Chemical Reactor
+ *
+ * @param aInputs item inputs
+ * @param aFluidInputs fluid inputs
+ * @param aFluidOutputs fluid outputs
+ * @param aOutputs item outputs
+ * @param aDuration must be > 0
+ * @param aEUtick must be > 0 <br>
+ * aInputs and aFluidInputs must contain at least one valid input. <br>
+ * aOutputs and aFluidOutputs must contain at least one valid output.
+ *
+ */
+ @Deprecated
+ boolean addMultiblockChemicalRecipe(ItemStack[] aInputs, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs,
+ ItemStack[] aOutputs, int aDuration, int aEUtick);
+
+ /**
+ * Adds a Blast Furnace Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 can be null
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ * @param aLevel should be > 0 is the minimum Heat Level needed for this Recipe
+ */
+ @Deprecated
+ boolean addBlastRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, ItemStack aOutput2, int aDuration,
+ int aEUt, int aLevel);
+
+ /**
+ * Adds a Blast Furnace Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 can be null
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ * @param aLevel should be > 0 is the minimum Heat Level needed for this Recipe
+ */
+ @Deprecated
+ boolean addBlastRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, FluidStack aFluidOutput,
+ ItemStack aOutput1, ItemStack aOutput2, int aDuration, int aEUt, int aLevel);
+
+ @Deprecated
+ boolean addBlastRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aInput3, ItemStack aInput4,
+ FluidStack aFluidInput, FluidStack aFluidOutput, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3,
+ ItemStack aOutput4, int aDuration, int aEUt, int aLevel);
+
+ /**
+ * Adds a Plasma Forge Recipe
+ *
+ * @param ItemInputArray Array of input items.
+ * @param FluidInputArray Array of output items.
+ * @param OutputItemArray Array of input fluids.
+ * @param FluidOutputArray Array of output items.
+ * @param aDuration Must be > 0. Duration in ticks.
+ * @param aEUt Should be > 0. EU/t.
+ * @param coil_heat_level Should be > 0. Heat of the coils used.
+ */
+ @Deprecated
+ boolean addPlasmaForgeRecipe(ItemStack[] ItemInputArray, FluidStack[] FluidInputArray, ItemStack[] OutputItemArray,
+ FluidStack[] FluidOutputArray, int aDuration, int aEUt, int coil_heat_level);
+
+ @Deprecated
+ boolean addPrimitiveBlastRecipe(ItemStack aInput1, ItemStack aInput2, int aCoalAmount, ItemStack aOutput1,
+ ItemStack aOutput2, int aDuration);
+
+ /**
+ * Adds a Canning Machine Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0, 100 ticks is standard.
+ * @param aEUt should be > 0, 1 EU/t is standard.
+ */
+ @Deprecated
+ boolean addCannerRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, ItemStack aOutput2, int aDuration,
+ int aEUt);
+
+ /**
+ * Adds an Alloy Smelter Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 can be null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addAlloySmelterRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addAlloySmelterRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, int aDuration, int aEUt,
+ boolean hidden);
+
+ /**
+ * Adds an Assembler Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aInput2 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addAssemblerRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, int aDuration, int aEUt);
+
+ /**
+ * Adds an Assembler Recipe
+ *
+ * @param aInputs must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ *
+ */
+ @Deprecated
+ boolean addAssemblerRecipe(ItemStack[] aInputs, FluidStack aFluidInput, ItemStack aOutput1, int aDuration,
+ int aEUt);
+
+ /**
+ * Adds an Assembler Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addAssemblerRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, ItemStack aOutput1,
+ int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addAssemblerRecipe(ItemStack aInput1, Object aOreDict, int aAmount, FluidStack aFluidInput,
+ ItemStack aOutput1, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addAssemblerRecipe(ItemStack[] aInputs, Object aOreDict, int aAmount, FluidStack aFluidInput,
+ ItemStack aOutput1, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addAssemblerRecipe(ItemStack aInput1, ItemStack aInput2, FluidStack aFluidInput, ItemStack aOutput1,
+ int aDuration, int aEUt, boolean aCleanroom);
+
+ @Deprecated
+ boolean addAssemblerRecipe(ItemStack[] aInputs, FluidStack aFluidInput, ItemStack aOutput1, int aDuration, int aEUt,
+ boolean aCleanroom);
+
+ /**
+ * Adds an Circuit Assembler Recipe
+ *
+ * @param aInputs must be 1-6 ItemStacks
+ * @param aFluidInput 0-1 fluids
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addCircuitAssemblerRecipe(ItemStack[] aInputs, FluidStack aFluidInput, ItemStack aOutput, int aDuration,
+ int aEUt);
+
+ @Deprecated
+ boolean addCircuitAssemblerRecipe(ItemStack[] aInputs, FluidStack aFluidInput, ItemStack aOutput, int aDuration,
+ int aEUt, boolean aCleanroom);
+
+ /**
+ * Adds an Assemblyline Recipe
+ *
+ * @param aInputs must be != null, 4-16 inputs
+ * @param aFluidInputs 0-4 fluids
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addAssemblylineRecipe(ItemStack aResearchItem, int aResearchTime, ItemStack[] aInputs,
+ FluidStack[] aFluidInputs, ItemStack aOutput1, int aDuration, int aEUt);
+
+ /**
+ * Adds a Assemblyline Recipe
+ *
+ * @param aInputs elements should be: ItemStack for single item; ItemStack[] for multiple equivalent items;
+ * {OreDict, amount} for oredict.
+ */
+ @Deprecated
+ boolean addAssemblylineRecipe(ItemStack aResearchItem, int aResearchTime, Object[] aInputs,
+ FluidStack[] aFluidInputs, ItemStack aOutput1, int aDuration, int aEUt);
+
+ /**
+ * Adds a Forge Hammer Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addForgeHammerRecipe(ItemStack aInput1, ItemStack aOutput1, int aDuration, int aEUt);
+
+ // Allows fluids as well as multiple items.
+ @Deprecated
+ boolean addForgeHammerRecipe(ItemStack[] ItemInputArray, FluidStack[] FluidInputArray, ItemStack[] ItemOutputArray,
+ FluidStack[] FluidOutputArray, int aDuration, int aEUt);
+
+ /**
+ * Adds a Wiremill Recipe
+ *
+ * @param aInput must be != null
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addWiremillRecipe(ItemStack aInput, ItemStack aOutput, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addWiremillRecipe(ItemStack aInput, ItemStack aCircuit, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Polariser Recipe
+ *
+ * @param aInput must be != null
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addPolarizerRecipe(ItemStack aInput, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Plate Bending Machine Recipe
+ *
+ * @param aInput must be != null
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addBenderRecipe(ItemStack aInput, ItemStack aOutput, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addBenderRecipe(ItemStack aInput, ItemStack aCircuit, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Extruder Machine Recipe
+ *
+ * @param aInput must be != null
+ * @param aShape must be != null, Set the stackSize to 0 if you don't want to let it consume this Item.
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addExtruderRecipe(ItemStack aInput, ItemStack aShape, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Slicer Machine Recipe
+ *
+ * @param aInput must be != null
+ * @param aShape must be != null, Set the stackSize to 0 if you don't want to let it consume this Item.
+ * @param aOutput must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ */
+ @Deprecated
+ boolean addSlicerRecipe(ItemStack aInput, ItemStack aShape, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * @param aInput must be != null
+ * @param aFluidInput must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ * @return if the recipe was successfully added
+ */
+ @Deprecated
+ boolean addOreWasherRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3,
+ FluidStack aFluidInput, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addOreWasherRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3,
+ FluidStack aFluidInput, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds an Implosion Compressor Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 amount of ITNT, should be > 0
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ */
+ @Deprecated
+ boolean addImplosionRecipe(ItemStack aInput1, int aInput2, ItemStack aOutput1, ItemStack aOutput2);
+
+ /**
+ * Adds a Grinder Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aInput2 id for the Cell needed for this Recipe
+ * @param aOutput1 must be != null
+ * @param aOutput2 can be null
+ * @param aOutput3 can be null
+ * @param aOutput4 can be null
+ */
+ @Deprecated
+ boolean addGrinderRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, ItemStack aOutput4);
+
+ /**
+ * Adds a Distillation Tower Recipe
+ *
+ * @param aInput must be != null
+ * @param aOutputs must be != null 1-5 Fluids
+ * @param aOutput2 can be null
+ */
+ @Deprecated
+ boolean addDistillationTowerRecipe(FluidStack aInput, FluidStack[] aOutputs, ItemStack aOutput2, int aDuration,
+ int aEUt);
+
+ @Deprecated
+ boolean addDistillationTowerRecipe(FluidStack aInput, ItemStack[] aCircuit, FluidStack[] aOutputs,
+ ItemStack aOutput2, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addSimpleArcFurnaceRecipe(ItemStack aInput, FluidStack aFluidInput, ItemStack[] aOutputs, int[] aChances,
+ int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addPlasmaArcFurnaceRecipe(ItemStack aInput, FluidStack aFluidInput, ItemStack[] aOutputs, int[] aChances,
+ int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addPlasmaArcFurnaceRecipe(ItemStack aInput, FluidStack aFluidInput, ItemStack[] aOutputs,
+ FluidStack aFluidPutput, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds a Distillation Tower Recipe
+ */
+ @Deprecated
+ boolean addDistillationRecipe(ItemStack aInput1, int aInput2, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, ItemStack aOutput4, int aDuration, int aEUt);
+
+ /**
+ * Adds a Lathe Machine Recipe
+ */
+ @Deprecated
+ boolean addLatheRecipe(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2, int aDuration, int aEUt);
+
+ /**
+ * Adds a Cutter Recipe
+ */
+ @Deprecated
+ boolean addCutterRecipe(ItemStack aInput, FluidStack aLubricant, ItemStack aOutput1, ItemStack aOutput2,
+ int aDuration, int aEUt);
+
+ /**
+ * Adds Cutter Recipes with default Lubricants
+ */
+ @Deprecated
+ boolean addCutterRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addCutterRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, int aDuration, int aEUt,
+ boolean aCleanroom);
+
+ @Deprecated
+ boolean addCutterRecipe(ItemStack aInput, ItemStack aCircuit, ItemStack aOutput1, ItemStack aOutput2, int aDuration,
+ int aEUt);
+
+ @Deprecated
+ boolean addCutterRecipe(ItemStack aInput, ItemStack aCircuit, ItemStack aOutput1, ItemStack aOutput2, int aDuration,
+ int aEUt, boolean aCleanroom);
+
+ @Deprecated
+ boolean addCutterRecipe(ItemStack[] aInputs, ItemStack[] aOutputs, int aDuration, int aEUt, int aSpecial);
+
+ @Deprecated
+ boolean addCutterRecipe(ItemStack[] aInputs, ItemStack[] aOutputs, int aDuration, int aEUt, boolean aCleanroom);
+
+ /**
+ * Adds a Boxing Recipe
+ */
+ @Deprecated
+ boolean addBoxingRecipe(ItemStack aContainedItem, ItemStack aEmptyBox, ItemStack aFullBox, int aDuration, int aEUt);
+
+ /**
+ * @param aInput must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ * @param aEUt should be > 0
+ * @return if the recipe was successfully added
+ */
+ @Deprecated
+ boolean addThermalCentrifugeRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3,
+ int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addThermalCentrifugeRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3,
+ int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds an Unboxing Recipe
+ */
+ @Deprecated
+ boolean addUnboxingRecipe(ItemStack aFullBox, ItemStack aContainedItem, ItemStack aEmptyBox, int aDuration,
+ int aEUt);
+
+ /**
+ * Adds a Vacuum Freezer Recipe
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 must be != null
+ * @param aDuration must be > 0
+ */
+ @Deprecated
+ boolean addVacuumFreezerRecipe(ItemStack aInput1, ItemStack aOutput1, int aDuration);
+
+ @Deprecated
+ boolean addVacuumFreezerRecipe(ItemStack aInput1, ItemStack aOutput1, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addVacuumFreezerRecipe(FluidStack aInput1, FluidStack aOutput1, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addVacuumFreezerRecipe(ItemStack[] aItemInput, FluidStack[] aFluidInput, ItemStack[] aItemOutput,
+ FluidStack[] aFluidOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Fuel for My Generators
+ *
+ * @param aInput1 must be != null
+ * @param aOutput1 can be null
+ * @param aEU EU per MilliBucket. If no Liquid Form of this Container is available, then it will give you
+ * EU*1000 per Item.
+ * @param aType 0 = Diesel; 1 = Gas Turbine; 2 = Thermal; 3 = Dense Fluid; 4 = Plasma; 5 = Magic; And if
+ * something is unclear or missing, then look at the GT_Recipe-Class
+ */
+ @Deprecated
+ boolean addFuel(ItemStack aInput1, ItemStack aOutput1, int aEU, int aType);
+
+ /**
+ * Adds an Amplifier Recipe for the Amplifabricator
+ */
+ @Deprecated
+ boolean addAmplifier(ItemStack aAmplifierItem, int aDuration, int aAmplifierAmountOutputted);
+
+ /**
+ * Adds a Recipe for the Brewing Machine (intentionally limited to Fluid IDs)
+ */
+ @Deprecated
+ boolean addBrewingRecipe(ItemStack aIngredient, Fluid aInput, Fluid aOutput, boolean aHidden);
+
+ @Deprecated
+ boolean addBrewingRecipe(ItemStack aIngredient, Fluid aInput, Fluid aOutput, int aDuration, int aEUt,
+ boolean aHidden);
+
+ @Deprecated
+ boolean addBrewingRecipeCustom(ItemStack aIngredient, FluidStack aInput, FluidStack aOutput, int aDuration,
+ int aEUt, boolean aHidden);
+
+ /**
+ * Adds a Recipe for the Fermenter
+ */
+ @Deprecated
+ boolean addFermentingRecipe(FluidStack aInput, FluidStack aOutput, int aDuration, boolean aHidden);
+
+ @Deprecated
+ boolean addFermentingRecipe(FluidStack aInput, FluidStack aOutput, int aDuration, int aEUT, boolean aHidden);
+
+ /**
+ * Adds a Recipe for the Fluid Heater
+ */
+ @Deprecated
+ boolean addFluidHeaterRecipe(ItemStack aCircuit, FluidStack aOutput, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addFluidHeaterRecipe(ItemStack aCircuit, FluidStack aInput, FluidStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Distillery
+ */
+ @Deprecated
+ boolean addDistilleryRecipe(ItemStack aCircuit, FluidStack aInput, FluidStack aOutput, ItemStack aSolidOutput,
+ int aDuration, int aEUt, boolean aHidden);
+
+ @Deprecated
+ boolean addDistilleryRecipe(ItemStack aCircuit, FluidStack aInput, FluidStack aOutput, int aDuration, int aEUt,
+ boolean aHidden);
+
+ @Deprecated
+ boolean addDistilleryRecipe(int circuitConfig, FluidStack aInput, FluidStack aOutput, ItemStack aSolidOutput,
+ int aDuration, int aEUt, boolean aHidden);
+
+ @Deprecated
+ boolean addDistilleryRecipe(int aCircuit, FluidStack aInput, FluidStack aOutput, int aDuration, int aEUt,
+ boolean aHidden);
+
+ /**
+ * Adds a Recipe for the Fluid Solidifier
+ */
+ @Deprecated
+ boolean addFluidSolidifierRecipe(ItemStack aMold, FluidStack aInput, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Fluid Solidifier
+ */
+ @Deprecated
+ boolean addFluidSolidifierRecipe(final ItemStack[] itemInputs, final FluidStack[] fluidInputs,
+ final ItemStack[] itemOutputs, final FluidStack[] fluidOutputs, final int EUPerTick,
+ final int aDurationInTicks);
+
+ /**
+ * Adds a Recipe for Fluid Smelting
+ */
+ @Deprecated
+ boolean addFluidSmelterRecipe(ItemStack aInput, ItemStack aRemains, FluidStack aOutput, int aChance, int aDuration,
+ int aEUt);
+
+ /**
+ * Adds a Recipe for Fluid Smelting
+ */
+ @Deprecated
+ boolean addFluidSmelterRecipe(ItemStack aInput, ItemStack aRemains, FluidStack aOutput, int aChance, int aDuration,
+ int aEUt, boolean hidden);
+
+ /**
+ * Adds a Recipe for Fluid Extraction
+ */
+ @Deprecated
+ boolean addFluidExtractionRecipe(ItemStack aInput, ItemStack aRemains, FluidStack aOutput, int aChance,
+ int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Fluid Canner
+ */
+ @Deprecated
+ boolean addFluidCannerRecipe(ItemStack aInput, ItemStack aOutput, FluidStack aFluidInput, FluidStack aFluidOutput);
+
+ @Deprecated
+ boolean addFluidCannerRecipe(ItemStack aInput, ItemStack aOutput, FluidStack aFluidInput, FluidStack aFluidOutput,
+ int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Chemical Bath
+ */
+ @Deprecated
+ boolean addChemicalBathRecipe(ItemStack aInput, FluidStack aBathingFluid, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, int[] aChances, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addChemicalBathRecipe(ItemStack aInput, FluidStack aBathingFluid, FluidStack aFluidOutput,
+ ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Electromagnetic Separator
+ */
+ @Deprecated
+ boolean addElectromagneticSeparatorRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Extractor
+ */
+ @Deprecated
+ boolean addExtractorRecipe(ItemStack aInput, ItemStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Printer
+ */
+ @Deprecated
+ boolean addPrinterRecipe(ItemStack aInput, FluidStack aFluid, ItemStack aSpecialSlot, ItemStack aOutput,
+ int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Autoclave
+ */
+ @Deprecated
+ boolean addAutoclaveRecipe(ItemStack aInput, FluidStack aFluid, ItemStack aOutput, int aChance, int aDuration,
+ int aEUt);
+
+ @Deprecated
+ boolean addAutoclaveRecipe(ItemStack aInput, FluidStack aFluid, ItemStack aOutput, int aChance, int aDuration,
+ int aEUt, boolean aCleanroom);
+
+ @Deprecated
+ boolean addAutoclaveRecipe(ItemStack aInput, ItemStack aCircuit, FluidStack aFluid, ItemStack aOutput, int aChance,
+ int aDuration, int aEUt, boolean aCleanroom);
+
+ @Deprecated
+ boolean addAutoclaveRecipe(ItemStack aInput, ItemStack aCircuit, FluidStack aFluidIn, FluidStack aFluidOut,
+ ItemStack aOutput, int aChance, int aDuration, int aEUt, boolean aCleanroom);
+
+ @Deprecated
+ boolean addAutoclaveSpaceRecipe(ItemStack aInput, FluidStack aFluid, ItemStack aOutput, int aChance, int aDuration,
+ int aEUt, boolean aCleanroom);
+
+ @Deprecated
+ boolean addAutoclaveSpaceRecipe(ItemStack aInput, ItemStack aCircuit, FluidStack aFluid, ItemStack aOutput,
+ int aChance, int aDuration, int aEUt, boolean aCleanroom);
+
+ @Deprecated
+ boolean addAutoclave4Recipe(ItemStack aInput, ItemStack aCircuit, FluidStack aFluidIn, FluidStack aFluidOut,
+ ItemStack[] aOutputs, int[] aChances, int aDuration, int aEUt, boolean aCleanroom);
+
+ /**
+ * Adds a Recipe for the Mixer
+ */
+ @Deprecated
+ boolean addMixerRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aInput3, ItemStack aInput4,
+ FluidStack aFluidInput, FluidStack aFluidOutput, ItemStack aOutput, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addMixerRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aInput3, ItemStack aInput4,
+ ItemStack aInput5, ItemStack aInput6, FluidStack aFluidInput, FluidStack aFluidOutput, ItemStack aOutput,
+ int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addMixerRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aInput3, ItemStack aInput4,
+ ItemStack aInput5, ItemStack aInput6, ItemStack aInput7, ItemStack aInput8, ItemStack aInput9,
+ FluidStack aFluidInput, FluidStack aFluidOutput, ItemStack aOutput, int aDuration, int aEUt);
+
+ @Deprecated
+ boolean addMixerRecipe(ItemStack aInput1, ItemStack aInput2, ItemStack aInput3, ItemStack aInput4,
+ ItemStack aInput5, ItemStack aInput6, ItemStack aInput7, ItemStack aInput8, ItemStack aInput9,
+ FluidStack aFluidInput, FluidStack aFluidOutput, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3,
+ ItemStack aOutput4, int aDuration, int aEUt);
+
+ // Use me only from now on!
+ @Deprecated
+ boolean addMixerRecipe(ItemStack[] ItemInputArray, FluidStack[] FluidInputArray, ItemStack[] ItemOutputArray,
+ FluidStack[] FluidOutputArray, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Laser Engraver.
+ */
+ @Deprecated
+ boolean addLaserEngraverRecipe(ItemStack aItemToEngrave, ItemStack aLens, ItemStack aEngravedItem, int aDuration,
+ int aEUt);
+
+ /**
+ * Adds a Recipe for the Laser Engraver.
+ */
+ @Deprecated
+ boolean addLaserEngraverRecipe(ItemStack aItemToEngrave, ItemStack aLens, ItemStack aEngravedItem, int aDuration,
+ int aEUt, boolean aCleanroom);
+
+ /**
+ * Adds a Generalised Laser Engraver Recipe.
+ *
+ * @param ItemInputArray Array of input items.
+ * @param FluidInputArray Array of output items.
+ * @param OutputItemArray Array of input fluids.
+ * @param FluidOutputArray Array of output items.
+ * @param aDuration Must be > 0. Duration in ticks.
+ * @param aEUt Should be > 0. EU/t.
+ * @param aCleanroom Boolean for usage of cleanroom in recipe.
+ */
+ @Deprecated
+ boolean addLaserEngraverRecipe(ItemStack[] ItemInputArray, FluidStack[] FluidInputArray,
+ ItemStack[] OutputItemArray, FluidStack[] FluidOutputArray, int aDuration, int aEUt, boolean aCleanroom);
+
+ /**
+ * Adds a Recipe for the Forming Press
+ */
+ @Deprecated
+ boolean addFormingPressRecipe(ItemStack aItemToImprint, ItemStack aForm, ItemStack aImprintedItem, int aDuration,
+ int aEUt);
+
+ // Allows more than 2 inputs and multiple outputs
+ @Deprecated
+ boolean addFormingPressRecipe(ItemStack[] ItemInputArray, ItemStack[] OutputItemArray, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Sifter. (up to 9 Outputs)
+ */
+ @Deprecated
+ boolean addSifterRecipe(ItemStack aItemToSift, ItemStack[] aSiftedItems, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds a Generalised Sifter Recipe.
+ *
+ * @param ItemInputArray Array of input items.
+ * @param FluidInputArray Array of output items.
+ * @param OutputItemArray Array of input fluids.
+ * @param FluidOutputArray Array of output items.
+ * @param aChances Array of output chances.
+ * @param aDuration Must be > 0. Duration in ticks.
+ * @param aEUt Should be > 0. EU/t.
+ * @param aCleanroom Boolean for usage of cleanroom in recipe.
+ */
+ @Deprecated
+ boolean addSifterRecipe(ItemStack[] ItemInputArray, FluidStack[] FluidInputArray, ItemStack[] OutputItemArray,
+ FluidStack[] FluidOutputArray, int[] aChances, int aDuration, int aEUt, boolean aCleanroom);
+
+ /**
+ * Adds a Recipe for the Arc Furnace. (up to 4 Outputs)
+ */
+ @Deprecated
+ boolean addArcFurnaceRecipe(ItemStack aInput, ItemStack[] aOutputs, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the Arc Furnace. (up to 4 Outputs)
+ */
+ @Deprecated
+ boolean addArcFurnaceRecipe(ItemStack aInput, ItemStack[] aOutputs, int[] aChances, int aDuration, int aEUt,
+ boolean hidden);
+
+ /**
+ * Adds a Recipe for the GT Pulveriser. (up to 4 Outputs)
+ */
+ @Deprecated
+ boolean addPulveriserRecipe(ItemStack aInput, ItemStack[] aOutputs, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Adds a Recipe for the GT Pulveriser. (up to 4 Outputs)
+ */
+ @Deprecated
+ boolean addPulveriserRecipe(ItemStack aInput, ItemStack[] aOutputs, int[] aChances, int aDuration, int aEUt,
+ boolean hidden);
+
+ /**
+ * Adds a Distillation Tower Recipe Every Fluid also gets separate distillation recipes
+ *
+ * @param aInput must be != null
+ * @param aOutputs must be != null 1-5 Fluids
+ * @param aOutput2 can be null
+ */
+ @Deprecated
+ boolean addUniversalDistillationRecipe(FluidStack aInput, FluidStack[] aOutputs, ItemStack aOutput2, int aDuration,
+ int aEUt);
+
+ @Deprecated
+ boolean addUniversalDistillationRecipewithCircuit(FluidStack aInput, ItemStack[] aCircuit, FluidStack[] aOutputs,
+ ItemStack aOutput2, int aDuration, int aEUt);
+
+ /**
+ * Adds Pyrolyse Recipe
+ *
+ * @param aInput input item stack
+ * @param aFluidInput fluid input
+ * @param intCircuit circuit index
+ * @param aOutput output item stack
+ * @param aFluidOutput fluid output
+ * @param aDuration recipe duration
+ * @param aEUt recipe EU/t expenditure
+ *
+ * @return if the recipe was successfully added
+ */
+ @Deprecated
+ boolean addPyrolyseRecipe(ItemStack aInput, FluidStack aFluidInput, int intCircuit, ItemStack aOutput,
+ FluidStack aFluidOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds Oil Cracking Recipe
+ *
+ * @param aInput input item stack
+ * @param aOutput output item stack
+ * @param aDuration recipe duration
+ * @param aEUt recipe EU/t expenditure
+ */
+ @Deprecated
+ boolean addCrackingRecipe(FluidStack aInput, FluidStack aOutput, int aDuration, int aEUt);
+
+ /**
+ * Adds Oil Cracking Recipe
+ *
+ * @param circuitConfig The circuit configuration to control cracking severity
+ * @param aInput The fluid to be cracked
+ * @param aInput2 The fluid to catalyze the cracking (typically Hydrogen or Steam)
+ * @param aOutput The cracked fluid
+ * @param aDuration recipe duration
+ * @param aEUt recipe EU/t expenditure
+ */
+ @Deprecated
+ boolean addCrackingRecipe(int circuitConfig, FluidStack aInput, FluidStack aInput2, FluidStack aOutput,
+ int aDuration, int aEUt);
+
+ /**
+ * Adds a Sound to the Sonictron9001 you should NOT call this in the preInit-Phase!
+ *
+ * @param aItemStack = The Item you want to display for this Sound
+ * @param aSoundName = The Name of the Sound in the resources/newsound-folder like Vanillasounds
+ * @return true if the Sound got added, otherwise false.
+ */
+ @Deprecated
+ boolean addSonictronSound(ItemStack aItemStack, String aSoundName);
+
+ @Deprecated
+ boolean addChemicalBathRecipe(ItemStack aInput, FluidStack aBathingFluid, ItemStack aOutput1, ItemStack aOutput2,
+ ItemStack aOutput3, FluidStack aFluidOutput, int[] aChances, int aDuration, int aEUt);
+
+ /**
+ * Add a Nano Forge Recipe. The Nano Forge's main use is to make nanites/nanorobots. Tier 1 Nano Forge - Can make
+ * partly biological, partly metal nanites TIer 2 Nano Forge - Can make mostly metal nanites with some biological
+ * aspects TIer 3 Nano Forge - Can make nanites entierly out of metal
+ *
+ * @param aInputs must not be null
+ * @param aFluidInputs can be null
+ * @param aOutputs must not be null, the nanite or other output
+ * @param aFluidOutputs can be null
+ * @param aChances can be null
+ * @param aDuration recipe duration
+ * @param aEUt recipe EU/t expenditure
+ * @param aSpecialValue defines the tier of nano forge required.
+ *
+ */
+ @Deprecated
+ boolean addNanoForgeRecipe(ItemStack[] aInputs, FluidStack[] aFluidInputs, ItemStack[] aOutputs,
+ FluidStack[] aFluidOutputs, int[] aChances, int aDuration, int aEUt, int aSpecialValue);
+
+ /**
+ * Add a breeder cell.
+ *
+ * @param input raw stack. should be undamaged.
+ * @param output breed output
+ * @param heatMultiplier bonus progress per neutron pulse per heat step
+ * @param heatStep divisor for hull heat
+ * @param reflector true if also acts as a neutron reflector, false otherwise.
+ * @param requiredPulses progress required to complete breeding
+ * @return added fake recipe
+ */
+ GT_Recipe addIC2ReactorBreederCell(ItemStack input, ItemStack output, boolean reflector, int heatStep,
+ int heatMultiplier, int requiredPulses);
+
+ /**
+ * Add a fuel cell.
+ *
+ * @param input raw stack. should be undamaged.
+ * @param output depleted stack
+ * @param aMox true if has mox behavior, false if uranium behavior.
+ * @param aHeat inherent heat output multiplier of the fuel material. should not add the extra heat from being a
+ * multi-cell!
+ * @param aEnergy inherent energy output multiplier of the fuel material. should not add the extra energy from being
+ * a multi-cell!
+ * @param aCells cell count
+ * @return added fake recipe
+ */
+ GT_Recipe addIC2ReactorFuelCell(ItemStack input, ItemStack output, boolean aMox, float aHeat, float aEnergy,
+ int aCells);
+
+ GT_RecipeBuilder stdBuilder();
+}
diff --git a/src/main/java/gregtech/api/interfaces/internal/IIC2TileEntity.java b/src/main/java/gregtech/api/interfaces/internal/IIC2TileEntity.java
new file mode 100644
index 0000000000..ce9b4c4282
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/internal/IIC2TileEntity.java
@@ -0,0 +1,14 @@
+package gregtech.api.interfaces.internal;
+
+import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords;
+import ic2.api.energy.tile.IEnergySink;
+import ic2.api.energy.tile.IEnergySource;
+import ic2.api.tile.IEnergyStorage;
+
+/**
+ * A simple compound Interface for generic EnergyTileEntities. I don't want to have imports of the IC2-API in my
+ * main-code
+ */
+public interface IIC2TileEntity extends IEnergyStorage, IEnergySink, IEnergySource, IHasWorldObjectAndCoords {
+ //
+}
diff --git a/src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java b/src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java
new file mode 100644
index 0000000000..5d99f83689
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java
@@ -0,0 +1,46 @@
+package gregtech.api.interfaces.internal;
+
+import java.util.List;
+
+import net.minecraft.block.Block;
+import net.minecraft.enchantment.Enchantment;
+import net.minecraft.item.ItemStack;
+
+import gregtech.api.enums.TC_Aspects;
+import gregtech.api.enums.TC_Aspects.TC_AspectStack;
+
+public interface IThaumcraftCompat {
+
+ int RESEARCH_TYPE_NORMAL = 0, RESEARCH_TYPE_SECONDARY = 1, RESEARCH_TYPE_FREE = 2, RESEARCH_TYPE_HIDDEN = 4,
+ RESEARCH_TYPE_VIRTUAL = 8, RESEARCH_TYPE_ROUND = 16, RESEARCH_TYPE_SPECIAL = 32, RESEARCH_TYPE_AUTOUNLOCK = 64;
+
+ /**
+ * The Research Keys of GT
+ */
+ String IRON_TO_STEEL = "GT_IRON_TO_STEEL", FILL_WATER_BUCKET = "GT_FILL_WATER_BUCKET",
+ WOOD_TO_CHARCOAL = "GT_WOOD_TO_CHARCOAL", TRANSZINC = "GT_TRANSZINC", TRANSNICKEL = "GT_TRANSNICKEL",
+ TRANSCOBALT = "GT_TRANSCOBALT", TRANSBISMUTH = "GT_TRANSBISMUTH", TRANSANTIMONY = "GT_TRANSANTIMONY",
+ TRANSCUPRONICKEL = "GT_TRANSCUPRONICKEL", TRANSBATTERYALLOY = "GT_TRANSBATTERYALLOY",
+ TRANSSOLDERINGALLOY = "GT_TRANSSOLDERINGALLOY", TRANSBRASS = "GT_TRANSBRASS", TRANSBRONZE = "GT_TRANSBRONZE",
+ TRANSINVAR = "GT_TRANSINVAR", TRANSELECTRUM = "GT_TRANSELECTRUM", TRANSALUMINIUM = "GT_TRANSALUMINIUM",
+ CRYSTALLISATION = "GT_CRYSTALLISATION", ADVANCEDENTROPICPROCESSING = "GT_ADVANCEDENTROPICPROCESSING", // unused
+ ADVANCEDMETALLURGY = "GT_ADVANCEDMETALLURGY";
+
+ boolean registerPortholeBlacklistedBlock(Block aBlock);
+
+ boolean registerThaumcraftAspectsToItem(ItemStack aStack, List<TC_AspectStack> aAspects, boolean aAdditive);
+
+ boolean registerThaumcraftAspectsToItem(ItemStack aStack, List<TC_AspectStack> aAspects, String aOreDict);
+
+ Object addCrucibleRecipe(String aResearch, Object aInput, ItemStack aOutput, List<TC_AspectStack> aAspects);
+
+ Object addInfusionRecipe(String aResearch, ItemStack aMainInput, ItemStack[] aSideInputs, ItemStack aOutput,
+ int aInstability, List<TC_Aspects.TC_AspectStack> aAspects);
+
+ Object addInfusionEnchantmentRecipe(String aResearch, Enchantment aEnchantment, int aInstability,
+ List<TC_Aspects.TC_AspectStack> aAspects, ItemStack[] aSideInputs);
+
+ Object addResearch(String aResearch, String aName, String aText, String[] aParentResearches, String aCategory,
+ ItemStack aIcon, int aComplexity, int aType, int aX, int aY, List<TC_AspectStack> aAspects,
+ ItemStack[] aResearchTriggers, Object[] aPages);
+}
diff --git a/src/main/java/gregtech/api/interfaces/internal/IUETileEntity.java b/src/main/java/gregtech/api/interfaces/internal/IUETileEntity.java
new file mode 100644
index 0000000000..7c9d487e05
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/internal/IUETileEntity.java
@@ -0,0 +1,5 @@
+package gregtech.api.interfaces.internal;
+
+public interface IUETileEntity /* extends IElectrical */ {
+ //
+}
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();
+}
diff --git a/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java b/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java
new file mode 100644
index 0000000000..22694cdafd
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java
@@ -0,0 +1,282 @@
+package gregtech.api.interfaces.modularui;
+
+import static gregtech.api.metatileentity.BaseTileEntity.BUTTON_FORBIDDEN_TOOLTIP;
+import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import net.minecraft.util.StatCollector;
+
+import com.gtnewhorizons.modularui.api.drawable.IDrawable;
+import com.gtnewhorizons.modularui.api.drawable.UITexture;
+import com.gtnewhorizons.modularui.api.math.Pos2d;
+import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder;
+import com.gtnewhorizons.modularui.api.widget.Widget;
+import com.gtnewhorizons.modularui.common.widget.ButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+
+import gregtech.api.enums.SoundResource;
+import gregtech.api.enums.VoidingMode;
+import gregtech.api.gui.modularui.GT_UITextures;
+import gregtech.api.interfaces.tileentity.IRecipeLockable;
+import gregtech.api.interfaces.tileentity.IVoidable;
+
+/**
+ * Machines implementing this interface can have logic and GUI buttons
+ * to configure various behaviors regarding multiblock.
+ * <ul>
+ * <li>Power switch</li>
+ * <li>Void protection</li>
+ * <li>Separated input buses</li>
+ * <li>Batch mode</li>
+ * <li>Recipe locking</li>
+ * </ul>
+ */
+public interface ControllerWithOptionalFeatures extends IVoidable, IRecipeLockable {
+
+ boolean isAllowedToWork();
+
+ void disableWorking();
+
+ void enableWorking();
+
+ Pos2d getPowerSwitchButtonPos();
+
+ default ButtonWidget createPowerSwitchButton(IWidgetBuilder<?> builder) {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (isAllowedToWork()) {
+ disableWorking();
+ } else {
+ enableWorking();
+ }
+ })
+ .setPlayClickSoundResource(
+ () -> isAllowedToWork() ? SoundResource.GUI_BUTTON_UP.resourceLocation
+ : SoundResource.GUI_BUTTON_DOWN.resourceLocation)
+ .setBackground(() -> {
+ if (isAllowedToWork()) {
+ return new IDrawable[] { GT_UITextures.BUTTON_STANDARD_PRESSED,
+ GT_UITextures.OVERLAY_BUTTON_POWER_SWITCH_ON };
+ } else {
+ return new IDrawable[] { GT_UITextures.BUTTON_STANDARD,
+ GT_UITextures.OVERLAY_BUTTON_POWER_SWITCH_OFF };
+ }
+ })
+ .attachSyncer(new FakeSyncWidget.BooleanSyncer(this::isAllowedToWork, val -> {
+ if (val) enableWorking();
+ else disableWorking();
+ }), builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.power_switch"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getPowerSwitchButtonPos())
+ .setSize(16, 16);
+ return (ButtonWidget) button;
+ }
+
+ Pos2d getVoidingModeButtonPos();
+
+ default ButtonWidget createVoidExcessButton(IWidgetBuilder<?> builder) {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (supportsVoidProtection()) {
+ Set<VoidingMode> allowed = getAllowedVoidingModes();
+ switch (clickData.mouseButton) {
+ case 0 -> setVoidingMode(getVoidingMode().nextInCollection(allowed));
+ case 1 -> setVoidingMode(getVoidingMode().previousInCollection(allowed));
+ }
+ widget.notifyTooltipChange();
+ }
+ })
+ .setPlayClickSound(supportsVoidProtection())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ ret.add(getVoidingMode().buttonTexture);
+ ret.add(getVoidingMode().buttonOverlay);
+ if (!supportsVoidProtection()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(
+ new FakeSyncWidget.IntegerSyncer(
+ () -> getVoidingMode().ordinal(),
+ val -> setVoidingMode(VoidingMode.fromOrdinal(val))),
+ builder)
+ .dynamicTooltip(
+ () -> Arrays.asList(
+ StatCollector.translateToLocal("GT5U.gui.button.voiding_mode"),
+ StatCollector.translateToLocal(getVoidingMode().getTransKey())))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getVoidingModeButtonPos())
+ .setSize(16, 16);
+ if (!supportsVoidProtection()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return (ButtonWidget) button;
+ }
+
+ /**
+ * @return if the multi supports input separation.
+ */
+ boolean supportsInputSeparation();
+
+ /**
+ * @return true if input separation is enabled, else false. This is getter is used for displaying the icon in the
+ * GUI
+ */
+ boolean isInputSeparationEnabled();
+
+ void setInputSeparation(boolean enabled);
+
+ default boolean getDefaultInputSeparationMode() {
+ return supportsInputSeparation();
+ }
+
+ Pos2d getInputSeparationButtonPos();
+
+ default ButtonWidget createInputSeparationButton(IWidgetBuilder<?> builder) {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (supportsInputSeparation()) {
+ setInputSeparation(!isInputSeparationEnabled());
+ }
+ })
+ .setPlayClickSound(supportsInputSeparation())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ if (isInputSeparationEnabled()) {
+ ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED);
+ if (supportsInputSeparation()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON_DISABLED);
+ }
+ } else {
+ ret.add(GT_UITextures.BUTTON_STANDARD);
+ if (supportsInputSeparation()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF_DISABLED);
+ }
+ }
+ if (!supportsInputSeparation()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(
+ new FakeSyncWidget.BooleanSyncer(this::isInputSeparationEnabled, this::setInputSeparation),
+ builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.input_separation"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getInputSeparationButtonPos())
+ .setSize(16, 16);
+ if (!supportsInputSeparation()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return (ButtonWidget) button;
+ }
+
+ /**
+ * @return if the multi supports batch mode.
+ */
+ boolean supportsBatchMode();
+
+ /**
+ * @return true if batch mode is enabled, else false. This is getter is used for displaying the icon in the GUI
+ */
+ boolean isBatchModeEnabled();
+
+ void setBatchMode(boolean enabled);
+
+ default boolean getDefaultBatchMode() {
+ return false;
+ }
+
+ Pos2d getBatchModeButtonPos();
+
+ default ButtonWidget createBatchModeButton(IWidgetBuilder<?> builder) {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (supportsBatchMode()) {
+ setBatchMode(!isBatchModeEnabled());
+ }
+ })
+ .setPlayClickSound(supportsBatchMode())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ if (isBatchModeEnabled()) {
+ ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED);
+ if (supportsBatchMode()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_ON);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_ON_DISABLED);
+ }
+ } else {
+ ret.add(GT_UITextures.BUTTON_STANDARD);
+ if (supportsBatchMode()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_OFF);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_OFF_DISABLED);
+ }
+ }
+ if (!supportsBatchMode()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(new FakeSyncWidget.BooleanSyncer(this::isBatchModeEnabled, this::setBatchMode), builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.batch_mode"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getBatchModeButtonPos())
+ .setSize(16, 16);
+ if (!supportsBatchMode()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return (ButtonWidget) button;
+ }
+
+ Pos2d getRecipeLockingButtonPos();
+
+ default ButtonWidget createLockToSingleRecipeButton(IWidgetBuilder<?> builder) {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (supportsSingleRecipeLocking()) {
+ setRecipeLocking(!isRecipeLockingEnabled());
+ }
+ })
+ .setPlayClickSound(supportsSingleRecipeLocking())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ if (isRecipeLockingEnabled()) {
+ ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED);
+ if (supportsSingleRecipeLocking()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_LOCKED);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_LOCKED_DISABLED);
+ }
+ } else {
+ ret.add(GT_UITextures.BUTTON_STANDARD);
+ if (supportsSingleRecipeLocking()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED_DISABLED);
+ }
+ }
+ if (!supportsSingleRecipeLocking()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(
+ new FakeSyncWidget.BooleanSyncer(this::isRecipeLockingEnabled, this::setRecipeLocking),
+ builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.lock_recipe"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getRecipeLockingButtonPos())
+ .setSize(16, 16);
+ if (!supportsSingleRecipeLocking()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return (ButtonWidget) button;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/modularui/IAddGregtechLogo.java b/src/main/java/gregtech/api/interfaces/modularui/IAddGregtechLogo.java
new file mode 100644
index 0000000000..12ac32c143
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/modularui/IAddGregtechLogo.java
@@ -0,0 +1,8 @@
+package gregtech.api.interfaces.modularui;
+
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+
+public interface IAddGregtechLogo {
+
+ default void addGregTechLogo(ModularWindow.Builder builder) {}
+}
diff --git a/src/main/java/gregtech/api/interfaces/modularui/IAddInventorySlots.java b/src/main/java/gregtech/api/interfaces/modularui/IAddInventorySlots.java
new file mode 100644
index 0000000000..4111848ecb
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/modularui/IAddInventorySlots.java
@@ -0,0 +1,15 @@
+package gregtech.api.interfaces.modularui;
+
+import com.gtnewhorizons.modularui.api.drawable.IDrawable;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+
+public interface IAddInventorySlots {
+
+ default void add1by1Slot(ModularWindow.Builder builder, IDrawable... background) {}
+
+ default void add2by2Slots(ModularWindow.Builder builder, IDrawable... background) {}
+
+ default void add3by3Slots(ModularWindow.Builder builder, IDrawable... background) {}
+
+ default void add4by4Slots(ModularWindow.Builder builder, IDrawable... background) {}
+}
diff --git a/src/main/java/gregtech/api/interfaces/modularui/IAddUIWidgets.java b/src/main/java/gregtech/api/interfaces/modularui/IAddUIWidgets.java
new file mode 100644
index 0000000000..1fa317b17f
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/modularui/IAddUIWidgets.java
@@ -0,0 +1,9 @@
+package gregtech.api.interfaces.modularui;
+
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+
+public interface IAddUIWidgets {
+
+ default void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {}
+}
diff --git a/src/main/java/gregtech/api/interfaces/modularui/IBindPlayerInventoryUI.java b/src/main/java/gregtech/api/interfaces/modularui/IBindPlayerInventoryUI.java
new file mode 100644
index 0000000000..426a24ad38
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/modularui/IBindPlayerInventoryUI.java
@@ -0,0 +1,9 @@
+package gregtech.api.interfaces.modularui;
+
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+
+public interface IBindPlayerInventoryUI {
+
+ void bindPlayerInventoryUI(ModularWindow.Builder builder, UIBuildContext buildContext);
+}
diff --git a/src/main/java/gregtech/api/interfaces/modularui/IGetGUITextureSet.java b/src/main/java/gregtech/api/interfaces/modularui/IGetGUITextureSet.java
new file mode 100644
index 0000000000..59aa2723c3
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/modularui/IGetGUITextureSet.java
@@ -0,0 +1,10 @@
+package gregtech.api.interfaces.modularui;
+
+import gregtech.api.gui.modularui.GUITextureSet;
+
+public interface IGetGUITextureSet {
+
+ default GUITextureSet getGUITextureSet() {
+ return null;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java b/src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java
new file mode 100644
index 0000000000..76d94ee299
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java
@@ -0,0 +1,11 @@
+package gregtech.api.interfaces.modularui;
+
+import gregtech.api.enums.Dyes;
+import gregtech.api.util.GT_Util;
+
+public interface IGetTitleColor {
+
+ default int getTitleColor() {
+ return GT_Util.getRGBaInt(Dyes.dyeWhite.getRGBA());
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IAllSidedTexturedTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IAllSidedTexturedTileEntity.java
new file mode 100644
index 0000000000..1d00aa5d76
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IAllSidedTexturedTileEntity.java
@@ -0,0 +1,24 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraft.block.Block;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.ITexture;
+
+/**
+ * Block which has same texture on all sides
+ */
+public interface IAllSidedTexturedTileEntity extends ITexturedTileEntity {
+
+ /**
+ * @return the Textures rendered by the GT Rendering
+ */
+ default ITexture[] getTexture(Block aBlock, ForgeDirection side) {
+ return getTexture(aBlock);
+ }
+
+ /**
+ * @return the Textures rendered by the GT Rendering
+ */
+ ITexture[] getTexture(Block aBlock);
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IBasicEnergyContainer.java b/src/main/java/gregtech/api/interfaces/tileentity/IBasicEnergyContainer.java
new file mode 100644
index 0000000000..37d62894bb
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IBasicEnergyContainer.java
@@ -0,0 +1,110 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+/**
+ * Interface for internal Code, which is mainly used for independent Energy conversion.
+ */
+public interface IBasicEnergyContainer extends IEnergyConnected, IHasWorldObjectAndCoords {
+
+ /**
+ * Gets if that Amount of Energy is stored inside the Machine. It is used for checking the contained Energy before
+ * consuming it. If this returns false, it will also give a Message inside the Scanner, that this Machine doesn't
+ * have enough Energy.
+ */
+ boolean isUniversalEnergyStored(long aEnergyAmount);
+
+ /**
+ * Gets the stored electric, kinetic or steam Energy (with EU as reference Value) Always returns the largest one.
+ */
+ long getUniversalEnergyStored();
+
+ /**
+ * Gets the largest electric, kinetic or steam Energy Capacity (with EU as reference Value)
+ */
+ long getUniversalEnergyCapacity();
+
+ /**
+ * Gets the amount of Energy Packets per tick.
+ */
+ long getOutputAmperage();
+
+ /**
+ * Gets the Output in EU/p.
+ */
+ long getOutputVoltage();
+
+ /**
+ * Gets the amount of Energy Packets per tick.
+ */
+ long getInputAmperage();
+
+ /**
+ * Gets the maximum Input in EU/p.
+ */
+ long getInputVoltage();
+
+ /**
+ * Decreases the Amount of stored universal Energy. If ignoring too less Energy, then it just sets the Energy to 0
+ * and returns false.
+ */
+ boolean decreaseStoredEnergyUnits(long aEnergy, boolean aIgnoreTooLessEnergy);
+
+ /**
+ * Increases the Amount of stored electric Energy. If ignoring too much Energy, then the Energy Limit is just being
+ * ignored.
+ */
+ boolean increaseStoredEnergyUnits(long aEnergy, boolean aIgnoreTooMuchEnergy);
+
+ /**
+ * Drain Energy Call for Electricity.
+ */
+ boolean drainEnergyUnits(ForgeDirection side, long aVoltage, long aAmperage);
+
+ /**
+ * returns the amount of Electricity, accepted by this Block the last 5 ticks as Average.
+ */
+ long getAverageElectricInput();
+
+ /**
+ * returns the amount of Electricity, outputted by this Block the last 5 ticks as Average.
+ */
+ long getAverageElectricOutput();
+
+ /**
+ * returns the amount of electricity contained in this Block, in EU units!
+ */
+ long getStoredEU();
+
+ /**
+ * returns the amount of electricity containable in this Block, in EU units!
+ */
+ long getEUCapacity();
+
+ /**
+ * returns the amount of Steam contained in this Block, in EU units!
+ */
+ default long getStoredSteam() {
+ return 0;
+ }
+
+ /**
+ * returns the amount of Steam containable in this Block, in EU units!
+ */
+ default long getSteamCapacity() {
+ return 0;
+ }
+
+ /**
+ * Increases stored Energy. Energy Base Value is in EU, even though it's Steam!
+ *
+ * @param aEnergy The Energy to add to the Machine.
+ * @param aIgnoreTooMuchEnergy if it shall ignore if it has too much Energy.
+ * @return if it was successful
+ * <p/>
+ * And yes, you can't directly decrease the Steam of a Machine. That is done by decreaseStoredEnergyUnits
+ */
+ default boolean increaseStoredSteam(long aEnergy, boolean aIgnoreTooMuchEnergy) {
+ return false;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java
new file mode 100644
index 0000000000..ec760dd346
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java
@@ -0,0 +1,27 @@
+package gregtech.api.interfaces.tileentity;
+
+import gregtech.api.enums.Dyes;
+import gregtech.api.util.GT_Util;
+
+public interface IColoredTileEntity {
+
+ /**
+ * @return 0 - 15 are Colors, while -1 means uncolored
+ */
+ byte getColorization();
+
+ /**
+ * Sets the Color Modulation of the Block
+ *
+ * @param aColor the Color you want to set it to. -1 for reset.
+ */
+ byte setColorization(byte aColor);
+
+ /**
+ * @return Actual color shown on GUI
+ */
+ default int getGUIColorization() {
+ return GT_Util
+ .getRGBInt((getColorization() != -1 ? Dyes.get(getColorization()) : Dyes.MACHINE_METAL).getRGBA());
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java b/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java
new file mode 100644
index 0000000000..8834678984
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java
@@ -0,0 +1,91 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.util.GT_CoverBehavior;
+import gregtech.api.util.GT_CoverBehaviorBase;
+import gregtech.api.util.ISerializableObject;
+import gregtech.common.covers.CoverInfo;
+
+public interface ICoverable extends IRedstoneTileEntity, IHasInventory, IBasicEnergyContainer {
+
+ boolean canPlaceCoverIDAtSide(ForgeDirection side, int aID);
+
+ boolean canPlaceCoverItemAtSide(ForgeDirection side, ItemStack aCover);
+
+ boolean dropCover(ForgeDirection side, ForgeDirection droppedSide, boolean aForced);
+
+ @Deprecated
+ void setCoverDataAtSide(ForgeDirection side, int aData);
+
+ default void setCoverDataAtSide(ForgeDirection side, ISerializableObject aData) {
+ if (aData instanceof ISerializableObject.LegacyCoverData)
+ setCoverDataAtSide(side, ((ISerializableObject.LegacyCoverData) aData).get());
+ }
+
+ void setCoverIdAndDataAtSide(ForgeDirection side, int aId, ISerializableObject aData);
+
+ void setCoverIDAtSide(ForgeDirection side, int aID);
+
+ boolean setCoverIDAtSideNoUpdate(ForgeDirection side, int aID);
+
+ void setCoverItemAtSide(ForgeDirection side, ItemStack aCover);
+
+ @Deprecated
+ int getCoverDataAtSide(ForgeDirection side);
+
+ default CoverInfo getCoverInfoAtSide(ForgeDirection side) {
+ return null;
+ }
+
+ default ISerializableObject getComplexCoverDataAtSide(ForgeDirection side) {
+ return new ISerializableObject.LegacyCoverData(getCoverDataAtSide(side));
+ }
+
+ int getCoverIDAtSide(ForgeDirection side);
+
+ ItemStack getCoverItemAtSide(ForgeDirection side);
+
+ @Deprecated
+ GT_CoverBehavior getCoverBehaviorAtSide(ForgeDirection side);
+
+ default GT_CoverBehaviorBase<?> getCoverBehaviorAtSideNew(ForgeDirection side) {
+ return getCoverBehaviorAtSide(side);
+ }
+
+ /**
+ * For use by the regular MetaTileEntities. Returns the Cover Manipulated input Redstone. Don't use this if you are
+ * a Cover Behavior. Only for MetaTileEntities.
+ */
+ byte getInternalInputRedstoneSignal(ForgeDirection side);
+
+ /**
+ * For use by the regular MetaTileEntities. This makes it not conflict with Cover based Redstone Signals. Don't use
+ * this if you are a Cover Behavior. Only for MetaTileEntities.
+ */
+ void setInternalOutputRedstoneSignal(ForgeDirection side, byte aStrength);
+
+ /**
+ * Causes a general Cover Texture update. Sends 6 Integers to Client + causes @issueTextureUpdate()
+ */
+ void issueCoverUpdate(ForgeDirection side);
+
+ /**
+ * Receiving a packet with cover data.
+ */
+ void receiveCoverData(ForgeDirection coverSide, int coverID, int coverData);
+
+ /**
+ * Receiving a packet with cover data.
+ *
+ * @param coverSide cover side
+ * @param aPlayer the player who made the change
+ */
+ default void receiveCoverData(ForgeDirection coverSide, int aCoverID, ISerializableObject aCoverData,
+ EntityPlayerMP aPlayer) {
+ if (aCoverData instanceof ISerializableObject.LegacyCoverData)
+ receiveCoverData(coverSide, aCoverID, ((ISerializableObject.LegacyCoverData) aCoverData).get());
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IDebugableTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IDebugableTileEntity.java
new file mode 100644
index 0000000000..5208944d66
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IDebugableTileEntity.java
@@ -0,0 +1,18 @@
+package gregtech.api.interfaces.tileentity;
+
+import java.util.ArrayList;
+
+import net.minecraft.entity.player.EntityPlayer;
+
+public interface IDebugableTileEntity {
+
+ /**
+ * Returns a Debug Message, for a generic DebugItem
+ *
+ * @param aPlayer the Player, who rightclicked with his Debug Item
+ * @param aLogLevel the Log Level of the Debug Item. 0 = Obvious 1 = Visible for the regular Scanner 2 = Only
+ * visible to more advanced Scanners 3 = Debug ONLY
+ * @return a String-Array containing the DebugInfo, every Index is a separate line (0 = first Line)
+ */
+ ArrayList<String> getDebugInfo(EntityPlayer aPlayer, int aLogLevel);
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IDigitalChest.java b/src/main/java/gregtech/api/interfaces/tileentity/IDigitalChest.java
new file mode 100644
index 0000000000..9a08e65b78
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IDigitalChest.java
@@ -0,0 +1,33 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraft.item.ItemStack;
+
+/**
+ * You are allowed to include this File in your Download, as i will not change it.
+ */
+public interface IDigitalChest extends IHasWorldObjectAndCoords {
+
+ /**
+ * Is this even a TileEntity of a Digital Chest? I need things like this Function for MetaTileEntities, you MUST
+ * check this!!! Do not assume that it's a Digital Chest or similar Device, when it just implements this Interface.
+ */
+ boolean isDigitalChest();
+
+ /**
+ * Gives an Array of Stacks with Size (of all the Data-stored Items) of the correspondent Item kinds (regular
+ * QChests have only one) Does NOT include the 64 "ready" Items inside the Slots, and neither the 128 Items in the
+ * overflow Buffer.
+ */
+ ItemStack[] getStoredItemData();
+
+ /**
+ * A generic Interface for just setting the amount of contained Items
+ */
+ void setItemCount(int aCount);
+
+ /**
+ * Gets the maximum Item count for this QChest alike Storage. This applies to the Data-Storage, not for the up to
+ * 192 buffered Items!
+ */
+ int getMaxItemCount();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConductor.java b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConductor.java
new file mode 100644
index 0000000000..e285c6f0e3
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConductor.java
@@ -0,0 +1,41 @@
+package gregtech.api.interfaces.tileentity;
+
+import gregtech.api.enums.Materials;
+
+/**
+ * Informative Class for Cables. Not used for now.
+ * <p/>
+ * Not all Data might be reliable. This is just for Information sake.
+ */
+public interface IEnergyConductor extends IEnergyConnected, IHasWorldObjectAndCoords {
+
+ /**
+ * @return if this is actually a Cable. (you must check this)
+ */
+ boolean isConductor();
+
+ /**
+ * @return the maximum Voltage of the Cable.
+ */
+ long getMaxVoltage();
+
+ /**
+ * @return the maximum Amperage of the Cable, per Wire.
+ */
+ long getMaxAmperage();
+
+ /**
+ * @return the Loss of the Cable, per Meter.
+ */
+ long getLossPerMeter();
+
+ /**
+ * @return the Material the Cable consists of. (may return Materials._NULL)
+ */
+ Materials getCableMaterial();
+
+ /**
+ * @return the Material the Cable Insulation consists of. (may return Materials._NULL)
+ */
+ Materials getInsulationMaterial();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
new file mode 100644
index 0000000000..91a9759e47
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
@@ -0,0 +1,178 @@
+package gregtech.api.interfaces.tileentity;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import cofh.api.energy.IEnergyReceiver;
+import gregtech.api.GregTech_API;
+import gregtech.api.logic.PowerLogic;
+import gregtech.api.logic.interfaces.PowerLogicHost;
+import gregtech.api.util.GT_Utility;
+import ic2.api.energy.tile.IEnergySink;
+
+/**
+ * Interface for getting Connected to the GregTech Energy Network.
+ * <p/>
+ * This is all you need to connect to the GT Network. IColoredTileEntity is needed for not connecting differently
+ * coloured Blocks to each other. IHasWorldObjectAndCoords is needed for the InWorld related Stuff. @BaseTileEntity does
+ * implement most of that Interface.
+ */
+public interface IEnergyConnected extends IColoredTileEntity {
+
+ /**
+ * Inject Energy Call for Electricity. Gets called by EnergyEmitters to inject Energy into your Block
+ * <p/>
+ * Note: you have to check for @inputEnergyFrom because the Network won't check for that by itself.
+ *
+ * @param side 0 - 5 = Vanilla Directions of YOUR Block the Energy gets inserted to. 6 = No specific Side (don't do
+ * Side checks for this Side)
+ * @return amount of used Amperes. 0 if not accepted anything.
+ */
+ long injectEnergyUnits(ForgeDirection side, long aVoltage, long aAmperage);
+
+ /**
+ * Sided Energy Input
+ */
+ boolean inputEnergyFrom(ForgeDirection side);
+
+ default boolean inputEnergyFrom(ForgeDirection side, boolean waitForActive) {
+ return inputEnergyFrom(side);
+ }
+
+ /**
+ * Sided Energy Output
+ */
+ boolean outputsEnergyTo(ForgeDirection side);
+
+ default boolean outputsEnergyTo(ForgeDirection side, boolean waitForActive) {
+ return outputsEnergyTo(side);
+ }
+
+ /**
+ * Utility for the Network
+ */
+ final class Util {
+
+ // TODO: Deduplicate code by rewokring the Enet system using the GTCEu one as inspiration - BlueWeabo
+ /**
+ * Emits Energy to the E-net. Also compatible with adjacent IC2 TileEntities.
+ *
+ * @return the used Amperage.
+ */
+ public static long emitEnergyToNetwork(long voltage, long amperage, IEnergyConnected emitter) {
+ long usedAmperes = 0;
+ if (!(emitter instanceof IHasWorldObjectAndCoords emitterTile)) {
+ return 0;
+ }
+
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ if (usedAmperes > amperage) break;
+ if (!emitter.outputsEnergyTo(side)) {
+ continue;
+ }
+
+ final ForgeDirection oppositeSide = Objects.requireNonNull(side.getOpposite());
+ final TileEntity tTileEntity = emitterTile.getTileEntityAtSide(side);
+ if (tTileEntity instanceof PowerLogicHost host) {
+
+ final PowerLogic logic = host.getPowerLogic(oppositeSide);
+ if (logic == null || logic.isEnergyReceiver()) {
+ continue;
+ }
+
+ usedAmperes += logic.injectEnergy(voltage, amperage - usedAmperes);
+ } else if (tTileEntity instanceof IEnergyConnected energyConnected) {
+ if (emitter.getColorization() >= 0) {
+ final byte tColor = energyConnected.getColorization();
+ if (tColor >= 0 && tColor != emitter.getColorization()) continue;
+ }
+ usedAmperes += energyConnected.injectEnergyUnits(oppositeSide, voltage, amperage - usedAmperes);
+
+ } else if (tTileEntity instanceof IEnergySink sink) {
+ if (sink.acceptsEnergyFrom((TileEntity) emitter, oppositeSide)) {
+ while (amperage > usedAmperes && sink.getDemandedEnergy() > 0
+ && sink.injectEnergy(oppositeSide, voltage, voltage) < voltage) usedAmperes++;
+ }
+ } else if (GregTech_API.mOutputRF && tTileEntity instanceof IEnergyReceiver receiver) {
+ final int rfOut = GT_Utility.safeInt(voltage * GregTech_API.mEUtoRF / 100);
+ if (receiver.receiveEnergy(oppositeSide, rfOut, true) == rfOut) {
+ receiver.receiveEnergy(oppositeSide, rfOut, false);
+ usedAmperes++;
+ }
+ }
+ }
+ return usedAmperes;
+ }
+
+ /**
+ * Same as {@link #emitEnergyToNetwork(long, long, IEnergyConnected)}, but instead we remove the energy directly from the logic itself.
+ * @param emitter The host, which is trying to emit energy in the network
+ * @param outputSide side from where energy is being outputted to. If its {@link ForgeDirection#UNKNOWN} then it doesn't emit energy to the network
+ */
+ public static void emitEnergyToNetwork(@Nonnull final PowerLogicHost emitter, @Nonnull final ForgeDirection outputSide) {
+ if (outputSide == ForgeDirection.UNKNOWN) return;
+ final PowerLogic emitterLogic = emitter.getPowerLogic();
+ long usedAmperes = 0;
+ long voltage = emitterLogic.getVoltage();
+ long amperage = emitterLogic.getMaxAmperage();
+ if (!(emitter instanceof final IHasWorldObjectAndCoords emitterTile)) {
+ return;
+ }
+ // We need to make sure we can actually output energy on this side. This is more of a safety check.
+ if (emitter.getPowerLogic(outputSide) == null) {
+ return;
+ }
+
+ final ForgeDirection oppositeSide = Objects.requireNonNull(outputSide.getOpposite());
+ final TileEntity tileEntity = emitterTile.getTileEntityAtSide(outputSide);
+ if (tileEntity instanceof PowerLogicHost host) {
+
+ final PowerLogic logic = host.getPowerLogic(oppositeSide);
+ if (logic == null || logic.isEnergyReceiver()) {
+ return;
+ }
+
+ usedAmperes += logic.injectEnergy(voltage, amperage);
+ emitterLogic.removeEnergyUnsafe(usedAmperes * voltage);
+ return;
+ }
+
+ if (tileEntity instanceof IEnergyConnected energyConnected) {
+ if (emitter instanceof IColoredTileEntity coloredEmitter && coloredEmitter.getColorization() >= 0) {
+ final byte tColor = energyConnected.getColorization();
+ if (tColor >= 0 && tColor != coloredEmitter.getColorization()) {
+ return;
+ }
+ }
+ usedAmperes += energyConnected.injectEnergyUnits(oppositeSide, voltage, amperage - usedAmperes);
+ emitterLogic.removeEnergyUnsafe(usedAmperes * voltage);
+ return;
+ }
+
+ if (tileEntity instanceof IEnergySink sink) {
+ if (sink.acceptsEnergyFrom((TileEntity) emitter, oppositeSide)) {
+ while (amperage > usedAmperes && sink.getDemandedEnergy() > 0
+ && sink.injectEnergy(oppositeSide, voltage, voltage) < voltage) {
+ usedAmperes++;
+ }
+ emitterLogic.removeEnergyUnsafe(usedAmperes * voltage);
+ return;
+ }
+ }
+
+ if (GregTech_API.mOutputRF && tileEntity instanceof IEnergyReceiver receiver) {
+ final int rfOut = GT_Utility.safeInt(voltage * GregTech_API.mEUtoRF / 100);
+ if (receiver.receiveEnergy(oppositeSide, rfOut, true) == rfOut) {
+ receiver.receiveEnergy(oppositeSide, rfOut, false);
+ usedAmperes++;
+ emitterLogic.removeEnergyUnsafe(usedAmperes * voltage);
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IFibreConnected.java b/src/main/java/gregtech/api/interfaces/tileentity/IFibreConnected.java
new file mode 100644
index 0000000000..2f7f26e723
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IFibreConnected.java
@@ -0,0 +1,34 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+/**
+ * This File has just internal Information about the Fibre Redstone State of a TileEntity
+ */
+public interface IFibreConnected extends IColoredTileEntity, IHasWorldObjectAndCoords {
+
+ /**
+ * If this Blocks accepts Fibre from this Side
+ */
+ void inputFibreFrom(ForgeDirection side);
+
+ /**
+ * If this Blocks emits Fibre to this Side
+ */
+ void outputsFibreTo(ForgeDirection side);
+
+ /**
+ * Sets the Signal this Blocks outputs to this Fibre Color
+ */
+ void setFibreOutput(ForgeDirection side, byte aColor, byte aRedstoneStrength);
+
+ /**
+ * Gets the Signal this Blocks outputs to this Fibre Color
+ */
+ byte getFibreOutput(ForgeDirection side, byte aColor);
+
+ /**
+ * Gets the Signal this Blocks receives from this Fibre Color
+ */
+ byte getFibreInput(ForgeDirection side, byte aColor);
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IGTEnet.java b/src/main/java/gregtech/api/interfaces/tileentity/IGTEnet.java
new file mode 100644
index 0000000000..77b894fea7
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IGTEnet.java
@@ -0,0 +1,19 @@
+package gregtech.api.interfaces.tileentity;
+
+public interface IGTEnet {
+
+ /**
+ * @return true if this Device consumes Energy at all
+ */
+ default boolean isEnetInput() {
+ return false;
+ }
+
+ /**
+ *
+ * @return true if this Device emits Energy at all
+ */
+ default boolean isEnetOutput() {
+ return false;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IGearEnergyTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IGearEnergyTileEntity.java
new file mode 100644
index 0000000000..7eeee90c8c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IGearEnergyTileEntity.java
@@ -0,0 +1,21 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+public interface IGearEnergyTileEntity {
+
+ /**
+ * If Rotation Energy can be accepted on this Side. This means that the Gear/Axle will connect to this Side, and can
+ * cause the Gear/Axle to stop if the Energy isn't accepted.
+ */
+ boolean acceptsRotationalEnergy(ForgeDirection side);
+
+ /**
+ * Inject Energy Call for Rotational Energy. Rotation Energy can't be stored, this is just for things like internal
+ * Dynamos, which convert it into Energy, or into Progress.
+ *
+ * @param side inject to this side
+ * @param aSpeed Positive = Clockwise, Negative = Counterclockwise
+ */
+ boolean injectRotationalEnergy(ForgeDirection side, long aSpeed, long aEnergy);
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IGregTechDeviceInformation.java b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechDeviceInformation.java
new file mode 100644
index 0000000000..001ed44825
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechDeviceInformation.java
@@ -0,0 +1,22 @@
+package gregtech.api.interfaces.tileentity;
+
+/**
+ * You are allowed to include this File in your Download, as i will not change it.
+ */
+public interface IGregTechDeviceInformation {
+
+ /**
+ * Is this even a TileEntity which allows GregTech Sensor Kits? I need things like this Function for
+ * MetaTileEntities, you MUST check this!!! Do not assume that it's a Information returning Device, when it just
+ * implements this Interface.
+ */
+ boolean isGivingInformation();
+
+ /**
+ * Up to 8 Strings can be returned. Note: If you insert "\\\\" in the String it tries to translate seperate Parts of
+ * the String instead of the String as a whole.
+ *
+ * @return an Array of Information Strings. Don't return null!
+ */
+ String[] getInfoData();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java
new file mode 100644
index 0000000000..d8231ee544
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java
@@ -0,0 +1,206 @@
+package gregtech.api.interfaces.tileentity;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.IFluidHandler;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.interfaces.IDescribable;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.modularui.IAddInventorySlots;
+import gregtech.api.interfaces.modularui.IGetGUITextureSet;
+import gregtech.api.util.shutdown.ShutDownReason;
+import gregtech.common.blocks.GT_Block_Machines;
+
+/**
+ * A simple compound Interface for all my TileEntities.
+ * <p/>
+ * Also delivers most of the Information about my TileEntities.
+ * <p/>
+ * It can cause Problems to include this Interface!
+ */
+public interface IGregTechTileEntity extends ITexturedTileEntity, IGearEnergyTileEntity, ICoverable, IFluidHandler,
+ ITurnable, IGregTechDeviceInformation, IUpgradableMachine, IDigitalChest, IDescribable, IMachineBlockUpdateable,
+ IGregtechWailaProvider, IGetGUITextureSet, IAddInventorySlots {
+
+ /**
+ * gets the Error displayed on the GUI
+ */
+ int getErrorDisplayID();
+
+ /**
+ * sets the Error displayed on the GUI
+ */
+ void setErrorDisplayID(int aErrorID);
+
+ /**
+ * @return the MetaID of the Block or the MetaTileEntity ID.
+ */
+ int getMetaTileID();
+
+ /**
+ * Internal Usage only!
+ */
+ int setMetaTileID(short aID);
+
+ /**
+ * @return the MetaTileEntity which is belonging to this, or null if it doesnt has one.
+ */
+ IMetaTileEntity getMetaTileEntity();
+
+ /**
+ * Sets the MetaTileEntity. Even though this uses the Universal Interface, certain BaseMetaTileEntities only accept
+ * one kind of MetaTileEntity so only use this if you are sure its the correct one or you will get a Class cast
+ * Error.
+ *
+ * @param aMetaTileEntity a MetaTileEntity
+ */
+ void setMetaTileEntity(IMetaTileEntity aMetaTileEntity);
+
+ /**
+ * Causes a general Texture update.
+ * <p/>
+ * Only used Client Side to mark Blocks dirty.
+ */
+ void issueTextureUpdate();
+
+ /**
+ * Causes the Machine to send its initial Data, like Covers and its ID.
+ */
+ void issueClientUpdate();
+
+ /**
+ * causes Explosion. Strength in Overload-EU
+ */
+ void doExplosion(long aExplosionEU);
+
+ /**
+ * Sets the Block on Fire in all 6 Directions
+ */
+ void setOnFire();
+
+ /**
+ * Sets the Block to Fire
+ */
+ void setToFire();
+
+ /**
+ * Sets the Owner of the Machine. Returns the set Name.
+ */
+ String setOwnerName(String aName);
+
+ /**
+ * gets the Name of the Machines Owner or "Player" if not set.
+ */
+ String getOwnerName();
+
+ /**
+ * Gets the UniqueID of the Machines Owner.
+ */
+ UUID getOwnerUuid();
+
+ /**
+ * Sets the UniqueID of the Machines Owner.
+ */
+ void setOwnerUuid(UUID uuid);
+
+ /**
+ * Sets initial Values from NBT
+ *
+ * @param aNBT is the NBTTag of readFromNBT
+ * @param aID is the MetaTileEntityID
+ */
+ void setInitialValuesAsNBT(NBTTagCompound aNBT, short aID);
+
+ /**
+ * Called when leftclicking the TileEntity
+ */
+ void onLeftclick(EntityPlayer aPlayer);
+
+ /**
+ * Called when rightclicking the TileEntity
+ */
+ boolean onRightclick(EntityPlayer aPlayer, ForgeDirection side, float aX, float aY, float aZ);
+
+ float getBlastResistance(ForgeDirection side);
+
+ default void onBlockDestroyed() {}
+
+ ArrayList<ItemStack> getDrops();
+
+ /**
+ * Check if the item at the specific index should be dropped or not
+ *
+ * @param index Index that will be checked
+ * @return True if it should drop, else false
+ */
+ boolean shouldDropItemAt(int index);
+
+ /**
+ * 255 = 100%
+ */
+ int getLightOpacity();
+
+ 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);
+
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ default void onMachineBlockUpdate() {
+ if (!isDead() && getMetaTileEntity() != null && getMetaTileEntity().getBaseMetaTileEntity() == this) {
+ getMetaTileEntity().onMachineBlockUpdate();
+ }
+ }
+
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ default boolean isMachineBlockUpdateRecursive() {
+ return !isDead() && getMetaTileEntity() != null
+ && getMetaTileEntity().getBaseMetaTileEntity() == this
+ && getMetaTileEntity().isMachineBlockUpdateRecursive();
+ }
+
+ default void setShutdownStatus(boolean newStatus) {}
+
+ default void setShutDownReason(@Nonnull ShutDownReason reason) {}
+
+ /**
+ * A randomly called display update to be able to add particles or other items for display The event is proxied by
+ * the {@link GT_Block_Machines#randomDisplayTick}
+ */
+ @SideOnly(Side.CLIENT)
+ default void onRandomDisplayTick() {
+ if (getMetaTileEntity() != null && getMetaTileEntity().getBaseMetaTileEntity() == this) {
+ getMetaTileEntity().onRandomDisplayTick(this);
+ }
+ }
+
+ /**
+ * gets the time statistics used for CPU timing
+ */
+ default int[] getTimeStatistics() {
+ return null;
+ }
+
+ default void startTimeStatistics() {}
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IGregtechWailaProvider.java b/src/main/java/gregtech/api/interfaces/tileentity/IGregtechWailaProvider.java
new file mode 100644
index 0000000000..61566d82fb
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IGregtechWailaProvider.java
@@ -0,0 +1,21 @@
+package gregtech.api.interfaces.tileentity;
+
+import java.util.List;
+
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
+public interface IGregtechWailaProvider {
+
+ default void getWailaBody(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor,
+ IWailaConfigHandler config) {}
+
+ default void getWailaNBTData(final EntityPlayerMP player, final TileEntity tile, final NBTTagCompound tag,
+ final World world, int x, int y, int z) {}
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IHasInventory.java b/src/main/java/gregtech/api/interfaces/tileentity/IHasInventory.java
new file mode 100644
index 0000000000..bee1756217
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IHasInventory.java
@@ -0,0 +1,37 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+
+public interface IHasInventory extends ISidedInventory, IHasWorldObjectAndCoords {
+
+ default void markInventoryBeenModified() {}
+
+ /**
+ * if the Inventory of this TileEntity got modified this tick
+ */
+ boolean hasInventoryBeenModified();
+
+ /**
+ * if this is just a Holoslot
+ */
+ boolean isValidSlot(int aIndex);
+
+ /**
+ * Tries to add a Stack to the Slot. It doesn't matter if the Slot is valid or invalid as described at the Function
+ * above.
+ *
+ * @return true if aStack == null, then false if aIndex is out of bounds, then false if aStack cannot be added, and
+ * then true if aStack has been added
+ */
+ boolean addStackToSlot(int aIndex, ItemStack aStack);
+
+ /**
+ * Tries to add X Items of a Stack to the Slot. It doesn't matter if the Slot is valid or invalid as described at
+ * the Function above.
+ *
+ * @return true if aStack == null, then false if aIndex is out of bounds, then false if aStack cannot be added, and
+ * then true if aStack has been added
+ */
+ boolean addStackToSlot(int aIndex, ItemStack aStack, int aAmount);
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java b/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java
new file mode 100644
index 0000000000..6d81d5c401
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java
@@ -0,0 +1,190 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraft.block.Block;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ChunkCoordinates;
+import net.minecraft.world.World;
+import net.minecraft.world.biome.BiomeGenBase;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.IFluidHandler;
+
+/**
+ * This is a bunch of Functions my TileEntities provide, to make life much easier, and to get rid of internal TileEntity
+ * stuff.
+ * <p/>
+ * This also makes access to adjacent TileEntities more Efficient.
+ * <p/>
+ * Note: It doesn't have to be a TileEntity in certain cases! And only certain cases, such as the Recipe checking of the
+ * findRecipe Function.
+ */
+public interface IHasWorldObjectAndCoords {
+
+ World getWorld();
+
+ int getXCoord();
+
+ short getYCoord();
+
+ int getZCoord();
+
+ default ChunkCoordinates getCoords() {
+ return new ChunkCoordinates(getXCoord(), getYCoord(), getZCoord());
+ }
+
+ boolean isServerSide();
+
+ boolean isClientSide();
+
+ int getRandomNumber(int aRange);
+
+ TileEntity getTileEntity(int aX, int aY, int aZ);
+
+ TileEntity getTileEntityOffset(int aX, int aY, int aZ);
+
+ TileEntity getTileEntityAtSide(ForgeDirection side);
+
+ TileEntity getTileEntityAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ IInventory getIInventory(int aX, int aY, int aZ);
+
+ IInventory getIInventoryOffset(int aX, int aY, int aZ);
+
+ IInventory getIInventoryAtSide(ForgeDirection side);
+
+ IInventory getIInventoryAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ IFluidHandler getITankContainer(int aX, int aY, int aZ);
+
+ IFluidHandler getITankContainerOffset(int aX, int aY, int aZ);
+
+ IFluidHandler getITankContainerAtSide(ForgeDirection side);
+
+ IFluidHandler getITankContainerAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ IGregTechTileEntity getIGregTechTileEntity(int aX, int aY, int aZ);
+
+ IGregTechTileEntity getIGregTechTileEntityOffset(int aX, int aY, int aZ);
+
+ IGregTechTileEntity getIGregTechTileEntityAtSide(ForgeDirection side);
+
+ IGregTechTileEntity getIGregTechTileEntityAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ Block getBlock(int aX, int aY, int aZ);
+
+ Block getBlockOffset(int aX, int aY, int aZ);
+
+ Block getBlockAtSide(ForgeDirection side);
+
+ Block getBlockAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ byte getMetaID(int aX, int aY, int aZ);
+
+ byte getMetaIDOffset(int aX, int aY, int aZ);
+
+ byte getMetaIDAtSide(ForgeDirection side);
+
+ byte getMetaIDAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ byte getLightLevel(int aX, int aY, int aZ);
+
+ byte getLightLevelOffset(int aX, int aY, int aZ);
+
+ byte getLightLevelAtSide(ForgeDirection side);
+
+ byte getLightLevelAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ boolean getOpacity(int aX, int aY, int aZ);
+
+ boolean getOpacityOffset(int aX, int aY, int aZ);
+
+ boolean getOpacityAtSide(ForgeDirection side);
+
+ boolean getOpacityAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ boolean getSky(int aX, int aY, int aZ);
+
+ boolean getSkyOffset(int aX, int aY, int aZ);
+
+ boolean getSkyAtSide(ForgeDirection side);
+
+ boolean getSkyAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ boolean getAir(int aX, int aY, int aZ);
+
+ boolean getAirOffset(int aX, int aY, int aZ);
+
+ boolean getAirAtSide(ForgeDirection side);
+
+ boolean getAirAtSideAndDistance(ForgeDirection side, int aDistance);
+
+ BiomeGenBase getBiome();
+
+ BiomeGenBase getBiome(int aX, int aZ);
+
+ int getOffsetX(ForgeDirection side, int aMultiplier);
+
+ short getOffsetY(ForgeDirection side, int aMultiplier);
+
+ int getOffsetZ(ForgeDirection side, int aMultiplier);
+
+ /**
+ * Checks if the TileEntity is Invalid or Unloaded. Stupid Minecraft cannot do that btw.
+ */
+ boolean isDead();
+
+ /**
+ * Sends a Block Event to the Client TileEntity.
+ *
+ * @param aValue value to sync
+ */
+ void sendBlockEvent(byte aID, byte aValue);
+
+ /**
+ * @return the Time this TileEntity has been loaded.
+ */
+ long getTimer();
+
+ /**
+ * Sets the Light Level of this Block on a Scale of 0 - 15 It could be that it doesn't work. This is just for
+ * convenience.
+ */
+ void setLightValue(byte aLightValue);
+
+ /**
+ * Function of the regular TileEntity
+ */
+ void writeToNBT(NBTTagCompound aNBT);
+
+ /**
+ * Function of the regular TileEntity
+ */
+ void readFromNBT(NBTTagCompound aNBT);
+
+ /**
+ * Function of the regular TileEntity
+ */
+ boolean isInvalidTileEntity();
+
+ /**
+ * Opens the GUI with this ID of this MetaTileEntity
+ *
+ * @deprecated Use ModularUI
+ */
+ @Deprecated
+ default boolean openGUI(EntityPlayer aPlayer, int aID) {
+ return false;
+ }
+
+ /**
+ * Opens the GUI with the ID = 0 of this TileEntity
+ *
+ * @deprecated Use ModularUI
+ */
+ @Deprecated
+ default boolean openGUI(EntityPlayer aPlayer) {
+ return false;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IIC2Enet.java b/src/main/java/gregtech/api/interfaces/tileentity/IIC2Enet.java
new file mode 100644
index 0000000000..971558c092
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IIC2Enet.java
@@ -0,0 +1,17 @@
+package gregtech.api.interfaces.tileentity;
+
+/**
+ * IC2 Energy Compat
+ */
+public interface IIC2Enet {
+
+ /**
+ * Should this tile/block join the ic2 enet
+ */
+ boolean shouldJoinIc2Enet();
+
+ /**
+ * Update the ic2 enet
+ */
+ void doEnetUpdate();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java b/src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java
new file mode 100644
index 0000000000..f772c1ee69
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java
@@ -0,0 +1,24 @@
+package gregtech.api.interfaces.tileentity;
+
+/**
+ * You are allowed to include this File in your Download, as i will not change it. Simple Interface for Machines, which
+ * need my Machine Blocks for MultiBlockStructures.
+ * <p/>
+ * Every Machine implementing this Interface will conduct Machine updates.
+ */
+public interface IMachineBlockUpdateable {
+
+ /**
+ * 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.
+ */
+ void onMachineBlockUpdate();
+
+ /**
+ * Should recurse?
+ */
+ default boolean isMachineBlockUpdateRecursive() {
+ return true;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IMachineProgress.java b/src/main/java/gregtech/api/interfaces/tileentity/IMachineProgress.java
new file mode 100644
index 0000000000..83570fedcc
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IMachineProgress.java
@@ -0,0 +1,96 @@
+package gregtech.api.interfaces.tileentity;
+
+import javax.annotation.Nonnull;
+
+import gregtech.api.util.shutdown.ShutDownReason;
+import gregtech.api.util.shutdown.ShutDownReasonRegistry;
+
+/**
+ * For Machines which have Progress
+ */
+public interface IMachineProgress extends IHasWorldObjectAndCoords {
+
+ /**
+ * returns the Progress this Machine has made. Warning, this can also be negative!
+ */
+ int getProgress();
+
+ /**
+ * returns the Progress the Machine needs to complete its task.
+ */
+ int getMaxProgress();
+
+ /**
+ * Manually increases the Progress of the Machine by vent cover.
+ */
+ boolean increaseProgress(int aProgressAmountInTicks);
+
+ /**
+ * returns if the Machine currently does something.
+ */
+ boolean hasThingsToDo();
+
+ /**
+ * returns if the Machine just got enableWorking called after being disabled. Used for Translocators, which need to
+ * check if they need to transfer immediately.
+ */
+ boolean hasWorkJustBeenEnabled();
+
+ /**
+ * allows Machine to work
+ */
+ void enableWorking();
+
+ /**
+ * disallows Machine to work
+ */
+ void disableWorking();
+
+ /**
+ * if the Machine is allowed to Work
+ */
+ boolean isAllowedToWork();
+
+ default void setAllowedToWork(Boolean allowedToWork) {
+ if (allowedToWork) {
+ enableWorking();
+ } else {
+ disableWorking();
+ }
+ }
+
+ /**
+ * used to control Machines via Redstone Signal Strength by special Covers In case of 0 the Machine is very likely
+ * doing nothing, or is just not being controlled at all.
+ */
+ default byte getWorkDataValue() {
+ return 0;
+ }
+
+ /**
+ * used to control Machines via Redstone Signal Strength by special Covers only Values between 0 and 15!
+ */
+ default void setWorkDataValue(byte aValue) {}
+
+ /**
+ * gives you the Active Status of the Machine
+ */
+ boolean isActive();
+
+ /**
+ * sets the visible Active Status of the Machine
+ */
+ void setActive(boolean aActive);
+
+ /**
+ * Indicates if the object in question was forced to shut down (i.e. loss of power)
+ */
+ default boolean wasShutdown() {
+ return false;
+ }
+
+ @Nonnull
+ default ShutDownReason getLastShutDownReason() {
+ return ShutDownReasonRegistry.NONE;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IOverclockDescriptionProvider.java b/src/main/java/gregtech/api/interfaces/tileentity/IOverclockDescriptionProvider.java
new file mode 100644
index 0000000000..495cd9def4
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IOverclockDescriptionProvider.java
@@ -0,0 +1,15 @@
+package gregtech.api.interfaces.tileentity;
+
+import javax.annotation.Nullable;
+
+import gregtech.api.objects.overclockdescriber.OverclockDescriber;
+
+/**
+ * Classes implementing this interface can provide {@link OverclockDescriber} to provide overclock behavior and NEI
+ * description.
+ */
+public interface IOverclockDescriptionProvider {
+
+ @Nullable
+ OverclockDescriber getOverclockDescriber();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IPipeRenderedTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IPipeRenderedTileEntity.java
new file mode 100644
index 0000000000..ab476449f0
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IPipeRenderedTileEntity.java
@@ -0,0 +1,18 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.ITexture;
+
+public interface IPipeRenderedTileEntity extends ICoverable, ITexturedTileEntity {
+
+ float getThickNess();
+
+ byte getConnections();
+
+ ITexture[] getTextureUncovered(ForgeDirection side);
+
+ default ITexture[] getTextureCovered(ForgeDirection side) {
+ return getTextureUncovered(side);
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java b/src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java
new file mode 100644
index 0000000000..54d178af3c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java
@@ -0,0 +1,31 @@
+package gregtech.api.interfaces.tileentity;
+
+import gregtech.api.recipe.check.SingleRecipeCheck;
+
+/**
+ * Machines implementing this interface can have logic to lock to a single recipe.
+ */
+public interface IRecipeLockable extends RecipeMapWorkable {
+
+ /**
+ * @return if this machine supports single recipe locking.
+ */
+ boolean supportsSingleRecipeLocking();
+
+ /**
+ * @return true if recipe locking is enabled, else false. This is getter is used for displaying the icon in the GUI
+ */
+ boolean isRecipeLockingEnabled();
+
+ void setRecipeLocking(boolean enabled);
+
+ default boolean getDefaultRecipeLockingMode() {
+ return false;
+ }
+
+ default SingleRecipeCheck getSingleRecipeCheck() {
+ return null;
+ }
+
+ default void setSingleRecipeCheck(SingleRecipeCheck recipeCheck) {}
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java
new file mode 100644
index 0000000000..1b280184ce
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java
@@ -0,0 +1,52 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+/**
+ * This File has just internal Information about the Redstone State of a TileEntity
+ */
+public interface IRedstoneEmitter extends IHasWorldObjectAndCoords {
+
+ /**
+ * gets the Redstone Level the TileEntity should emit to the given Output Side
+ *
+ * @param side the {@link ForgeDirection} side
+ * @return the Redstone Level the TileEntity
+ */
+ byte getOutputRedstoneSignal(ForgeDirection side);
+
+ /**
+ * sets the Redstone Level the TileEntity should emit to the given Output Side
+ * <p/>
+ * Do not use this if ICoverable is implemented. ICoverable has @getInternalOutputRedstoneSignal for Machine
+ * internal Output Redstone, so that it doesnt conflict with Cover Redstone. This sets the true Redstone Output
+ * Signal. Only Cover Behaviors should use it, not MetaTileEntities.
+ */
+ void setOutputRedstoneSignal(ForgeDirection side, byte aStrength);
+
+ /**
+ * gets the Redstone Level the TileEntity should emit to the given Output Side
+ */
+ byte getStrongOutputRedstoneSignal(ForgeDirection side);
+
+ /**
+ * sets the Redstone Level the TileEntity should emit to the given Output Side
+ * <p/>
+ * Do not use this if ICoverable is implemented. ICoverable has @getInternalOutputRedstoneSignal for Machine
+ * internal Output Redstone, so that it doesnt conflict with Cover Redstone. This sets the true Redstone Output
+ * Signal. Only Cover Behaviors should use it, not MetaTileEntities.
+ */
+ void setStrongOutputRedstoneSignal(ForgeDirection side, byte aStrength);
+
+ /**
+ * Gets the Output for the comparator on the given Side
+ */
+ byte getComparatorValue(ForgeDirection side);
+
+ /**
+ * Get the redstone output signal strength for a given side
+ */
+ default byte getGeneralRS(ForgeDirection side) {
+ return 0;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneReceiver.java b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneReceiver.java
new file mode 100644
index 0000000000..a41e9aaf7a
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneReceiver.java
@@ -0,0 +1,33 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+/**
+ * This File has just internal Information about the Redstone State of a TileEntity
+ */
+public interface IRedstoneReceiver extends IHasWorldObjectAndCoords {
+
+ /**
+ * gets the Redstone Level of the TileEntity to the given Input Side
+ * <p/>
+ * Do not use this if ICoverable is implemented. ICoverable has @getInternalInputRedstoneSignal for Machine internal
+ * Input Redstone This returns the true incoming Redstone Signal. Only Cover Behaviors should check it, not
+ * MetaTileEntities.
+ */
+ byte getInputRedstoneSignal(ForgeDirection side);
+
+ /**
+ * gets the strongest Redstone Level the TileEntity receives
+ */
+ byte getStrongestRedstone();
+
+ /**
+ * gets if the TileEntity receives Redstone
+ */
+ boolean getRedstone();
+
+ /**
+ * gets if the TileEntity receives Redstone at this Side
+ */
+ boolean getRedstone(ForgeDirection side);
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneTileEntity.java
new file mode 100644
index 0000000000..1deb5f1d7c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneTileEntity.java
@@ -0,0 +1,17 @@
+package gregtech.api.interfaces.tileentity;
+
+/**
+ * This File has just internal Information about the Redstone State of a TileEntity
+ */
+public interface IRedstoneTileEntity extends IRedstoneEmitter, IRedstoneReceiver {
+
+ /**
+ * enables/disables Redstone Output in general.
+ */
+ void setGenericRedstoneOutput(boolean aOnOff);
+
+ /**
+ * Causes a general Block update. Sends nothing to Client, just causes a Block Update.
+ */
+ void issueBlockUpdate();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/ITexturedTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/ITexturedTileEntity.java
new file mode 100644
index 0000000000..379111b07e
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/ITexturedTileEntity.java
@@ -0,0 +1,14 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraft.block.Block;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.ITexture;
+
+public interface ITexturedTileEntity {
+
+ /**
+ * @return the Textures rendered by the GT Rendering
+ */
+ ITexture[] getTexture(Block aBlock, ForgeDirection side);
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/ITurnable.java b/src/main/java/gregtech/api/interfaces/tileentity/ITurnable.java
new file mode 100644
index 0000000000..64cc8675ef
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/ITurnable.java
@@ -0,0 +1,46 @@
+package gregtech.api.interfaces.tileentity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+/**
+ * Implemented by all my Machines. However without any security checks, if the Players are even allowed to rotate it.
+ */
+public interface ITurnable {
+
+ /**
+ * Get the block's facing.
+ *
+ * @return front Block facing
+ */
+ ForgeDirection getFrontFacing();
+
+ /**
+ * Set the block's facing
+ *
+ * @param side facing to set the block to
+ */
+ void setFrontFacing(ForgeDirection side);
+
+ /**
+ * Get the block's back facing.
+ *
+ * @return opposite Block facing
+ */
+ ForgeDirection getBackFacing();
+
+ /**
+ * Determine if the wrench can be used to set the block's facing.
+ */
+ boolean isValidFacing(ForgeDirection side);
+
+ /**
+ * Get the list of valid facings
+ */
+ default boolean[] getValidFacings() {
+ final boolean[] validFacings = new boolean[6];
+ for (final ForgeDirection facing : ForgeDirection.VALID_DIRECTIONS) {
+ validFacings[facing.ordinal()] = isValidFacing(facing);
+ }
+ return validFacings;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IUpgradableMachine.java b/src/main/java/gregtech/api/interfaces/tileentity/IUpgradableMachine.java
new file mode 100644
index 0000000000..546ada0c9d
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IUpgradableMachine.java
@@ -0,0 +1,42 @@
+package gregtech.api.interfaces.tileentity;
+
+/**
+ * To access my Machines a bit easier
+ */
+public interface IUpgradableMachine extends IMachineProgress {
+
+ /**
+ * Accepts Upgrades. Some Machines have an Upgrade Limit.
+ */
+ boolean isUpgradable();
+
+ /**
+ * Accepts Muffler Upgrades
+ */
+ boolean isMufflerUpgradable();
+
+ /**
+ * Accepts Steam-Converter Upgrades
+ */
+ boolean isSteamEngineUpgradable();
+
+ /**
+ * Adds Muffler Upgrade
+ */
+ boolean addMufflerUpgrade();
+
+ /**
+ * Adds MJ-Converter Upgrade
+ */
+ boolean addSteamEngineUpgrade();
+
+ /**
+ * Does this Machine have an Muffler
+ */
+ boolean hasMufflerUpgrade();
+
+ /**
+ * Does this Machine have a Steam-Converter
+ */
+ boolean hasSteamEngineUpgrade();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IVoidable.java b/src/main/java/gregtech/api/interfaces/tileentity/IVoidable.java
new file mode 100644
index 0000000000..841fd07bba
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IVoidable.java
@@ -0,0 +1,89 @@
+package gregtech.api.interfaces.tileentity;
+
+import java.util.List;
+import java.util.Set;
+
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.FluidStack;
+
+import gregtech.api.enums.VoidingMode;
+import gregtech.api.interfaces.fluid.IFluidStore;
+
+/**
+ * Machines implementing this interface can have logic to configure whether to void excess output or not.
+ */
+public interface IVoidable {
+
+ /**
+ * @return if this machine can prevent excess item and fluid from voiding.
+ */
+ boolean supportsVoidProtection();
+
+ default Set<VoidingMode> getAllowedVoidingModes() {
+ return VoidingMode.ALL_OPTIONS;
+ }
+
+ /**
+ * @return if this machine is configured to not void excess item.
+ */
+ default boolean protectsExcessItem() {
+ return supportsVoidProtection() && getVoidingMode().protectItem;
+ }
+
+ /**
+ * @return if this machine is configured to not void excess fluid.
+ */
+ default boolean protectsExcessFluid() {
+ return supportsVoidProtection() && getVoidingMode().protectFluid;
+ }
+
+ VoidingMode getVoidingMode();
+
+ void setVoidingMode(VoidingMode mode);
+
+ default VoidingMode getDefaultVoidingMode() {
+ return supportsVoidProtection() ? VoidingMode.VOID_NONE : VoidingMode.VOID_ALL;
+ }
+
+ /**
+ * @param toOutput List of items this machine is going to output.
+ * @return List of slots available for item outputs. Null element represents empty slot.
+ */
+ List<ItemStack> getItemOutputSlots(ItemStack[] toOutput);
+
+ /**
+ * @param toOutput List of fluids this machine is going to output.
+ * @return List of slots available for fluid outputs.
+ */
+ List<? extends IFluidStore> getFluidOutputSlots(FluidStack[] toOutput);
+
+ /**
+ * @return How many slots of items this machine can output per recipe. Item outputs whose slot number
+ * exceeding this limit will be voided.
+ */
+ default int getItemOutputLimit() {
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * @return How many slots of fluids this machine can output per recipe. Fluid outputs whose slot number
+ * exceeding this limit will be voided.
+ */
+ default int getFluidOutputLimit() {
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * @return If this machine has ability to dump item outputs to ME network.
+ * This doesn't need to check if it can actually dump to ME,
+ * as this might be called every tick and cause lag.
+ */
+ boolean canDumpItemToME();
+
+ /**
+ * @return If this machine has ability to dump fluid outputs to ME network.
+ * This doesn't need to check if it can actually dump to ME,
+ * as this might be called every tick and cause lag.
+ */
+ boolean canDumpFluidToME();
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IWirelessEnergyHatchInformation.java b/src/main/java/gregtech/api/interfaces/tileentity/IWirelessEnergyHatchInformation.java
new file mode 100644
index 0000000000..fa58e5dd54
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IWirelessEnergyHatchInformation.java
@@ -0,0 +1,17 @@
+package gregtech.api.interfaces.tileentity;
+
+public interface IWirelessEnergyHatchInformation {
+
+ // This interface is solely for usage by wireless hatches/dynamos.
+
+ // Ticks between energy additions to the hatch. For a dynamo this is how many ticks between energy being consumed
+ // and added to the global energy map.
+ long ticks_between_energy_addition = 100L * 20L;
+
+ // Total number of energy additions this multi can store before it is full.
+ long number_of_energy_additions = 4L;
+
+ default long totalStorage(long tier_eu_per_tick) {
+ return tier_eu_per_tick * ticks_between_energy_addition * number_of_energy_additions;
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/RecipeMapWorkable.java b/src/main/java/gregtech/api/interfaces/tileentity/RecipeMapWorkable.java
new file mode 100644
index 0000000000..7d4db4396c
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/RecipeMapWorkable.java
@@ -0,0 +1,49 @@
+package gregtech.api.interfaces.tileentity;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.item.ItemStack;
+
+import gregtech.api.recipe.RecipeMap;
+
+/**
+ * Machines implementing this interface are capable of executing certain recipes provided by {@link RecipeMap}.
+ * They will also be automatically registered as NEI recipe catalyst for the corresponding recipemaps.
+ */
+public interface RecipeMapWorkable {
+
+ /**
+ * @return RecipeMap this machine currently can execute. In general, it's allowed to be null.
+ */
+ RecipeMap<?> getRecipeMap();
+
+ /**
+ * @return ItemStack form of this machine.
+ */
+ ItemStack getStackForm(long amount);
+
+ /**
+ * If the machine supports multiple recipemaps by switching mode, override this method so that it will be displayed
+ * as NEI recipe catalyst on all the supported recipemaps.
+ *
+ * @return List of possible {@link RecipeMap}s this machine can execute. Must not contain null element.
+ */
+ @Nonnull
+ default Collection<RecipeMap<?>> getAvailableRecipeMaps() {
+ RecipeMap<?> recipeMap = getRecipeMap();
+ if (recipeMap != null) {
+ return Collections.singletonList(recipeMap);
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * @return Priority for NEI recipe catalyst. Higher priority comes first.
+ */
+ default int getRecipeCatalystPriority() {
+ return 0;
+ }
+}