aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api
diff options
context:
space:
mode:
authorJason Mitchell <mitchej@gmail.com>2022-07-17 12:57:04 -0700
committerJason Mitchell <mitchej+github@gmail.com>2022-07-22 12:57:20 -0700
commit8c4dd7de80e06875b942b1343f2ca4895ce2d758 (patch)
tree82f9185d76899d581950cc71f2406b9bc702bcbf /src/main/java/gregtech/api
parent48e6a5fde81f33d3ff4cb2ef610c39abd33a5821 (diff)
downloadGT5-Unofficial-8c4dd7de80e06875b942b1343f2ca4895ce2d758.tar.gz
GT5-Unofficial-8c4dd7de80e06875b942b1343f2ca4895ce2d758.tar.bz2
GT5-Unofficial-8c4dd7de80e06875b942b1343f2ca4895ce2d758.zip
MultiTileEntity
Diffstat (limited to 'src/main/java/gregtech/api')
-rw-r--r--src/main/java/gregtech/api/enums/GT_Values.java8
-rw-r--r--src/main/java/gregtech/api/fluid/FluidTankGT.java444
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java603
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityBlockInternal.java134
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java35
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityContainer.java27
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityItemInternal.java303
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityRegistry.java230
-rw-r--r--src/main/java/gregtech/api/multitileentity/base/BaseMultiTileEntity.java1047
-rw-r--r--src/main/java/gregtech/api/multitileentity/base/BaseNontickableMultiTileEntity.java55
-rw-r--r--src/main/java/gregtech/api/multitileentity/base/BaseTickableMultiTileEntity.java113
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IItemUpdatable.java15
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java227
-rw-r--r--src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java283
-rw-r--r--src/main/java/gregtech/api/net/GT_Packet_TileEntity.java60
-rw-r--r--src/main/java/gregtech/api/util/GT_Util.java152
16 files changed, 3709 insertions, 27 deletions
diff --git a/src/main/java/gregtech/api/enums/GT_Values.java b/src/main/java/gregtech/api/enums/GT_Values.java
index ed22331360..5765fc42c2 100644
--- a/src/main/java/gregtech/api/enums/GT_Values.java
+++ b/src/main/java/gregtech/api/enums/GT_Values.java
@@ -1,5 +1,6 @@
package gregtech.api.enums;
+import gregtech.api.fluid.FluidTankGT;
import gregtech.api.interfaces.internal.IGT_Mod;
import gregtech.api.interfaces.internal.IGT_RecipeAdder;
import gregtech.api.net.IGT_NetworkHandler;
@@ -7,6 +8,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.oredict.OreDictionary;
import java.util.HashSet;
@@ -445,4 +448,9 @@ public class GT_Values {
public static boolean worldTickHappened = false;
public static final int[] emptyIntArray = new int[0];
+ public static final IFluidTank[] emptyFluidTank = new IFluidTank[0];
+ public static final FluidTankGT[] emptyFluidTankGT = new FluidTankGT[0];
+ public static final FluidTankInfo[] emptyFluidTankInfo = new FluidTankInfo[0];
+ public static final FluidStack[] emptyFluidStack = new FluidStack[0];
+ public static final ItemStack[] emptyItemStackArray = new ItemStack[0];
}
diff --git a/src/main/java/gregtech/api/fluid/FluidTankGT.java b/src/main/java/gregtech/api/fluid/FluidTankGT.java
new file mode 100644
index 0000000000..5df9e2638a
--- /dev/null
+++ b/src/main/java/gregtech/api/fluid/FluidTankGT.java
@@ -0,0 +1,444 @@
+package gregtech.api.fluid;
+
+import gregtech.api.util.GT_Utility;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidTank;
+
+import java.util.Map;
+
+import static com.google.common.primitives.Ints.saturatedCast;
+
+public class FluidTankGT implements IFluidTank {
+ public final FluidTankGT[] AS_ARRAY = new FluidTankGT[] {this};
+ private FluidStack mFluid;
+ private long mCapacity = 0, mAmount = 0;
+ private boolean mPreventDraining = false, mVoidExcess = false, mChangedFluids = false;
+ /** HashMap of adjustable Tank Sizes based on Fluids if needed. */
+ private Map<String, Long> mAdjustableCapacity = null;
+ private long mAdjustableMultiplier = 1;
+ /** Gives you a Tank Index in case there is multiple Tanks on a TileEntity that cares. */
+ public int mIndex = 0;
+
+ public FluidTankGT() {
+ mCapacity = Long.MAX_VALUE;
+ }
+
+ public FluidTankGT(long aCapacity) {
+ mCapacity = aCapacity;
+ }
+
+ public FluidTankGT(FluidStack aFluid) {
+ mFluid = aFluid;
+ if (aFluid != null) {
+ mCapacity = aFluid.amount;
+ mAmount = aFluid.amount;
+ }
+ }
+
+ public FluidTankGT(FluidStack aFluid, long aCapacity) {
+ mFluid = aFluid;
+ mCapacity = aCapacity;
+ mAmount = (aFluid == null ? 0 : aFluid.amount);
+ }
+
+ public FluidTankGT(FluidStack aFluid, long aAmount, long aCapacity) {
+ mFluid = aFluid;
+ mCapacity = aCapacity;
+ mAmount = (aFluid == null ? 0 : aAmount);
+ }
+
+ public FluidTankGT(Fluid aFluid, long aAmount) {
+ this(new FluidStack(aFluid, saturatedCast(aAmount)));
+ mAmount = aAmount;
+ }
+
+ public FluidTankGT(Fluid aFluid, long aAmount, long aCapacity) {
+ this(new FluidStack(aFluid, saturatedCast(aAmount)), aCapacity);
+ mAmount = aAmount;
+ }
+
+ public FluidTankGT(NBTTagCompound aNBT, String aKey, long aCapacity) {
+ this(aNBT.hasKey(aKey) ? aNBT.getCompoundTag(aKey) : null, aCapacity);
+ }
+
+ public FluidTankGT(NBTTagCompound aNBT, long aCapacity) {
+ mCapacity = aCapacity;
+ if (aNBT != null && !aNBT.hasNoTags()) {
+ mFluid = FluidStack.loadFluidStackFromNBT(aNBT);
+ mAmount = (isEmpty() ? 0 : aNBT.hasKey("LAmount") ? aNBT.getLong("LAmount") : mFluid.amount);
+ }
+ }
+
+ public FluidTankGT readFromNBT(NBTTagCompound aNBT, String aKey) {
+ if (aNBT.hasKey(aKey)) {
+ aNBT = aNBT.getCompoundTag(aKey);
+ if (aNBT != null && !aNBT.hasNoTags()) {
+ mFluid = FluidStack.loadFluidStackFromNBT(aNBT);
+ mAmount = (isEmpty() ? 0 : aNBT.hasKey("LAmount") ? aNBT.getLong("LAmount") : mFluid.amount);
+ }
+ }
+ return this;
+ }
+
+ public NBTTagCompound writeToNBT(NBTTagCompound aNBT, String aKey) {
+ if (mFluid != null && (mPreventDraining || mAmount > 0)) {
+ final NBTTagCompound tNBT = new NBTTagCompound();
+ mFluid.amount = (int) mAmount;
+ aNBT.setTag(aKey, mFluid.writeToNBT(tNBT));
+ if (mAmount > Integer.MAX_VALUE) tNBT.setLong("LAmount", mAmount);
+ } else {
+ aNBT.removeTag(aKey);
+ }
+ return aNBT;
+ }
+
+ public FluidStack drain(int aDrained) {
+ return drain(aDrained, true);
+ }
+
+ @Override
+ public FluidStack drain(int aDrained, boolean aDoDrain) {
+ if (isEmpty() || aDrained <= 0) return null;
+ if (mAmount < aDrained) aDrained = (int)mAmount;
+ final FluidStack rFluid = new FluidStack(mFluid, aDrained);
+ if (aDoDrain) {
+ mAmount -= aDrained;
+ if (mAmount <= 0) {
+ if (mPreventDraining) {
+ mAmount = 0;
+ } else {
+ setEmpty();
+ }
+ }
+ }
+ return rFluid;
+ }
+
+ public boolean drainAll(long aDrained) {
+ if (isEmpty() || mAmount < aDrained) return false;
+ mAmount -= aDrained;
+ if (mAmount <= 0) {
+ if (mPreventDraining) {
+ mAmount = 0;
+ } else {
+ setEmpty();
+ }
+ }
+ return true;
+ }
+
+ public long remove(long aDrained) {
+ if (isEmpty() || mAmount <= 0 || aDrained <= 0) return 0;
+ if (mAmount < aDrained) aDrained = mAmount;
+ mAmount -= aDrained;
+ if (mAmount <= 0) {
+ if (mPreventDraining) {
+ mAmount = 0;
+ } else {
+ setEmpty();
+ }
+ }
+ return aDrained;
+ }
+
+ public long add(long aFilled) {
+ if (isEmpty() || aFilled <= 0) return 0;
+ final long tCapacity = capacity();
+ if (mAmount + aFilled > tCapacity) {
+ if (!mVoidExcess) aFilled = tCapacity - mAmount;
+ mAmount = tCapacity;
+ return aFilled;
+ }
+ mAmount += aFilled;
+ return aFilled;
+ }
+
+ public long add(long aFilled, FluidStack aFluid) {
+ if (aFluid == null || aFilled <= 0) return 0;
+ if (isEmpty()) {
+ mFluid = aFluid.copy();
+ mChangedFluids = true;
+ mAmount = Math.min(capacity(aFluid), aFilled);
+ return mVoidExcess ? aFilled : mAmount;
+ }
+ return contains(aFluid) ? add(aFilled) : 0;
+ }
+
+ public int fill(FluidStack aFluid) {
+ return fill(aFluid, true);
+ }
+
+ @Override
+ public int fill(FluidStack aFluid, boolean aDoFill) {
+ if (aFluid == null) return 0;
+ if (aDoFill) {
+ if (isEmpty()) {
+ mFluid = aFluid.copy();
+ mChangedFluids = true;
+ mAmount = Math.min(capacity(aFluid), aFluid.amount);
+ return mVoidExcess ? aFluid.amount : (int) mAmount;
+ }
+ if (!contains(aFluid)) return 0;
+ final long tCapacity = capacity(aFluid);
+ long tFilled = tCapacity - mAmount;
+ if (aFluid.amount < tFilled) {
+ mAmount += aFluid.amount;
+ tFilled = aFluid.amount;
+ } else mAmount = tCapacity;
+ return mVoidExcess ? aFluid.amount : (int) tFilled;
+ }
+ return saturatedCast(isEmpty() ? mVoidExcess ? aFluid.amount : Math.min(capacity(aFluid), aFluid.amount) : contains(aFluid) ? mVoidExcess ? aFluid.amount : Math.min(capacity(aFluid) - mAmount, aFluid.amount) : 0);
+ }
+
+ public boolean canFillAll(FluidStack aFluid) {
+ return aFluid == null || aFluid.amount <= 0 || (isEmpty() ? mVoidExcess || aFluid.amount <= capacity(aFluid) : contains(aFluid) && (mVoidExcess || mAmount + aFluid.amount <= capacity(aFluid)));
+ }
+
+ public boolean canFillAll(long aAmount) {
+ return aAmount <= 0 || mVoidExcess || mAmount + aAmount <= capacity();
+ }
+
+ public boolean fillAll(FluidStack aFluid) {
+ if (aFluid == null || aFluid.amount <= 0) return true;
+ if (isEmpty()) {
+ final long tCapacity = capacity(aFluid);
+ if (aFluid.amount <= tCapacity || mVoidExcess) {
+ mFluid = aFluid.copy();
+ mChangedFluids = true;
+ mAmount = aFluid.amount;
+ if (mAmount > tCapacity) mAmount = tCapacity;
+ return true;
+ }
+ return false;
+ }
+ if (contains(aFluid)) {
+ if (mAmount + aFluid.amount <= capacity()) {
+ mAmount += aFluid.amount;
+ return true;
+ }
+ if (mVoidExcess) {
+ mAmount = capacity();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean fillAll(FluidStack aFluid, long aMultiplier) {
+ if (aMultiplier <= 0) return true;
+ if (aMultiplier == 1) return fillAll(aFluid);
+ if (aFluid == null || aFluid.amount <= 0) return true;
+ if (isEmpty()) {
+ final long tCapacity = capacity(aFluid);
+ if (aFluid.amount * aMultiplier <= tCapacity || mVoidExcess) {
+ mFluid = aFluid.copy();
+ mChangedFluids = true;
+ mAmount = aFluid.amount * aMultiplier;
+ if (mAmount > tCapacity) mAmount = tCapacity;
+ return true;
+ }
+ return false;
+ }
+ if (contains(aFluid)) {
+ if (mAmount + aFluid.amount * aMultiplier <= capacity()) {
+ mAmount += aFluid.amount * aMultiplier;
+ return true;
+ }
+ if (mVoidExcess) {
+ mAmount = capacity();
+ return true;
+ }
+ }
+ return false;
+ }
+ /** Resets Tank Contents entirely */
+ public FluidTankGT setEmpty() {
+ mFluid = null;
+ mChangedFluids = true;
+ mAmount = 0;
+ return this;
+ }
+
+ /** Sets Fluid Content, taking Amount from the Fluid Parameter */
+ public FluidTankGT setFluid(FluidStack aFluid) {
+ mFluid = aFluid;
+ mChangedFluids = true;
+ mAmount = (aFluid == null ? 0 : aFluid.amount);
+ return this;
+ }
+
+ /** Sets Fluid Content and Amount */
+ public FluidTankGT setFluid(FluidStack aFluid, long aAmount) {
+ mFluid = aFluid;
+ mChangedFluids = true;
+ mAmount = (aFluid == null ? 0 : aAmount);
+ return this;
+ }
+
+ /** Sets Fluid Content, taking Amount from the Tank Parameter */
+ public FluidTankGT setFluid(FluidTankGT aTank) {
+ mFluid = new FluidStack(aTank.mFluid, saturatedCast(aTank.mAmount));
+ mChangedFluids = true;
+ mAmount = aTank.mAmount;
+ return this;
+ }
+
+ /** Sets the Tank Index for easier Reverse Mapping. */
+ public FluidTankGT setIndex(int aIndex) {
+ mIndex = aIndex;
+ return this;
+ }
+
+ /** Sets the Capacity */
+ public FluidTankGT setCapacity(long aCapacity) {
+ if (aCapacity >= 0) mCapacity = aCapacity;
+ return this;
+ }
+ /** Sets the Capacity Multiplier */
+ public FluidTankGT setCapacityMultiplier(long aCapacityMultiplier) {
+ if (aCapacityMultiplier >= 0) mAdjustableMultiplier = aCapacityMultiplier;
+ return this;
+ }
+
+ /** Sets Tank capacity Map, should it be needed. */
+ public FluidTankGT setCapacity(Map<String, Long> aMap, long aCapacityMultiplier) {
+ mAdjustableCapacity = aMap;
+ mAdjustableMultiplier = aCapacityMultiplier;
+ return this;
+ }
+
+ /** Always keeps at least 0 Liters of Fluid instead of setting it to null */
+ public FluidTankGT setPreventDraining() {
+ return setPreventDraining(true);
+ }
+
+ /** Always keeps at least 0 Liters of Fluid instead of setting it to null */
+ public FluidTankGT setPreventDraining(boolean aPrevent) {
+ mPreventDraining = aPrevent;
+ return this;
+ }
+
+ /** Voids any Overlow */
+ public FluidTankGT setVoidExcess() {
+ return setVoidExcess(true);
+ }
+
+ /** Voids any Overlow */
+ public FluidTankGT setVoidExcess(boolean aVoidExcess) {
+ mVoidExcess = aVoidExcess;
+ return this;
+ }
+
+ public boolean isFull() {
+ return mFluid != null && mAmount >= capacity();
+ }
+
+ public long capacity() {
+ return capacity(mFluid);
+ }
+
+ public long capacity(FluidStack aFluid) {
+ if(mAdjustableCapacity == null || aFluid == null)
+ return mCapacity;
+ return capacity(aFluid.getFluid());
+ }
+
+ public long capacity(Fluid aFluid) {
+ if(mAdjustableCapacity == null || aFluid == null)
+ return mCapacity;
+ return capacity(aFluid.getName());
+ }
+
+ public long capacity(String aFluid) {
+ if( mAdjustableCapacity == null || aFluid == null)
+ return mCapacity;
+
+ final Long tSize = mAdjustableCapacity.get(aFluid);
+ return tSize == null ? Math.max(mAmount, mCapacity) : Math.max(tSize * mAdjustableMultiplier, Math.max(mAmount, mCapacity));
+ }
+
+ public boolean isHalf() {
+ return mFluid != null && mAmount * 2 >= capacity();
+ }
+
+ public boolean contains(Fluid aFluid) {
+ return mFluid != null && mFluid.getFluid() == aFluid;
+ }
+
+ public boolean contains(FluidStack aFluid) {
+ return GT_Utility.areFluidsEqual(mFluid, aFluid);
+ }
+
+ public boolean has(long aAmount) {
+ return mAmount >= aAmount;
+ }
+
+ public boolean has() {
+ return mAmount > 0;
+ }
+
+ public boolean check() {
+ if (mChangedFluids) {
+ mChangedFluids = false;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean update() {
+ return mChangedFluids = true;
+ }
+
+ public boolean changed() {
+ return mChangedFluids;
+ }
+
+ public long amount() {
+ return isEmpty() ? 0 : mAmount;
+ }
+
+ public boolean isEmpty() {
+ return mFluid == null;
+ }
+
+ public long amount(long aMax) {
+ return isEmpty() || aMax <= 0 ? 0 : Math.min(mAmount, aMax);
+ }
+
+ public String name() {
+ return mFluid == null ? null : mFluid.getFluid().getName();
+ }
+
+ public FluidStack get() {
+ return mFluid;
+ }
+
+ public FluidStack get(long aMax) {
+ return isEmpty() || aMax <= 0 ? null : new FluidStack(mFluid, saturatedCast(Math.min(mAmount, aMax)));
+ }
+
+ @Override
+ public FluidStack getFluid() {
+ if (mFluid != null) mFluid.amount = saturatedCast(mAmount);
+ return mFluid;
+ }
+
+ @Override
+ public int getFluidAmount() {
+ return saturatedCast(mAmount);
+ }
+
+ @Override
+ public int getCapacity() {
+ return saturatedCast(capacity());
+ }
+
+ @Override
+ public FluidTankInfo getInfo() {
+ return new FluidTankInfo(isEmpty() ? null : mFluid.copy(), saturatedCast(capacity()));
+ }
+
+}
diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
new file mode 100644
index 0000000000..13d2385381
--- /dev/null
+++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
@@ -0,0 +1,603 @@
+package gregtech.api.multitileentity;
+
+import com.cricketcraft.chisel.api.IFacade;
+import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.IDebugableBlock;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IDebugableTileEntity;
+import gregtech.api.metatileentity.BaseTileEntity;
+import gregtech.api.metatileentity.CoverableTileEntity;
+import gregtech.api.metatileentity.GregTechTileClientEvents;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_BreakBlock;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_GetBlockHardness;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_GetComparatorInputOverride;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_GetWeakChanges;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_HasMultiBlockMachineRelevantData;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_IsProvidingStrongPower;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_IsProvidingWeakPower;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_OnNeighborBlockChange;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_ShouldCheckWeakPower;
+import gregtech.api.objects.XSTR;
+import gregtech.api.util.GT_Log;
+import gregtech.api.util.GT_Util;
+import gregtech.api.util.GT_Utility;
+import gregtech.common.render.GT_Renderer_Block;
+import gregtech.common.render.IRenderedBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.ITileEntityProvider;
+import net.minecraft.block.material.Material;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EnumCreatureType;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.stats.StatList;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.IIcon;
+import net.minecraft.util.MovingObjectPosition;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.Explosion;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.event.ForgeEventFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static gregtech.api.enums.GT_Values.OFFX;
+import static gregtech.api.enums.GT_Values.OFFY;
+import static gregtech.api.enums.GT_Values.OFFZ;
+import static gregtech.api.util.GT_Util.LAST_BROKEN_TILEENTITY;
+import static gregtech.api.util.GT_Util.getTileEntity;
+import static gregtech.api.util.GT_Util.setTileEntity;
+
+/*
+ * MultiTileEntityBlock ported from GT6
+ */
+public class MultiTileEntityBlock extends Block implements IDebugableBlock, ITileEntityProvider, IRenderedBlock, IFacade {
+ protected static final Map<String, MultiTileEntityBlock> MULTI_BLOCK_MAP = new HashMap<>();
+ private static boolean LOCK = false;
+
+ protected final String mNameInternal, mTool;
+ protected final int mHarvestLevelOffset, mHarvestLevelMinimum, mHarvestLevelMaximum;
+ protected final boolean mOpaque, mNormalCube;
+
+ public static String getName(String aMaterialName, SoundType aSoundType, String aTool, int aHarvestLevelOffset, int aHarvestLevelMinimum, int aHarvestLevelMaximum, boolean aOpaque, boolean aNormalCube) {
+ return "gt.block.multiblock." + aMaterialName + "." + aSoundType.soundName + "." + aTool + "." + aHarvestLevelOffset + "." + aHarvestLevelMinimum + "." + aHarvestLevelMaximum + "." + aOpaque + "." + aNormalCube;
+
+ }
+ /**
+ * @param aMaterialName the Name of the vanilla Material Field. In case this is not a vanilla Material, insert the Name you want to give your own Material instead.
+ * @param aMaterial the Material used to determine the Block.
+ * @param aSoundType the Sound Type of the Block.
+ * @param aTool the Tool used to harvest this Block.
+ * @param aHarvestLevelOffset obvious
+ * @param aHarvestLevelMinimum obvious
+ * @param aHarvestLevelMaximum obvious
+ * @param aOpaque if this Block is Opaque.
+ * @param aNormalCube if this Block is a normal Cube (for Redstone Stuff).
+ */
+ public static MultiTileEntityBlock getOrCreate(
+ String aModID, String aMaterialName, Material aMaterial, SoundType aSoundType, String aTool, int aHarvestLevelOffset, int aHarvestLevelMinimum,
+ int aHarvestLevelMaximum, boolean aOpaque, boolean aNormalCube
+ ) {
+ final MultiTileEntityBlock rBlock = MULTI_BLOCK_MAP.get(aModID + ":" + getName(aMaterialName, aSoundType, aTool = aTool.toLowerCase(), aHarvestLevelOffset, aHarvestLevelMinimum, aHarvestLevelMaximum, aOpaque, aNormalCube));
+ return rBlock == null ? new MultiTileEntityBlock(aModID, aMaterialName, aMaterial, aSoundType, aTool, aHarvestLevelOffset, aHarvestLevelMinimum, aHarvestLevelMaximum, aOpaque, aNormalCube) : rBlock;
+ }
+ protected MultiTileEntityBlock(String aModID, String aMaterialName, Material aMaterial, SoundType aSoundType, String aTool, int aHarvestLevelOffset, int aHarvestLevelMinimum, int aHarvestLevelMaximum, boolean aOpaque, boolean aNormalCube) {
+ super(aMaterial);
+ if(GregTech_API.sPreloadFinished) throw new IllegalStateException("Blocks can only be initialized within preInit!");
+
+ mNameInternal = getName(aMaterialName, aSoundType, aTool, aHarvestLevelOffset, aHarvestLevelMinimum, aHarvestLevelMaximum, aOpaque, aNormalCube);
+ GameRegistry.registerBlock(this, ItemBlock.class, mNameInternal);
+
+ MULTI_BLOCK_MAP.put(aModID + ":" + mNameInternal, this);
+
+ setStepSound(aSoundType);
+ mOpaque = aOpaque;
+ mNormalCube = aNormalCube;
+
+ mTool = aTool.toLowerCase();
+ mHarvestLevelOffset = aHarvestLevelOffset;
+ mHarvestLevelMinimum = Math.max(0, aHarvestLevelMinimum);
+ mHarvestLevelMaximum = Math.max(aHarvestLevelMinimum, aHarvestLevelMaximum);
+
+ opaque = isOpaqueCube();
+ lightOpacity = isOpaqueCube() ? 255 : 0;
+
+ }
+
+ @Override
+ public final void breakBlock(World aWorld, int aX, int aY, int aZ, Block aBlock, int aMetaData) {
+ final TileEntity aTileEntity = getTileEntity(aWorld, aX, aY, aZ, true);
+ if (aTileEntity != null) LAST_BROKEN_TILEENTITY.set(aTileEntity);
+ if (aTileEntity == null || !aTileEntity.shouldRefresh(this, aBlock, aMetaData, aMetaData, aWorld, aX, aY, aZ)) return;
+ if (aTileEntity instanceof IMTE_BreakBlock && ((IMTE_BreakBlock)aTileEntity).breakBlock()) return;
+ if (aTileEntity instanceof IMTE_HasMultiBlockMachineRelevantData && ((IMTE_HasMultiBlockMachineRelevantData)aTileEntity).hasMultiBlockMachineRelevantData())
+ GregTech_API.causeMachineUpdate(aWorld, aX, aY, aZ);
+
+ aWorld.removeTileEntity(aX, aY, aZ);
+ }
+
+ @Override
+ public ArrayList<String> getDebugInfo(EntityPlayer aPlayer, int aX, int aY, int aZ, int aLogLevel) {
+ final TileEntity aTileEntity = aPlayer.worldObj.getTileEntity(aX, aY, aZ);
+ if (aTileEntity instanceof IDebugableTileEntity) {
+ return ((IDebugableTileEntity) aTileEntity).getDebugInfo(aPlayer, aLogLevel);
+ }
+ return (ArrayList<String>) Collections.<String>emptyList();
+ }
+
+ @Override
+ public final boolean func_149730_j/*isFullBlock*/() {
+ return mOpaque;
+ }
+
+ @Override
+ public final boolean isNormalCube() {
+ return mNormalCube;
+ }
+
+ @Override
+ public final boolean renderAsNormalBlock() {
+ return mOpaque || mNormalCube;
+ }
+
+ @Override
+ public int getRenderType() {
+ return GT_Renderer_Block.INSTANCE == null ? super.getRenderType() : GT_Renderer_Block.INSTANCE.mRenderID;
+ }
+
+ @Override
+ public final float getBlockHardness(World aWorld, int aX, int aY, int aZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMTE_GetBlockHardness ? ((IMTE_GetBlockHardness) aTileEntity).getBlockHardness() : 1.0F;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public IIcon getIcon(IBlockAccess aIBlockAccess, int aX, int aY, int aZ, int aSide) {
+ return Textures.BlockIcons.MACHINE_LV_SIDE.getIcon();
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public IIcon getIcon(int aSide, int aMeta) {
+ return Textures.BlockIcons.MACHINE_LV_SIDE.getIcon();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB aAABB, List aList, Entity aEntity) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (aTileEntity instanceof IMultiTileEntity) ((IMultiTileEntity) aTileEntity).addCollisionBoxesToList(aAABB, aList, aEntity);
+ else super.addCollisionBoxesToList(aWorld, aX, aY, aZ, aAABB, aList, aEntity);
+ }
+
+ @Override
+ public final AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMultiTileEntity ? ((IMultiTileEntity) aTileEntity).getCollisionBoundingBoxFromPool()
+ : aTileEntity == null ? null : super.getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ);
+ }
+
+ @Override
+ public final AxisAlignedBB getSelectedBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMultiTileEntity ? ((IMultiTileEntity) aTileEntity).getSelectedBoundingBoxFromPool()
+ : super.getSelectedBoundingBoxFromPool(aWorld, aX, aY, aZ);
+ }
+
+ @Override
+ public void setBlockBoundsBasedOnState(IBlockAccess blockAccess, int aX, int aY, int aZ) {
+ final TileEntity aTileEntity = blockAccess.getTileEntity(aX, aY, aZ);
+ if (aTileEntity instanceof IMultiTileEntity) {
+ ((IMultiTileEntity)aTileEntity).setBlockBoundsBasedOnState(this);
+ return;
+ }
+ super.setBlockBoundsBasedOnState(blockAccess, aX, aY, aZ);
+ }
+
+ @Override
+ public final boolean isOpaqueCube() {
+ return mOpaque;
+ }
+
+ @Override
+ public final void onNeighborChange(IBlockAccess aWorld, int aX, int aY, int aZ, int aTileX, int aTileY, int aTileZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (!LOCK) {
+ LOCK = true;
+ if (aTileEntity instanceof BaseTileEntity) ((BaseTileEntity) aTileEntity).onAdjacentBlockChange(aTileX, aTileY, aTileZ);
+ LOCK = false;
+ }
+ }
+
+ @Override
+ public void onNeighborBlockChange(World aWorld, int aX, int aY, int aZ, Block aBlock) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (!LOCK) {
+ LOCK = true;
+ if (aTileEntity instanceof BaseTileEntity) ((BaseTileEntity) aTileEntity).onAdjacentBlockChange(aX, aY, aZ);
+ LOCK = false;
+ }
+ if (aTileEntity instanceof IMTE_OnNeighborBlockChange) ((IMTE_OnNeighborBlockChange) aTileEntity).onNeighborBlockChange(aWorld, aBlock);
+ if (aTileEntity == null) aWorld.setBlockToAir(aX, aY, aZ);
+ }
+
+ @Override
+ public final void onBlockAdded(World aWorld, int aX, int aY, int aZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (aTileEntity instanceof IMultiTileEntity) ((IMultiTileEntity) aTileEntity).onBlockAdded();
+ }
+
+ @Override
+ public float getPlayerRelativeBlockHardness(EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMultiTileEntity && ((IMultiTileEntity) aTileEntity).privateAccess() && !((IMultiTileEntity) aTileEntity).playerOwnsThis(aPlayer, true) ? -1.0F
+ : super.getPlayerRelativeBlockHardness(aPlayer, aWorld, aX, aY, aZ);
+ }
+
+ @Override
+ public final void onBlockClicked(World aWorld, int aX, int aY, int aZ, EntityPlayer aPlayer) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (aTileEntity instanceof IMultiTileEntity) ((IMultiTileEntity) aTileEntity).onLeftClick(aPlayer);
+ else super.onBlockClicked(aWorld, aX, aY, aZ, aPlayer);
+ }
+
+ @Override
+ public boolean onBlockActivated(World aWorld, int aX, int aY, int aZ, EntityPlayer aPlayer, int aSide, float aHitX, float aHitY, float aHitZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (aPlayer != null && ItemList.TC_Thaumometer.isStackEqual(aPlayer.getHeldItem(), true, true)) return false;
+ return aTileEntity instanceof IMultiTileEntity && ((IMultiTileEntity) aTileEntity).onBlockActivated(aPlayer, (byte)aSide, aHitX, aHitY, aHitZ);
+ }
+
+ @Override
+ public final int isProvidingWeakPower(IBlockAccess aWorld, int aX, int aY, int aZ, int aSide) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMTE_IsProvidingWeakPower ? ((IMTE_IsProvidingWeakPower) aTileEntity).isProvidingWeakPower((byte)aSide) :
+ super.isProvidingWeakPower(aWorld, aX, aY, aZ, aSide);
+ }
+
+ @Override
+ public final int isProvidingStrongPower(IBlockAccess aWorld, int aX, int aY, int aZ, int aSide) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMTE_IsProvidingStrongPower ? ((IMTE_IsProvidingStrongPower) aTileEntity).isProvidingStrongPower((byte)aSide)
+ : super.isProvidingStrongPower(aWorld, aX, aY, aZ, aSide);
+ }
+
+
+ @Override
+ public final boolean shouldCheckWeakPower(IBlockAccess aWorld, int aX, int aY, int aZ, int aSide) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMTE_ShouldCheckWeakPower ? ((IMTE_ShouldCheckWeakPower) aTileEntity).shouldCheckWeakPower((byte)aSide)
+ : isNormalCube(aWorld, aX, aY, aZ);
+ }
+
+ @Override
+ public final boolean getWeakChanges(IBlockAccess aWorld, int aX, int aY, int aZ) {
+ final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ return aTileEntity instanceof IMTE_GetWeakChanges ? ((IMTE_GetWeakChanges) aTileEntity).getWeakChanges()
+ : super.getWeakChanges(aWorld, aX, aY, aZ);
+ }
+
+
+ @Override
+ public final void harvestBlock(World aWorld, EntityPlayer aPlayer, int aX, int aY, int aZ, int aMeta) {
+ if (aPlayer == null) aPlayer = harvesters.get();
+ aPlayer.addStat(StatList.mineBlockStatArray[getIdFromBlock(this)], 1);
+ aPlayer.addExhaustion(0.025F);
+ final boolean aSilkTouch = EnchantmentHelper.getSilkTouc