aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java')
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java2538
1 files changed, 2538 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
new file mode 100644
index 0000000000..bf6358c884
--- /dev/null
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
@@ -0,0 +1,2538 @@
+package gregtech.api.metatileentity;
+
+import static gregtech.GT_Mod.GT_FML_LOGGER;
+import static gregtech.api.enums.GT_Values.NW;
+import static gregtech.api.enums.GT_Values.V;
+import static gregtech.api.objects.XSTR.XSTR_INSTANCE;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+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.entity.player.EntityPlayerMP;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.EnumSkyBlock;
+import net.minecraft.world.World;
+import net.minecraft.world.biome.BiomeGenBase;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTankInfo;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.gtnewhorizon.structurelib.alignment.IAlignment;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider;
+import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable;
+import com.gtnewhorizon.structurelib.alignment.constructable.IConstructableProvider;
+
+import appeng.api.networking.IGridNode;
+import appeng.api.networking.security.IActionHost;
+import appeng.api.util.AECableType;
+import appeng.api.util.DimensionalCoord;
+import appeng.helpers.ICustomNameObject;
+import appeng.me.helpers.AENetworkProxy;
+import appeng.me.helpers.IGridProxyable;
+import appeng.tile.TileEvent;
+import appeng.tile.events.TileEventType;
+import cpw.mods.fml.relauncher.ReflectionHelper;
+import gregtech.GT_Mod;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.SoundResource;
+import gregtech.api.enums.Textures;
+import gregtech.api.graphs.GenerateNodeMap;
+import gregtech.api.graphs.GenerateNodeMapPower;
+import gregtech.api.graphs.Node;
+import gregtech.api.interfaces.ICleanroom;
+import gregtech.api.interfaces.ICleanroomReceiver;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IDebugableTileEntity;
+import gregtech.api.interfaces.tileentity.IEnergyConnected;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.interfaces.tileentity.IGregtechWailaProvider;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch;
+import gregtech.api.net.GT_Packet_TileEntity;
+import gregtech.api.objects.GT_ItemStack;
+import gregtech.api.objects.blockupdate.BlockUpdateHandler;
+import gregtech.api.util.GT_CoverBehaviorBase;
+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 gregtech.api.util.shutdown.ShutDownReason;
+import gregtech.api.util.shutdown.ShutDownReasonRegistry;
+import gregtech.common.GT_Pollution;
+import gregtech.common.covers.CoverInfo;
+import ic2.api.Direction;
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
+/**
+ * NEVER INCLUDE THIS FILE IN YOUR MOD!!!
+ * <p/>
+ * This is the main TileEntity for EVERYTHING.
+ */
+public class BaseMetaTileEntity extends CommonMetaTileEntity
+ implements IGregTechTileEntity, IActionHost, IGridProxyable, IAlignmentProvider, IConstructableProvider,
+ IDebugableTileEntity, IGregtechWailaProvider, ICleanroomReceiver, ICustomNameObject {
+
+ private static final Field ENTITY_ITEM_HEALTH_FIELD = ReflectionHelper
+ .findField(EntityItem.class, "health", "field_70291_e");
+ private final boolean[] mActiveEUInputs = new boolean[] { false, false, false, false, false, false };
+ private final boolean[] mActiveEUOutputs = new boolean[] { false, false, false, false, false, false };
+ private final int[] mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING];
+ private boolean hasTimeStatisticsStarted;
+ public long mLastSoundTick = 0;
+ public boolean mWasShutdown = false;
+ public @Nonnull ShutDownReason lastShutDownReason = ShutDownReasonRegistry.NONE;
+ protected MetaTileEntity mMetaTileEntity;
+ protected long mStoredEnergy = 0, mStoredSteam = 0;
+ protected int mAverageEUInputIndex = 0, mAverageEUOutputIndex = 0;
+ protected boolean mReleaseEnergy = false;
+ protected final long[] mAverageEUInput = new long[] { 0, 0, 0, 0, 0 };
+ protected final long[] mAverageEUOutput = new long[] { 0, 0, 0, 0, 0 };
+ private boolean mHasEnoughEnergy = true, mRunningThroughTick = false, mInputDisabled = false,
+ mOutputDisabled = false, mMuffler = false, mLockUpgrade = false;
+ private boolean mActive = false, mWorkUpdate = false, mSteamConverter = false, mWorks = true;
+ private boolean oRedstone = false;
+ private byte mColor = 0, oColor = 0, oStrongRedstone = 0, oRedstoneData = 63, oTextureData = 0, oUpdateData = 0,
+ oTexturePage = 0;
+ private byte oLightValueClient = 0, oLightValue = -1, mLightValue = 0, mOtherUpgrades = 0, mWorkData = 0;
+ private ForgeDirection mFacing = ForgeDirection.DOWN, oFacing = ForgeDirection.DOWN;
+ private int mDisplayErrorCode = 0, oX = 0, oY = 0, oZ = 0, mTimeStatisticsIndex = 0, mLagWarningCount = 0;
+ private long oOutput = 0, mAcceptedAmperes = Long.MAX_VALUE;
+ private long mLastCheckTick = 0;
+ private String mOwnerName = "";
+ private UUID mOwnerUuid = GT_Utility.defaultUuid;
+ private NBTTagCompound mRecipeStuff = new NBTTagCompound();
+ private int cableUpdateDelay = 30;
+
+ public BaseMetaTileEntity() {}
+
+ @Override
+ public void writeToNBT(NBTTagCompound aNBT) {
+ try {
+ super.writeToNBT(aNBT);
+ } catch (Throwable e) {
+ GT_FML_LOGGER.error("Encountered CRITICAL ERROR while saving MetaTileEntity.", e);
+ }
+ try {
+ aNBT.setInteger("mID", mID);
+ aNBT.setLong("mStoredSteam", mStoredSteam);
+ aNBT.setLong("mStoredEnergy", mStoredEnergy);
+ writeCoverNBT(aNBT, false);
+ aNBT.setByte("mColor", mColor);
+ aNBT.setByte("mLightValue", mLightValue);
+ aNBT.setByte("mOtherUpgrades", mOtherUpgrades);
+ aNBT.setByte("mWorkData", mWorkData);
+ aNBT.setShort("mFacing", (short) mFacing.ordinal());
+ aNBT.setString("mOwnerName", mOwnerName);
+ aNBT.setString("mOwnerUuid", mOwnerUuid == null ? "" : mOwnerUuid.toString());
+ aNBT.setBoolean("mLockUpgrade", mLockUpgrade);
+ aNBT.setBoolean("mMuffler", mMuffler);
+ aNBT.setBoolean("mSteamConverter", mSteamConverter);
+ aNBT.setBoolean("mActive", mActive);
+ aNBT.setBoolean("mWorks", !mWorks);
+ aNBT.setBoolean("mInputDisabled", mInputDisabled);
+ aNBT.setBoolean("mOutputDisabled", mOutputDisabled);
+ aNBT.setTag("GT.CraftingComponents", mRecipeStuff);
+ } catch (Throwable e) {
+ GT_FML_LOGGER.error("Encountered CRITICAL ERROR while saving MetaTileEntity.", e);
+ }
+ saveMetaTileNBT(aNBT);
+ }
+
+ @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.getLong("mStoredSteam");
+ mStoredEnergy = aNBT.getLong("mStoredEnergy");
+ mColor = aNBT.getByte("mColor");
+ mLightValue = aNBT.getByte("mLightValue");
+ mWorkData = aNBT.getByte("mWorkData");
+ mFacing = oFacing = ForgeDirection.getOrientation(aNBT.getShort("mFacing"));
+ mOwnerName = aNBT.getString("mOwnerName");
+ try {
+ mOwnerUuid = UUID.fromString(aNBT.getString("mOwnerUuid"));
+ } catch (IllegalArgumentException e) {
+ mOwnerUuid = null;
+ }
+ mLockUpgrade = aNBT.getBoolean("mLockUpgrade");
+ mMuffler = aNBT.getBoolean("mMuffler");
+ mSteamConverter = aNBT.getBoolean("mSteamConverter");
+ mActive = aNBT.getBoolean("mActive");
+ mWorks = !aNBT.getBoolean("mWorks");
+ mInputDisabled = aNBT.getBoolean("mInputDisabled");
+ mOutputDisabled = aNBT.getBoolean("mOutputDisabled");
+ mOtherUpgrades = (byte) (aNBT.getByte("mOtherUpgrades") + aNBT.getByte("mBatteries")
+ + aNBT.getByte("mLiBatteries"));
+
+ mRecipeStuff = aNBT.getCompoundTag("GT.CraftingComponents");
+ final int nbtVersion = aNBT.getInteger("nbtVersion");
+ readCoverNBT(aNBT);
+ loadMetaTileNBT(aNBT);
+ }
+
+ 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 };
+
+ updateCoverBehavior();
+ }
+
+ /**
+ * 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);
+ }
+
+ protected boolean isRainPossible() {
+ BiomeGenBase biome = getBiome();
+ // see net.minecraft.client.renderer.EntityRenderer.renderRainSnow
+ return biome.rainfall > 0 && (biome.canSpawnLightningBolt() || biome.getEnableSnow());
+ }
+
+ /**
+ * Check if this is exposed to rain
+ *
+ * @return True if exposed to rain, else false
+ */
+ public boolean isRainExposed() {
+ final int precipitationHeightAtSide2 = worldObj.getPrecipitationHeight(xCoord, zCoord - 1);
+ final int precipitationHeightAtSide3 = worldObj.getPrecipitationHeight(xCoord, zCoord + 1);
+ final int precipitationHeightAtSide4 = worldObj.getPrecipitationHeight(xCoord - 1, zCoord);
+ final int precipitationHeightAtSide5 = worldObj.getPrecipitationHeight(xCoord + 1, zCoord);
+ return (getCoverIDAtSide(ForgeDirection.UP) == 0
+ && worldObj.getPrecipitationHeight(xCoord, zCoord) - 2 < yCoord)
+ || (getCoverIDAtSide(ForgeDirection.NORTH) == 0 && precipitationHeightAtSide2 - 1 < yCoord
+ && precipitationHeightAtSide2 > -1)
+ || (getCoverIDAtSide(ForgeDirection.SOUTH) == 0 && precipitationHeightAtSide3 - 1 < yCoord
+ && precipitationHeightAtSide3 > -1)
+ || (getCoverIDAtSide(ForgeDirection.WEST) == 0 && precipitationHeightAtSide4 - 1 < yCoord
+ && precipitationHeightAtSide4 > -1)
+ || (getCoverIDAtSide(ForgeDirection.EAST) == 0 && precipitationHeightAtSide5 - 1 < yCoord
+ && precipitationHeightAtSide5 > -1);
+ }
+
+ @Override
+ public void updateEntity() {
+ super.updateEntity();
+
+ if (!hasValidMetaTileEntity()) {
+ if (mMetaTileEntity == null) return;
+ mMetaTileEntity.setBaseMetaTileEntity(this);
+ }
+
+ mRunningThroughTick = true;
+ long tTime;
+ if (hasTimeStatisticsStarted) {
+ tTime = System.nanoTime();
+ } else {
+ tTime = 0;
+ }
+ final boolean aSideServer = isServerSide();
+ final boolean aSideClient = isClientSide();
+
+ try {
+ if (hasValidMetaTileEntity()) {
+ if (mTickTimer++ == 0) {
+ oX = xCoord;
+ oY = yCoord;
+ oZ = zCoord;
+ if (aSideServer) {
+ checkDropCover();
+ } else {
+ requestCoverDataIfNeeded();
+ }
+ worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this);
+ mMetaTileEntity.onFirstTick(this);
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ }
+ if (aSideClient) {
+ 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) {
+ if (GT_Mod.gregtechproxy.mUseBlockUpdateHandler) {
+ BlockUpdateHandler.Instance.enqueueBlockUpdate(worldObj, getLocation());
+ } else {
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ }
+ mNeedsUpdate = false;
+ }
+ }
+ if (aSideServer && mTickTimer > 10) {
+ if (!doCoverThings()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ }
+ if (aSideServer) {
+ if (++mAverageEUInputIndex >= mAverageEUInput.length) mAverageEUInputIndex = 0;
+ if (++mAverageEUOutputIndex >= mAverageEUOutput.length) mAverageEUOutputIndex = 0;
+
+ mAverageEUInput[mAverageEUInputIndex] = 0;
+ mAverageEUOutput[mAverageEUOutputIndex] = 0;
+ }
+
+ mMetaTileEntity.onPreTick(this, mTickTimer);
+
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ if (aSideServer) {
+ if (mRedstone != oRedstone || mTickTimer == 10) {
+ updateCoverBehavior();
+ oRedstone = mRedstone;
+ issueBlockUpdate();
+ }
+ if (mTickTimer == 10) joinEnet();
+
+ if (xCoord != oX || yCoord != oY || zCoord != oZ) {
+ oX = xCoord;
+ oY = yCoord;
+ oZ = zCoord;
+ issueClientUpdate();
+ clearTileEntityBuffer();
+ }
+
+ if (mFacing != oFacing) {
+ oFacing = mFacing;
+ checkDropCover();
+ issueBlockUpdate();
+ }
+
+ if (mTickTimer > 20 && mMetaTileEntity.isElectric()) {
+ mAcceptedAmperes = 0;
+
+ if (getOutputVoltage() != oOutput) {
+ oOutput = getOutputVoltage();
+ }
+
+ if (mMetaTileEntity.isEnetOutput() || mMetaTileEntity.isEnetInput()) {
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ final int ordinalSide = side.ordinal();
+ boolean temp = isEnergyInputSide(side);
+ if (temp != mActiveEUInputs[ordinalSide]) {
+ mActiveEUInputs[ordinalSide] = temp;
+ }
+ temp = isEnergyOutputSide(side);
+ if (temp != mActiveEUOutputs[ordinalSide]) {
+ mActiveEUOutputs[ordinalSide] = temp;
+ }
+ }
+ }
+
+ if (mMetaTileEntity.isEnetOutput() && oOutput > 0) {
+ final long tOutputVoltage = Math
+ .max(oOutput, oOutput + (1L << Math.max(0, GT_Utility.getTier(oOutput) - 1)));
+ final long tUsableAmperage = Math.min(
+ getOutputAmperage(),
+ (getStoredEU() - mMetaTileEntity.getMinimumStoredEU()) / tOutputVoltage);
+ if (tUsableAmperage > 0) {
+ final long tEU = tOutputVoltage
+ * Util.emitEnergyToNetwork(oOutput, tUsableAmperage, this);
+ mAverageEUOutput[mAverageEUOutputIndex] += tEU;
+ decreaseStoredEU(tEU, true);
+ }
+ }
+ if (getEUCapacity() > 0) {
+ if (GregTech_API.sMachineFireExplosions && getRandomNumber(1000) == 0) {
+ final Block tBlock = getBlockAtSide(ForgeDirection.getOrientation(getRandomNumber(6)));
+ if (tBlock instanceof BlockFire) doEnergyExplosion();
+ }
+
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+
+ if (GregTech_API.sMachineRainExplosions) {
+ if (mMetaTileEntity.willExplodeInRain()) {
+ if (getRandomNumber(1000) == 0 && isRainPossible()) {
+ // Short-circuit so raincheck happens before isRainExposed,
+ // saves sme TPS since rain exposed check can be slow
+ // This logic can be compressed further by only checking for
+ // isRainExposed once IF we can guarantee it never thunders without
+ // raining, but I don't know if this is true or not.
+ if (worldObj.isRaining() && isRainExposed()) {
+ if (getRandomNumber(10) == 0) {
+ try {
+ GT_Mod.achievements.issueAchievement(
+ this.getWorldObj()
+ .getPlayerEntityByName(mOwnerName),
+ "badweather");
+ } catch (Exception ignored) {}
+ GT_Log.exp.println(
+ "Machine at: " + this.getXCoord()
+ + " | "
+ + this.getYCoord()
+ + " | "
+ + this.getZCoord()
+ + " DIMID: "
+ + this.worldObj.provider.dimensionId
+ + " explosion due to rain!");
+ doEnergyExplosion();
+ } else {
+ GT_Log.exp.println(
+ "Machine at: " + this.getXCoord()
+ + " | "
+ + this.getYCoord()
+ + " | "
+ + this.getZCoord()
+ + " DIMID: "
+ + this.worldObj.provider.dimensionId
+ + " set to Fire due to rain!");
+ setOnFire();
+ }
+ }
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ if (GregTech_API.sMachineThunderExplosions && worldObj.isThundering()
+ && getRandomNumber(3) == 0
+ && isRainExposed()) {
+ try {
+ GT_Mod.achievements.issueAchievement(
+ this.getWorldObj()
+ .getPlayerEntityByName(mOwnerName),
+ "badweather");
+ } catch (Exception ignored) {}
+ GT_Log.exp.println(
+ "Machine at: " + this.getXCoord()
+ + " | "
+ + this.getYCoord()
+ + " | "
+ + this.getZCoord()
+ + " DIMID: "
+ + this.worldObj.provider.dimensionId
+ + " explosion due to Thunderstorm!");
+ doEnergyExplosion();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ }
+ if (aSideServer) {
+ 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 (ic2.api.info.Info.itemEnergy.getEnergyValue(mMetaTileEntity.mInventory[i]) > 0) {
+ if ((getStoredEU()
+ + ic2.api.info.Info.itemEnergy.getEnergyValue(mMetaTileEntity.mInventory[i]))
+ < getEUCapacity()) {
+ increaseStoredEnergyUnits(
+ (long) ic2.api.info.Info.itemEnergy
+ .getEnergyValue(mMetaTileEntity.mInventory[i]),
+ false);
+ mMetaTileEntity.mInventory[i].stackSize--;
+ mInventoryChanged = true;
+ }
+ }
+ if (mMetaTileEntity.mInventory[i].stackSize <= 0) {
+ mMetaTileEntity.mInventory[i] = null;
+ mInventoryChanged = true;
+ }
+ }
+ }
+ }
+ }
+ if (aSideServer) {
+ 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;
+ }
+ }
+ }
+ }
+ }
+ updateStatus();
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ mMetaTileEntity.onPostTick(this, mTickTimer);
+ if (!hasValidMetaTileEntity()) {
+ mRunningThroughTick = false;
+ return;
+ }
+ if (aSideServer) {
+ if (mTickTimer > 20 && cableUpdateDelay == 0) {
+ generatePowerNodes();
+ }
+ cableUpdateDelay--;
+ if (mTickTimer % 10 == 0) {
+ sendClientData();
+ }
+
+ if (mTickTimer > 10) {
+ byte tData = (byte) ((mFacing.ordinal() & 7) | (mActive ? 8 : 0)
+ | (mRedstone ? 16 : 0)
+ | (mLockUpgrade ? 32 : 0)
+ | (mWorks ? 64 : 0)
+ | (mMuffler ? 128 : 0));
+ if (tData != oTextureData)
+ sendBlockEvent(GregTechTileClientEvents.CHANGE_COMMON_DATA, oTextureData = tData);
+
+ tData = mMetaTileEntity.getUpdateData();
+ if (tData != oUpdateData)
+ sendBlockEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, oUpdateData = tData);
+ if (mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) {
+ tData = ((GT_MetaTileEntity_Hatch) mMetaTileEntity).getTexturePage();
+ if (tData != oTexturePage) sendBlockEvent(
+ GregTechTileClientEvents.CHANGE_CUSTOM_DATA,
+ (byte) ((oTexturePage = tData) | 0x80)); // set last bit as a flag for page
+ }
+ if (mColor != oColor) sendBlockEvent(GregTechTileClientEvents.CHANGE_COLOR, 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(GregTechTileClientEvents.CHANGE_REDSTONE_OUTPUT, 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(GregTechTileClientEvents.CHANGE_LIGHT, oLightValue = mLightValue);
+ }
+ }
+
+ if (mNeedsBlockUpdate) {
+ updateNeighbours(mStrongRedstone, oStrongRedstone);
+ oStrongRedstone = mStrongRedstone;
+ mNeedsBlockUpdate = false;
+ }
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ e.printStackTrace(GT_Log.err);
+ try {
+ mMetaTileEntity.onTickFail(this, mTickTimer);
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ ex.printStackTrace(GT_Log.err);
+ }
+ }
+
+ if (aSideServer && hasTimeStatisticsStarted && hasValidMetaTileEntity()) {
+ tTime = System.nanoTime() - tTime;
+ mTimeStatisticsIndex = (mTimeStatisticsIndex + 1) % mTimeStatistics.length;
+ mTimeStatistics[mTimeStatisticsIndex] = (int) tTime;
+ if (tTime > 0 && tTime > (GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING * 1_000_000L)
+ && mTickTimer > 1000
+ && getMetaTileEntity().doTickProfilingMessageDuringThisTick()
+ && mLagWarningCount++ < 10)
+ GT_FML_LOGGER.warn(
+ "WARNING: Possible Lag Source at [" + xCoord
+ + ", "
+ + yCoord
+ + ", "
+ + zCoord
+ + "] in Dimension "
+ + worldObj.provider.dimensionId
+ + " with "
+ + tTime
+ + "ns caused by an instance of "
+ + getMetaTileEntity().getClass());
+ }
+
+ mWorkUpdate = mInventoryChanged = mRunningThroughTick = false;
+ }
+
+ @Override
+ public void getWailaBody(ItemStack itemStack, List<String> currentTip, IWailaDataAccessor accessor,
+ IWailaConfigHandler config) {
+ if (hasValidMetaTileEntity()) {
+ getMetaTileEntity().getWailaBody(itemStack, currentTip, accessor, config);
+ }
+ super.getWailaBody(itemStack, currentTip, accessor, config);
+ }
+
+ @Override
+ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y,
+ int z) {
+ super.getWailaNBTData(player, tile, tag, world, x, y, z);
+ if (hasValidMetaTileEntity()) {
+ getMetaTileEntity().getWailaNBTData(player, tile, tag, world, x, y, z);
+ }
+ }
+
+ private void sendClientData() {
+ if (mSendClientData) {
+ NW.sendPacketToAllPlayersInRange(
+ worldObj,
+ new GT_Packet_TileEntity(
+ xCoord,
+ (short) yCoord,
+ zCoord,
+ mID,
+ getCoverInfoAtSide(ForgeDirection.DOWN).getCoverID(),
+ getCoverInfoAtSide(ForgeDirection.UP).getCoverID(),
+ getCoverInfoAtSide(ForgeDirection.NORTH).getCoverID(),
+ getCoverInfoAtSide(ForgeDirection.SOUTH).getCoverID(),
+ getCoverInfoAtSide(ForgeDirection.WEST).getCoverID(),
+ getCoverInfoAtSide(ForgeDirection.EAST).getCoverID(),
+ oTextureData = (byte) ((mFacing.ordinal() & 7) | (mActive ? 8 : 0)
+ | (mRedstone ? 16 : 0)
+ | (mLockUpgrade ? 32 : 0)
+ | (mWorks ? 64 : 0)),
+ oTexturePage = (hasValidMetaTileEntity() && mMetaTileEntity instanceof GT_MetaTileEntity_Hatch)
+ ? ((GT_MetaTileEntity_Hatch) mMetaTileEntity).getTexturePage()
+ : 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;
+ }
+ sendCoverDataIfNeeded();
+ }
+
+ public final void receiveMetaTileEntityData(short aID, int aCover0, int aCover1, int aCover2, int aCover3,
+ int aCover4, int aCover5, byte aTextureData, byte aTexturePage, byte aUpdateData, byte aRedstoneData,
+ byte aColorData) {
+ issueTextureUpdate();
+ if (mID != aID && aID > 0) {
+ mID = aID;
+ createNewMetatileEntity(mID);
+ }
+
+ setCoverIDAtSide(ForgeDirection.DOWN, aCover0);
+ setCoverIDAtSide(ForgeDirection.UP, aCover1);
+ setCoverIDAtSide(ForgeDirection.NORTH, aCover2);
+ setCoverIDAtSide(ForgeDirection.SOUTH, aCover3);
+ setCoverIDAtSide(ForgeDirection.WEST, aCover4);
+ setCoverIDAtSide(ForgeDirection.EAST, aCover5);
+
+ receiveClientEvent(GregTechTileClientEvents.CHANGE_COMMON_DATA, aTextureData);
+ receiveClientEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, aUpdateData & 0x7F);
+ receiveClientEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, aTexturePage | 0x80);
+ receiveClientEvent(GregTechTileClientEvents.CHANGE_COLOR, aColorData);
+ receiveClientEvent(GregTechTileClientEvents.CHANGE_REDSTONE_OUTPUT, aRedstoneData);
+ }
+
+ @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(
+ "Encountered Exception while receiving Data from the Server, the Client should've been crashed by now, but I prevented that. Please report immediately to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+
+ if (isClientSide()) {
+ issueTextureUpdate();
+ switch (aEventID) {
+ case GregTechTileClientEvents.CHANGE_COMMON_DATA -> {
+ mFacing = ForgeDirection.getOrientation((byte) (aValue & 7));
+ mActive = ((aValue & 8) != 0);
+ mRedstone = ((aValue & 16) != 0);
+ // mLockUpgrade = ((aValue&32) != 0);
+ mWorks = ((aValue & 64) != 0);
+ mMuffler = ((aValue & 128) != 0);
+ }
+ case GregTechTileClientEvents.CHANGE_CUSTOM_DATA -> {
+ if (hasValidMetaTileEntity()) {
+ if ((aValue & 0x80) == 0) // Is texture index
+ mMetaTileEntity.onValueUpdate((byte) (aValue & 0x7F));
+ else if (mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) // is texture page and hatch
+ ((GT_MetaTileEntity_Hatch) mMetaTileEntity).onTexturePageUpdate((byte) (aValue & 0x7F));
+ }
+ }
+ case GregTechTileClientEvents.CHANGE_COLOR -> {
+ if (aValue > 16 || aValue < 0) aValue = 0;
+ mColor = (byte) aValue;
+ }
+ case GregTechTileClientEvents.CHANGE_REDSTONE_OUTPUT -> {
+ mSidedRedstone[0] = (byte) ((aValue & 1) == 1 ? 15 : 0);
+ mSidedRedstone[1] = (byte) ((aValue & 2) == 2 ? 15 : 0);
+ mSidedRedstone[2] = (byte) ((aValue & 4) == 4 ? 15 : 0);
+ mSidedRedstone[3] = (byte) ((aValue & 8) == 8 ? 15 : 0);
+ mSidedRedstone[4] = (byte) ((aValue & 16) == 16 ? 15 : 0);
+ mSidedRedstone[5] = (byte) ((aValue & 32) == 32 ? 15 : 0);
+ }
+ case GregTechTileClientEvents.DO_SOUND -> {
+ if (hasValidMetaTileEntity() && mTickTimer > 20)
+ mMetaTileEntity.doSound((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
+ }
+ case GregTechTileClientEvents.START_SOUND_LOOP -> {
+ if (hasValidMetaTileEntity() && mTickTimer > 20)
+ mMetaTileEntity.startSoundLoop((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
+ }
+ case GregTechTileClientEvents.STOP_SOUND_LOOP -> {
+ if (hasValidMetaTileEntity() && mTickTimer > 20)
+ mMetaTileEntity.stopSoundLoop((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
+ }
+ case GregTechTileClientEvents.CHANGE_LIGHT -> mLightValue = (byte) aValue;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public ArrayList<String> getDebugInfo(EntityPlayer aPlayer, int aLogLevel) {
+ final ArrayList<String> tList = new ArrayList<>();
+ if (aLogLevel > 2) {
+ tList.add(
+ "Meta-ID: " + EnumChatFormatting.BLUE
+ + mID
+ + EnumChatFormatting.RESET
+ + (canAccessData() ? EnumChatFormatting.GREEN + " valid" + EnumChatFormatting.RESET
+ : EnumChatFormatting.RED + " invalid" + EnumChatFormatting.RESET)
+ + (mMetaTileEntity == null
+ ? EnumChatFormatting.RED + " MetaTileEntity == null!" + EnumChatFormatting.RESET
+ : " "));
+ }
+ if (aLogLevel > 1 && mMetaTileEntity != null) {
+ if (hasTimeStatisticsStarted) {
+ double tAverageTime = 0;
+ double tWorstTime = 0;
+ int amountOfZero = 0;
+ for (int tTime : mTimeStatistics) {
+ tAverageTime += tTime;
+ if (tTime > tWorstTime) {
+ tWorstTime = tTime;
+ }
+ if (tTime == 0) {
+ amountOfZero += 1;
+ }
+ // Uncomment this line to print out tick-by-tick times.
+ // tList.add("tTime " + tTime);
+ }
+ // tick time zero means it has not been updated yet
+ int samples = mTimeStatistics.length - amountOfZero;
+ if (samples > 0) {
+ tList.add(
+ "Average CPU load of ~" + GT_Utility.formatNumbers(tAverageTime / samples)
+ + "ns over "
+ + GT_Utility.formatNumbers(samples)
+ + " ticks with worst time of "
+ + GT_Utility.formatNumbers(tWorstTime)
+ + "ns.");
+ }
+ } else {
+ startTimeStatistics();
+ tList.add("Just started tick time statistics.");
+ }
+ tList.add(
+ "Recorded " + GT_Utility.formatNumbers(mMetaTileEntity.mSoundRequests)
+ + " sound requests in "
+ + GT_Utility.formatNumbers(mTickTimer - mLastCheckTick)
+ + " ticks.");
+ mLastCheckTick = mTickTimer;
+ mMetaTileEntity.mSoundRequests = 0;
+ if (mLagWarningCount > 0) {
+ tList.add(
+ "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) ? " "
+ : EnumChatFormatting.RED + " not " + EnumChatFormatting.RESET) + "accessible for you");
+ }
+ if (aLogLevel > 0) {
+ if (getSteamCapacity() > 0 && hasSteamEngineUpgrade()) tList.add(
+ GT_Utility.formatNumbers(getStoredSteam()) + " of "
+ + GT_Utility.formatNumbers(getSteamCapacity())
+ + " Steam");
+ tList.add(
+ "Machine is " + (mActive ? EnumChatFormatting.GREEN + "active" + EnumChatFormatting.RESET
+ : EnumChatFormatting.RED + "inactive" + EnumChatFormatting.RESET));
+ if (!mHasEnoughEnergy) tList
+ .add(EnumChatFormatting.RED + "ATTENTION: This Device needs more power." + EnumChatFormatting.RESET);
+ }
+ if (joinedIc2Enet) tList.add("Joined IC2 ENet");
+ return mMetaTileEntity.getSpecialDebugInfo(this, aPlayer, aLogLevel, tList);
+ }
+
+ @Override
+ public boolean isGivingInformation() {
+ if (canAccessData()) return mMetaTileEntity.isGivingInformation();
+ return false;
+ }
+
+ @Override
+ public ForgeDirection getBackFacing() {
+ return mFacing.getOpposite();
+ }
+
+ @Override
+ public ForgeDirection getFrontFacing() {
+ return mFacing;
+ }
+
+ @Override
+ public void setFrontFacing(ForgeDirection aFacing) {
+ if (isValidFacing(aFacing)) {
+ mFacing = aFacing;
+ mMetaTileEntity.onFacingChange();
+
+ doEnetUpdate();
+ cableUpdateDelay = 10;
+
+ if (mMetaTileEntity.shouldTriggerBlockUpdate()) {
+ // If we're triggering a block update this will call onMachineBlockUpdate()
+ GregTech_API.causeMachineUpdate(worldObj, xCoord, yCoord, zCoord);
+ } else {
+ // If we're not trigger a cascading one, call the update here.
+ 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()) {
+ markDirty();
+ mMetaTileEntity.setInventorySlotContents(
+ aIndex,
+ worldObj.isRemote ? aStack : GT_OreDictUnificator.setStack(true, aStack));
+ }
+ }
+
+ @Override
+ public String getInventoryName() {
+ if (canAccessData()) return mMetaTileEntity.getInventoryName();
+ if (GregTech_API.METATILEENTITIES[mID] != null) return GregTech_API.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 > 1
+ && 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;
+ leaveEnet();
+ if (canAccessData()) {
+ invalidateAE();
+ mMetaTileEntity.onRemoval();
+ mMetaTileEntity.setBaseMetaTileEntity(null);
+ }
+ super.invalidate();
+ }
+
+ @Override
+ public void onChunkUnload() {
+ if (canAccessData()) {
+ mMetaTileEntity.onUnload();
+ }
+
+ super.onChunkUnload();
+ onChunkUnloadAE();
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return false;
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(int slot) {
+ final ItemStack stack = getStackInSlot(slot);
+ if (stack != null) setInventorySlotContents(slot, null);
+ return stack;
+ }
+
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ public void onMachineBlockUpdate() {
+ if (canAccessData()) mMetaTileEntity.onMachineBlockUpdate();
+ cableUpdateDelay = 10;
+ }
+
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ public boolean isMachineBlockUpdateRecursive() {
+ return canAccessData() && mMetaTileEntity.isMachineBlockUpdateRecursive();
+ }
+
+ @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;
+ }
+
+ @Override
+ public boolean hasThingsToDo() {
+ return getMaxProgress() > 0;
+ }
+
+ @Override
+ public void enableWorking() {
+ if (!mWorks) mWorkUpdate = true;
+ mWorks = true;
+ mWasShutdown = false;
+ }
+
+ @Override
+ public void disableWorking() {
+ mWorks = false;
+ if (hasValidMetaTileEntity()) {
+ mMetaTileEntity.onDisableWorking();
+ }
+ }
+
+ @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;
+ if (hasValidMetaTileEntity()) {
+ mMetaTileEntity.onSetActive(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(ForgeDirection side) {
+ return inputEnergyFrom(side, true);
+ }
+
+ @Override
+ public boolean inputEnergyFrom(ForgeDirection side, boolean waitForActive) {
+ if (side == ForgeDirection.UNKNOWN) return true;
+ if (isServerSide() && waitForActive) return mActiveEUInputs[side.ordinal()] && !mReleaseEnergy;
+ return isEnergyInputSide(side);
+ }
+
+ @Override
+ public boolean outputsEnergyTo(ForgeDirection side) {
+ return outputsEnergyTo(side, true);
+ }
+
+ @Override
+ public boolean outputsEnergyTo(ForgeDirection side, boolean waitForActive) {
+ if (side == ForgeDirection.UNKNOWN) return true;
+ if (isServerSide() && waitForActive) return (mActiveEUOutputs[side.ordinal()]) || mReleaseEnergy;
+ return isEnergyOutputSide(side);
+ }
+
+ @Override
+ public boolean isEnetOutput() {
+ return mMetaTileEntity != null && mMetaTileEntity.isEnetOutput();
+ }
+
+ @Override
+ public boolean isEnetInput() {
+ return mMetaTileEntity != null && mMetaTileEntity.isEnetInput();
+ }
+
+ public void generatePowerNodes() {
+ if (isServerSide() && (isEnetInput() || isEnetOutput())) {
+ final int time = MinecraftServer.getServer()
+ .getTickCounter();
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ if (outputsEnergyTo(side, false) || inputEnergyFrom(side, false)) {
+ final IGregTechTileEntity TE = getIGregTechTileEntityAtSide(side);
+ if (TE instanceof BaseMetaPipeEntity) {
+ final Node node = ((BaseMetaPipeEntity) TE).getNode();
+ if (node == null) {
+ new GenerateNodeMapPower((BaseMetaPipeEntity) TE);
+ } else if (node.mCreationTime != time) {
+ GenerateNodeMap.clearNodeMap(node, -1);
+ new GenerateNodeMapPower((BaseMetaPipeEntity) TE);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @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 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(Block aBlock, ForgeDirection side) {
+ final ITexture coverTexture = getCoverTexture(side);
+ final ITexture[] textureUncovered = hasValidMetaTileEntity()
+ ? mMetaTileEntity
+ .getTexture(this, side, mFacing, (byte) (mColor - 1), mActive, getOutputRedstoneSignal(side) > 0)
+ : Textures.BlockIcons.ERROR_RENDERING;
+ final ITexture[] textureCovered;
+ if (coverTexture != null) {
+ textureCovered = Arrays.copyOf(textureUncovered, textureUncovered.length + 1);
+ textureCovered[textureUncovered.length] = coverTexture;
+ return textureCovered;
+ } else {
+ return textureUncovered;
+ }
+ }
+
+ private boolean isEnergyInputSide(ForgeDirection side) {
+ if (side != ForgeDirection.UNKNOWN) {
+ if (!getCoverInfoAtSide(side).letsEnergyIn()) return false;
+ if (isInvalid() || mReleaseEnergy) return false;
+ if (canAccessData() && mMetaTileEntity.isElectric() && mMetaTileEntity.isEnetInput())
+ return mMetaTileEntity.isInputFacing(side);
+ }
+ return false;
+ }
+
+ private boolean isEnergyOutputSide(ForgeDirection side) {
+ if (side != ForgeDirection.UNKNOWN) {
+ if (!getCoverInfoAtSide(side).letsEnergyOut()) return false;
+ if (isInvalid() || mReleaseEnergy) return mReleaseEnergy;
+ if (canAccessData() && mMetaTileEntity.isElectric() && mMetaTileEntity.isEnetOutput())
+ return mMetaTileEntity.isOutputFacing(side);
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean hasValidMetaTileEntity() {
+ return mMetaTileEntity != null && mMetaTileEntity.getBaseMetaTileEntity() == this;
+ }
+
+ @Override
+ 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.length() == 0))
+ if ((mOwnerName.length() == 0) && isServerSide()) {
+ setOwnerName(aPlayer.getDisplayName());
+ setOwnerUuid(aPlayer.getUniqueID());
+ } else return !privateAccess() || aPlayer.getDisplayName()
+ .equals("Player") || mOwnerName.equals("Player") || mOwnerName.equals(aPlayer.getDisplayName());
+ return true;
+ }
+
+ public boolean privateAccess() {
+ if (!canAccessData()) return mLockUpgrade;
+ return mLockUpgrade || mMetaTileEntity.ownerControl();
+ }
+
+ @Nullable
+ @Override
+ public ICleanroom getCleanroom() {
+ if (canAccessData()) {
+ return mMetaTileEntity.getCleanroom();
+ }
+ return null;
+ }
+
+ @Override
+ public void setCleanroom(ICleanroom cleanroom) {
+ if (canAccessData()) {
+ mMetaTileEntity.setCleanroom(cleanroom);
+ }
+ }
+
+ public void doEnergyExplosion() {
+ if (getUniversalEnergyCapacity() > 0 && getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 5) {
+ GT_Log.exp.println(
+ "Energy Explosion, injected " + getUniversalEnergyStored()
+ + "EU >= "
+ + getUniversalEnergyCapacity() / 5D
+ + "Capacity of the Machine!");
+
+ doExplosion(
+ oOutput * (getUniversalEnergyStored() >= getUniversalEnergyCapacity() ? 4
+ : getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 2 ? 2 : 1));
+ GT_Mod.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 ignored) {}
+ }
+ mReleaseEnergy = false;
+ // Normal Explosion Code
+ mMetaTileEntity.onExplosion();
+ if (GT_Mod.gregtechproxy.mExplosionItemDrop) {
+ for (int i = 0; i < this.getSizeInventory(); i++) {
+ final ItemStack tItem = this.getStackInSlot(i);
+ if ((tItem != null) && (tItem.stackSize > 0) && (this.isValidSlot(i))) {
+ dropItems(tItem);
+ this.setInventorySlotContents(i, null);
+ }
+ }
+ }
+ if (mRecipeStuff != null) {
+ for (int i = 0; i < 9; i++) {
+ if (this.getRandomNumber(100) < 50) {
+ dropItems(GT_Utility.loadItem(mRecipeStuff, "Ingredient." + i));
+ }
+ }
+ }
+
+ GT_Pollution.addPollution((TileEntity) this, GT_Mod.gregtechproxy.mPollutionOnExplosion);
+ mMetaTileEntity.doExplosion(aAmount);
+ }
+ }
+
+ public void dropItems(ItemStack tItem) {
+ if (tItem == null) return;
+ final EntityItem tItemEntity = new EntityItem(
+ this.worldObj,
+ this.xCoord + XSTR_INSTANCE.nextFloat() * 0.8F + 0.1F,
+ this.yCoord + XSTR_INSTANCE.nextFloat() * 0.8F + 0.1F,
+ this.zCoord + XSTR_INSTANCE.nextFloat() * 0.8F + 0.1F,
+ new ItemStack(tItem.getItem(), tItem.stackSize, tItem.getItemDamage()));
+ if (tItem.hasTagCompound()) {
+ tItemEntity.getEntityItem()
+ .setTagCompound(
+ (NBTTagCompound) tItem.getTagCompound()
+ .copy());
+ }
+ tItemEntity.motionX = (XSTR_INSTANCE.nextGaussian() * 0.0500000007450581D);
+ tItemEntity.motionY = (XSTR_INSTANCE.nextGaussian() * 0.0500000007450581D + 0.2000000029802322D);
+ tItemEntity.motionZ = (XSTR_INSTANCE.nextGaussian() * 0.0500000007450581D);
+ tItemEntity.hurtResistantTime = 999999;
+ tItemEntity.lifespan = 60000;
+ try {
+ ENTITY_ITEM_HEALTH_FIELD.setInt(tItemEntity, 99999999);
+ } catch (Exception ignored) {}
+ this.worldObj.spawnEntityInWorld(tItemEntity);
+ tItem.stackSize = 0;
+ }
+
+ @Override
+ public ArrayList<ItemStack> getDrops() {
+ final ItemStack rStack = new ItemStack(GregTech_API.sBlockMachines, 1, mID);
+ final 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);
+
+ writeCoverNBT(tNBT, true);
+
+ if (hasValidMetaTileEntity()) mMetaTileEntity.setItemNBT(tNBT);
+ if (!tNBT.hasNoTags()) rStack.setTagCompound(tNBT);
+
+ onBaseTEDestroyed();
+ return new ArrayList<>(Collections.singletonList(rStack));
+ }
+
+ @Override
+ public boolean shouldDropItemAt(int index) {
+ return this.mMetaTileEntity == null || this.mMetaTileEntity.shouldDropItemAt(index);
+ }
+
+ public int getUpgradeCount() {
+ return (mMuffler ? 1 : 0) + (mLockUpgrade ? 1 : 0) + (mSteamConverter ? 1 : 0) + mOtherUpgrades;
+ }
+
+ @Override
+ public boolean onRightclick(EntityPlayer aPlayer, ForgeDirection side, float aX, float aY, float aZ) {
+ if (isClientSide()) {
+ // Configure Cover, sneak can also be: screwdriver, wrench, side cutter, soldering iron
+ if (aPlayer.isSneaking()) {
+ final ForgeDirection tSide = (getCoverIDAtSide(side) == 0)
+ ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ)
+ : side;
+ return (getCoverBehaviorAtSideNew(tSide).hasCoverGUI());
+ } else if (getCoverBehaviorAtSideNew(side).onCoverRightclickClient(side, this, aPlayer, aX, aY, aZ)) {
+ return true;
+ }
+
+ if (!getCoverInfoAtSide(side).isGUIClickable()) return false;
+ }
+
+ if (isServerSide()) {
+ if (!privateAccess() || aPlayer.getDisplayName()
+ .equalsIgnoreCase(getOwnerName())) {
+ final 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 (aPlayer.isSneaking() && mMetaTileEntity instanceof GT_MetaTileEntity_BasicMachine
+ && ((GT_MetaTileEntity_BasicMachine) mMetaTileEntity)
+ .setMainFacing(GT_Utility.determineWrenchingSide(side, aX, aY, aZ))) {
+ GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer);
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_WRENCH,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ cableUpdateDelay = 10;
+ } else if (mMetaTileEntity.onWrenchRightClick(
+ side,
+ GT_Utility.determineWrenchingSide(side, aX, aY, aZ),
+ aPlayer,
+ aX,
+ aY,
+ aZ,
+ tCurrentItem)) {
+ GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer);
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_WRENCH,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ cableUpdateDelay = 10;
+ }
+ return true;
+ }
+
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sScrewdriverList)) {
+ if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) {
+ setCoverDataAtSide(
+ side,
+ getCoverBehaviorAtSideNew(side).onCoverScrewdriverClick(
+ side,
+ getCoverIDAtSide(side),
+ getComplexCoverDataAtSide(side),
+ this,
+ aPlayer,
+ aX,
+ aY,
+ aZ));
+ mMetaTileEntity.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ, tCurrentItem);
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_WRENCH,
+ 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,
+ GT_Utility.trans("086", "Auto-Input: ") + (mInputDisabled
+ ? GT_Utility.trans("087", "Disabled")
+ : GT_Utility.trans("088", "Enabled") + GT_Utility.trans("089", " Auto-Output: ")
+ + (mOutputDisabled ? GT_Utility.trans("087", "Disabled")
+ : GT_Utility.trans("088", "Enabled"))));
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.RANDOM_ANVIL_USE,
+ 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();
+ {
+ String tChat = GT_Utility.trans("090", "Machine Processing: ")
+ + (isAllowedToWork() ? GT_Utility.trans("088", "Enabled")
+ : GT_Utility.trans("087", "Disabled"));
+ if (getMetaTileEntity() != null && getMetaTileEntity().hasAlternativeModeText())
+ tChat = getMetaTileEntity().getAlternativeModeText();
+ GT_Utility.sendChatToPlayer(aPlayer, tChat);
+ }
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_RUBBER_TRAMPOLINE,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ }
+ return true;
+ }
+
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSolderingToolList)) {
+ final ForgeDirection tSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ);
+ if (mMetaTileEntity.onSolderingToolRightClick(side, tSide, aPlayer, aX, aY, aZ, tCurrentItem)) {
+ // logic handled internally
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_BATTERY_USE,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ } else if (GT_ModHandler.useSolderingIron(tCurrentItem, aPlayer)) {
+ mStrongRedstone ^= tSide.flag;
+ GT_Utility.sendChatToPlayer(
+ aPlayer,
+ GT_Utility.trans("091", "Redstone Output at Side ") + tSide
+ + GT_Utility.trans("092", " set to: ")
+ + ((mStrongRedstone & tSide.flag) != 0 ? GT_Utility.trans("093", "Strong")
+ : GT_Utility.trans("094", "Weak")));
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_BATTERY_USE,
+ 3.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ issueBlockUpdate();
+ }
+ doEnetUpdate();
+ cableUpdateDelay = 10;
+ return true;
+ }
+
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWireCutterList)) {
+ final ForgeDirection tSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ);
+ if (mMetaTileEntity.onWireCutterRightClick(side, tSide, aPlayer, aX, aY, aZ, tCurrentItem)) {
+ // logic handled internally
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_WRENCH,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ }
+ doEnetUpdate();
+ cableUpdateDelay = 10;
+ return true;
+ }
+
+ ForgeDirection coverSide = side;
+ if (getCoverIDAtSide(side) == 0) coverSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ);
+
+ if (getCoverIDAtSide(coverSide) == 0) {
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCovers.keySet())) {
+ final GT_CoverBehaviorBase<?> coverBehavior = GregTech_API
+ .getCoverBehaviorNew(tCurrentItem);
+ if (coverBehavior.isCoverPlaceable(coverSide, tCurrentItem, this)
+ && mMetaTileEntity.allowCoverOnSide(coverSide, new GT_ItemStack(tCurrentItem))) {
+
+ setCoverItemAtSide(coverSide, tCurrentItem);
+ coverBehavior.onPlayerAttach(aPlayer, tCurrentItem, this, coverSide);
+
+ if (!aPlayer.capabilities.isCreativeMode) tCurrentItem.stackSize--;
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_WRENCH,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ sendClientData();
+ }
+ return true;
+ }
+ } else {
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCrowbarList)) {
+ if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) {
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.RANDOM_BREAK,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ dropCover(coverSide, side, false);
+ }
+ return true;
+ } else if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sJackhammerList)) {
+ // Configuration of delicate electronics calls for a tool with precision and subtlety.
+ if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) {
+ final CoverInfo info = getCoverInfoAtSide(coverSide);
+ if (info != CoverInfo.EMPTY_INFO) {
+ final GT_CoverBehaviorBase<?> behavior = info.getCoverBehavior();
+ if (behavior.allowsTickRateAddition()) {
+ info.onCoverJackhammer(aPlayer);
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.IC2_TOOLS_DRILL_DRILL_SOFT,
+ 1.0F,
+ 1,
+ xCoord,
+ yCoord,
+ zCoord);
+
+ } else {
+ GT_Utility.sendChatToPlayer(
+ aPlayer,
+ StatCollector.translateToLocal("gt.cover.info.chat.tick_rate_not_allowed"));
+ }
+ return true;
+ }
+ }
+ }
+ }
+ // End item != null
+ } else if (aPlayer.isSneaking()) { // Sneak click, no tool -> open cover config if possible.
+ side = (getCoverIDAtSide(side) == 0) ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ) : side;
+ return getCoverIDAtSide(side) > 0 && getCoverBehaviorAtSideNew(side).onCoverShiftRightClick(
+ side,
+ getCoverIDAtSide(side),
+ getComplexCoverDataAtSide(side),
+ this,
+ aPlayer);
+ }
+
+ if (getCoverBehaviorAtSideNew(side).onCoverRightClick(
+ side,
+ getCoverIDAtSide(side),
+ getComplexCoverDataAtSide(side),
+ this,
+ aPlayer,
+ aX,
+ aY,
+ aZ)) return true;
+
+ if (!getCoverInfoAtSide(side).isGUIClickable()) return false;
+
+ if (isUpgradable() && tCurrentItem != null) {
+ if (ItemList.Upgrade_Muffler.isStackEqual(aPlayer.inventory.getCurrentItem())) {
+ if (addMufflerUpgrade()) {
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.RANDOM_CLICK,
+ 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());
+ setOwnerUuid(aPlayer.getUniqueID());
+ GT_Utility.sendSoundToPlayers(
+ worldObj,
+ SoundResource.RANDOM_CLICK,
+ 1.0F,
+ -1,
+ xCoord,
+ yCoord,
+ zCoord);
+ if (!aPlayer.capabilities.isCreativeMode) aPlayer.inventory.getCurrentItem().stackSize--;
+ }
+ return true;
+ }
+ }
+ }
+ }
+
+ try {
+ if (!aPlayer.isSneaking() && hasValidMetaTileEntity())
+ return mMetaTileEntity.onRightclick(this, aPlayer, side, aX, aY, aZ);
+ } catch (Throwable e) {
+ GT_Log.err.println(
+ "Encountered Exception while rightclicking TileEntity, the Game should've crashed now, but I prevented that. Please report immediately to GregTech Intergalactical!!!");
+ e.printStackTrace(GT_Log.err);
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onLeftclick(EntityPlayer aPlayer) {
+ try {
+ if (aPlayer != null && hasValidMetaTileEntity()) mMetaTileEntity.onLeftclick(this, aPlayer);
+ } catch (Throwable e) {
+ GT_Log.err.println(
+ "Encountered Exception while leftclicking TileEntity, the Game should've crashed now, but I prevented that. Please report immediately 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 ordinalSide) {
+ final CoverInfo coverInfo = getCoverInfoAtSide(ForgeDirection.getOrientation(ordinalSide));
+ if (canAccessData() && (coverInfo.letsItemsOut(-1) || coverInfo.letsItemsIn(-1)))
+ return mMetaTileEntity.getAccessibleSlotsFromSide(ordinalSide);
+ return GT_Values.emptyIntArray;
+ }
+
+ /**
+ * Can put aStack into Slot at Side
+ */
+ @Override
+ public boolean canInsertItem(int slotIndex, ItemStack stack, int ordinalSide) {
+ return canAccessData() && (mRunningThroughTick || !mInputDisabled)
+ && getCoverInfoAtSide(ForgeDirection.getOrientation(ordinalSide)).letsItemsIn(slotIndex)
+ && mMetaTileEntity.canInsertItem(slotIndex, stack, ordinalSide);
+ }
+
+ /**
+ * Can pull stack out of Slot from Side
+ */
+ @Override
+ public boolean canExtractItem(int slotIndex, ItemStack stack, int ordinalSide) {
+ final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide);
+ return canAccessData() && (mRunningThroughTick || !mOutputDisabled)
+ && getCoverBehaviorAtSideNew(side)
+ .letsItemsOut(side, getCoverIDAtSide(side), getComplexCoverDataAtSide(side), slotIndex, this)
+ && mMetaTileEntity.canExtractItem(slotIndex, stack, ordinalSide);
+ }
+
+ @Override
+ public boolean isUpgradable() {
+ return canAccessData() && getUpgradeCount() < 8;
+ }
+
+ @Override
+ public byte getGeneralRS(ForgeDirection side) {
+ if (mMetaTileEntity == null) return 0;
+ return mMetaTileEntity.allowGeneralRedstoneOutput() ? mSidedRedstone[side.ordinal()] : 0;
+ }
+
+ @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 void markInventoryBeenModified() {
+ mInventoryChanged = true;
+ }
+
+ @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) {
+ if (aMetaTileEntity instanceof MetaTileEntity || aMetaTileEntity == null)
+ mMetaTileEntity = (MetaTileEntity) aMetaTileEntity;
+ else {
+ GT_FML_LOGGER.error(
+ "Unknown meta tile entity set! Class {}, inventory name {}.",
+ aMetaTileEntity.getClass(),
+ aMetaTileEntity.getInventoryName());
+ }
+ }
+
+ public byte getLightValue() {
+ return mLightValue;
+ }
+
+ @Override
+ public void setLightValue(byte aLightValue) {
+ mLightValue = (byte) (aLightValue & 15);
+ }
+
+ @Override
+ public long getAverageElectricInput() {
+ long rEU = 0;
+ for (int i = 0; i < mAverageEUInput.length; ++i) if (i != mAverageEUInputIndex) rEU += mAverageEUInput[i];
+ return rEU / (mAverageEUInput.length - 1);
+ }
+
+ @Override
+ public long getAverageElectricOutput() {
+ long rEU = 0;
+ for (int i = 0; i < mAverageEUOutput.length; ++i) if (i != mAverageEUOutputIndex) rEU += mAverageEUOutput[i];
+ return rEU / (mAverageEUOutput.length - 1);
+ }
+
+ @Override
+ protected void updateOutputRedstoneSignal(ForgeDirection side) {
+ if (mMetaTileEntity.hasSidedRedstoneOutputBehavior()) {
+ setOutputRedstoneSignal(side, (byte) 0);
+ } else {
+ setOutputRedstoneSignal(side, (byte) 15);
+ }
+ }
+
+ @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 UUID getOwnerUuid() {
+ return mOwnerUuid;
+ }
+
+ @Override
+ public void setOwnerUuid(UUID uuid) {
+ mOwnerUuid = uuid;
+ }
+
+ @Override
+ public byte getComparatorValue(ForgeDirection side) {
+ return canAccessData() ? mMetaTileEntity.getComparatorValue(side) : 0;
+ }
+
+ @Override
+ public ItemStack decrStackSize(int aIndex, int aAmount) {
+ if (canAccessData()) {
+ mInventoryChanged = true;
+ return mMetaTileEntity.decrStackSize(aIndex, aAmount);
+ }
+ return null;
+ }
+
+ @Override
+ public long injectEnergyUnits(ForgeDirection side, long aVoltage, long aAmperage) {
+ if (!canAccessData() || !mMetaTileEntity.isElectric()
+ || !inputEnergyFrom(side)
+ || aAmperage <= 0
+ || aVoltage <= 0
+ || getStoredEU() >= getEUCapacity()
+ || mMetaTileEntity.maxAmperesIn() <= mAcceptedAmperes) return 0;
+ if (aVoltage > getInputVoltage()) {
+ GT_Log.exp
+ .println("Energy Explosion, injected " + aVoltage + "EU/t in a " + getInputVoltage() + "EU/t Machine!");
+ 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(ForgeDirection side, long aVoltage, long aAmperage) {
+ if (!canAccessData() || !mMetaTileEntity.isElectric()
+ || !outputsEnergyTo(side)
+ || getStoredEU() - (aVoltage * aAmperage) < mMetaTileEntity.getMinimumStoredEU()) return false;
+ if (decreaseStoredEU(aVoltage * aAmperage, false)) {
+ mAverageEUOutput[mAverageEUOutputIndex] += aVoltage * aAmperage;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean acceptsRotationalEnergy(ForgeDirection side) {
+ if (!canAccessData() || getCoverIDAtSide(side) != 0) return false;
+ return mMetaTileEntity.acceptsRotationalEnergy(side);
+ }
+
+ @Override
+ public boolean injectRotationalEnergy(ForgeDirection side, long aSpeed, long aEnergy) {
+ if (!canAccessData() || getCoverIDAtSide(side) != 0) return false;
+ return mMetaTileEntity.injectRotationalEnergy(side, aSpeed, aEnergy);
+ }
+
+ @Override
+ public int fill(ForgeDirection side, FluidStack aFluid, boolean doFill) {
+ if (mTickTimer > 5 && canAccessData()
+ && (mRunningThroughTick || !mInputDisabled)
+ && (side == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidInput(side)
+ && getCoverInfoAtSide(side).letsFluidIn(aFluid == null ? null : aFluid.getFluid()))))
+ return mMetaTileEntity.fill(side, aFluid, doFill);
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection side, int maxDrain, boolean doDrain) {
+ if (mTickTimer > 5 && canAccessData()
+ && (mRunningThroughTick || !mOutputDisabled)
+ && (side == ForgeDirection.UNKNOWN
+ || (mMetaTileEntity.isLiquidOutput(side) && getCoverInfoAtSide(side).letsFluidOut(
+ mMetaTileEntity.getFluid() == null ? null
+ : mMetaTileEntity.getFluid()
+ .getFluid()))))
+ return mMetaTileEntity.drain(side, maxDrain, doDrain);
+ return null;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection side, FluidStack aFluid, boolean doDrain) {
+ if (mTickTimer > 5 && canAccessData()
+ && (mRunningThroughTick || !mOutputDisabled)
+ && (side == ForgeDirection.UNKNOWN || (mMetaTileEntity.isLiquidOutput(side)
+ && getCoverInfoAtSide(side).letsFluidOut(aFluid == null ? null : aFluid.getFluid()))))
+ return mMetaTileEntity.drain(side, aFluid, doDrain);
+ return null;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection side, Fluid aFluid) {
+ if (mTickTimer > 5 && canAccessData()
+ && (mRunningThroughTick || !mInputDisabled)
+ && (side == ForgeDirection.UNKNOWN
+ || (mMetaTileEntity.isLiquidInput(side) && getCoverInfoAtSide(side).letsFluidIn(aFluid))))
+ return mMetaTileEntity.canFill(side, aFluid);
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection side, Fluid aFluid) {
+ if (mTickTimer > 5 && canAccessData()
+ && (mRunningThroughTick || !mOutputDisabled)
+ && (side == ForgeDirection.UNKNOWN
+ || (mMetaTileEntity.isLiquidOutput(side) && getCoverInfoAtSide(side).letsFluidOut(aFluid))))
+ return mMetaTileEntity.canDrain(side, aFluid);
+ return false;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection side) {
+ if (canAccessData() && (side == ForgeDirection.UNKNOWN
+ || (mMetaTileEntity.isLiquidInput(side) && getCoverInfoAtSide(side).letsFluidIn(null))
+ || (mMetaTileEntity.isLiquidOutput(side) && getCoverInfoAtSide(side).letsFluidOut(null))))
+ return mMetaTileEntity.getTankInfo(side);
+ return new FluidTankInfo[] {};
+ }
+
+ public double getOutputEnergyUnitsPerTick() {
+ return oOutput;
+ }
+
+ public boolean isTeleporterCompatible(ForgeDirection side) {
+ 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(aDirection, (int) aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+ public boolean acceptsEnergyFrom(TileEntity aEmitter, ForgeDirection aDirection) {
+ return inputEnergyFrom(aDirection);
+ }
+
+ public boolean emitsEnergyTo(TileEntity aReceiver, ForgeDirection aDirection) {
+ return outputsEnergyTo(aDirection);
+ }
+
+ 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(aForgeDirection, 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(aDirection.toForgeDirection(), aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+ public boolean isTeleporterCompatible(Direction ignoredDirection) {
+ return canAccessData() && mMetaTileEntity.isTeleporterCompatible();
+ }
+
+ public boolean acceptsEnergyFrom(TileEntity ignoredTileEntity, Direction aDirection) {
+ return inputEnergyFrom(aDirection.toForgeDirection());
+ }
+
+ public boolean emitsEnergyTo(TileEntity ignoredTileEntity, Direction aDirection) {
+ return outputsEnergyTo(aDirection.toForgeDirection());
+ }
+
+ @Override
+ public boolean addStackToSlot(int slotIndex, ItemStack stack) {
+ if (GT_Utility.isStackInvalid(stack)) return true;
+ if (slotIndex < 0 || slotIndex >= getSizeInventory()) return false;
+ final ItemStack toStack = getStackInSlot(slotIndex);
+ if (GT_Utility.isStackInvalid(toStack)) {
+ setInventorySlotContents(slotIndex, stack);
+ return true;
+ }
+ final ItemStack fromStack = GT_OreDictUnificator.get(stack);
+ if (GT_Utility.areStacksEqual(toStack, fromStack) && toStack.stackSize + fromStack.stackSize
+ <= Math.min(fromStack.getMaxStackSize(), getInventoryStackLimit())) {
+ toStack.stackSize += fromStack.stackSize;
+ markDirty();
+ 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;
+ mColor = (byte) (aColor + 1);
+ if (canAccessData()) mMetaTileEntity.onColorChangeServer(aColor);
+ return mColor;
+ }
+
+ @Override
+ public float getBlastResistance(ForgeDirection side) {
+ return canAccessData() ? Math.max(0, getMetaTileEntity().getExplosionResistance(side)) : 10.0F;
+ }
+
+ @Override
+ public void onBlockDestroyed() {
+ if (canAccessData()) getMetaTileEntity().onBlockDestroyed();
+ }
+
+ @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 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);
+ }
+
+ /**
+ * Shifts the machine Inventory index according to the change in Input/Output Slots. This is NOT done automatically.
+ * If you want to change slot count for a machine this method needs to be adapted. Currently this method only works
+ * for GT_MetaTileEntity_BasicMachine
+ *
+ * @param slotIndex The original Inventory index
+ * @param nbtVersion The GregTech version in which the original Inventory Index was saved.
+ * @return The corrected Inventory index
+ */
+ @Override
+ protected int migrateInventoryIndex(int slotIndex, int nbtVersion) {
+ final int oldInputSize;
+ final int newInputSize;
+ final int oldOutputSize;
+ final int newOutputSize;
+ final int chemistryUpdateVersion = GT_Mod.calculateTotalGTVersion(509, 31);
+ final int configCircuitAdditionVersion = GT_Mod.calculateTotalGTVersion(509, 40);
+ final int wireAdditionVersion = GT_Mod.calculateTotalGTVersion(509, 41);
+ final int disassemblerRemoveVersion = GT_Mod.calculateTotalGTVersion(509, 42, 44);
+ if (nbtVersion < 1000000) nbtVersion *= 1000;
+ // 4 is old GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT
+ if (nbtVersion < configCircuitAdditionVersion && getMetaTileEntity() instanceof GT_MetaTileEntity_BasicMachine
+ && slotIndex >= 4) slotIndex += 1;
+ if (mID >= 211 && mID <= 218) { // Assembler
+ if (nbtVersion < chemistryUpdateVersion) {
+ oldInputSize = 2;
+ oldOutputSize = 1;
+ } else {
+ return slotIndex;
+ }
+ newInputSize = 6;
+ newOutputSize = 1;
+
+ } else if (mID >= 421 && mID <= 428) { // Chemical Reactor
+ if (nbtVersion < chemistryUpdateVersion) {
+ oldInputSize = 2;
+ oldOutputSize = 1;
+ } else {
+ return slotIndex;
+ }
+ newInputSize = 2;
+ newOutputSize = 2;
+
+ } else if (mID >= 531 && mID <= 538) { // Distillery
+ if (nbtVersion < chemistryUpdateVersion) {
+ oldInputSize = 1;
+ oldOutputSize = 0;
+ } else {
+ return slotIndex;
+ }
+ newInputSize = 1;
+ newOutputSize = 1;
+ } else if (mID >= 581 && mID <= 588) { // Mixer
+ if (nbtVersion < chemistryUpdateVersion) {
+ oldInputSize = 4;
+ oldOutputSize = 1;
+ } else {
+ return slotIndex;
+ }
+ newInputSize = 6;
+ newOutputSize = 1;
+
+ } else if (mID >= 351 && mID <= 355 || mID >= 11050 && mID <= 11056) { // wire mill
+ if (nbtVersion < wireAdditionVersion) {
+ oldInputSize = 1;
+ oldOutputSize = 1;
+ } else {
+ return slotIndex;
+ }
+ newInputSize = 2;
+ newOutputSize = 1;
+
+ } else if (mID >= 654 && mID <= 655 || mID >= 11070 && mID <= 11076) { // arc furnace
+ if (nbtVersion < disassemblerRemoveVersion) {
+ oldInputSize = 1;
+ oldOutputSize = 4;
+ } else {
+ return slotIndex;
+ }
+ newInputSize = 1;
+ newOutputSize = 9;
+
+ } else {
+ return slotIndex;
+ }
+
+ int indexShift = 0;
+ if (slotIndex >= GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT + oldInputSize) {
+ indexShift += newInputSize - oldInputSize;
+ }
+ if (slotIndex >= GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT + oldInputSize + oldOutputSize) {
+ indexShift += newOutputSize - oldOutputSize;
+ }
+ return slotIndex + indexShift;
+ }
+
+ @Override
+ public IGridNode getGridNode(ForgeDirection forgeDirection) {
+ final AENetworkProxy gp = getProxy();
+ return gp != null ? gp.getNode() : null;
+ }
+
+ @Override
+ public AECableType getCableConnectionType(ForgeDirection forgeDirection) {
+ return mMetaTileEntity == null ? AECableType.NONE : mMetaTileEntity.getCableConnectionType(forgeDirection);
+ }
+
+ @Override
+ public void securityBreak() {}
+
+ @Override
+ public IGridNode getActionableNode() {
+ final AENetworkProxy gp = getProxy();
+ return gp != null ? gp.getNode() : null;
+ }
+
+ @Override
+ public AENetworkProxy getProxy() {
+ return mMetaTileEntity == null ? null : mMetaTileEntity.getProxy();
+ }
+
+ @Override
+ public DimensionalCoord getLocation() {
+ return new DimensionalCoord(this);
+ }
+
+ @Override
+ public void gridChanged() {
+ if (mMetaTileEntity != null) mMetaTileEntity.gridChanged();
+ }
+
+ @TileEvent(TileEventType.WORLD_NBT_READ)
+ public void readFromNBT_AENetwork(final NBTTagCompound data) {
+ final AENetworkProxy gp = getProxy();
+ if (gp != null) getProxy().readFromNBT(data);
+ }
+
+ @TileEvent(TileEventType.WORLD_NBT_WRITE)
+ public void writeToNBT_AENetwork(final NBTTagCompound data) {
+ final AENetworkProxy gp = getProxy();
+ if (gp != null) gp.writeToNBT(data);
+ }
+
+ void onChunkUnloadAE() {
+ final AENetworkProxy gp = getProxy();
+ if (gp != null) gp.onChunkUnload();
+ }
+
+ void invalidateAE() {
+ final AENetworkProxy gp = getProxy();
+ if (gp != null) gp.invalidate();
+ }
+
+ @Override
+ public boolean wasShutdown() {
+ return mWasShutdown;
+ }
+
+ @Override
+ public void setShutdownStatus(boolean newStatus) {
+ mWasShutdown = newStatus;
+ }
+
+ @Override
+ public void setShutDownReason(@NotNull ShutDownReason reason) {
+ lastShutDownReason = reason;
+ }
+
+ @Override
+ public @NotNull ShutDownReason getLastShutDownReason() {
+ return lastShutDownReason;
+ }
+
+ @Override
+ public IAlignment getAlignment() {
+ return getMetaTileEntity() instanceof IAlignmentProvider
+ ? ((IAlignmentProvider) getMetaTileEntity()).getAlignment()
+ : getMetaTileEntity() instanceof IAlignment ? (IAlignment) getMetaTileEntity() : null;
+ }
+
+ @Nullable
+ @Override
+ public IConstructable getConstructable() {
+ return getMetaTileEntity() instanceof IConstructable ? (IConstructable) getMetaTileEntity() : null;
+ }
+
+ @Override
+ public int[] getTimeStatistics() {
+ return mTimeStatistics;
+ }
+
+ @Override
+ public void startTimeStatistics() {
+ hasTimeStatisticsStarted = true;
+ }
+
+ @Nullable
+ @Override
+ public List<ItemStack> getItemsForHoloGlasses() {
+ if (canAccessData()) {
+ return mMetaTileEntity.getItemsForHoloGlasses();
+ }
+ return null;
+ }
+
+ @Override
+ public String getCustomName() {
+ return getMetaTileEntity() instanceof ICustomNameObject customNameObject ? customNameObject.getCustomName()
+ : null;
+ }
+
+ @Override
+ public boolean hasCustomName() {
+ return getMetaTileEntity() instanceof ICustomNameObject customNameObject && customNameObject.hasCustomName();
+ }
+
+ @Override
+ public void setCustomName(String name) {
+ if (getMetaTileEntity() instanceof ICustomNameObject customNameObject) customNameObject.setCustomName(name);
+ }
+}