diff options
Diffstat (limited to 'src/main/java/gregtech/api/interfaces')
90 files changed, 4701 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/IDataCopyable.java b/src/main/java/gregtech/api/interfaces/IDataCopyable.java new file mode 100644 index 0000000000..9994354fa7 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/IDataCopyable.java @@ -0,0 +1,30 @@ +package gregtech.api.interfaces; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; + +public interface IDataCopyable { + + /** + * Implementation will set the type field. caller can assume the returned tag (if not null) always contains a "type" + * field + * with a value of {@link #getCopiedDataIdentifier(EntityPlayer)} + * Implementation should not try to alert player of situations that copy has failed. + * + * @return null if cannot copy (e.g. not properly configured yet) or the data to copy. + */ + NBTTagCompound getCopiedData(EntityPlayer player); + + /** + * Callee should check if the given tag is valid. + * Implementation should not try to alert player of situations that paste has failed. + * + * @return true if pasted. false otherwise. + */ + boolean pasteCopiedData(EntityPlayer player, NBTTagCompound nbt); + + /** + * @return the type identifier. this should be a constant for the given set of arguments. + */ + String getCopiedDataIdentifier(EntityPlayer player); +} 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/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/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..482b7899ab --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/IHatchElement.java @@ -0,0 +1,213 @@ +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.minecraft.block.Block; +import net.minecraftforge.common.util.ForgeDirection; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.StructureUtility; + +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() + .exclusive() + .build(); + } + + default <T2 extends T> IStructureElement<T2> newAnyOrCasing(int aCasingIndex, int aDot, Block casingBlock, + int casingMeta) { + if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException(); + return GT_StructureUtility.<T2>buildHatchAdder() + .anyOf(this) + .casingIndex(aCasingIndex) + .dot(aDot) + .continueIfSuccess() + .buildAndChain(StructureUtility.ofBlock(casingBlock, casingMeta)); + } + + 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) + .exclusive() + .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..0b647d9c01 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/IItemContainer.java @@ -0,0 +1,44 @@ +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); + + default IItemContainer hidden() { + return this; + } + + 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/IRecipeMutableAccess.java b/src/main/java/gregtech/api/interfaces/IRecipeMutableAccess.java new file mode 100644 index 0000000000..5c6d931d5a --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/IRecipeMutableAccess.java @@ -0,0 +1,18 @@ +package gregtech.api.interfaces; + +import net.minecraft.item.ItemStack; + +/** + * Mixed-in interface for recipe classes in Forge and Vanilla that allows mutating the input and output items. + */ +public interface IRecipeMutableAccess { + + /** @return Gets the current output item of the recipe */ + ItemStack gt5u$getRecipeOutputItem(); + + /** Sets a new output item on the recipe */ + void gt5u$setRecipeOutputItem(ItemStack newItem); + + /** @return The raw list or array of recipe inputs, the exact type depends on the underlying recipe type. */ + Object gt5u$getRecipeInputs(); +} 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..e3c3a8cbaa --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java @@ -0,0 +1,8 @@ +package gregtech.api.interfaces.internal; + +import gregtech.api.util.GT_RecipeBuilder; + +public interface IGT_RecipeAdder { + + 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/IItemLockable.java b/src/main/java/gregtech/api/interfaces/metatileentity/IItemLockable.java new file mode 100644 index 0000000000..65bfb416e2 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/metatileentity/IItemLockable.java @@ -0,0 +1,41 @@ +package gregtech.api.interfaces.metatileentity; + +import javax.annotation.Nullable; + +import net.minecraft.item.ItemStack; + +/** + * Implement this interface if your MetaTileEntity supports item locking. + */ +public interface IItemLockable { + + /** + * Set the locked item. + * <p> + * Implementers should make a copy of this item, as it can be either a physical item or a ghost item dragged from + * NEI. + * + * @param itemStack An item stack to lock + * @see com.gtnewhorizons.modularui.api.forge.ItemHandlerHelper#copyStackWithSize(ItemStack, int) + */ + void setLockedItem(@Nullable ItemStack itemStack); + + /** + * Get the locked item. + * + * @return an ItemStack of the locked item. Returns null if there is no locked item. + */ + @Nullable + ItemStack getLockedItem(); + + /** + * Clears the lock on the machine. + */ + void clearLock(); + + boolean isLocked(); + + default boolean acceptsItemLock() { + return false; + } +} 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..4959f8b060 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java @@ -0,0 +1,512 @@ +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.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_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(); + + /** + * 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); + + /** + * 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..66eee78822 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java @@ -0,0 +1,392 @@ +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> + * <li>Multiple machine modes</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 has more than 1 mode + */ + default boolean supportsMachineModeSwitch() { + return false; + } + + /** + * @return the current mode number. This is a getter is used for displaying the icon in the GUI + */ + default int getMachineMode() { + return 0; + } + + /** + * @return name for the current machine mode on this machine. Defaults "Unknown Mode" + */ + default String getMachineModeName() { + return "Unknown Mode"; + } + + /** + * @param index Index of machineModeIcons to pull from + * @return UITexture associated with that machineMode + */ + default UITexture getMachineModeIcon(int index) { + return null; + } + + /** + * @param index Number to set machineMode to + */ + default void setMachineMode(int index) {} + + /** + * @return Returns the next machineMode number in the sequence + */ + default int nextMachineMode() { + return 0; + } + + /** + * @return Returns whether machine supports mode switch by default + */ + default boolean getDefaultModeSwitch() { + return supportsMachineModeSwitch(); + } + + Pos2d getMachineModeSwitchButtonPos(); + + /** + * Called when the mode switch button is clicked + */ + default void onMachineModeSwitchClick() {} + + default ButtonWidget createModeSwitchButton(IWidgetBuilder<?> builder) { + if (!supportsMachineModeSwitch()) return null; + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { + if (supportsMachineModeSwitch()) { + onMachineModeSwitchClick(); + setMachineMode(nextMachineMode()); + } + }) + .setPlayClickSound(supportsMachineModeSwitch()) + .setBackground(() -> { + List<UITexture> ret = new ArrayList<>(); + if (supportsMachineModeSwitch()) { + ret.add(GT_UITextures.BUTTON_STANDARD); + ret.add(getMachineModeIcon(getMachineMode())); + } else return null; + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer(new FakeSyncWidget.IntegerSyncer(this::getMachineMode, this::setMachineMode), builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.mode_switch")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getMachineModeSwitchButtonPos()) + .setSize(16, 16); + 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; + } + + Pos2d getStructureUpdateButtonPos(); + + int getStructureUpdateTime(); + + void setStructureUpdateTime(int time); + + default ButtonWidget createStructureUpdateButton(IWidgetBuilder<?> builder) { + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { setStructureUpdateTime(1); }) + .setPlayClickSound(true) + .setBackground(() -> { + List<UITexture> ret = new ArrayList<>(); + if (getStructureUpdateTime() > -20) { + ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED); + } else { + ret.add(GT_UITextures.BUTTON_STANDARD); + } + ret.add(GT_UITextures.OVERLAY_BUTTON_STRUCTURE_UPDATE); + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer( + new FakeSyncWidget.IntegerSyncer(this::getStructureUpdateTime, this::setStructureUpdateTime), + builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.structure_update")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getStructureUpdateButtonPos()) + .setSize(16, 16); + 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..b62c3e92cf --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java @@ -0,0 +1,169 @@ +package gregtech.api.interfaces.tileentity; + +import net.minecraft.block.Block; +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(); +} 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; + } +} |