aboutsummaryrefslogtreecommitdiff
path: root/src/Java/gregtech/api/metatileentity
diff options
context:
space:
mode:
Diffstat (limited to 'src/Java/gregtech/api/metatileentity')
-rw-r--r--src/Java/gregtech/api/metatileentity/BaseMetaTileEntityEx.java2081
-rw-r--r--src/Java/gregtech/api/metatileentity/MetaTileEntityEx.java972
-rw-r--r--src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachineEx.java798
-rw-r--r--src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTankEx.java251
-rw-r--r--src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlockEx.java67
5 files changed, 4169 insertions, 0 deletions
diff --git a/src/Java/gregtech/api/metatileentity/BaseMetaTileEntityEx.java b/src/Java/gregtech/api/metatileentity/BaseMetaTileEntityEx.java
new file mode 100644
index 0000000000..1669a11f9a
--- /dev/null
+++ b/src/Java/gregtech/api/metatileentity/BaseMetaTileEntityEx.java
@@ -0,0 +1,2081 @@
+package gregtech.api.metatileentity;
+
+import static gregtech.api.enums.GT_Values.NW;
+import static gregtech.api.enums.GT_Values.V;
+import gregtech.GT_Mod;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IEnergyConnected;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.net.GT_Packet_TileEntity;
+import gregtech.api.objects.GT_ItemStack;
+import gregtech.api.util.GT_CoverBehavior;
+import gregtech.api.util.GT_Log;
+import gregtech.api.util.GT_ModHandler;
+import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.xmod.gregtech.common.Meta_GT_Proxy;
+import ic2.api.Direction;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockFire;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.network.Packet;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.EnumSkyBlock;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.Constants;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTankInfo;
+
+/**
+ * NEVER INCLUDE THIS FILE IN YOUR MOD!!!
+ * <p/>
+ * This is the main TileEntity for EVERYTHING.
+ */
+public class BaseMetaTileEntityEx extends BaseTileEntity implements IGregTechTileEntity {
+ private final GT_CoverBehavior[] mCoverBehaviors = new GT_CoverBehavior[]{GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior};
+ protected MetaTileEntityEx mMetaTileEntity;
+ protected long mStoredEnergy = 0, mStoredSteam = 0;
+ protected int mAverageEUInputIndex = 0, mAverageEUOutputIndex = 0;
+ protected boolean mReleaseEnergy = false;
+ protected int[] mAverageEUInput = new int[]{0, 0, 0, 0, 0}, mAverageEUOutput = new int[]{0, 0, 0, 0, 0};
+ private boolean[] mActiveEUInputs = new boolean[]{false, false, false, false, false, false}, mActiveEUOutputs = new boolean[]{false, false, false, false, false, false};
+ private byte[] mSidedRedstone = new byte[]{15, 15, 15, 15, 15, 15};
+ private int[] mCoverSides = new int[]{0, 0, 0, 0, 0, 0}, mCoverData = new int[]{0, 0, 0, 0, 0, 0}, mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING];
+
+
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ private boolean mHasEnoughEnergy = true;
+ private boolean mRunningThroughTick = false;
+ private boolean mInputDisabled = false;
+ private boolean mOutputDisabled = false;
+ private boolean mMuffler = false;
+ private boolean mLockUpgrade = false;
+ private boolean mActive = false;
+ private boolean mRedstone = false;
+ private boolean mWorkUpdate = false;
+ private boolean mSteamConverter = false;
+ private boolean mInventoryChanged = false;
+ private boolean mWorks = true;
+ private boolean mNeedsUpdate = true;
+ private boolean mNeedsBlockUpdate = true;
+ private boolean mSendClientData = false;
+ private boolean oRedstone = false;
+ //TODO
+ //TODO
+
+ // Create a new NBT Tag List to store itemstacks as NBT Tags
+ protected NBTTagList mInventoryItems = new NBTTagList();
+ protected ItemStack[] mInventory;
+ //TODO
+ //TODO
+ //TODO
+
+ private byte mColor = 0, oColor = 0, mStrongRedstone = 0, oRedstoneData = 63, oTextureData = 0, oUpdateData = 0, oLightValueClient = -1, oLightValue = -1, mLightValue = 0, mOtherUpgrades = 0, mFacing = 0, oFacing = 0, mWorkData = 0;
+ private int mDisplayErrorCode = 0, oX = 0, oY = 0, oZ = 0, mTimeStatisticsIndex = 0, mLagWarningCount = 0;
+ private short mID = 0;
+ private long mTickTimer = 0, oOutput = 0, mAcceptedAmperes = Long.MAX_VALUE;
+ private String mOwnerName = "";
+ private NBTTagCompound mRecipeStuff = new NBTTagCompound();
+
+ public BaseMetaTileEntityEx() {
+ /* this.mInventory = mMetaTileEntity.mInventory;
+ Utils.LOG_INFO(UtilsItems.getArrayStackNames(mInventory));*/
+ }
+
+
+ @Override
+ public void writeToNBT(NBTTagCompound aNBT) {
+ try {
+ super.writeToNBT(aNBT);
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered CRITICAL ERROR while saving MetaTileEntity, the Chunk whould've been corrupted by now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ try {
+ aNBT.setInteger("mID", mID);
+ aNBT.setLong("mStoredSteam", mStoredSteam);
+ aNBT.setLong("mStoredEnergy", mStoredEnergy);
+ aNBT.setIntArray("mCoverData", mCoverData);
+ aNBT.setIntArray("mCoverSides", mCoverSides);
+ aNBT.setByteArray("mRedstoneSided", mSidedRedstone);
+ aNBT.setByte("mColor", mColor);
+ aNBT.setByte("mLightValue", mLightValue);
+ aNBT.setByte("mOtherUpgrades", mOtherUpgrades);
+ aNBT.setByte("mWorkData", mWorkData);
+ aNBT.setByte("mStrongRedstone", mStrongRedstone);
+ aNBT.setShort("mFacing", mFacing);
+ aNBT.setString("mOwnerName", mOwnerName);
+ aNBT.setBoolean("mLockUpgrade", mLockUpgrade);
+ aNBT.setBoolean("mMuffler", mMuffler);
+ aNBT.setBoolean("mSteamConverter", mSteamConverter);
+ aNBT.setBoolean("mActive", mActive);
+ aNBT.setBoolean("mRedstone", mRedstone);
+ aNBT.setBoolean("mWorks", !mWorks);
+ aNBT.setBoolean("mInputDisabled", mInputDisabled);
+ aNBT.setBoolean("mOutputDisabled", mOutputDisabled);
+ aNBT.setTag("GT.CraftingComponents", mRecipeStuff);
+
+ //Let's try save the contents of the inventory
+ // Create a new NBT Tag List to store itemstacks as NBT Tags
+ NBTTagList items = new NBTTagList();
+
+ for (int i = 0; i < getSizeInventory(); ++i)
+ {
+ // Only write stacks that contain items
+ if (getStackInSlot(i) != null){
+ // Make a new NBT Tag Compound to write the itemstack and slot index to
+ NBTTagCompound item = new NBTTagCompound();
+ item.setInteger("Slot", i);
+ // Writes the itemstack in slot(i) to the Tag Compound we just made
+ getStackInSlot(i).writeToNBT(item);
+ // add the tag compound to our tag list
+ items.appendTag(item);
+ }
+ }
+ // Add the TagList to the ItemStack's Tag Compound with the name "ItemInventory"
+ aNBT.setTag("TileEntityInventory", items);
+
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered CRITICAL ERROR while saving MetaTileEntity, the Chunk whould've been corrupted by now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ try {
+ if (hasValidMetaTileEntity()) {
+ NBTTagList tItemList = new NBTTagList();
+ for (int i = 0; i < mMetaTileEntity.getRealInventory().length; i++) {
+ ItemStack tStack = mMetaTileEntity.getRealInventory()[i];
+ if (tStack != null) {
+ NBTTagCompound tTag = new NBTTagCompound();
+ tTag.setInteger("IntSlot", i);
+ tStack.writeToNBT(tTag);
+ tItemList.appendTag(tTag);
+ }
+ }
+ aNBT.setTag("Inventory", tItemList);
+
+ try {
+ mMetaTileEntity.saveNBTData(aNBT);
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered CRITICAL ERROR while saving MetaTileEntity, the Chunk whould've been corrupted by now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered CRITICAL ERROR while saving MetaTileEntity, the Chunk whould've been corrupted by now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+
+
+ @Override
+ public void readFromNBT(NBTTagCompound aNBT) {
+ super.readFromNBT(aNBT);
+ setInitialValuesAsNBT(aNBT, (short) 0);
+ }
+
+
+ @Override
+ public void setInitialValuesAsNBT(NBTTagCompound aNBT, short aID) {
+ if (aNBT == null) {
+ if (aID > 0) mID = aID;
+ else mID = mID > 0 ? mID : 0;
+ if (mID != 0) createNewMetatileEntity(mID);
+ mSidedRedstone = (hasValidMetaTileEntity() && mMetaTileEntity.hasSidedRedstoneOutputBehavior() ? new byte[]{0, 0, 0, 0, 0, 0} : new byte[]{15, 15, 15, 15, 15, 15});
+ } else {
+ if (aID <= 0) mID = (short) aNBT.getInteger("mID");
+ else mID = aID;
+ mStoredSteam = aNBT.getInteger("mStoredSteam");
+ mStoredEnergy = aNBT.getInteger("mStoredEnergy");
+ mColor = aNBT.getByte("mColor");
+ mLightValue = aNBT.getByte("mLightValue");
+ mWorkData = aNBT.getByte("mWorkData");
+ mStrongRedstone = aNBT.getByte("mStrongRedstone");
+ mFacing = oFacing = (byte) aNBT.getShort("mFacing");
+ mOwnerName = aNBT.getString("mOwnerName");
+ mLockUpgrade = aNBT.getBoolean("mLockUpgrade");
+ mMuffler = aNBT.getBoolean("mMuffler");
+ mSteamConverter = aNBT.getBoolean("mSteamConverter");
+ mActive = aNBT.getBoolean("mActive");
+ mRedstone = aNBT.getBoolean("mRedstone");
+ mWorks = !aNBT.getBoolean("mWorks");
+ mInputDisabled = aNBT.getBoolean("mInputDisabled");
+ mOutputDisabled = aNBT.getBoolean("mOutputDisabled");
+ mOtherUpgrades = (byte) (aNBT.getByte("mOtherUpgrades") + aNBT.getByte("mBatteries") + aNBT.getByte("mLiBatteries"));
+ mCoverSides = aNBT.getIntArray("mCoverSides");
+ mCoverData = aNBT.getIntArray("mCoverData");
+ mSidedRedstone = aNBT.getByteArray("mRedstoneSided");
+ mRecipeStuff = aNBT.getCompoundTag("GT.CraftingComponents");
+
+ //Loading Invetory contents
+ // Gets the custom taglist we wrote to this compound, if any
+ NBTTagList items = aNBT.getTagList("TileEntityInventory", Constants.NBT.TAG_COMPOUND);
+ for (int i = 0; i < items.tagCount(); ++i){
+ NBTTagCompound item = (NBTTagCompound) items.getCompoundTagAt(i);
+ int slot = item.getInteger("Slot");
+ // Just double-checking that the saved slot index is within our inventory array bounds
+ if (slot >= 0 && slot < getSizeInventory()) {
+ mInventory[slot] = ItemStack.loadItemStackFromNBT(item);
+ }
+ }
+
+ if (mCoverData.length != 6) mCoverData = new int[]{0, 0, 0, 0, 0, 0};
+ if (mCoverSides.length != 6) mCoverSides = new int[]{0, 0, 0, 0, 0, 0};
+ if (mSidedRedstone.length != 6)
+ if (hasValidMetaTileEntity() && mMetaTileEntity.hasSidedRedstoneOutputBehavior())
+ mSidedRedstone = new byte[]{0, 0, 0, 0, 0, 0};
+ else mSidedRedstone = new byte[]{15, 15, 15, 15, 15, 15};
+
+ for (byte i = 0; i < 6; i++) mCoverBehaviors[i] = GregTech_API.getCoverBehavior(mCoverSides[i]);
+
+ if (mID != 0 && createNewMetatileEntity(mID)) {
+ NBTTagList tItemList = aNBT.getTagList("Inventory", 10);
+ for (int i = 0; i < tItemList.tagCount(); i++) {
+ NBTTagCompound tTag = tItemList.getCompoundTagAt(i);
+ int tSlot = tTag.getInteger("IntSlot");
+ if (tSlot >= 0 && tSlot < mMetaTileEntity.getRealInventory().length) {
+ mMetaTileEntity.getRealInventory()[tSlot] = GT_Utility.loadItem(tTag);
+ }
+ }
+
+ try {
+ mMetaTileEntity.loadNBTData(aNBT);
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered Exception while loading MetaTileEntity, the Server should've crashed now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+ }
+
+ if (mCoverData.length != 6) mCoverData = new int[]{0, 0, 0, 0, 0, 0};
+ if (mCoverSides.length != 6) mCoverSides = new int[]{0, 0, 0, 0, 0, 0};
+ if (mSidedRedstone.length != 6)
+ if (hasValidMetaTileEntity() && mMetaTileEntity.hasSidedRedstoneOutputBehavior())
+ mSidedRedstone = new byte[]{0, 0, 0, 0, 0, 0};
+ else mSidedRedstone = new byte[]{15, 15, 15, 15, 15, 15};
+
+ for (byte i = 0; i < 6; i++) mCoverBehaviors[i] = GregTech_API.getCoverBehavior(mCoverSides[i]);
+ }
+
+ private boolean createNewMetatileEntity(short aID) {
+ if (aID <= 0 || aID >= Meta_GT_Proxy.METATILEENTITIES.length || Meta_GT_Proxy.METATILEENTITIES[aID] == null) {
+ GT_Log.err.println("GT++ - MetaID " + aID + " not loadable => locking TileEntity!");
+ } else {
+ if (aID != 0) {
+ if (hasValidMetaTileEntity()) mMetaTileEntity.setBaseMetaTileEntity(null);
+ Meta_GT_Proxy.METATILEENTITIES[aID].newMetaEntity(this).setBaseMetaTileEntity(this);
+ mTickTimer = 0;
+ mID = aID;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Used for ticking special BaseMetaTileEntities, which need that for Energy Conversion
+ * It's called right before onPostTick()
+ */
+ public void updateStatus() {
+ //
+ }
+
+ /**
+ * Called when trying to charge Items
+ */
+ public void chargeItem(ItemStack aStack) {
+ decreaseStoredEU(GT_ModHandler.chargeElectricItem(aStack, (int) Math.min(Integer.MAX_VALUE, getStoredEU()), (int) Math.min(Integer.MAX_VALUE, mMetaTileEntity.getOutputTier()), false, false), true);
+ }
+
+ /**
+ * Called when trying to discharge Items
+ */
+ public void dischargeItem(ItemStack aStack) {
+ increaseStoredEnergyUnits(GT_ModHandler.dischargeElectricItem(aStack, (int) Math.min(Integer.MAX_VALUE, getEUCapacity() - getStoredEU()), (int) Math.min(Integer.MAX_VALUE, mMetaTileEntity.getInputTier()), false, false, false), true);
+ }
+
+
+ @Override
+ public void updateEntity() {
+ super.updateEntity();
+
+ if (!hasValidMetaTileEntity()) {
+ if (mMetaTileEntity == null) return;
+ mMetaTileEntity.setBaseMetaTileEntity(this);
+ }
+
+ mRunningThroughTick = true;
+ long tTime = System.currentTimeMillis();
+
+ for (int tCode = 0; hasValidMetaTileEntity() && tCode >= 0; ) {
+ try {
+ switch (tCode) {
+ case 0:
+ tCode++;
+ if (mTickTimer++ == 0) {
+ oX = xCoord;
+ oY = yCoord;
+ oZ = zCoord;
+ if (isServerSide()) for (byte i = 0; i < 6; i++)
+ if (getCoverIDAtSide(i) != 0)
+ if (!mMetaTileEntity.allowCoverOnSide(i, new GT_ItemStack(getCoverIDAtSide(i))))
+ dropCover(i, i, true);
+
+ worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this);
+
+ mMetaTileEntity.onFirstTick(this);
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ }
+ case 1:
+ tCode++;
+ if (isClientSide()) {
+ if (mColor != oColor) {
+ mMetaTileEntity.onColorChangeClient(oColor = mColor);
+ issueTextureUpdate();
+ }
+
+ if (mLightValue != oLightValueClient) {
+ worldObj.setLightValue(EnumSkyBlock.Block, xCoord, yCoord, zCoord, mLightValue);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord + 1, yCoord, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord - 1, yCoord, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord + 1, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord - 1, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord + 1);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord - 1);
+ oLightValueClient = mLightValue;
+ issueTextureUpdate();
+ }
+
+ if (mNeedsUpdate) {
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ //worldObj.func_147479_m(xCoord, yCoord, zCoord);
+ mNeedsUpdate = false;
+ }
+ }
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ if (isServerSide() && mTickTimer > 10) {
+ for (byte i = (byte) (tCode - 2); i < 6; i++)
+ if (getCoverIDAtSide(i) != 0) {
+ tCode++;
+ GT_CoverBehavior tCover = getCoverBehaviorAtSide(i);
+ int tCoverTickRate = tCover.getTickRate(i, getCoverIDAtSide(i), mCoverData[i], this);
+ if (tCoverTickRate > 0 && mTickTimer % tCoverTickRate == 0) {
+ mCoverData[i] = tCover.doCoverThings(i, getInputRedstoneSignal(i), getCoverIDAtSide(i), mCoverData[i], this, mTickTimer);
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ }
+ }
+
+ }
+ case 8:
+ tCode = 9;
+ if (isServerSide()) {
+ if (++mAverageEUInputIndex >= mAverageEUInput.length) mAverageEUInputIndex = 0;
+ if (++mAverageEUOutputIndex >= mAverageEUOutput.length) mAverageEUOutputIndex = 0;
+
+ mAverageEUInput[mAverageEUInputIndex] = 0;
+ mAverageEUOutput[mAverageEUOutputIndex] = 0;
+ }
+ case 9:
+ tCode++;
+ mMetaTileEntity.onPreTick(this, mTickTimer);
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ case 10:
+ tCode++;
+ if (isServerSide()) {
+ if (mRedstone != oRedstone || mTickTimer == 10) {
+ for (byte i = 0; i < 6; i++)
+ mCoverBehaviors[i] = GregTech_API.getCoverBehavior(mCoverSides[i]);
+ oRedstone = mRedstone;
+ issueBlockUpdate();
+ }
+
+ if (xCoord != oX || yCoord != oY || zCoord != oZ) {
+ oX = xCoord;
+ oY = yCoord;
+ oZ = zCoord;
+ issueClientUpdate();
+ clearTileEntityBuffer();
+ }
+
+ if (mFacing != oFacing) {
+ oFacing = mFacing;
+ for (byte i = 0; i < 6; i++)
+ if (getCoverIDAtSide(i) != 0)
+ if (!mMetaTileEntity.allowCoverOnSide(i, new GT_ItemStack(getCoverIDAtSide(i))))
+ dropCover(i, i, true);
+ issueBlockUpdate();
+ }
+
+ if (mTickTimer > 20 && mMetaTileEntity.isElectric()) {
+ mAcceptedAmperes = 0;
+
+ if (getOutputVoltage() != oOutput) {
+ oOutput = getOutputVoltage();
+ }
+
+ if (mMetaTileEntity.isEnetOutput() || mMetaTileEntity.isEnetInput()) {
+ for (byte i = 0; i < 6; i++) {
+ boolean
+ temp = isEnergyInputSide(i);
+ if (temp != mActiveEUInputs[i]) {
+ mActiveEUInputs[i] = temp;
+ }
+ temp = isEnergyOutputSide(i);
+ if (temp != mActiveEUOutputs[i]) {
+ mActiveEUOutputs[i] = temp;
+ }
+ }
+ }
+
+ if (mMetaTileEntity.isEnetOutput() && oOutput > 0) {
+ long tOutputVoltage = Math.max(oOutput, oOutput + (1 << GT_Utility.getTier(oOutput))), tUsableAmperage = Math.min(getOutputAmperage(), (getStoredEU() - mMetaTileEntity.getMinimumStoredEU()) / tOutputVoltage);
+ if (tUsableAmperage > 0) {
+ long tEU = tOutputVoltage * IEnergyConnected.Util.emitEnergyToNetwork(oOutput, tUsableAmperage, this);
+ mAverageEUOutput[mAverageEUOutputIndex] += tEU;
+ decreaseStoredEU(tEU, true);
+ }
+ }
+ if (getEUCapacity() > 0) {
+ if (GregTech_API.sMachineFireExplosions && getRandomNumber(1000) == 0) {
+ Block tBlock = getBlockAtSide((byte) getRandomNumber(6));
+ if (tBlock != null && tBlock instanceof BlockFire) doEnergyExplosion();
+ }
+
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+
+ if (getRandomNumber(1000) == 0) {
+ if ((getCoverIDAtSide((byte) 1) == 0 && worldObj.getPrecipitationHeight(xCoord, zCoord) - 2 < yCoord)
+ || (getCoverIDAtSide((byte) 2) == 0 && worldObj.getPrecipitationHeight(xCoord, zCoord - 1) - 1 < yCoord)
+ || (getCoverIDAtSide((byte) 3) == 0 && worldObj.getPrecipitationHeight(xCoord, zCoord + 1) - 1 < yCoord)
+ || (getCoverIDAtSide((byte) 4) == 0 && worldObj.getPrecipitationHeight(xCoord - 1, zCoord) - 1 < yCoord)
+ || (getCoverIDAtSide((byte) 5) == 0 && worldObj.getPrecipitationHeight(xCoord + 1, zCoord) - 1 < yCoord)) {
+ if (GregTech_API.sMachineRainExplosions && worldObj.isRaining() && getBiome().rainfall > 0) {
+ if (getRandomNumber(10) == 0) {
+ try {
+ GT_Mod.instance.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "badweather");
+ } catch (Exception e) {
+ }
+ doEnergyExplosion();
+ } else setOnFire();
+ }
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ if (GregTech_API.sMachineThunderExplosions && worldObj.isThundering() && getBiome().rainfall > 0 && getRandomNumber(3) == 0) {
+ try {
+ GT_Mod.instance.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "badweather");
+ } catch (Exception e) {
+ }
+ doEnergyExplosion();
+ }
+ }
+ }
+ }
+ }
+
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ }
+ case 11:
+ tCode++;
+ if (isServerSide()) {
+ if (mMetaTileEntity.dechargerSlotCount() > 0 && getStoredEU() < getEUCapacity()) {
+ for (int i = mMetaTileEntity.dechargerSlotStartIndex(), k = mMetaTileEntity.dechargerSlotCount() + i; i < k; i++) {
+ if (mMetaTileEntity.mInventory[i] != null && getStoredEU() < getEUCapacity()) {
+ dischargeItem(mMetaTileEntity.mInventory[i]);
+ if (mMetaTileEntity.mInventory[i].stackSize <= 0)
+ mMetaTileEntity.mInventory[i] = null;
+ mInventoryChanged = true;
+ }
+ }
+ }
+ }
+ case 12:
+ tCode++;
+ if (isServerSide()) {
+ if (mMetaTileEntity.rechargerSlotCount() > 0 && getStoredEU() > 0) {
+ for (int i = mMetaTileEntity.rechargerSlotStartIndex(), k = mMetaTileEntity.rechargerSlotCount() + i; i < k; i++) {
+ if (getStoredEU() > 0 && mMetaTileEntity.mInventory[i] != null) {
+ chargeItem(mMetaTileEntity.mInventory[i]);
+ if (mMetaTileEntity.mInventory[i].stackSize <= 0)
+ mMetaTileEntity.mInventory[i] = null;
+ mInventoryChanged = true;
+ }
+ }
+ }
+ }
+ case 13:
+ tCode++;
+ updateStatus();
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ case 14:
+ tCode++;
+ mMetaTileEntity.onPostTick(this, mTickTimer);
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ case 15:
+ tCode++;
+ if (isServerSide()) {
+ if (mTickTimer % 10 == 0) {
+ if (mSendClientData) {
+ NW.sendPacketToAllPlayersInRange(worldObj, new GT_Packet_TileEntity(xCoord, (short) yCoord, zCoord, mID, mCoverSides[0], mCoverSides[1], mCoverSides[2], mCoverSides[3], mCoverSides[4], mCoverSides[5], oTextureData = (byte) ((mFacing & 7) | (mActive ? 8 : 0) | (mRedstone ? 16 : 0) | (mLockUpgrade ? 32 : 0)), oUpdateData = hasValidMetaTileEntity() ? mMetaTileEntity.getUpdateData() : 0, oRedstoneData = (byte) (((mSidedRedstone[0] > 0) ? 1 : 0) | ((mSidedRedstone[1] > 0) ? 2 : 0) | ((mSidedRedstone[2] > 0) ? 4 : 0) | ((mSidedRedstone[3] > 0) ? 8 : 0) | ((mSidedRedstone[4] > 0) ? 16 : 0) | ((mSidedRedstone[5] > 0) ? 32 : 0)), oColor = mColor), xCoord, zCoord);
+ mSendClientData = false;
+ }
+ }
+
+ if (mTickTimer > 10) {
+ byte tData = (byte) ((mFacing & 7) | (mActive ? 8 : 0) | (mRedstone ? 16 : 0) | (mLockUpgrade ? 32 : 0));
+ if (tData != oTextureData) sendBlockEvent((byte) 0, oTextureData = tData);
+ tData = mMetaTileEntity.getUpdateData();
+ if (tData != oUpdateData) sendBlockEvent((byte) 1, oUpdateData = tData);
+ if (mColor != oColor) sendBlockEvent((byte) 2, oColor = mColor);
+ tData = (byte) (((mSidedRedstone[0] > 0) ? 1 : 0) | ((mSidedRedstone[1] > 0) ? 2 : 0) | ((mSidedRedstone[2] > 0) ? 4 : 0) | ((mSidedRedstone[3] > 0) ? 8 : 0) | ((mSidedRedstone[4] > 0) ? 16 : 0) | ((mSidedRedstone[5] > 0) ? 32 : 0));
+ if (tData != oRedstoneData) sendBlockEvent((byte) 3, oRedstoneData = tData);
+ if (mLightValue != oLightValue) {
+ worldObj.setLightValue(EnumSkyBlock.Block, xCoord, yCoord, zCoord, mLightValue);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord + 1, yCoord, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord - 1, yCoord, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord + 1, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord - 1, zCoord);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord + 1);
+ worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord - 1);
+ issueTextureUpdate();
+ sendBlockEvent((byte) 7, oLightValue = mLightValue);
+ }
+ }
+
+ if (mNeedsBlockUpdate) {
+ worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, getBlockOffset(0, 0, 0));
+ mNeedsBlockUpdate = false;
+ }
+ }
+ default:
+ tCode = -1;
+ break;
+ }
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered Exception while ticking MetaTileEntity in Step " + (tCode - 1) + ". The Game should've crashed now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+
+ if (isServerSide() && hasValidMetaTileEntity()) {
+ tTime = System.currentTimeMillis() - tTime;
+ if (mTimeStatistics.length > 0)
+ mTimeStatistics[mTimeStatisticsIndex = (mTimeStatisticsIndex + 1) % mTimeStatistics.length] = (int) tTime;
+ if (tTime > 0 && tTime > GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10)
+ System.out.println("GT++ - WARNING: Possible Lag Source at [" + xCoord + ", " + yCoord + ", " + zCoord + "] in Dimension " + worldObj.provider.dimensionId + " with " + tTime + "ms caused by an instance of " + getMetaTileEntity().getClass());
+ }
+
+ mWorkUpdate = mInventoryChanged = mRunningThroughTick = false;
+ }
+
+
+ @Override
+ public Packet getDescriptionPacket() {
+ issueClientUpdate();
+ return null;
+ }
+
+
+ @Override
+ public boolean receiveClientEvent(int aEventID, int aValue) {
+ super.receiveClientEvent(aEventID, aValue);
+
+ if (hasValidMetaTileEntity()) {
+ try {
+ mMetaTileEntity.receiveClientEvent((byte) aEventID, (byte) aValue);
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered Exception while receiving Data from the Server, the Client should've been crashed by now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+
+ if (isClientSide()) {
+ issueTextureUpdate();
+ switch (aEventID) {
+ case 0:
+ mFacing = (byte) (aValue & 7);
+ mActive = ((aValue & 8) != 0);
+ mRedstone = ((aValue & 16) != 0);
+ //mLockUpgrade = ((aValue&32) != 0);
+ break;
+ case 1:
+ if (hasValidMetaTileEntity()) mMetaTileEntity.onValueUpdate((byte) aValue);
+ break;
+ case 2:
+ if (aValue > 16 || aValue < 0) aValue = 0;
+ mColor = (byte) aValue;
+ break;
+ case 3:
+ mSidedRedstone[0] = (byte) ((aValue & 1) > 0 ? 15 : 0);
+ mSidedRedstone[1] = (byte) ((aValue & 2) > 0 ? 15 : 0);
+ mSidedRedstone[2] = (byte) ((aValue & 4) > 0 ? 15 : 0);
+ mSidedRedstone[3] = (byte) ((aValue & 8) > 0 ? 15 : 0);
+ mSidedRedstone[4] = (byte) ((aValue & 16) > 0 ? 15 : 0);
+ mSidedRedstone[5] = (byte) ((aValue & 32) > 0 ? 15 : 0);
+ break;
+ case 4:
+ if (hasValidMetaTileEntity() && mTickTimer > 20)
+ mMetaTileEntity.doSound((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
+ break;
+ case 5:
+ if (hasValidMetaTileEntity() && mTickTimer > 20)
+ mMetaTileEntity.startSoundLoop((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
+ break;
+ case 6:
+ if (hasValidMetaTileEntity() && mTickTimer > 20)
+ mMetaTileEntity.stopSoundLoop((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
+ break;
+ case 7:
+ mLightValue = (byte) aValue;
+ break;
+ }
+ }
+ return true;
+ }
+
+ public ArrayList<String> getDebugInfo(EntityPlayer aPlayer, int aLogLevel) {
+ ArrayList<String> tList = new ArrayList<String>();
+ if (aLogLevel > 2) {
+ tList.add("GT++ - Meta-ID: " + mID + (canAccessData() ? " valid" : " invalid") + (mMetaTileEntity == null ? " MetaTileEntity == null!" : " "));
+ }
+ if (aLogLevel > 1) {
+ if (mTimeStatistics.length > 0) {
+ double tAverageTime = 0;
+ for (int tTime : mTimeStatistics) tAverageTime += tTime;
+ tList.add("GT++ - This particular TileEntity has caused an average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ms over the last " + mTimeStatistics.length + " ticks.");
+ }
+ if (mLagWarningCount > 0) {
+ tList.add("GT++ - This TileEntity has also caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server.");
+ }
+ tList.add("Is" + (mMetaTileEntity.isAccessAllowed(aPlayer) ? " " : " not ") + "accessible for you");
+ }
+ if (aLogLevel > 0) {
+ if (getSteamCapacity() > 0 && hasSteamEngineUpgrade())
+ tList.add(getStoredSteam() + " of " + getSteamCapacity() + " Steam");
+ tList.add("Machine is " + (mActive ? "active" : "inactive"));
+ if (!mHasEnoughEnergy)
+ tList.add("GT++ - ATTENTION: This Device consumes Energy at a higher Rate than you input. You could insert more to speed up the process.");
+ }
+ return mMetaTileEntity.getSpecialDebugInfo(this, aPlayer, aLogLevel, tList);
+ }
+
+
+ @Override
+ public void issueTextureUpdate() {
+ mNeedsUpdate = true;
+ }
+
+
+ @Override
+ public void issueBlockUpdate() {
+ mNeedsBlockUpdate = true;
+ }
+
+
+ @Override
+ public void issueClientUpdate() {
+ mSendClientData = true;
+ }
+
+
+ @Override
+ public void issueCoverUpdate(byte aSide) {
+ issueClientUpdate();
+ }
+
+
+ @Override
+ public byte getStrongestRedstone() {
+ return (byte) Math.max(getInternalInputRedstoneSignal((byte) 0), Math.max(getInternalInputRedstoneSignal((byte) 1), Math.max(getInternalInputRedstoneSignal((byte) 2), Math.max(getInternalInputRedstoneSignal((byte) 3), Math.max(getInternalInputRedstoneSignal((byte) 4), getInternalInputRedstoneSignal((byte) 5))))));
+ }
+
+
+ @Override
+ public boolean getRedstone() {
+ return getRedstone((byte) 0) || getRedstone((byte) 1) || getRedstone((byte) 2) || getRedstone((byte) 3) || getRedstone((byte) 4) || getRedstone((byte) 5);
+ }
+
+
+ @Override
+ public boolean getRedstone(byte aSide) {
+ return getInternalInputRedstoneSignal(aSide) > 0;
+ }
+
+ public ITexture getCoverTexture(byte aSide) {
+ return GregTech_API.sCovers.get(new GT_ItemStack(getCoverIDAtSide(aSide)));
+ }
+
+
+ @Override
+ public boolean isGivingInformation() {
+ if (canAccessData()) return mMetaTileEntity.isGivingInformation();
+ return false;
+ }
+
+
+ @Override
+ public boolean isValidFacing(byte aSide) {
+ if (canAccessData()) return mMetaTileEntity.isFacingValid(aSide);
+ return false;
+ }
+
+
+ @Override
+ public byte getBackFacing() {
+ return GT_Utility.getOppositeSide(mFacing);
+ }
+
+
+ @Override
+ public byte getFrontFacing() {
+ return mFacing;
+ }
+
+
+ @Override
+ public void setFrontFacing(byte aFacing) {
+ if (isValidFacing(aFacing)) {
+ mFacing = aFacing;
+ mMetaTileEntity.onFacingChange();
+ onMachineBlockUpdate();
+ }
+ }
+
+
+ @Override
+ public int getSizeInventory() {
+ if (canAccessData()) return mMetaTileEntity.getSizeInventory();
+ return 0;
+ }
+
+
+ @Override
+ public ItemStack getStackInSlot(int aIndex) {
+ if (canAccessData()) return mMetaTileEntity.getStackInSlot(aIndex);
+ return null;
+ }
+
+
+ @Override
+ public void setInventorySlotContents(int aIndex, ItemStack aStack) {
+ mInventoryChanged = true;
+ if (canAccessData())
+ mMetaTileEntity.setInventorySlotContents(aIndex, worldObj.isRemote ? aStack : GT_OreDictUnificator.setStack(true, aStack));
+ }
+
+
+ @Override
+ public String getInventoryName() {
+ if (canAccessData()) return mMetaTileEntity.getInventoryName();
+ if (Meta_GT_Proxy.METATILEENTITIES[mID] != null) return Meta_GT_Proxy.METATILEENTITIES[mID].getInventoryName();
+ return "";
+ }
+
+
+ @Override
+ public int getInventoryStackLimit() {
+ if (canAccessData()) return mMetaTileEntity.getInventoryStackLimit();
+ return 64;
+ }
+
+
+ @Override
+ public void openInventory() {
+ if (canAccessData()) mMetaTileEntity.onOpenGUI();
+ }
+
+
+ @Override
+ public void closeInventory() {
+ if (canAccessData()) mMetaTileEntity.onCloseGUI();
+ }
+
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer aPlayer) {
+ return canAccessData() && playerOwnsThis(aPlayer, false) && mTickTimer > 40 && getTileEntityOffset(0, 0, 0) == this && aPlayer.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64 && mMetaTileEntity.isAccessAllowed(aPlayer);
+ }
+
+
+ @Override
+ public void validate() {
+ super.validate();
+ mTickTimer = 0;
+ }
+
+
+ @Override
+ public void invalidate() {
+ tileEntityInvalid = false;
+ if (canAccessData()) {
+ mMetaTileEntity.onRemoval();
+ mMetaTileEntity.setBaseMetaTileEntity(null);
+ }
+ super.invalidate();
+ }
+
+
+ @Override
+ public void onChunkUnload() {
+ super.onChunkUnload();
+ }
+
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return false;
+ }
+
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(int slot) {
+ ItemStack stack = getStackInSlot(slot);
+ if (stack != null) setInventorySlotContents(slot, null);
+ return stack;
+ }
+
+
+ @Override
+ public void onMachineBlockUpdate() {
+ if (canAccessData()) mMetaTileEntity.onMachineBlockUpdate();
+ }
+
+
+ @Override
+ public int getProgress() {
+ return canAccessData() ? mMetaTileEntity.getProgresstime() : 0;
+ }
+
+
+ @Override
+ public int getMaxProgress() {
+ return canAccessData() ? mMetaTileEntity.maxProgresstime() : 0;
+ }
+
+
+ @Override
+ public boolean increaseProgress(int aProgressAmountInTicks) {
+ return canAccessData() ? mMetaTileEntity.increaseProgress(aProgressAmountInTicks) != aProgressAmountInTicks : false;
+ }
+
+
+ @Override
+ public boolean hasThingsToDo() {
+ return getMaxProgress() > 0;
+ }
+
+
+ @Override
+ public void enableWorking() {
+ if (!mWorks) mWorkUpdate = true;
+ mWorks = true;
+ }
+
+
+ @Override
+ public void disableWorking() {
+ mWorks = false;
+ }
+
+
+ @Override
+ public boolean isAllowedToWork() {
+ return mWorks;
+ }
+
+
+ @Override
+ public boolean hasWorkJustBeenEnabled() {
+ return mWorkUpdate;
+ }
+
+
+ @Override
+ public byte getWorkDataValue() {
+ return mWorkData;
+ }
+
+
+ @Override
+ public void setWorkDataValue(byte aValue) {
+ mWorkData = aValue;
+ }
+
+
+ @Override
+ public int getMetaTileID() {
+ return mID;
+ }
+
+
+ @Override
+ public int setMetaTileID(short aID) {
+ return mID = aID;
+ }
+
+
+ @Override
+ public boolean isActive() {
+ return mActive;
+ }
+
+
+ @Override
+ public void setActive(boolean aActive) {
+ mActive = aActive;
+ }
+
+
+ @Override
+ public long getTimer() {
+ return mTickTimer;
+ }
+
+
+ @Override
+ public boolean decreaseStoredEnergyUnits(long aEnergy, boolean aIgnoreTooLessEnergy) {
+ if (!canAccessData()) return false;
+ return mHasEnoughEnergy = decreaseStoredEU(aEnergy, aIgnoreTooLessEnergy) || decreaseStoredSteam(aEnergy, false) || (aIgnoreTooLessEnergy && (decreaseStoredSteam(aEnergy, true)));
+ }
+
+
+ @Override
+ public boolean increaseStoredEnergyUnits(long aEnergy, boolean aIgnoreTooMuchEnergy) {
+ if (!canAccessData()) return false;
+ if (getStoredEU() < getEUCapacity() || aIgnoreTooMuchEnergy) {
+ setStoredEU(mMetaTileEntity.getEUVar() + aEnergy);
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public boolean inputEnergyFrom(byte aSide) {
+ if (aSide == 6) return true;
+ if (isServerSide()) return (aSide >= 0 && aSide < 6 ? mActiveEUInputs[aSide] : false) && !mReleaseEnergy;
+ return isEnergyInputSide(aSide);
+ }
+
+
+ @Override
+ public boolean outputsEnergyTo(byte aSide) {
+ if (aSide == 6) return true;
+ if (isServerSide()) return (aSide >= 0 && aSide < 6 ? mActiveEUOutputs[aSide] : false) || mReleaseEnergy;
+ return isEnergyOutputSide(aSide);
+ }
+
+
+ @Override
+ public long getOutputAmperage() {
+ if (canAccessData() && mMetaTileEntity.isElectric()) return mMetaTileEntity.maxAmperesOut();
+ return 0;
+ }
+
+
+ @Override
+ public long getOutputVoltage() {
+ if (canAccessData() && mMetaTileEntity.isElectric() && mMetaTileEntity.isEnetOutput())
+ return mMetaTileEntity.maxEUOutput();
+ return 0;
+ }
+
+
+ @Override
+ public long getInputAmperage() {
+ if (canAccessData() && mMetaTileEntity.isElectric()) return mMetaTileEntity.maxAmperesIn();
+ return 0;
+ }
+
+
+ @Override
+ public long getInputVoltage() {
+ if (canAccessData() && mMetaTileEntity.isElectric()) return mMetaTileEntity.maxEUInput();
+ return Integer.MAX_VALUE;
+ }
+
+
+ @Override
+ public boolean increaseStoredSteam(long aEnergy, boolean aIgnoreTooMuchEnergy) {
+ if (!canAccessData()) return false;
+ if (mMetaTileEntity.getSteamVar() < getSteamCapacity() || aIgnoreTooMuchEnergy) {
+ setStoredSteam(mMetaTileEntity.getSteamVar() + aEnergy);
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public String[] getDescription() {
+ if (canAccessData()) return mMetaTileEntity.getDescription();
+ return new String[0];
+ }
+
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ if (canAccessData()) return mMetaTileEntity.isValidSlot(aIndex);
+ return false;
+ }
+
+
+ @Override
+ public long getUniversalEnergyStored() {
+ return Math.max(getStoredEU(), getStoredSteam());
+ }
+
+
+ @Override
+ public long getUniversalEnergyCapacity() {
+ return Math.max(getEUCapacity(), getSteamCapacity());
+ }
+
+
+ @Override
+ public long getStoredEU() {
+ if (canAccessData()) return Math.min(mMetaTileEntity.getEUVar(), getEUCapacity());
+ return 0;
+ }
+
+
+ @Override
+ public long getEUCapacity() {
+ if (canAccessData()) return mMetaTileEntity.maxEUStore();
+ return 0;
+ }
+
+
+ @Override
+ public long getStoredSteam() {
+ if (canAccessData()) return Math.min(mMetaTileEntity.getSteamVar(), getSteamCapacity());
+ return 0;
+ }
+
+
+ @Override
+ public long getSteamCapacity() {
+ if (canAccessData()) return mMetaTileEntity.maxSteamStore();
+ return 0;
+ }
+
+ @Override
+ public ITexture[] getTexture(byte aSide) {
+ ITexture rIcon = getCoverTexture(aSide);
+ if (rIcon != null) return new ITexture[]{rIcon};
+ if (hasValidMetaTileEntity())
+ return mMetaTileEntity.getTexture(this, aSide, mFacing, (byte) (mColor - 1), mActive, getOutputRedstoneSignal(aSide) > 0);
+ return Textures.BlockIcons.ERROR_RENDERING;
+ }
+
+ private boolean isEnergyInputSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) {
+ if (!getCoverBehaviorAtSide(aSide).letsEnergyIn(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this))
+ return false;
+ if (isInvalid() || mReleaseEnergy) return false;
+ if (canAccessData() && mMetaTileEntity.isElectric() && mMetaTileEntity.isEnetInput())
+ return mMetaTileEntity.isInputFacing(aSide);
+ }
+ return false;
+ }
+
+ private boolean isEnergyOutputSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) {
+ if (!getCoverBehaviorAtSide(aSide).letsEnergyOut(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this))
+ return false;
+ if (isInvalid() || mReleaseEnergy) return mReleaseEnergy;
+ if (canAccessData() && mMetaTileEntity.isElectric() && mMetaTileEntity.isEnetOutput())
+ return mMetaTileEntity.isOutputFacing(aSide);
+ }
+ return false;
+ }
+
+
+ protected boolean hasValidMetaTileEntity() {
+ return mMetaTileEntity != null && mMetaTileEntity.getBaseMetaTileEntity() == this;
+ }
+
+
+ protected boolean canAccessData() {
+ return !isDead && hasValidMetaTileEntity();
+ }
+
+
+ public boolean setStoredEU(long aEnergy) {
+ if (!canAccessData()) return false;
+ if (aEnergy < 0) aEnergy = 0;
+ mMetaTileEntity.setEUVar(aEnergy);
+ return true;
+ }
+
+
+ public boolean setStoredSteam(long aEnergy) {
+ if (!canAccessData()) return false;
+ if (aEnergy < 0) aEnergy = 0;
+ mMetaTileEntity.setSteamVar(aEnergy);
+ return true;
+ }
+
+
+ public boolean decreaseStoredEU(long aEnergy, boolean aIgnoreTooLessEnergy) {
+ if (!canAccessData()) {
+ return false;
+ }
+ if (mMetaTileEntity.getEUVar() - aEnergy >= 0 || aIgnoreTooLessEnergy) {
+ setStoredEU(mMetaTileEntity.getEUVar() - aEnergy);
+ if (mMetaTileEntity.getEUVar() < 0) {
+ setStoredEU(0);
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+
+ public boolean decreaseStoredSteam(long aEnergy, boolean aIgnoreTooLessEnergy) {
+ if (!canAccessData()) return false;
+ if (mMetaTileEntity.getSteamVar() - aEnergy >= 0 || aIgnoreTooLessEnergy) {
+ setStoredSteam(mMetaTileEntity.getSteamVar() - aEnergy);
+ if (mMetaTileEntity.getSteamVar() < 0) {
+ setStoredSteam(0);
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+
+ public boolean playerOwnsThis(EntityPlayer aPlayer, boolean aCheckPrecicely) {
+ if (!canAccessData()) return false;
+ if (aCheckPrecicely || privateAccess() || mOwnerName.equals(""))
+ if (mOwnerName.equals("") && isServerSide()) setOwnerName(aPlayer.getDisplayName());
+ else if (privateAccess() && !aPlayer.getDisplayName().equals("Player") && !mOwnerName.equals("Player") && !mOwnerName.equals(aPlayer.getDisplayName()))
+ return false;
+ return true;
+ }
+
+
+ public boolean privateAccess() {
+ if (!canAccessData()) return mLockUpgrade;
+ return mLockUpgrade || mMetaTileEntity.ownerControl();
+ }
+
+
+ public void doEnergyExplosion() {
+ if (getUniversalEnergyCapacity() > 0 && getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 5) {
+ doExplosion(oOutput * (getUniversalEnergyStored() >= getUniversalEnergyCapacity() ? 4 : getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 2 ? 2 : 1));
+ GT_Mod.instance.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "electricproblems");
+ }
+ }
+
+
+ @Override
+ public void doExplosion(long aAmount) {
+ if (canAccessData()) {
+ // This is only for Electric Machines
+ if (GregTech_API.sMachineWireFire && mMetaTileEntity.isElectric()) {
+ try {
+ mReleaseEnergy = true;
+ IEnergyConnected.Util.emitEnergyToNetwork(V[5], Math.max(1, getStoredEU() / V[5]), this);
+ } catch (Exception e) {/* Fun Fact: all these "do nothing" Comments you see in my Code, are just there to let Eclipse shut up about the intended empty Brackets, but I need eclipse to yell at me in some of the regular Cases where I forget to add Code */}
+ }
+ mReleaseEnergy = false;
+ // Normal Explosion Code
+ mMetaTileEntity.onExplosion();
+ mMetaTileEntity.doExplosion(aAmount);
+ }
+ }
+
+
+
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+
+
+ @Override
+ public ArrayList<ItemStack> getDrops() {
+ ItemStack rStack = new ItemStack(GregTech_API.sBlockMachines, 1, mID);
+ NBTTagCompound tNBT = new NBTTagCompound();
+ if (mRecipeStuff != null && !mRecipeStuff.hasNoTags()) tNBT.setTag("GT.CraftingComponents", mRecipeStuff);
+ if (mMuffler) tNBT.setBoolean("mMuffler", mMuffler);
+ if (mLockUpgrade) tNBT.setBoolean("mLockUpgrade", mLockUpgrade);
+ if (mSteamConverter) tNBT.setBoolean("mSteamConverter", mSteamConverter);
+ if (mColor > 0) tNBT.setByte("mColor", mColor);
+ if (mOtherUpgrades > 0) tNBT.setByte("mOtherUpgrades", mOtherUpgrades);
+ if (mStrongRedstone > 0) tNBT.setByte("mStrongRedstone", mStrongRedstone);
+ for (byte i = 0; i < mCoverSides.length; i++) {
+ if (mCoverSides[i] != 0) {
+ tNBT.setIntArray("mCoverData", mCoverData);
+ tNBT.setIntArray("mCoverSides", mCoverSides);
+ break;
+ }
+ }
+ if (hasValidMetaTileEntity()) mMetaTileEntity.setItemNBT(tNBT);
+ if (!tNBT.hasNoTags()) rStack.setTagCompound(tNBT);
+ return new ArrayList<ItemStack>(Arrays.asList(rStack));
+ }
+
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+ //TODO
+
+
+ public int getUpgradeCount() {
+ return (mMuffler ? 1 : 0) + (mLockUpgrade ? 1 : 0) + (mSteamConverter ? 1 : 0) + mOtherUpgrades;
+ }
+
+
+ @Override
+ public boolean onRightclick(EntityPlayer aPlayer, byte aSide, float aX, float aY, float aZ) {
+ if (isClientSide()) {
+ if (getCoverBehaviorAtSide(aSide).onCoverRightclickClient(aSide, this, aPlayer, aX, aY, aZ)) return true;
+ if (!getCoverBehaviorAtSide(aSide).isGUIClickable(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this))
+ return false;
+ }
+ if (isServerSide()) {
+ if (!privateAccess() || aPlayer.getDisplayName().equalsIgnoreCase(getOwnerName())) {
+ ItemStack tCurrentItem = aPlayer.inventory.getCurrentItem();
+ if (tCurrentItem != null) {
+ if (getColorization() >= 0 && GT_Utility.areStacksEqual(new ItemStack(Items.water_bucket, 1), tCurrentItem)) {
+ tCurrentItem.func_150996_a(Items.bucket);
+ setColorization((byte) (getColorization() >= 16 ? -2 : -1));
+ return true;
+ }
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWrenchList)) {
+ if (mMetaTileEntity.onWrenchRightClick(aSide, GT_Utility.determineWrenchingSide(aSide, aX, aY, aZ), aPlayer, aX, aY, aZ)) {
+ GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer);
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(100), 1.0F, -1, xCoord, yCoord, zCoord);
+ }
+ return true;
+ }
+
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sScrewdriverList)) {
+ if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) {
+ setCoverDataAtSide(aSide, getCoverBehaviorAtSide(aSide).onCoverScrewdriverclick(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this, aPlayer, aX, aY, aZ));
+ mMetaTileEntity.onScrewdriverRightClick(aSide, aPlayer, aX, aY, aZ);
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(100), 1.0F, -1, xCoord, yCoord, zCoord);
+ }
+ return true;
+ }
+
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sHardHammerList)) {
+ if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) {
+ mInputDisabled = !mInputDisabled;
+ if (mInputDisabled) mOutputDisabled = !mOutputDisabled;
+ GT_Utility.sendChatToPlayer(aPlayer, "Auto-Input: " + (mInputDisabled ? "Disabled" : "Enabled") + " Auto-Output: " + (mOutputDisabled ? "Disabled" : "Enabled"));
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(1), 1.0F, -1, xCoord, yCoord, zCoord);
+ }
+ return true;
+ }
+
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSoftHammerList)) {
+ if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) {
+ if (mWorks) disableWorking();
+ else enableWorking();
+ GT_Utility.sendChatToPlayer(aPlayer, "Machine Processing: " + (isAllowedToWork() ? "Enabled" : "Disabled"));
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(101), 1.0F, -1, xCoord, yCoord, zCoord);
+ }
+ return true;
+ }
+
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSolderingToolList)) {
+ byte tSide = GT_Utility.determineWrenchingSide(aSide, aX, aY, aZ);
+ if (GT_ModHandler.useSolderingIron(tCurrentItem, aPlayer)) {
+ mStrongRedstone ^= (1 << tSide);
+ GT_Utility.sendChatToPlayer(aPlayer, "Redstone Output at Side " + tSide + " set to: " + ((mStrongRedstone & (1 << tSide)) != 0 ? "Strong" : "Weak"));
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(103), 3.0F, -1, xCoord, yCoord, zCoord);
+ }
+ return true;
+ }
+
+ if (getCoverIDAtSide(aSide) == 0) {
+ if (GregTech_API.sCovers.containsKey(new GT_ItemStack(tCurrentItem))) {
+ if (GregTech_API.getCoverBehavior(tCurrentItem).isCoverPlaceable(aSide, new GT_ItemStack(tCurrentItem), this) && mMetaTileEntity.allowCoverOnSide(aSide, new GT_ItemStack(tCurrentItem))) {
+ setCoverItemAtSide(aSide, tCurrentItem);
+ if (!aPlayer.capabilities.isCreativeMode) tCurrentItem.stackSize--;
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(100), 1.0F, -1, xCoord, yCoord, zCoord);
+ }
+ return true;
+ }
+ } else {
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCrowbarList)) {
+ if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) {
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(0), 1.0F, -1, xCoord, yCoord, zCoord);
+ dropCover(aSide, aSide, false);
+ }
+ return true;
+ }
+ }
+ }
+
+ if (getCoverBehaviorAtSide(aSide).onCoverRightclick(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this, aPlayer, aX, aY, aZ))
+ return true;
+
+ if (!getCoverBehaviorAtSide(aSide).isGUIClickable(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this))
+ return false;
+
+ if (isUpgradable() && aPlayer.inventory.getCurrentItem() != null) {/*
+ if (ItemList.Upgrade_SteamEngine.isStackEqual(aPlayer.inventory.getCurrentItem())) {
+ if (addSteamEngineUpgrade()) {
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(3), 1.0F, -1, xCoord, yCoord, zCoord);
+ if (!aPlayer.capabilities.isCreativeMode) aPlayer.inventory.getCurrentItem().stackSize--;
+ }
+ return true;
+ }*/
+ if (ItemList.Upgrade_Muffler.isStackEqual(aPlayer.inventory.getCurrentItem())) {
+ if (addMufflerUpgrade()) {
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(3), 1.0F, -1, xCoord, yCoord, zCoord);
+ if (!aPlayer.capabilities.isCreativeMode) aPlayer.inventory.getCurrentItem().stackSize--;
+ }
+ return true;
+ }
+ if (ItemList.Upgrade_Lock.isStackEqual(aPlayer.inventory.getCurrentItem())) {
+ if (isUpgradable() && !mLockUpgrade) {
+ mLockUpgrade = true;
+ setOwnerName(aPlayer.getDisplayName());
+ GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(3), 1.0F, -1, xCoord, yCoord, zCoord);
+ if (!aPlayer.capabilities.isCreativeMode) aPlayer.inventory.getCurrentItem().stackSize--;
+ }
+ return true;
+ }
+ }
+ }
+ }
+
+ try {
+ if (hasValidMetaTileEntity()) return mMetaTileEntity.onRightclick(this, aPlayer, aSide, aX, aY, aZ);
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered Exception while rightclicking TileEntity, the Game should've crashed now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+
+ return true;
+ }
+
+
+ @Override
+ public void onLeftclick(EntityPlayer aPlayer) {
+ try {
+ if (aPlayer != null && hasValidMetaTileEntity()) mMetaTileEntity.onLeftclick(this, aPlayer);
+ } catch (Throwable e) {
+ GT_Log.err.println("GT++ - Encountered Exception while leftclicking TileEntity, the Game should've crashed now, but I prevented that. Please report immidietly to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+
+
+ @Override
+ public boolean isDigitalChest() {
+ if (canAccessData()) return mMetaTileEntity.isDigitalChest();
+ return false;
+ }
+
+
+ @Override
+ public ItemStack[] getStoredItemData() {
+ if (canAccessData()) return mMetaTileEntity.getStoredItemData();
+ return null;
+ }
+
+
+ @Override
+ public void setItemCount(int aCount) {
+ if (canAccessData()) mMetaTileEntity.setItemCount(aCount);
+ }
+
+
+ @Override
+ public int getMaxItemCount() {
+ if (canAccessData()) return mMetaTileEntity.getMaxItemCount();
+ return 0;
+ }
+
+ /**
+ * Can put aStack into Slot
+ */
+
+ @Override
+ public boolean isItemValidForSlot(int aIndex, ItemStack aStack) {
+ return canAccessData() && mMetaTileEntity.isItemValidForSlot(aIndex, aStack);
+ }
+
+ /**
+ * returns all valid Inventory Slots, no matter which Side (Unless it's covered).
+ * The Side Stuff is done in the following two Functions.
+ */
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int aSide) {
+ if (canAccessData() && (getCoverBehaviorAtSide((byte) aSide).letsItemsOut((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), -1, this) || getCoverBehaviorAtSide((byte) aSide).letsItemsIn((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), -1, this)))
+ return mMetaTileEntity.getAccessibleSlotsFromSide(aSide);
+ return new int[0];
+ }
+
+ /**
+ * Can put aStack into Slot at Side
+ */
+
+ @Override
+ public boolean canInsertItem(int aIndex, ItemStack aStack, int aSide) {
+ return canAccessData() && (mRunningThroughTick || !mInputDisabled) && getCoverBehaviorAtSide((byte) aSide).letsItemsIn((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), aIndex, this) && mMetaTileEntity.canInsertItem(aIndex, aStack, aSide);
+ }
+
+ /**
+ * Can pull aStack out of Slot from Side
+ */
+
+ @Override
+ public boolean canExtractItem(int aIndex, ItemStack aStack, int aSide) {
+ return canAccessData() && (mRunningThroughTick || !mOutputDisabled) && getCoverBehaviorAtSide((byte) aSide).letsItemsOut((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), aIndex, this) && mMetaTileEntity.canExtractItem(aIndex, aStack, aSide);
+ }
+
+
+ @Override
+ public boolean isUpgradable() {
+ return canAccessData() && getUpgradeCount() < 8;
+ }
+
+
+ @Override
+ public byte getInternalInputRedstoneSignal(byte aSide) {
+ return (byte) (getCoverBehaviorAtSide(aSide).getRedstoneInput(aSide, getInputRedstoneSignal(aSide), getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this) & 15);
+ }
+
+
+ @Override
+ public byte getInputRedstoneSignal(byte aSide) {
+ return (byte) (worldObj.getIndirectPowerLevelTo(getOffsetX(aSide, 1), getOffsetY(aSide, 1), getOffsetZ(aSide, 1), aSide) & 15);
+ }
+
+
+ @Override
+ public byte getOutputRedstoneSignal(byte aSide) {
+ return getCoverBehaviorAtSide(aSide).manipulatesSidedRedstoneOutput(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this) ? mSidedRedstone[aSide] : 0;
+ // return (byte)(getCoverBehaviorAtSide(aSide).manipulatesSidedRedstoneOutput(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this) || (mRedstone && getCoverBehaviorAtSide(aSide).letsRedstoneGoOut(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this))?mSidedRedstone[aSide]&15:0);
+ }
+
+
+ @Override
+ public void setInternalOutputRedstoneSignal(byte aSide, byte aStrength) {
+ if (!getCoverBehaviorAtSide(aSide).manipulatesSidedRedstoneOutput(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this))
+ setOutputRedstoneSignal(aSide, aStrength);
+ }
+
+
+ @Override
+ public void setOutputRedstoneSignal(byte aSide, byte aStrength) {
+ aStrength = (byte) Math.min(Math.max(0, aStrength), 15);
+ if (aSide >= 0 && aSide < 6 && mSidedRedstone[aSide] != aStrength) {
+ mSidedRedstone[aSide] = aStrength;
+ issueBlockUpdate();
+ }
+ }
+
+
+ @Override
+ public boolean isSteamEngineUpgradable() {
+ return isUpgradable() && !hasSteamEngineUpgrade() && getSteamCapacity() > 0;
+ }
+
+
+ @Override
+ public boolean addSteamEngineUpgrade() {
+ if (isSteamEngineUpgradable()) {
+ issueBlockUpdate();
+ mSteamConverter = true;
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public boolean hasSteamEngineUpgrade() {
+ if (canAccessData() && mMetaTileEntity.isSteampowered()) return true;
+ return mSteamConverter;
+ }
+
+
+ @Override
+ public boolean hasMufflerUpgrade() {
+ return mMuffler;
+ }
+
+
+ @Override
+ public boolean isMufflerUpgradable() {
+ return isUpgradable() && !hasMufflerUpgrade();
+ }
+
+
+ @Override
+ public boolean addMufflerUpgrade() {
+ if (isMufflerUpgradable()) return mMuffler = true;
+ return false;
+ }
+
+
+ @Override
+ public boolean hasInventoryBeenModified() {
+ return mInventoryChanged;
+ }
+
+
+ @Override
+ public void setGenericRedstoneOutput(boolean aOnOff) {
+ mRedstone = aOnOff;
+ }
+
+
+ @Override
+ public int getErrorDisplayID() {
+ return mDisplayErrorCode;
+ }
+
+
+ @Override
+ public void setErrorDisplayID(int aErrorID) {
+ mDisplayErrorCode = aErrorID;
+ }
+
+
+ @Override
+ public IMetaTileEntity getMetaTileEntity() {
+ return hasValidMetaTileEntity() ? mMetaTileEntity : null;
+ }
+
+
+ @Override
+ public void setMetaTileEntity(IMetaTileEntity aMetaTileEntity) {
+ mMetaTileEntity = (MetaTileEntityEx) aMetaTileEntity;
+ }
+
+
+ @Override
+ public GT_CoverBehavior getCoverBehaviorAtSide(byte aSide) {
+ return aSide >= 0 && aSide < mCoverBehaviors.length ? mCoverBehaviors[aSide] : GregTech_API.sNoBehavior;
+ }
+
+
+ @Override
+ public void setCoverIDAtSide(byte aSide, int aID) {
+ if (aSide >= 0 && aSide < 6) {
+ mCoverSides[aSide] = aID;
+ mCoverData[aSide] = 0;
+ mCoverBehaviors[aSide] = GregTech_API.getCoverBehavior(aID);
+ issueCoverUpdate(aSide);
+ issueBlockUpdate();
+ }
+ }
+
+
+ @Override
+ public void setCoverItemAtSide(byte aSide, ItemStack aCover) {
+ GregTech_API.getCoverBehavior(aCover).placeCover(aSide, aCover, this);
+ }
+
+
+ @Override
+ public int getCoverIDAtSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) return mCoverSides[aSide];
+ return 0;
+ }
+
+
+ @Override
+ public ItemStack getCoverItemAtSide(byte aSide) {
+ return GT_Utility.intToStack(getCoverIDAtSide(aSide));
+ }
+
+
+ @Override
+ public boolean canPlaceCoverIDAtSide(byte aSide, int aID) {
+ return getCoverIDAtSide(aSide) == 0;
+ }
+
+
+ @Override
+ public boolean canPlaceCoverItemAtSide(byte aSide, ItemStack aCover) {
+ return getCoverIDAtSide(aSide) == 0;
+ }
+
+
+ @Override
+ public void setCoverDataAtSide(byte aSide, int aData) {
+ if (aSide >= 0 && aSide < 6) mCoverData[aSide] = aData;
+ }
+
+
+ @Override
+ public int getCoverDataAtSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) return mCoverData[aSide];
+ return 0;
+ }
+
+
+ public byte getLightValue() {
+ return mLightValue;
+ }
+
+
+ @Override
+ public void setLightValue(byte aLightValue) {
+ mLightValue = (byte) (aLightValue & 15);
+ }
+
+
+ @Override
+ public long getAverageElectricInput() {
+ int rEU = 0;
+ for (int tEU : mAverageEUInput) rEU += tEU;
+ return rEU / mAverageEUInput.length;
+ }
+
+
+ @Override
+ public long getAverageElectricOutput() {
+ int rEU = 0;
+ for (int tEU : mAverageEUOutput) rEU += tEU;
+ return rEU / mAverageEUOutput.length;
+ }
+
+
+ @Override
+ public boolean dropCover(byte aSide, byte aDroppedSide, boolean aForced) {
+ if (getCoverBehaviorAtSide(aSide).onCoverRemoval(aSide, getCoverIDAtSide(aSide), mCoverData[aSide], this, aForced) || aForced) {
+ ItemStack tStack = getCoverBehaviorAtSide(aSide).getDrop(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this);
+ if (tStack != null) {
+ tStack.setTagCompound(null);
+ EntityItem tEntity = new EntityItem(worldObj, getOffsetX(aDroppedSide, 1) + 0.5, getOffsetY(aDroppedSide, 1) + 0.5, getOffsetZ(aDroppedSide, 1) + 0.5, tStack);
+ tEntity.motionX = 0;
+ tEntity.motionY = 0;
+ tEntity.motionZ = 0;
+ worldObj.spawnEntityInWorld(tEntity);
+ }
+ setCoverIDAtSide(aSide, 0);
+ if (mMetaTileEntity.hasSidedRedstoneOutputBehavior()) {
+ setOutputRedstoneSignal(aSide, (byte) 0);
+ } else {
+ setOutputRedstoneSignal(aSide, (byte) 15);
+ }
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public String getOwnerName() {
+ if (GT_Utility.isStringInvalid(mOwnerName)) return "Player";
+ return mOwnerName;
+ }
+
+
+ @Override
+ public String setOwnerName(String aName) {
+ if (GT_Utility.isStringInvalid(aName)) return mOwnerName = "Player";
+ return mOwnerName = aName;
+ }
+
+
+ @Override
+ public byte getComparatorValue(byte aSide) {
+ return canAccessData() ? mMetaTileEntity.getComparatorValue(aSide) : 0;
+ }
+
+
+ @Override
+ public byte getStrongOutputRedstoneSignal(byte aSide) {
+ return aSide >= 0 && aSide < 6 && (mStrongRedstone & (1 << aSide)) != 0 ? (byte) (mSidedRedstone[aSide] & 15) : 0;
+ }
+
+
+ @Override
+ public void setStrongOutputRedstoneSignal(byte aSide, byte aStrength) {
+ mStrongRedstone |= (1 << aSide);
+ setOutputRedstoneSignal(aSide, aStrength);
+ }
+
+
+ @Override
+ public ItemStack decrStackSize(int aIndex, int aAmount) {
+ if (canAccessData()) {
+ mInventoryChanged = true;
+ return mMetaTileEntity.decrStackSize(aIndex, aAmount);
+ }
+ return null;
+ }
+
+
+ @Override
+ public long injectEnergyUnits(byte aSide, long aVoltage, long aAmperage) {
+ if (!canAccessData() || !mMetaTileEntity.isElectric() || !inputEnergyFrom(aSide) || aAmperage <= 0 || aVoltage <= 0 || getStoredEU() >= getEUCapacity() || mMetaTileEntity.maxAmperesIn() <= mAcceptedAmperes)
+ return 0;
+ if (aVoltage > getInputVoltage()) {
+ doExplosion(aVoltage);
+ return 0;
+ }
+ if (increaseStoredEnergyUnits(aVoltage * (aAmperage = Math.min(aAmperage, Math.min(mMetaTileEntity.maxAmperesIn() - mAcceptedAmperes, 1 + ((getEUCapacity() - getStoredEU()) / aVoltage)))), true)) {
+ mAverageEUInput[mAverageEUInputIndex] += aVoltage * aAmperage;
+ mAcceptedAmperes += aAmperage;
+ return aAmperage;
+ }
+ return 0;
+ }
+
+
+ @Override
+ public boolean drainEnergyUnits(byte aSide, long aVoltage, long aAmperage) {
+ if (!canAccessData() || !mMetaTileEntity.isElectric() || !outputsEnergyTo(aSide) || getStoredEU() - (aVoltage * aAmperage) < mMetaTileEntity.getMinimumStoredEU())
+ return false;
+ if (decreaseStoredEU(aVoltage * aAmperage, false)) {
+ mAverageEUOutput[mAverageEUOutputIndex] += aVoltage * aAmperage;
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public boolean acceptsRotationalEnergy(byte aSide) {
+ if (!canAccessData() || getCoverIDAtSide(aSide) != 0) return false;
+ return mMetaTileEntity.acceptsRotationalEnergy(aSide);
+ }
+
+
+ @Override
+ public boolean injectRotationalEnergy(byte aSide, long aSpeed, long aEnergy) {
+ if (!canAccessData() || getCoverIDAtSide(aSide) != 0) return false;
+ return mMetaTileEntity.injectRotationalEnergy(aSide, aSpeed, aEnergy);
+ }
+
+
+ @Override
+ public int fill(ForgeDirection aSide, FluidStack aFluid, boolean doFill) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mInputDisabled) && (aSide == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidInput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidIn((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid == null ? null : aFluid.getFluid(), this))))
+ return mMetaTileEntity.fill(aSide, aFluid, doFill);
+ return 0;
+ }
+
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, int maxDrain, boolean doDrain) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mOutputDisabled) && (aSide == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), mMetaTileEntity.getFluid() == null ? null : mMetaTileEntity.getFluid().getFluid(), this))))
+ return mMetaTileEntity.drain(aSide, maxDrain, doDrain);
+ return null;
+ }
+
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, FluidStack aFluid, boolean doDrain) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mOutputDisabled) && (aSide == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid == null ? null : aFluid.getFluid(), this))))
+ return mMetaTileEntity.drain(aSide, aFluid, doDrain);
+ return null;
+ }
+
+
+ @Override
+ public boolean canFill(ForgeDirection aSide, Fluid aFluid) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mInputDisabled) && (aSide == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidInput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidIn((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid, this))))
+ return mMetaTileEntity.canFill(aSide, aFluid);
+ return false;
+ }
+
+
+ @Override
+ public boolean canDrain(ForgeDirection aSide, Fluid aFluid) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mOutputDisabled) && (aSide == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid, this))))
+ return mMetaTileEntity.canDrain(aSide, aFluid);
+ return false;
+ }
+
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection aSide) {
+ if (canAccessData() && (aSide == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidInput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidIn((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), null, this)) || (mMetaTileEntity.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), null, this))))
+ return mMetaTileEntity.getTankInfo(aSide);
+ return new FluidTankInfo[]{};
+ }
+
+
+ public double getOutputEnergyUnitsPerTick() {
+ return oOutput;
+ }
+
+
+ public boolean isTeleporterCompatible(ForgeDirection aSide) {
+ return canAccessData() && mMetaTileEntity.isTeleporterCompatible();
+ }
+
+
+ public double demandedEnergyUnits() {
+ if (mReleaseEnergy || !canAccessData() || !mMetaTileEntity.isEnetInput()) return 0;
+ return getEUCapacity() - getStoredEU();
+ }
+
+
+ public double injectEnergyUnits(ForgeDirection aDirection, double aAmount) {
+ return injectEnergyUnits((byte) aDirection.ordinal(), (int) aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+
+ public boolean acceptsEnergyFrom(TileEntity aEmitter, ForgeDirection aDirection) {
+ return inputEnergyFrom((byte) aDirection.ordinal());
+ }
+
+
+ public boolean emitsEnergyTo(TileEntity aReceiver, ForgeDirection aDirection) {
+ return outputsEnergyTo((byte) aDirection.ordinal());
+ }
+
+
+ public double getOfferedEnergy() {
+ return (canAccessData() && getStoredEU() - mMetaTileEntity.getMinimumStoredEU() >= oOutput) ? Math.max(0, oOutput) : 0;
+ }
+
+
+ public void drawEnergy(double amount) {
+ mAverageEUOutput[mAverageEUOutputIndex] += amount;
+ decreaseStoredEU((int) amount, true);
+ }
+
+
+ public int injectEnergy(ForgeDirection aForgeDirection, int aAmount) {
+ return injectEnergyUnits((byte) aForgeDirection.ordinal(), aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+
+ public int addEnergy(int aEnergy) {
+ if (!canAccessData()) return 0;
+ if (aEnergy > 0)
+ increaseStoredEnergyUnits(aEnergy, true);
+ else
+ decreaseStoredEU(-aEnergy, true);
+ return (int) Math.min(Integer.MAX_VALUE, mMetaTileEntity.getEUVar());
+ }
+
+
+ public boolean isAddedToEnergyNet() {
+ return false;
+ }
+
+
+ public int demandsEnergy() {
+ if (mReleaseEnergy || !canAccessData() || !mMetaTileEntity.isEnetInput()) return 0;
+ return getCapacity() - getStored();
+ }
+
+
+ public int getCapacity() {
+ return (int) Math.min(Integer.MAX_VALUE, getEUCapacity());
+ }
+
+
+ public int getStored() {
+ return (int) Math.min(Integer.MAX_VALUE, Math.min(getStoredEU(), getCapacity()));
+ }
+
+
+ public void setStored(int aEU) {
+ if (canAccessData()) setStoredEU(aEU);
+ }
+
+
+ public int getMaxSafeInput() {
+ return (int) Math.min(Integer.MAX_VALUE, getInputVoltage());
+ }
+
+
+ public int getMaxEnergyOutput() {
+ if (mReleaseEnergy) return Integer.MAX_VALUE;
+ return getOutput();
+ }
+
+
+ public int getOutput() {
+ return (int) Math.min(Integer.MAX_VALUE, oOutput);
+ }
+
+
+ public int injectEnergy(Direction aDirection, int aAmount) {
+ return injectEnergyUnits((byte) aDirection.toSideValue(), aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+
+ public boolean isTeleporterCompatible(Direction aSide) {
+ return canAccessData() && mMetaTileEntity.isTeleporterCompatible();
+ }
+
+
+ public boolean acceptsEnergyFrom(TileEntity aReceiver, Direction aDirection) {
+ return inputEnergyFrom((byte) aDirection.toSideValue());
+ }
+
+
+ public boolean emitsEnergyTo(TileEntity aReceiver, Direction aDirection) {
+ return outputsEnergyTo((byte) aDirection.toSideValue());
+ }
+
+
+ @Override
+ public boolean isInvalidTileEntity() {
+ return isInvalid();
+ }
+
+
+ @Override
+ public boolean addStackToSlot(int aIndex, ItemStack aStack) {
+ if (GT_Utility.isStackInvalid(aStack)) return true;
+ if (aIndex < 0 || aIndex >= getSizeInventory()) return false;
+ ItemStack tStack = getStackInSlot(aIndex);
+ if (GT_Utility.isStackInvalid(tStack)) {
+ setInventorySlotContents(aIndex, aStack);
+ return true;
+ }
+ aStack = GT_OreDictUnificator.get(aStack);
+ if (GT_Utility.areStacksEqual(tStack, aStack) && tStack.stackSize + aStack.stackSize <= Math.min(aStack.getMaxStackSize(), getInventoryStackLimit())) {
+ tStack.stackSize += aStack.stackSize;
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public boolean addStackToSlot(int aIndex, ItemStack aStack, int aAmount) {
+ return addStackToSlot(aIndex, GT_Utility.copyAmount(aAmount, aStack));
+ }
+
+
+ @Override
+ public byte getColorization() {
+ return (byte) (mColor - 1);
+ }
+
+
+ @Override
+ public byte setColorization(byte aColor) {
+ if (aColor > 15 || aColor < -1) aColor = -1;
+ if (canAccessData()) mMetaTileEntity.onColorChangeServer(aColor);
+ return mColor = (byte) (aColor + 1);
+ }
+
+
+ @Override
+ public float getBlastResistance(byte aSide) {
+ return canAccessData() ? Math.max(0, getMetaTileEntity().getExplosionResistance(aSide)) : 10.0F;
+ }
+
+
+ @Override
+ public boolean isUniversalEnergyStored(long aEnergyAmount) {
+ if (getUniversalEnergyStored() >= aEnergyAmount) return true;
+ mHasEnoughEnergy = false;
+ return false;
+ }
+
+
+ @Override
+ public String[] getInfoData() {
+ {
+ if (canAccessData()) return getMetaTileEntity().getInfoData();
+ return new String[]{};
+ }
+ }
+
+
+ @Override
+ public void markDirty() {
+ super.markDirty();
+ mInventoryChanged = true;
+ }
+
+
+ @Override
+ public int getLightOpacity() {
+ return mMetaTileEntity == null ? getLightValue() > 0 ? 0 : 255 : mMetaTileEntity.getLightOpacity();
+ }
+
+
+ @Override
+ public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, List<AxisAlignedBB> outputAABB, Entity collider) {
+ mMetaTileEntity.addCollisionBoxesToList(aWorld, aX, aY, aZ, inputAABB, outputAABB, collider);
+ }
+
+
+ @Override
+ public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) {
+ return mMetaTileEntity.getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ);
+ }
+
+
+ @Override
+ public void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity collider) {
+ mMetaTileEntity.onEntityCollidedWithBlock(aWorld, aX, aY, aZ, collider);
+ }
+} \ No newline at end of file
diff --git a/src/Java/gregtech/api/metatileentity/MetaTileEntityEx.java b/src/Java/gregtech/api/metatileentity/MetaTileEntityEx.java
new file mode 100644
index 0000000000..acfcf083be
--- /dev/null
+++ b/src/Java/gregtech/api/metatileentity/MetaTileEntityEx.java
@@ -0,0 +1,972 @@
+package gregtech.api.metatileentity;
+
+import static gregtech.api.enums.GT_Values.GT;
+import static gregtech.api.enums.GT_Values.V;
+import gregtech.api.GregTech_API;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.objects.GT_ItemStack;
+import gregtech.api.util.GT_Config;
+import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_ModHandler;
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.core.block.ModBlocks;
+import gtPlusPlus.core.util.Utils;
+import gtPlusPlus.xmod.gregtech.common.Meta_GT_Proxy;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.init.Blocks;
+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.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTankInfo;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/**
+ * NEVER INCLUDE THIS FILE IN YOUR MOD!!!
+ * <p/>
+ * Extend this Class to add a new MetaMachine
+ * Call the Constructor with the desired ID at the load-phase (not preload and also not postload!)
+ * Implement the newMetaEntity-Method to return a new ready instance of your MetaTileEntity
+ * <p/>
+ * Call the Constructor like the following example inside the Load Phase, to register it.
+ * "new GT_MetaTileEntity_E_Furnace(54, "GT_E_Furnace", "Automatic E-Furnace");"
+ */
+public abstract class MetaTileEntityEx implements IMetaTileEntity {
+ /**
+ * Only assigned for the MetaTileEntity in the List! Also only used to get the localized Name for the ItemStack and for getInvName.
+ */
+ public final String mName;
+ /**
+ * The Inventory of the MetaTileEntity. Amount of Slots can be larger than 256. HAYO!
+ */
+ public final ItemStack[] mInventory;
+ public boolean doTickProfilingInThisTick = true;
+ /**
+ * accessibility to this Field is no longer given, see below
+ */
+ private IGregTechTileEntity mBaseMetaTileEntity;
+
+ /**
+ * This registers your Machine at the List.
+ * Use only ID's larger than 2048, because i reserved these ones.
+ * See also the List in the API, as it has a Description containing all the reservations.
+ *
+ * @param aID the ID
+ * @example for Constructor overload.
+ * <p/>
+ * public GT_MetaTileEntity_EBench(int aID, String mName, String mNameRegional) {
+ * super(aID, mName, mNameRegional);
+ * }
+ */
+ public MetaTileEntityEx(int aID, String aBasicName, String aRegionalName, int aInvSlotCount) {
+ if (GregTech_API.sPostloadStarted || !GregTech_API.sPreloadStarted)
+ throw new IllegalAccessError("This Constructor has to be called in the load Phase");
+ if (Meta_GT_Proxy.METATILEENTITIES[aID] == null) {
+ Meta_GT_Proxy.METATILEENTITIES[aID] = this;
+ } else {
+ Utils.LOG_INFO("Taken by: "+Meta_GT_Proxy.METATILEENTITIES[aID].getMetaName());
+ throw new IllegalArgumentException("MetaMachine-Slot Nr. " + aID + " is already occupied!");
+ }
+ mName = aBasicName.replaceAll(" ", "_").toLowerCase();
+ setBaseMetaTileEntity(Meta_GT_Proxy.constructBaseMetaTileEntity());
+ getBaseMetaTileEntity().setMetaTileID((short) aID);
+ GT_LanguageManager.addStringLocalization("gt.plusplus.blockmachines." + mName + ".name", aRegionalName);
+ mInventory = new ItemStack[aInvSlotCount];
+
+ if (GT.isClientSide()) {
+ ItemStack tStack = new ItemStack(ModBlocks.blockMetaTileEntity, 1, aID);
+ tStack.getItem().addInformation(tStack, null, new ArrayList<String>(), true);
+ }
+ }
+
+ /**
+ * This is the normal Constructor.
+ */
+ public MetaTileEntityEx(String aName, int aInvSlotCount) {
+ mInventory = new ItemStack[aInvSlotCount];
+ mName = aName;
+ }
+
+
+ @Override
+ public IGregTechTileEntity getBaseMetaTileEntity() {
+ return mBaseMetaTileEntity;
+ }
+
+
+ @Override
+ public void setBaseMetaTileEntity(IGregTechTileEntity aBaseMetaTileEntity) {
+ if (mBaseMetaTileEntity != null && aBaseMetaTileEntity == null) {
+ mBaseMetaTileEntity.getMetaTileEntity().inValidate();
+ mBaseMetaTileEntity.setMetaTileEntity(null);
+ }
+ mBaseMetaTileEntity = aBaseMetaTileEntity;
+ if (mBaseMetaTileEntity != null) {
+ mBaseMetaTileEntity.setMetaTileEntity(this);
+ }
+ }
+
+
+ @Override
+ public ItemStack getStackForm(long aAmount) {
+ return new ItemStack(GregTech_API.sBlockMachines, (int) aAmount, getBaseMetaTileEntity().getMetaTileID());
+ }
+
+ public String getLocalName() {
+ return GT_LanguageManager.getTranslation("gt.plusplus.blockmachines." + mName + ".name");
+ }
+
+
+ @Override
+ public void onServerStart() {/*Do nothing*/}
+
+
+ @Override
+ public void onWorldSave(File aSaveDirectory) {/*Do nothing*/}
+
+
+ @Override
+ public void onWorldLoad(File aSaveDirectory) {/*Do nothing*/}
+
+
+ @Override
+ public void onConfigLoad(GT_Config aConfig) {/*Do nothing*/}
+
+
+ @Override
+ public void setItemNBT(NBTTagCompound aNBT) {/*Do nothing*/}
+
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerIcons(IIconRegister aBlockIconRegister) {/*Do nothing*/}
+
+
+ @Override
+ public boolean allowCoverOnSide(byte aSide, GT_ItemStack aStack) {
+ return true;
+ }
+
+
+ @Override
+ public void onScrewdriverRightClick(byte aSide, EntityPlayer aPlayer, float aX, float aY, float aZ) {/*Do nothing*/}
+
+
+ @Override
+ public boolean onWrenchRightClick(byte aSide, byte aWrenchingSide, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (getBaseMetaTileEntity().isValidFacing(aWrenchingSide)) {
+ getBaseMetaTileEntity().setFrontFacing(aWrenchingSide);
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public void onExplosion() {/*Do nothing*/}
+
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {/*Do nothing*/}
+
+
+ @Override
+ public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {/*Do nothing*/}
+
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {/*Do nothing*/}
+
+
+ @Override
+ public void inValidate() {/*Do nothing*/}
+
+
+ @Override
+ public void onRemoval() {/*Do nothing*/}
+
+
+ @Override
+ public void initDefaultModes(NBTTagCompound aNBT) {/*Do nothing*/}
+
+ /**
+ * When a GUI is opened
+ */
+ public void onOpenGUI() {/*Do nothing*/}
+
+ /**
+ * When a GUI is closed
+ */
+ public void onCloseGUI() {/*Do nothing*/}
+
+ /**
+ * a Player rightclicks the Machine
+ * Sneaky rightclicks are not getting passed to this!
+ */
+ public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
+ return false;
+ }
+
+
+ @Override
+ public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, byte aSide, float aX, float aY, float aZ) {
+ return onRightclick(aBaseMetaTileEntity, aPlayer);
+ }
+
+
+ @Override
+ public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {/*Do nothing*/}
+
+
+ @Override
+ public void onValueUpdate(byte aValue) {/*Do nothing*/}
+
+
+ @Override
+ public byte getUpdateData() {
+ return 0;
+ }
+
+
+ @Override
+ public void doSound(byte aIndex, double aX, double aY, double aZ) {/*Do nothing*/}
+
+
+ @Override
+ public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) {/*Do nothing*/}
+
+
+ @Override
+ public void stopSoundLoop(byte aValue, double aX, double aY, double aZ) {/*Do nothing*/}
+
+ /**
+ * @return true if this Device emits Energy at all
+ */
+ public boolean isElectric() {
+ return true;
+ }
+
+ /**
+ * @return true if this Device emits Energy at all
+ */
+ public boolean isPneumatic() {
+ return false;
+ }
+
+ /**
+ * @return true if this Device emits Energy at all
+ */
+ public boolean isSteampowered() {
+ return false;
+ }
+
+ /**
+ * @return true if this Device emits Energy at all
+ */
+ public boolean isEnetOutput() {
+ return false;
+ }
+
+ /**
+ * @return true if this Device consumes Energy at all
+ */
+ public boolean isEnetInput() {
+ return false;
+ }
+
+ /**
+ * @return the amount of EU, which can be stored in this Device. Default is 0 EU.
+ */
+
+ public long maxEUStore() {
+ return 0;
+ }
+
+ /**
+ * @return the amount of EU/t, which can be accepted by this Device before it explodes.
+ */
+
+ public long maxEUInput() {
+ return 0;
+ }
+
+ /**
+ * @return the amount of EU/t, which can be outputted by this Device.
+ */
+
+ public long maxEUOutput() {
+ return 0;
+ }
+
+ /**
+ * @return the amount of E-net Impulses of the maxEUOutput size, which can be outputted by this Device.
+ * Default is 1 Pulse, this shouldn't be set to smaller Values than 1, as it won't output anything in that Case!
+ */
+
+ public long maxAmperesOut() {
+ return 1;
+ }
+
+ /**
+ * How many Amperes this Block can suck at max. Surpassing this value won't blow it up.
+ */
+
+ public long maxAmperesIn() {
+ return 1;
+ }
+
+ /**
+ * @return true if that Side is an Output.
+ */
+
+ public boolean isOutputFacing(byte aSide) {
+ return false;
+ }
+
+ /**
+ * @return true if that Side is an Input.
+ */
+
+ public boolean isInputFacing(byte aSide) {
+ return false;
+ }
+
+ /**
+ * @return true if Transformer Upgrades increase Packet Amount.
+ */
+
+ public boolean isTransformingLowEnergy() {
+ return true;
+ }
+
+
+ @Override
+ public boolean isFacingValid(byte aFacing) {
+ return false;
+ }
+
+
+ @Override
+ public boolean isAccessAllowed(EntityPlayer aPlayer) {
+ return false;
+ }
+
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return true;
+ }
+
+
+ @Override
+ public boolean setStackToZeroInsteadOfNull(int aIndex) {
+ return false;
+ }
+
+ /**
+ * This is used to get the internal Energy. I use this for the IDSU.
+ */
+ public long getEUVar() {
+ return ((BaseMetaTileEntityEx) mBaseMetaTileEntity).mStoredEnergy;
+ }
+
+ /**
+ * This is used to set the internal Energy to the given Parameter. I use this for the IDSU.
+ */
+ public void setEUVar(long aEnergy) {
+ ((BaseMetaTileEntityEx) mBaseMetaTileEntity).mStoredEnergy = aEnergy;
+ }
+
+ /**
+ * This is used to get the internal Steam Energy.
+ */
+ public long getSteamVar() {
+ return ((BaseMetaTileEntityEx) mBaseMetaTileEntity).mStoredSteam;
+ }
+
+ /**
+ * This is used to set the internal Steam Energy to the given Parameter.
+ */
+ public void setSteamVar(long aSteam) {
+ ((BaseMetaTileEntityEx) mBaseMetaTileEntity).mStoredSteam = aSteam;
+ }
+
+ /**
+ * @return the amount of Steam, which can be stored in this Device. Default is 0 EU.
+ */
+
+ public long maxSteamStore() {
+ return 0;
+ }
+
+ /**
+ * @return the amount of EU, which this Device stores before starting to emit Energy.
+ * useful if you don't want to emit stored Energy until a certain Level is reached.
+ */
+
+ public long getMinimumStoredEU() {
+ return 512;
+ }
+
+ /**
+ * Determines the Tier of the Machine, used for de-charging Tools.
+ */
+
+ public long getInputTier() {
+ return GT_Utility.getTier(getBaseMetaTileEntity().getInputVoltage());
+ }
+
+ /**
+ * Determines the Tier of the Machine, used for charging Tools.
+ */
+
+ public long getOutputTier() {
+ return GT_Utility.getTier(getBaseMetaTileEntity().getOutputVoltage());
+ }
+
+ /**
+ * gets the first RechargerSlot
+ */
+
+ public int rechargerSlotStartIndex() {
+ return 0;
+ }
+
+ /**
+ * gets the amount of RechargerSlots
+ */
+
+ public int rechargerSlotCount() {
+ return 0;
+ }
+
+ /**
+ * gets the first DechargerSlot
+ */
+
+ public int dechargerSlotStartIndex() {
+ return 0;
+ }
+
+ /**
+ * gets the amount of DechargerSlots
+ */
+
+ public int dechargerSlotCount() {
+ return 0;
+ }
+
+ /**
+ * gets if this is protected from other Players per default or not
+ */
+
+ public boolean ownerControl() {
+ return false;
+ }
+
+
+ @Override
+ public ArrayList<String> getSpecialDebugInfo(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, int aLogLevel, ArrayList<String> aList) {
+ return aList;
+ }
+
+
+ @Override
+ public boolean isLiquidInput(byte aSide) {
+ return true;
+ }
+
+
+ @Override
+ public boolean isLiquidOutput(byte aSide) {
+ return true;
+ }
+
+ /**
+ * gets the contained Liquid
+ */
+
+ @Override
+ public FluidStack getFluid() {
+ return null;
+ }
+
+ /**
+ * tries to fill this Tank
+ */
+
+ @Override
+ public int fill(FluidStack resource, boolean doFill) {
+ return 0;
+ }
+
+ /**
+ * tries to empty this Tank
+ */
+
+ @Override
+ public FluidStack drain(int maxDrain, boolean doDrain) {
+ return null;
+ }
+
+ /**
+ * Tank pressure
+ */
+
+ public int getTankPressure() {
+ return 0;
+ }
+
+ /**
+ * Liquid Capacity
+ */
+
+ @Override
+ public int getCapacity() {
+ return 0;
+ }
+
+
+ @Override
+ public void onMachineBlockUpdate() {/*Do nothing*/}
+
+
+ @Override
+ public void receiveClientEvent(byte aEventID, byte aValue) {/*Do nothing*/}
+
+
+ @Override
+ public boolean isSimpleMachine() {
+ return false;
+ }
+
+ /**
+ * If this accepts up to 4 Overclockers
+ */
+
+ public boolean isOverclockerUpgradable() {
+ return false;
+ }
+
+ /**
+ * If this accepts Transformer Upgrades
+ */
+
+ public boolean isTransformerUpgradable() {
+ return false;
+ }
+
+ /**
+ * Progress this machine has already made
+ */
+
+ public int getProgresstime() {
+ return 0;
+ }
+
+ /**
+ * Progress this Machine has to do to produce something
+ */
+
+ public int maxProgresstime() {
+ return 0;
+ }
+
+ /**
+ * Increases the Progress, returns the overflown Progress.
+ */
+
+ public int increaseProgress(int aProgress) {
+ return 0;
+ }
+
+ /**
+ * If this TileEntity makes use of Sided Redstone behaviors.
+ * Determines only, if the Output Redstone Array is getting filled with 0 for true, or 15 for false.
+ */
+
+ public boolean hasSidedRedstoneOutputBehavior() {
+ return false;
+ }
+
+ /**
+ * When the Facing gets changed.
+ */
+
+ public void onFacingChange() {/*Do nothing*/}
+
+ /**
+ * if the IC2 Teleporter can drain from this.
+ */
+
+ public boolean isTeleporterCompatible() {
+ return isEnetOutput() && getBaseMetaTileEntity().getOutputVoltage() >= 128 && getBaseMetaTileEntity().getUniversalEnergyCapacity() >= 500000;
+ }
+
+ /**
+ * Gets the Output for the comparator on the given Side
+ */
+
+ @Override
+ public byte getComparatorValue(byte aSide) {
+ return 0;
+ }
+
+
+ @Override
+ public boolean acceptsRotationalEnergy(byte aSide) {
+ return false;
+ }
+
+
+ @Override
+ public boolean injectRotationalEnergy(byte aSide, long aSpeed, long aEnergy) {
+ return false;
+ }
+
+
+ @Override
+ public String getSpecialVoltageToolTip() {
+ return null;
+ }
+
+
+ @Override
+ public boolean isGivingInformation() {
+ return false;
+ }
+
+
+ @Override
+ public String[] getInfoData() {
+ return new String[]{};
+ }
+
+
+ public boolean isDigitalChest() {
+ return false;
+ }
+
+
+ public ItemStack[] getStoredItemData() {
+ return null;
+ }
+
+
+ public void setItemCount(int aCount) {/*Do nothing*/}
+
+
+ public int getMaxItemCount() {
+ return 0;
+ }
+
+
+ @Override
+ public int getSizeInventory() {
+ return mInventory.length;
+ }
+
+
+ @Override
+ public ItemStack getStackInSlot(int aIndex) {
+ if (aIndex >= 0 && aIndex < mInventory.length) return mInventory[aIndex];
+ return null;
+ }
+
+
+ @Override
+ public void setInventorySlotContents(int aIndex, ItemStack aStack) {
+ if (aIndex >= 0 && aIndex < mInventory.length) mInventory[aIndex] = aStack;
+ }
+
+
+ @Override
+ public String getInventoryName() {
+ if (GregTech_API.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()] != null)
+ return GregTech_API.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()].getMetaName();
+ return "";
+ }
+
+
+ @Override
+ public int getInventoryStackLimit() {
+ return 64;
+ }
+
+
+ @Override
+ public boolean isItemValidForSlot(int aIndex, ItemStack aStack) {
+ return getBaseMetaTileEntity().isValidSlot(aIndex);
+ }
+
+
+ @Override
+ public ItemStack decrStackSize(int aIndex, int aAmount) {
+ ItemStack tStack = getStackInSlot(aIndex), rStack = GT_Utility.copy(tStack);
+ if (tStack != null) {
+ if (tStack.stackSize <= aAmount) {
+ if (setStackToZeroInsteadOfNull(aIndex)) tStack.stackSize = 0;
+ else setInventorySlotContents(aIndex, null);
+ } else {
+ rStack = tStack.splitStack(aAmount);
+ if (tStack.stackSize == 0 && !setStackToZeroInsteadOfNull(aIndex))
+ setInventorySlotContents(aIndex, null);
+ }
+ }
+ return rStack;
+ }
+
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int aSide) {
+ ArrayList<Integer> tList = new ArrayList<Integer>();
+ IGregTechTileEntity tTileEntity = getBaseMetaTileEntity();
+ boolean tSkip = tTileEntity.getCoverBehaviorAtSide((byte) aSide).letsItemsIn((byte) aSide, tTileEntity.getCoverIDAtSide((byte) aSide), tTileEntity.getCoverDataAtSide((byte) aSide), -2, tTileEntity) || tTileEntity.getCoverBehaviorAtSide((byte) aSide).letsItemsOut((byte) aSide, tTileEntity.getCoverIDAtSide((byte) aSide), tTileEntity.getCoverDataAtSide((byte) aSide), -2, tTileEntity);
+ for (int i = 0; i < getSizeInventory(); i++)
+ if (isValidSlot(i) && (tSkip || tTileEntity.getCoverBehaviorAtSide((byte) aSide).letsItemsOut((byte) aSide, tTileEntity.getCoverIDAtSide((byte) aSide), tTileEntity.getCoverDataAtSide((byte) aSide), i, tTileEntity) || tTileEntity.getCoverBehaviorAtSide((byte) aSide).letsItemsIn((byte) aSide, tTileEntity.getCoverIDAtSide((byte) aSide), tTileEntity.getCoverDataAtSide((byte) aSide), i, tTileEntity)))
+ tList.add(i);
+ int[] rArray = new int[tList.size()];
+ for (int i = 0; i < rArray.length; i++) rArray[i] = tList.get(i);
+ return rArray;
+ }
+
+
+ @Override
+ public boolean canInsertItem(int aIndex, ItemStack aStack, int aSide) {
+ return isValidSlot(aIndex) && aStack != null && aIndex < mInventory.length && (mInventory[aIndex] == null || GT_Utility.areStacksEqual(aStack, mInventory[aIndex])) && allowPutStack(getBaseMetaTileEntity(), aIndex, (byte) aSide, aStack);
+ }
+
+
+ @Override
+ public boolean canExtractItem(int aIndex, ItemStack aStack, int aSide) {
+ return isValidSlot(aIndex) && aStack != null && aIndex < mInventory.length && allowPullStack(getBaseMetaTileEntity(), aIndex, (byte) aSide, aStack);
+ }
+
+
+ @Override
+ public boolean canFill(ForgeDirection aSide, Fluid aFluid) {
+ return fill(aSide, new FluidStack(aFluid, 1), false) == 1;
+ }
+
+
+ @Override
+ public boolean canDrain(ForgeDirection aSide, Fluid aFluid) {
+ return drain(aSide, new FluidStack(aFluid, 1), false) != null;
+ }
+
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection aSide) {
+ if (getCapacity() <= 0 && !getBaseMetaTileEntity().hasSteamEngineUpgrade()) return new FluidTankInfo[]{};
+ return new FluidTankInfo[]{getInfo()};
+ }
+
+
+ public int fill_default(ForgeDirection aSide, FluidStack aFluid, boolean doFill) {
+ return fill(aFluid, doFill);
+ }
+
+
+ @Override
+ public int fill(ForgeDirection aSide, FluidStack aFluid, boolean doFill) {
+ if (getBaseMetaTileEntity().hasSteamEngineUpgrade() && GT_ModHandler.isSteam(aFluid) && aFluid.amount > 1) {
+ int tSteam = (int) Math.min(Integer.MAX_VALUE, Math.min(aFluid.amount / 2, getBaseMetaTileEntity().getSteamCapacity() - getBaseMetaTileEntity().getStoredSteam()));
+ if (tSteam > 0) {
+ if (doFill) getBaseMetaTileEntity().increaseStoredSteam(tSteam, true);
+ return tSteam * 2;
+ }
+ } else {
+ return fill_default(aSide, aFluid, doFill);
+ }
+ return 0;
+ }
+
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, FluidStack aFluid, boolean doDrain) {
+ if (getFluid() != null && aFluid != null && getFluid().isFluidEqual(aFluid))
+ return drain(aFluid.amount, doDrain);
+ return null;
+ }
+
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, int maxDrain, boolean doDrain) {
+ return drain(maxDrain, doDrain);
+ }
+
+
+ @Override
+ public int getFluidAmount() {
+ return 0;
+ }
+
+
+ @Override
+ public FluidTankInfo getInfo() {
+ return new FluidTankInfo(this);
+ }
+
+
+ @Override
+ public String getMetaName() {
+ return mName;
+ }
+
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(int i) {
+ return null;
+ }
+
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return false;
+ }
+
+
+ @Override
+ public boolean doTickProfilingMessageDuringThisTick() {
+ return doTickProfilingInThisTick;
+ }
+
+
+ @Override
+ public void markDirty() {
+ //
+ }
+
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer entityplayer) {
+ return false;
+ }
+
+
+ @Override
+ public void openInventory() {
+ //
+ }
+
+
+ @Override
+ public void closeInventory() {
+ //
+ }
+
+
+ @Override
+ public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ return null;
+ }
+
+
+ @Override
+ public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ return null;
+ }
+
+
+ @Override
+ public boolean connectsToItemPipe(byte aSide) {
+ return false;
+ }
+
+
+ @Override
+ public float getExplosionResistance(byte aSide) {
+ return 10.0F;
+ }
+
+
+ @Override
+ public ItemStack[] getRealInventory() {
+ return mInventory;
+ }
+
+
+ @Override
+ public void onColorChangeServer(byte aColor) {
+ //
+ }
+
+
+ @Override
+ public void onColorChangeClient(byte aColor) {
+ //
+ }
+
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public boolean renderInInventory(Block aBlock, int aMeta, RenderBlocks aRenderer) {
+ return false;
+ }
+
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public boolean renderInWorld(IBlockAccess aWorld, int aX, int aY, int aZ, Block aBlock, RenderBlocks aRenderer) {
+ return false;
+ }
+
+
+ @Override
+ public void doExplosion(long aExplosionPower) {
+ float tStrength = aExplosionPower < V[0] ? 1.0F : aExplosionPower < V[1] ? 2.0F : aExplosionPower < V[2] ? 3.0F : aExplosionPower < V[3] ? 4.0F : aExplosionPower < V[4] ? 5.0F : aExplosionPower < V[4] * 2 ? 6.0F : aExplosionPower < V[5] ? 7.0F : aExplosionPower < V[6] ? 8.0F : aExplosionPower < V[7] ? 9.0F : 10.0F;
+ int tX = getBaseMetaTileEntity().getXCoord(), tY = getBaseMetaTileEntity().getYCoord(), tZ = getBaseMetaTileEntity().getZCoord();
+ World tWorld = getBaseMetaTileEntity().getWorld();
+ GT_Utility.sendSoundToPlayers(tWorld, GregTech_API.sSoundList.get(209), 1.0F, -1, tX, tY, tZ);
+ tWorld.setBlock(tX, tY, tZ, Blocks.air);
+ if (GregTech_API.sMachineExplosions)
+ tWorld.createExplosion(null, tX + 0.5, tY + 0.5, tZ + 0.5, tStrength, true);
+ }
+
+
+ @Override
+ public int getLightOpacity() {
+ return ((BaseMetaTileEntityEx) getBaseMetaTileEntity()).getLightValue() > 0 ? 0 : 255;
+ }
+
+
+ @Override
+ public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, List<AxisAlignedBB> outputAABB, Entity collider) {
+ AxisAlignedBB axisalignedbb1 = getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ);
+ if (axisalignedbb1 != null && inputAABB.intersectsWith(axisalignedbb1)) outputAABB.add(axisalignedbb1);
+ }
+
+
+ @Override
+ public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) {
+ return AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1, aY + 1, aZ + 1);
+ }
+
+
+ @Override
+ public void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity collider) {
+ //
+ }
+
+
+ @Override
+ public void onCreated(ItemStack aStack, World aWorld, EntityPlayer aPlayer) {
+ //
+ }
+} \ No newline at end of file
diff --git a/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachineEx.java b/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachineEx.java
new file mode 100644
index 0000000000..fbf59d4de5
--- /dev/null
+++ b/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachineEx.java
@@ -0,0 +1,798 @@
+package gregtech.api.metatileentity.implementations;
+
+import static gregtech.api.enums.GT_Values.V;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Textures;
+import gregtech.api.gui.GT_Container_BasicMachine;
+import gregtech.api.gui.GT_GUIContainer_BasicMachine;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.objects.GT_ItemStack;
+import gregtech.api.objects.GT_RenderedTexture;
+import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_Recipe;
+import gregtech.api.util.GT_Recipe.GT_Recipe_Map;
+import gregtech.api.util.GT_Utility;
+
+import java.util.Arrays;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.IFluidHandler;
+
+/**
+ * NEVER INCLUDE THIS FILE IN YOUR MOD!!!
+ * <p/>
+ * This is the main construct for my Basic Machines such as the Automatic Extractor
+ * Extend this class to make a simple Machine
+ */
+public abstract class GT_MetaTileEntity_BasicMachineEx extends GT_MetaTileEntity_BasicTankEx {
+ /**
+ * return values for checkRecipe()
+ */
+ protected static final int
+ DID_NOT_FIND_RECIPE = 0,
+ FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS = 1,
+ FOUND_AND_SUCCESSFULLY_USED_RECIPE = 2;
+ private static final int OTHER_SLOT_COUNT = 4;
+ public final ItemStack[] mOutputItems;
+ public final int mInputSlotCount, mAmperage;
+ public boolean mAllowInputFromOutputSide = false, mFluidTransfer = false, mItemTransfer = false, mHasBeenUpdated = false, mStuttering = false, mCharge = false, mDecharge = false;
+ public int mMainFacing = -1, mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mOutputBlocked = 0;
+ public FluidStack mOutputFluid;
+ public String mGUIName = "", mNEIName = "";
+ private NBTTagCompound mRecipeStuff = new NBTTagCompound();
+ /**
+ * Contains the Recipe which has been previously used, or null if there was no previous Recipe, which could have been buffered
+ */
+ protected GT_Recipe mLastRecipe = null;
+ private FluidStack mFluidOut;
+
+ /**
+ * @param aOverlays 0 = SideFacingActive
+ * 1 = SideFacingInactive
+ * 2 = FrontFacingActive
+ * 3 = FrontFacingInactive
+ * 4 = TopFacingActive
+ * 5 = TopFacingInactive
+ * 6 = BottomFacingActive
+ * 7 = BottomFacingInactive
+ * ----- Not all Array Elements have to be initialised, you can also just use 8 Parameters for the Default Pipe Texture Overlays -----
+ * 8 = BottomFacingPipeActive
+ * 9 = BottomFacingPipeInactive
+ * 10 = TopFacingPipeActive
+ * 11 = TopFacingPipeInactive
+ * 12 = SideFacingPipeActive
+ * 13 = SideFacingPipeInactive
+ */
+ public GT_MetaTileEntity_BasicMachineEx(int aID, String aName, String aNameRegional, int aTier, int aAmperage, String aDescription, int aInputSlotCount, int aOutputSlotCount, String aGUIName, String aNEIName, ITexture... aOverlays) {
+ super(aID, aName, aNameRegional, aTier, OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, aDescription, aOverlays);
+ mInputSlotCount = Math.max(0, aInputSlotCount);
+ mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)];
+ mAmperage = aAmperage;
+ mGUIName = aGUIName;
+ mNEIName = aNEIName;
+ }
+
+ public GT_MetaTileEntity_BasicMachineEx(String aName, int aTier, int aAmperage, String aDescription, ITexture[][][] aTextures, int aInputSlotCount, int aOutputSlotCount, String aGUIName, String aNEIName) {
+ super(aName, aTier, OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, aDescription, aTextures);
+ mInputSlotCount = Math.max(0, aInputSlotCount);
+ mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)];
+ mAmperage = aAmperage;
+ mGUIName = aGUIName;
+ mNEIName = aNEIName;
+ }
+
+ @Override
+ public ITexture[][][] getTextureSet(ITexture[] aTextures) {
+ ITexture[][][] rTextures = new ITexture[14][17][];
+ aTextures = Arrays.copyOf(aTextures, 14);
+
+ for (int i = 0; i < aTextures.length; i++)
+ if (aTextures[i] != null) for (byte c = -1; c < 16; c++) {
+ if (rTextures[i][c + 1] == null)
+ rTextures[i][c + 1] = new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][c + 1], aTextures[i]};
+ }
+
+ for (byte c = -1; c < 16; c++) {
+ if (rTextures[0][c + 1] == null) rTextures[0][c + 1] = getSideFacingActive(c);
+ if (rTextures[1][c + 1] == null) rTextures[1][c + 1] = getSideFacingInactive(c);
+ if (rTextures[2][c + 1] == null) rTextures[2][c + 1] = getFrontFacingActive(c);
+ if (rTextures[3][c + 1] == null) rTextures[3][c + 1] = getFrontFacingInactive(c);
+ if (rTextures[4][c + 1] == null) rTextures[4][c + 1] = getTopFacingActive(c);
+ if (rTextures[5][c + 1] == null) rTextures[5][c + 1] = getTopFacingInactive(c);
+ if (rTextures[6][c + 1] == null) rTextures[6][c + 1] = getBottomFacingActive(c);
+ if (rTextures[7][c + 1] == null) rTextures[7][c + 1] = getBottomFacingInactive(c);
+ if (rTextures[8][c + 1] == null) rTextures[8][c + 1] = getBottomFacingPipeActive(c);
+ if (rTextures[9][c + 1] == null) rTextures[9][c + 1] = getBottomFacingPipeInactive(c);
+ if (rTextures[10][c + 1] == null) rTextures[10][c + 1] = getTopFacingPipeActive(c);
+ if (rTextures[11][c + 1] == null) rTextures[11][c + 1] = getTopFacingPipeInactive(c);
+ if (rTextures[12][c + 1] == null) rTextures[12][c + 1] = getSideFacingPipeActive(c);
+ if (rTextures[13][c + 1] == null) rTextures[13][c + 1] = getSideFacingPipeInactive(c);
+ }
+ return rTextures;
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, byte aSide, byte aFacing, byte aColorIndex, boolean aActive, boolean aRedstone) {
+ return mTextures[mMainFacing < 2 ? aSide == aFacing ? aActive ? 2 : 3 : aSide == 0 ? aActive ? 6 : 7 : aSide == 1 ? aActive ? 4 : 5 : aActive ? 0 : 1 : aSide == mMainFacing ? aActive ? 2 : 3 : (showPipeFacing() && aSide == aFacing) ? aSide == 0 ? aActive ? 8 : 9 : aSide == 1 ? aActive ? 10 : 11 : aActive ? 12 : 13 : aSide == 0 ? aActive ? 6 : 7 : aSide == 1 ? aActive ? 4 : 5 : aActive ? 0 : 1][aColorIndex + 1];
+ }
+
+ @Override
+ public boolean isSimpleMachine() {
+ return false;
+ }
+
+ @Override
+ public boolean isOverclockerUpgradable() {
+ return false;
+ }
+
+ @Override
+ public boolean isTransformerUpgradable() {
+ return false;
+ }
+
+ @Override
+ public boolean isElectric() {
+ return true;
+ }
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return aIndex > 0 && super.isValidSlot(aIndex) && aIndex != OTHER_SLOT_COUNT + mInputSlotCount + mOutputItems.length;
+ }
+
+ @Override
+ public boolean isFacingValid(byte aFacing) {
+ return mMainFacing > 1 || aFacing > 1;
+ }
+
+ @Override
+ public boolean isEnetInput() {
+ return true;
+ }
+
+ @Override
+ public boolean isInputFacing(byte aSide) {
+ return aSide != mMainFacing;
+ }
+
+ @Override
+ public boolean isOutputFacing(byte aSide) {
+ return false;
+ }
+
+ @Override
+ public boolean isTeleporterCompatible() {
+ return false;
+ }
+
+ @Override
+ public boolean isLiquidInput(byte aSide) {
+ return aSide != mMainFacing && (mAllowInputFromOutputSide || aSide != getBaseMetaTileEntity().getFrontFacing());
+ }
+
+ @Override
+ public boolean isLiquidOutput(byte aSide) {
+ return aSide != mMainFacing;
+ }
+
+ @Override
+ public long getMinimumStoredEU() {
+ return V[mTier] * 16;
+ }
+
+ @Override
+ public long maxEUStore() {
+ return V[mTier] * 64;
+ }
+
+ @Override
+ public long maxEUInput() {
+ return V[mTier];
+ }
+
+ @Override
+ public long maxSteamStore() {
+ return maxEUStore();
+ }
+
+ @Override
+ public long maxAmperesIn() {
+ return (mEUt * 2) / V[mTier] + 1;
+ }
+
+ @Override
+ public int getInputSlot() {
+ return OTHER_SLOT_COUNT;
+ }
+
+ @Override
+ public int getOutputSlot() {
+ return OTHER_SLOT_COUNT + mInputSlotCount;
+ }
+
+ @Override
+ public int getStackDisplaySlot() {
+ return 2;
+ }
+
+ @Override
+ public int rechargerSlotStartIndex() {
+ return 1;
+ }
+
+ @Override
+ public int dechargerSlotStartIndex() {
+ return 1;
+ }
+
+ @Override
+ public int rechargerSlotCount() {
+ return mCharge ? 1 : 0;
+ }
+
+ @Override
+ public int dechargerSlotCount() {
+ return mDecharge ? 1 : 0;
+ }
+
+ @Override
+ public boolean isAccessAllowed(EntityPlayer aPlayer) {
+ return true;
+ }
+
+ @Override
+ public int getProgresstime() {
+ return mProgresstime;
+ }
+
+ @Override
+ public int maxProgresstime() {
+ return mMaxProgresstime;
+ }
+
+ @Override
+ public int increaseProgress(int aProgress) {
+ mProgresstime += aProgress;
+ return mMaxProgresstime - mProgresstime;
+ }
+
+ @Override
+ public boolean isFluidInputAllowed(FluidStack aFluid) {
+ return getFillableStack() != null || (getRecipeList() != null && getRecipeList().containsInput(aFluid));
+ }
+
+ @Override
+ public boolean isFluidChangingAllowed() {
+ return true;
+ }
+
+ @Override
+ public boolean doesFillContainers() {
+ return false;
+ }
+
+ @Override
+ public boolean doesEmptyContainers() {
+ return false;
+ }
+
+ @Override
+ public boolean canTankBeFilled() {
+ return true;
+ }
+
+ @Override
+ public boolean canTankBeEmptied() {
+ return true;
+ }
+
+ @Override
+ public boolean displaysItemStack() {
+ return true;
+ }
+
+ @Override
+ public boolean displaysStackSize() {
+ return true;
+ }
+
+ @Override
+ public FluidStack getDisplayedFluid() {
+ return displaysOutputFluid() ? getDrainableStack() : null;
+ }
+
+ @Override
+ public FluidStack getDrainableStack() {
+ return mFluidOut;
+ }
+
+ @Override
+ public FluidStack setDrainableStack(FluidStack aFluid) {
+ mFluidOut = aFluid;
+ return mFluidOut;
+ }
+
+ @Override
+ public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
+ if (aBaseMetaTileEntity.isClientSide()) return true;
+ aBaseMetaTileEntity.openGUI(aPlayer);
+ return true;
+ }
+
+ @Override
+ public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ return new GT_Container_BasicMachine(aPlayerInventory, aBaseMetaTileEntity);
+ }
+
+ @Override
+ public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ return new GT_GUIContainer_BasicMachine(aPlayerInventory, aBaseMetaTileEntity, getLocalName(), mGUIName, GT_Utility.isStringValid(mNEIName) ? mNEIName : getRecipeList() != null ? getRecipeList().mUnlocalizedName : "");
+ }
+
+ @Override
+ public void initDefaultModes(NBTTagCompound aNBT) {
+ mMainFacing = -1;
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setBoolean("mFluidTransfer", mFluidTransfer);
+ aNBT.setBoolean("mItemTransfer", mItemTransfer);
+ aNBT.setBoolean("mHasBeenUpdated", mHasBeenUpdated);
+ aNBT.setBoolean("mAllowInputFromOutputSide", mAllowInputFromOutputSide);
+ aNBT.setInteger("mEUt", mEUt);
+ aNBT.setInteger("mMainFacing", mMainFacing);
+ aNBT.setInteger("mProgresstime", mProgresstime);
+ aNBT.setInteger("mMaxProgresstime", mMaxProgresstime);
+ aNBT.setTag("GT.CraftingComponents", mRecipeStuff);
+ if (mOutputFluid != null) aNBT.setTag("mOutputFluid", mOutputFluid.writeToNBT(new NBTTagCompound()));
+ if (mFluidOut != null) aNBT.setTag("mFluidOut", mFluidOut.writeToNBT(new NBTTagCompound()));
+
+ for (int i = 0; i < mOutputItems.length; i++)
+ if (mOutputItems[i] != null)
+ aNBT.setTag("mOutputItem" + i, mOutputItems[i].writeToNBT(new NBTTagCompound()));
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ mFluidTransfer = aNBT.getBoolean("mFluidTransfer");
+ mItemTransfer = aNBT.getBoolean("mItemTransfer");
+ mHasBeenUpdated = aNBT.getBoolean("mHasBeenUpdated");
+ mAllowInputFromOutputSide = aNBT.getBoolean("mAllowInputFromOutputSide");
+ mEUt = aNBT.getInteger("mEUt");
+ mMainFacing = aNBT.getInteger("mMainFacing");
+ mProgresstime = aNBT.getInteger("mProgresstime");
+ mMaxProgresstime = aNBT.getInteger("mMaxProgresstime");
+ mRecipeStuff = aNBT.getCompoundTag("GT.CraftingComponents");
+ mOutputFluid = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mOutputFluid"));
+ mFluidOut = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluidOut"));
+
+ for (int i = 0; i < mOutputItems.length; i++) mOutputItems[i] = GT_Utility.loadItem(aNBT, "mOutputItem" + i);
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+
+ if (aBaseMetaTileEntity.isServerSide()) {
+ mCharge = aBaseMetaTileEntity.getStoredEU() / 2 > aBaseMetaTileEntity.getEUCapacity() / 3;
+ mDecharge = aBaseMetaTileEntity.getStoredEU() < aBaseMetaTileEntity.getEUCapacity() / 3;
+
+ doDisplayThings();
+
+ boolean tSucceeded = false;
+
+ if (mMaxProgresstime > 0 && (mProgresstime >= 0 || aBaseMetaTileEntity.isAllowedToWork())) {
+ aBaseMetaTileEntity.setActive(true);
+ if (mProgresstime < 0 || drainEnergyForProcess(mEUt)) {
+ if (++mProgresstime >= mMaxProgresstime) {
+ for (int i = 0; i < mOutputItems.length; i++)
+ for (int j = 0; j < mOutputItems.length; j++)
+ if (aBaseMetaTileEntity.addStackToSlot(getOutputSlot() + ((j + i) % mOutputItems.length), mOutputItems[i]))
+ break;
+ if (mOutputFluid != null)
+ if (getDrainableStack() == null) setDrainableStack(mOutputFluid.copy());
+ else if (mOutputFluid.isFluidEqual(getDrainableStack()))
+ getDrainableStack().amount += mOutputFluid.amount;
+ for (int i = 0; i < mOutputItems.length; i++) mOutputItems[i] = null;
+ mOutputFluid = null;
+ mEUt = 0;
+ mProgresstime = 0;
+ mMaxProgresstime = 0;
+ mStuttering = false;
+ tSucceeded = true;
+ endProcess();
+ }
+ if (mProgresstime > 5) mStuttering = false;
+ } else {
+ if (!mStuttering) {
+ stutterProcess();
+ if (canHaveInsufficientEnergy()) mProgresstime = -100;
+ mStuttering = true;
+ }
+ }
+ } else {
+ aBaseMetaTileEntity.setActive(false);
+ }
+
+ boolean tRemovedOutputFluid = false;
+
+ if (doesAutoOutputFluids() && getDrainableStack() != null && aBaseMetaTileEntity.getFrontFacing() != mMainFacing && (tSucceeded || aTick % 20 == 0)) {
+ IFluidHandler tTank = aBaseMetaTileEntity.getITankContainerAtSide(aBaseMetaTileEntity.getFrontFacing());
+ if (tTank != null) {
+ FluidStack tDrained = drain(1000, false);
+ if (tDrained != null) {
+ int tFilledAmount = tTank.fill(ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()), tDrained, false);
+ if (tFilledAmount > 0)
+ tTank.fill(ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()), drain(tFilledAmount, true), true);
+ }
+ }
+ if (getDrainableStack() == null) tRemovedOutputFluid = true;
+ }
+
+ if (doesAutoOutput() && !isOutputEmpty() && aBaseMetaTileEntity.getFrontFacing() != mMainFacing && (tSucceeded || mOutputBlocked % 300 == 1 || aBaseMetaTileEntity.hasInventoryBeenModified() || aTick % 600 == 0)) {
+ TileEntity tTileEntity2 = aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getFrontFacing());
+ for (int i = 0, tCosts = 1; i < mOutputItems.length && tCosts > 0 && aBaseMetaTileEntity.isUniversalEnergyStored(128); i++) {
+ tCosts = GT_Utility.moveOneItemStack(aBaseMetaTileEntity, tTileEntity2, aBaseMetaTileEntity.getFrontFacing(), aBaseMetaTileEntity.getBackFacing(), null, false, (byte) 64, (byte) 1, (byte) 64, (byte) 1);
+ if (tCosts > 0) aBaseMetaTileEntity.decreaseStoredEnergyUnits(tCosts, true);
+ }
+ }
+
+ if (mOutputBlocked != 0) if (isOutputEmpty()) mOutputBlocked = 0;
+ else mOutputBlocked++;
+
+ if (allowToCheckRecipe()) {
+ if (mMaxProgresstime <= 0 && aBaseMetaTileEntity.isAllowedToWork() && (tRemovedOutputFluid || tSucceeded || aBaseMetaTileEntity.hasInventoryBeenModified() || aTick % 600 == 0 || aBaseMetaTileEntity.hasWorkJustBeenEnabled()) && hasEnoughEnergyToCheckRecipe()) {
+ if (checkRecipe() == 2) {
+ if (mInventory[3] != null && mInventory[3].stackSize <= 0) mInventory[3] = null;
+ for (int i = getInputSlot(), j = i + mInputSlotCount; i < j; i++)
+ if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null;
+ for (int i = 0; i < mOutputItems.length; i++) {
+ mOutputItems[i] = GT_Utility.copy(mOutputItems[i]);
+ if (mOutputItems[i] != null && mOutputItems[i].stackSize > 64)
+ mOutputItems[i].stackSize = 64;
+ mOutputItems[i] = GT_OreDictUnificator.get(true, mOutputItems[i]);
+ }
+ if (mFluid != null && mFluid.amount <= 0) mFluid = null;
+ mMaxProgresstime = Math.max(1, mMaxProgresstime);
+ if (GT_Utility.isDebugItem(mInventory[dechargerSlotStartIndex()])) {
+ mEUt = mMaxProgresstime = 1;
+ }
+ startProcess();
+ } else {
+ mMaxProgresstime = 0;
+ for (int i = 0; i < mOutputItems.length; i++) mOutputItems[i] = null;
+ mOutputFluid = null;
+ }
+ }
+ } else {
+ if (!mStuttering) {
+ stutterProcess();
+ mStuttering = true;
+ }
+ }
+ }
+ }
+
+ protected void doDisplayThings() {
+ if (mMainFacing < 2 && getBaseMetaTileEntity().getFrontFacing() > 1) {
+ mMainFacing = getBaseMetaTileEntity().getFrontFacing();
+ }
+ if (mMainFacing >= 2 && !mHasBeenUpdated) {
+ mHasBeenUpdated = true;
+ getBaseMetaTileEntity().setFrontFacing(getBaseMetaTileEntity().getBackFacing());
+ }
+
+ if (displaysInputFluid()) {
+ int tDisplayStackSlot = OTHER_SLOT_COUNT + mInputSlotCount + mOutputItems.length;
+ if (getFillableStack() == null) {
+ if (ItemList.Display_Fluid.isStackEqual(mInventory[tDisplayStackSlot], true, true))
+ mInventory[tDisplayStackSlot] = null;
+ } else {
+ mInventory[tDisplayStackSlot] = GT_Utility.getFluidDisplayStack(getFillableStack(), displaysStackSize());
+ }
+ }
+ }
+
+ protected boolean hasEnoughEnergyToCheckRecipe() {
+ return getBaseMetaTileEntity().isUniversalEnergyStored(getMinimumStoredEU() / 2);
+ }
+
+ protected boolean drainEnergyForProcess(long aEUt) {
+ return getBaseMetaTileEntity().decreaseStoredEnergyUnits(aEUt, false);
+ }
+
+ protected void calculateOverclockedNess(GT_Recipe aRecipe) {
+ calculateOverclockedNess(aRecipe.mEUt, aRecipe.mDuration);
+ }
+
+ protected void calculateOverclockedNess(int aEUt, int aDuration) {
+ if (aEUt <= 16) {
+ mEUt = aEUt * (1 << (mTier - 1)) * (1 << (mTier - 1));
+ mMaxProgresstime = aDuration / (1 << (mTier - 1));
+ } else {
+ mEUt = aEUt;
+ mMaxProgresstime = aDuration;
+ while (mEUt <= V[mTier - 1] * mAmperage) {
+ mEUt *= 4;
+ mMaxProgresstime /= 2;
+ }
+ }
+ }
+
+ protected ItemStack getSpecialSlot() {
+ return mInventory[3];
+ }
+
+ protected ItemStack getOutputAt(int aIndex) {
+ return mInventory[getOutputSlot() + aIndex];
+ }
+
+ protected ItemStack[] getAllOutputs() {
+ ItemStack[] rOutputs = new ItemStack[mOutputItems.length];
+ for (int i = 0; i < mOutputItems.length; i++) rOutputs[i] = getOutputAt(i);
+ return rOutputs;
+ }
+
+ protected boolean canOutput(GT_Recipe aRecipe) {
+ return aRecipe != null && (aRecipe.mNeedsEmptyOutput ? isOutputEmpty() && getDrainableStack() == null : canOutput(aRecipe.getFluidOutput(0)) && canOutput(aRecipe.mOutputs));
+ }
+
+ protected boolean canOutput(ItemStack... aOutputs) {
+ if (aOutputs == null) return true;
+ ItemStack[] tOutputSlots = getAllOutputs();
+ for (int i = 0; i < tOutputSlots.length && i < aOutputs.length; i++)
+ if (tOutputSlots[i] != null && aOutputs[i] != null && (!GT_Utility.areStacksEqual(tOutputSlots[i], aOutputs[i], false) || tOutputSlots[i].stackSize + aOutputs[i].stackSize > tOutputSlots[i].getMaxStackSize())) {
+ mOutputBlocked++;
+ return false;
+ }
+ return true;
+ }
+
+ protected boolean canOutput(FluidStack aOutput) {
+ return getDrainableStack() == null || aOutput == null || (getDrainableStack().isFluidEqual(aOutput) && (getDrainableStack().amount <= 0 || getDrainableStack().amount + aOutput.amount <= getCapacity()));
+ }
+
+ protected ItemStack getInputAt(int aIndex) {
+ return mInventory[getInputSlot() + aIndex];
+ }
+
+ protected ItemStack[] getAllInputs() {
+ ItemStack[] rInputs = new ItemStack[mInputSlotCount];
+ for (int i = 0; i < mInputSlotCount; i++) rInputs[i] = getInputAt(i);
+ return rInputs;
+ }
+
+ protected boolean isOutputEmpty() {
+ boolean rIsEmpty = true;
+ for (ItemStack tOutputSlotContent : getAllOutputs()) if (tOutputSlotContent != null) rIsEmpty = false;
+ return rIsEmpty;
+ }
+
+ protected boolean displaysInputFluid() {
+ return true;
+ }
+
+ protected boolean displaysOutputFluid() {
+ return true;
+ }
+
+ @Override
+ public void onValueUpdate(byte aValue) {
+ mMainFacing = aValue;
+ }
+
+ @Override
+ public byte getUpdateData() {
+ return (byte) mMainFacing;
+ }
+
+ @Override
+ public void doSound(byte aIndex, double aX, double aY, double aZ) {
+ super.doSound(aIndex, aX, aY, aZ);
+ if (aIndex == 8) GT_Utility.doSoundAtClient(GregTech_API.sSoundList.get(210), 100, 1.0F, aX, aY, aZ);
+ }
+
+ public boolean doesAutoOutput() {
+ return mItemTransfer;
+ }
+
+ public boolean doesAutoOutputFluids() {
+ return mFluidTransfer;
+ }
+
+ public boolean allowToCheckRecipe() {
+ return true;
+ }
+
+ public boolean showPipeFacing() {
+ return true;
+ }
+
+ /**
+ * Called whenever the Machine successfully started a Process, useful for Sound Effects
+ */
+ public void startProcess() {
+ //
+ }
+
+ /**
+ * Called whenever the Machine successfully finished a Process, useful for Sound Effects
+ */
+ public void endProcess() {
+ //
+ }
+
+ /**
+ * Called whenever the Machine aborted a Process, useful for Sound Effects
+ */
+ public void abortProcess() {
+ //
+ }
+
+ /**
+ * Called whenever the Machine aborted a Process but still works on it, useful for Sound Effects
+ */
+ public void stutterProcess() {
+ if (useStandardStutterSound()) sendSound((byte) 8);
+ }
+
+ /**
+ * If this Machine can have the Insufficient Energy Line Problem
+ */
+ public boolean canHaveInsufficientEnergy() {
+ return true;
+ }
+
+ public boolean useStandardStutterSound() {
+ return true;
+ }
+
+ @Override
+ public String[] getInfoData() {
+ return new String[]{
+ mRecipeStuff.toString(),
+ mNEIName,
+ "Progress:", (mProgresstime / 20) + " secs",
+ (mMaxProgresstime / 20) + " secs",
+ "Stored Energy:",
+ getBaseMetaTileEntity().getStoredEU() + "EU",
+ getBaseMetaTileEntity().getEUCapacity() + "EU"};
+ }
+
+ @Override
+ public boolean isGivingInformation() {
+ return true;
+ }
+
+ @Override
+ public void onScrewdriverRightClick(byte aSide, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (aSide == getBaseMetaTileEntity().getFrontFacing() || aSide == mMainFacing) {
+ mAllowInputFromOutputSide = !mAllowInputFromOutputSide;
+ GT_Utility.sendChatToPlayer(aPlayer, mAllowInputFromOutputSide ? "Input from Output Side allowed" : "Input from Output Side forbidden");
+ }
+ }
+
+ @Override
+ public boolean allowCoverOnSide(byte aSide, GT_ItemStack aCoverID) {
+ return (aSide != mMainFacing || GregTech_API.getCoverBehavior(aCoverID.toStack()).isGUIClickable(aSide, GT_Utility.stackToInt(aCoverID.toStack()), 0, getBaseMetaTileEntity()));
+ }
+
+ @Override
+ public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) {
+ return aSide != mMainFacing && aIndex >= getOutputSlot() && aIndex < getOutputSlot() + mOutputItems.length;
+ }
+
+ @Override
+ public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) {
+ if (aSide == mMainFacing || aIndex < getInputSlot() || aIndex >= getInputSlot() + mInputSlotCount || (!mAllowInputFromOutputSide && aSide == aBaseMetaTileEntity.getFrontFacing()))
+ return false;
+ for (int i = getInputSlot(), j = i + mInputSlotCount; i < j; i++)
+ if (GT_Utility.areStacksEqual(GT_OreDictUnificator.get(aStack), mInventory[i])) return i == aIndex;
+ return true;
+ }
+
+ /**
+ * @return the Recipe List which is used for this Machine, this is a useful Default Handler
+ */
+ public GT_Recipe_Map getRecipeList() {
+ return null;
+ }
+
+ /**
+ * Override this to check the Recipes yourself, super calls to this could be useful if you just want to add a special case
+ * <p/>
+ * I thought about Enum too, but Enum doesn't add support for people adding other return Systems.
+ * <p/>
+ * Funny how Eclipse marks the word Enum as not correctly spelled.
+ *
+ * @return see constants above
+ */
+ public int checkRecipe() {
+ GT_Recipe_Map tMap = getRecipeList();
+ if (tMap == null) return DID_NOT_FIND_RECIPE;
+ GT_Recipe tRecipe = tMap.findRecipe(getBaseMetaTileEntity(), mLastRecipe, false, V[mTier], new FluidStack[]{getFillableStack()}, getSpecialSlot(), getAllInputs());
+ if (tRecipe == null) return DID_NOT_FIND_RECIPE;
+ if (tRecipe.mCanBeBuffered) mLastRecipe = tRecipe;
+ if (!canOutput(tRecipe)) {
+ mOutputBlocked++;
+ return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS;
+ }
+ if (!tRecipe.isRecipeInputEqual(true, new FluidStack[]{getFillableStack()}, getAllInputs()))
+ return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS;
+
+ for (int i = 0; i < mOutputItems.length; i++)
+ if (getBaseMetaTileEntity().getRandomNumber(10000) < tRecipe.getOutputChance(i))
+ mOutputItems[i] = tRecipe.getOutput(i);
+ mOutputFluid = tRecipe.getFluidOutput(0);
+ calculateOverclockedNess(tRecipe);
+ return FOUND_AND_SUCCESSFULLY_USED_RECIPE;
+ }
+
+ public ITexture[] getSideFacingActive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getSideFacingInactive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getFrontFacingActive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getFrontFacingInactive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getTopFacingActive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getTopFacingInactive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getBottomFacingActive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getBottomFacingInactive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1]};
+ }
+
+ public ITexture[] getBottomFacingPipeActive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1], new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_PIPE_OUT)};
+ }
+
+ public ITexture[] getBottomFacingPipeInactive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1], new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_PIPE_OUT)};
+ }
+
+ public ITexture[] getTopFacingPipeActive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1], new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_PIPE_OUT)};
+ }
+
+ public ITexture[] getTopFacingPipeInactive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1], new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_PIPE_OUT)};
+ }
+
+ public ITexture[] getSideFacingPipeActive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1], new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_PIPE_OUT)};
+ }
+
+ public ITexture[] getSideFacingPipeInactive(byte aColor) {
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1], new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_PIPE_OUT)};
+ }
+} \ No newline at end of file
diff --git a/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTankEx.java b/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTankEx.java
new file mode 100644
index 0000000000..46f347cba2
--- /dev/null
+++ b/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTankEx.java
@@ -0,0 +1,251 @@
+package gregtech.api.metatileentity.implementations;
+
+import gregtech.api.enums.ItemList;
+import gregtech.api.gui.GT_Container_BasicTank;
+import gregtech.api.gui.GT_GUIContainer_BasicTank;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.util.GT_Utility;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraftforge.fluids.FluidStack;
+
+/**
+ * NEVER INCLUDE THIS FILE IN YOUR MOD!!!
+ * <p/>
+ * This is the main construct for my generic Tanks. Filling and emptying behavior have to be implemented manually
+ */
+public abstract class GT_MetaTileEntity_BasicTankEx extends GT_MetaTileEntity_TieredMachineBlockEx {
+
+ public FluidStack mFluid;
+
+ /**
+ * @param aInvSlotCount should be 3
+ */
+ public GT_MetaTileEntity_BasicTankEx(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription, ITexture... aTextures) {
+ super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures);
+ }
+
+ public GT_MetaTileEntity_BasicTankEx(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aInvSlotCount, aDescription, aTextures);
+ }
+
+ @Override
+ public boolean isSimpleMachine() {
+ return false;
+ }
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return aIndex != getStackDisplaySlot();
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ if (mFluid != null) aNBT.setTag("mFluid", mFluid.writeToNBT(new NBTTagCompound()));
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ mFluid = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid"));
+ }
+
+ public abstract boolean doesFillContainers();
+
+ public abstract boolean doesEmptyContainers();
+
+ public abstract boolean canTankBeFilled();
+
+ public abstract boolean canTankBeEmptied();
+
+ public abstract boolean displaysItemStack();
+
+ public abstract boolean displaysStackSize();
+
+ public int getInputSlot() {
+ return 0;
+ }
+
+ public int getOutputSlot() {
+ return 1;
+ }
+
+ public int getStackDisplaySlot() {
+ return 2;
+ }
+
+ public boolean isFluidInputAllowed(FluidStack aFluid) {
+ return true;
+ }
+
+ public boolean isFluidChangingAllowed() {
+ return true;
+ }
+
+ public FluidStack getFillableStack() {
+ return mFluid;
+ }
+
+ public FluidStack setFillableStack(FluidStack aFluid) {
+ mFluid = aFluid;
+ return mFluid;
+ }
+
+ public FluidStack getDrainableStack() {
+ return mFluid;
+ }
+
+ public FluidStack setDrainableStack(FluidStack aFluid) {
+ mFluid = aFluid;
+ return mFluid;
+ }
+
+ public FluidStack getDisplayedFluid() {
+ return getDrainableStack();
+ }
+
+ @Override
+ public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ return new GT_Container_BasicTank(aPlayerInventory, aBaseMetaTileEntity);
+ }
+
+ @Override
+ public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
+ return new GT_GUIContainer_BasicTank(aPlayerInventory, aBaseMetaTileEntity, getLocalName());
+ }
+
+ @Override
+ public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ if (aBaseMetaTileEntity.isServerSide()) {
+ if (isFluidChangingAllowed() && getFillableStack() != null && getFillableStack().amount <= 0)
+ setFillableStack(null);
+
+ if (displaysItemStack() && getStackDisplaySlot() >= 0 && getStackDisplaySlot() < mInventory.length) {
+ if (getDisplayedFluid() == null) {
+ if (ItemList.Display_Fluid.isStackEqual(mInventory[getStackDisplaySlot()], true, true))
+ mInventory[getStackDisplaySlot()] = null;
+ } else {
+ mInventory[getStackDisplaySlot()] = GT_Utility.getFluidDisplayStack(getDisplayedFluid(), displaysStackSize());
+ }
+ }
+
+ if (doesEmptyContainers()) {
+ FluidStack tFluid = GT_Utility.getFluidForFilledItem(mInventory[getInputSlot()], true);
+ if (tFluid != null && isFluidInputAllowed(tFluid)) {
+ if (getFillableStack() == null) {
+ if (isFluidInputAllowed(tFluid) && tFluid.amount <= getCapacity()) {
+ if (aBaseMetaTileEntity.addStackToSlot(getOutputSlot(), GT_Utility.getContainerItem(mInventory[getInputSlot()], true), 1)) {
+ setFillableStack(tFluid.copy());
+ aBaseMetaTileEntity.decrStackSize(getInputSlot(), 1);
+ }
+ }
+ } else {
+ if (tFluid.isFluidEqual(getFillableStack()) && tFluid.amount + getFillableStack().amount <= getCapacity()) {
+ if (aBaseMetaTileEntity.addStackToSlot(getOutputSlot(), GT_Utility.getContainerItem(mInventory[getInputSlot()], true), 1)) {
+ getFillableStack().amount += tFluid.amount;
+ aBaseMetaTileEntity.decrStackSize(getInputSlot(), 1);
+ }
+ }
+ }
+ }
+ }
+
+ if (doesFillContainers()) {
+ ItemStack tOutput = GT_Utility.fillFluidContainer(getDrainableStack(), mInventory[getInputSlot()], false, true);
+ if (tOutput != null && aBaseMetaTileEntity.addStackToSlot(getOutputSlot(), tOutput, 1)) {
+ FluidStack tFluid = GT_Utility.getFluidForFilledItem(tOutput, true);
+ aBaseMetaTileEntity.decrStackSize(getInputSlot(), 1);
+ if (tFluid != null) getDrainableStack().amount -= tFluid.amount;
+ if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) setDrainableStack(null);
+ }
+ }
+ }
+ }
+
+ @Override
+ public FluidStack getFluid() {
+ return getDrainableStack();
+ }
+
+ @Override
+ public int getFluidAmount() {
+ return getDrainableStack() != null ? getDrainableStack().amount : 0;
+ }
+
+ @Override
+ public int fill(FluidStack aFluid, boolean doFill) {
+ if (aFluid == null || aFluid.getFluid().getID() <= 0 || aFluid.amount <= 0 || !canTankBeFilled() || !isFluidInputAllowed(aFluid))
+ return 0;
+
+ if (getFillableStack() == null || getFillableStack().getFluid().getID() <= 0) {
+ if (aFluid.amount <= getCapacity()) {
+ if (doFill) {
+ setFillableStack(aFluid.copy());
+ getBaseMetaTileEntity().markDirty();
+ }
+ return aFluid.amount;
+ }
+ if (doFill) {
+ setFillableStack(aFluid.copy());
+ getFillableStack().amount = getCapacity();
+ getBaseMetaTileEntity().markDirty();
+ }
+ return getCapacity();
+ }
+
+ if (!getFillableStack().isFluidEqual(aFluid))
+ return 0;
+
+ int space = getCapacity() - getFillableStack().amount;
+ if (aFluid.amount <= space) {
+ if (doFill) {
+ getFillableStack().amount += aFluid.amount;
+ getBaseMetaTileEntity().markDirty();
+ }
+ return aFluid.amount;
+ }
+ if (doFill)
+ getFillableStack().amount = getCapacity();
+ return space;
+ }
+
+ @Override
+ public FluidStack drain(int maxDrain, boolean doDrain) {
+ if (getDrainableStack() == null || !canTankBeEmptied()) return null;
+ if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) {
+ setDrainableStack(null);
+ getBaseMetaTileEntity().markDirty();
+ return null;
+ }
+
+ int used = maxDrain;
+ if (getDrainableStack().amount < used)
+ used = getDrainableStack().amount;
+
+ if (doDrain) {
+ getDrainableStack().amount -= used;
+ getBaseMetaTileEntity().markDirty();
+ }
+
+ FluidStack drained = getDrainableStack().copy();
+ drained.amount = used;
+
+ if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) {
+ setDrainableStack(null);
+ getBaseMetaTileEntity().markDirty();
+ }
+
+ return drained;
+ }
+
+ @Override
+ public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) {
+ return aIndex == getOutputSlot();
+ }
+
+ @Override
+ public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) {
+ return aIndex == getInputSlot();
+ }
+} \ No newline at end of file
diff --git a/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlockEx.java b/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlockEx.java
new file mode 100644
index 0000000000..7e70c8dafb
--- /dev/null
+++ b/src/Java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlockEx.java
@@ -0,0 +1,67 @@
+package gregtech.api.metatileentity.implementations;
+
+import static gregtech.api.enums.GT_Values.GT;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.metatileentity.MetaTileEntityEx;
+
+public abstract class GT_MetaTileEntity_TieredMachineBlockEx extends MetaTileEntityEx {
+ /**
+ * Value between [0 - 9] to describe the Tier of this Machine.
+ */
+ public final byte mTier;
+
+ /**
+ * A simple Description.
+ */
+ public final String mDescription;
+
+ /**
+ * Contains all Textures used by this Block.
+ */
+ public final ITexture[][][] mTextures;
+
+ public GT_MetaTileEntity_TieredMachineBlockEx(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription, ITexture... aTextures) {
+ super(aID, aName, aNameRegional, aInvSlotCount);
+ mTier = (byte) Math.max(0, Math.min(aTier, 9));
+ mDescription = aDescription;
+
+ // must always be the last call!
+ if (GT.isClientSide()) mTextures = getTextureSet(aTextures);
+ else mTextures = null;
+ }
+
+ public GT_MetaTileEntity_TieredMachineBlockEx(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) {
+ super(aName, aInvSlotCount);
+ mTier = (byte) aTier;
+ mDescription = aDescription;
+ mTextures = aTextures;
+ }
+
+ @Override
+ public byte getTileEntityBaseType() {
+ return (byte) (Math.min(3, mTier <= 0 ? 0 : 1 + ((mTier - 1) / 4)));
+ }
+
+ @Override
+ public long getInputTier() {
+ return mTier;
+ }
+
+ @Override
+ public long getOutputTier() {
+ return mTier;
+ }
+
+ @Override
+ public String[] getDescription() {
+ return new String[]{mDescription};
+ }
+
+ /**
+ * Used Client Side to get a Texture Set for this Block.
+ * Called after setting the Tier and the Description so that those two are accessible.
+ *
+ * @param aTextures is the optional Array you can give to the Constructor.
+ */
+ public abstract ITexture[][][] getTextureSet(ITexture[] aTextures);
+} \ No newline at end of file