aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/tectech/thing/metaTileEntity/multi/base
diff options
context:
space:
mode:
authorNotAPenguin <michiel.vandeginste@gmail.com>2024-09-02 23:17:17 +0200
committerGitHub <noreply@github.com>2024-09-02 23:17:17 +0200
commit1b820de08a05070909a267e17f033fcf58ac8710 (patch)
tree02831a025986a06b20f87e5bcc69d1e0c639a342 /src/main/java/tectech/thing/metaTileEntity/multi/base
parentafd3fd92b6a6ab9ab0d0dc3214e6bc8ff7a86c9b (diff)
downloadGT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.gz
GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.bz2
GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.zip
The Great Renaming (#3014)
* move kekztech to a single root dir * move detrav to a single root dir * move gtnh-lanthanides to a single root dir * move tectech and delete some gross reflection in gt++ * remove more reflection inside gt5u * delete more reflection in gt++ * fix imports * move bartworks and bwcrossmod * fix proxies * move galactigreg and ggfab * move gtneioreplugin * try to fix gt++ bee loader * apply the rename rules to BW * apply rename rules to bwcrossmod * apply rename rules to detrav scanner mod * apply rename rules to galacticgreg * apply rename rules to ggfab * apply rename rules to goodgenerator * apply rename rules to gtnh-lanthanides * apply rename rules to gt++ * apply rename rules to kekztech * apply rename rules to kubatech * apply rename rules to tectech * apply rename rules to gt apply the rename rules to gt * fix tt import * fix mui hopefully * fix coremod except intergalactic * rename assline recipe class * fix a class name i stumbled on * rename StructureUtility to GTStructureUtility to prevent conflict with structurelib * temporary rename of GTTooltipDataCache to old name * fix gt client/server proxy names
Diffstat (limited to 'src/main/java/tectech/thing/metaTileEntity/multi/base')
-rw-r--r--src/main/java/tectech/thing/metaTileEntity/multi/base/INameFunction.java6
-rw-r--r--src/main/java/tectech/thing/metaTileEntity/multi/base/IStatusFunction.java6
-rw-r--r--src/main/java/tectech/thing/metaTileEntity/multi/base/LedStatus.java64
-rw-r--r--src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java327
-rw-r--r--src/main/java/tectech/thing/metaTileEntity/multi/base/SoundLoop.java59
-rw-r--r--src/main/java/tectech/thing/metaTileEntity/multi/base/TTMultiblockBase.java2760
-rw-r--r--src/main/java/tectech/thing/metaTileEntity/multi/base/render/TTRenderedExtendedFacingTexture.java25
7 files changed, 3247 insertions, 0 deletions
diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/INameFunction.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/INameFunction.java
new file mode 100644
index 0000000000..697c748ba4
--- /dev/null
+++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/INameFunction.java
@@ -0,0 +1,6 @@
+package tectech.thing.metaTileEntity.multi.base;
+
+public interface INameFunction<T extends TTMultiblockBase> {
+
+ String apply(T t, Parameters.IParameter iParameter);
+}
diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/IStatusFunction.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/IStatusFunction.java
new file mode 100644
index 0000000000..b051f0dfa3
--- /dev/null
+++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/IStatusFunction.java
@@ -0,0 +1,6 @@
+package tectech.thing.metaTileEntity.multi.base;
+
+public interface IStatusFunction<T extends TTMultiblockBase> {
+
+ LedStatus apply(T t, Parameters.IParameter iParameter);
+}
diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/LedStatus.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/LedStatus.java
new file mode 100644
index 0000000000..022408f688
--- /dev/null
+++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/LedStatus.java
@@ -0,0 +1,64 @@
+package tectech.thing.metaTileEntity.multi.base;
+
+import java.util.function.Supplier;
+
+import net.minecraft.util.EnumChatFormatting;
+
+import tectech.TecTech;
+
+public enum LedStatus {
+
+ STATUS_UNUSED(() -> EnumChatFormatting.DARK_GRAY + "Unused", true), //
+ STATUS_TOO_LOW(() -> EnumChatFormatting.BLUE + "Too Low", false), //
+ STATUS_LOW(() -> EnumChatFormatting.AQUA + "Low", true), //
+ STATUS_WRONG(() -> EnumChatFormatting.DARK_PURPLE + "Wrong", false), //
+ STATUS_OK(() -> EnumChatFormatting.GREEN + "Valid", true), //
+ STATUS_TOO_HIGH(() -> EnumChatFormatting.RED + "Too High", false), //
+ STATUS_HIGH(() -> EnumChatFormatting.GOLD + "High", true), //
+ STATUS_UNDEFINED(() -> EnumChatFormatting.GRAY + "Unknown", false),
+ STATUS_NEUTRAL(() -> EnumChatFormatting.WHITE + "Neutral", true),
+ STATUS_WTF(() -> LedStatus.values()[TecTech.RANDOM.nextInt(9)].name.get(), false);
+
+ public final Supplier<String> name;
+ public final boolean isOk;
+
+ LedStatus(Supplier<String> name, boolean ok) {
+ this.name = name;
+ this.isOk = ok;
+ }
+
+ public byte getOrdinalByte() {
+ return (byte) ordinal();
+ }
+
+ public static LedStatus getStatus(byte value) {
+ try {
+ return LedStatus.values()[value];
+ } catch (Exception e) {
+ return STATUS_UNDEFINED;
+ }
+ }
+
+ public static LedStatus[] makeArray(int count, LedStatus defaultValue) {
+ LedStatus[] statuses = new LedStatus[count];
+ for (int i = 0; i < count; i++) {
+ statuses[i] = defaultValue;
+ }
+ return statuses;
+ }
+
+ public static LedStatus fromLimitsInclusiveOuterBoundary(double value, double min, double low, double high,
+ double max, double... excludedNumbers) {
+ if (value < min) return STATUS_TOO_LOW;
+ if (value > max) return STATUS_TOO_HIGH;
+
+ if (value < low) return STATUS_LOW;
+ if (value > high) return STATUS_HIGH;
+ for (double val : excludedNumbers) {
+ if (val == value) return STATUS_WRONG;
+ }
+ if (Double.isNaN(value)) return STATUS_WRONG;
+ return STATUS_OK;
+ }
+
+}
diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java
new file mode 100644
index 0000000000..27eb961166
--- /dev/null
+++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java
@@ -0,0 +1,327 @@
+package tectech.thing.metaTileEntity.multi.base;
+
+import java.util.ArrayList;
+
+/**
+ * Instantiate parameters as field in parametersInstantiation_EM();
+ */
+public class Parameters {
+
+ private static final IStatusFunction<?> LED_STATUS_FUNCTION_DEFAULT = (b, p) -> LedStatus.STATUS_UNDEFINED;
+ private static final INameFunction<?> NAME_FUNCTION_DEFAULT = (b, p) -> "Undefined";
+
+ final Group[] groups = new Group[10];
+
+ double[] iParamsIn = new double[20]; // number I from parametrizers
+ double[] iParamsOut = new double[20]; // number O to parametrizers
+ final ArrayList<Group.ParameterIn> parameterInArrayList = new ArrayList<>();
+ final ArrayList<Group.ParameterOut> parameterOutArrayList = new ArrayList<>();
+
+ // package private for use in gui
+ LedStatus[] eParamsInStatus = LedStatus.makeArray(20, LedStatus.STATUS_UNUSED); // LED status for I
+ LedStatus[] eParamsOutStatus = LedStatus.makeArray(20, LedStatus.STATUS_UNUSED); // LED status for O
+
+ double getIn(int hatchNo, int parameterId) {
+ return iParamsIn[hatchNo + 10 * parameterId];
+ }
+
+ double getOut(int hatchNo, int parameterId) {
+ return iParamsOut[hatchNo + 10 * parameterId];
+ }
+
+ LedStatus getStatusIn(int hatchNo, int parameterId) {
+ return eParamsInStatus[hatchNo + 10 * parameterId];
+ }
+
+ LedStatus getStatusOut(int hatchNo, int parameterId) {
+ return eParamsOutStatus[hatchNo + 10 * parameterId];
+ }
+
+ private final TTMultiblockBase parent;
+
+ Parameters(TTMultiblockBase parent) {
+ this.parent = parent;
+ }
+
+ public boolean trySetParameters(int hatch, double parameter0, double parameter1) {
+ Group p = groups[hatch];
+ if (parent.mMaxProgresstime <= 0 || (p != null && p.updateWhileRunning)) {
+ iParamsIn[hatch] = parameter0;
+ iParamsIn[hatch + 10] = parameter1;
+ return true;
+ }
+ return false;
+ }
+
+ @SuppressWarnings("unused") // Used in GTNH-Intergalactic, do not delete.
+ public boolean trySetParameters(int hatchNo, int parameterId, double parameter) {
+ Group p = groups[hatchNo];
+ if (parent.mMaxProgresstime <= 0 || (p != null && p.updateWhileRunning)) {
+ iParamsIn[hatchNo + 10 * parameterId] = parameter;
+ return true;
+ }
+ return false;
+ }
+
+ public void setToDefaults(int hatch, boolean defaultIn, boolean defaultOut) {
+ Group p = groups[hatch];
+ if (p == null) {
+ if (defaultIn) {
+ iParamsIn[hatch] = 0;
+ iParamsIn[hatch + 10] = 0;
+ }
+ if (defaultOut) {
+ iParamsOut[hatch] = 0;
+ iParamsOut[hatch + 10] = 0;
+ }
+ } else {
+ p.setToDefaults(defaultIn, defaultOut);
+ }
+ }
+
+ public void setToDefaults(boolean defaultIn, boolean defaultOut) {
+ for (int hatch = 0; hatch < 10; hatch++) {
+ setToDefaults(hatch, defaultIn, defaultOut);
+ }
+ }
+
+ public Group getGroup(int hatchNo, boolean updateWhileRunning) {
+ return groups[hatchNo] != null ? groups[hatchNo] : new Group(hatchNo, updateWhileRunning);
+ }
+
+ public Group getGroup(int hatchNo) {
+ return groups[hatchNo] != null ? groups[hatchNo] : new Group(hatchNo, false);
+ }
+
+ public interface IParameter {
+
+ double get();
+
+ double getDefault();
+
+ void updateStatus();
+
+ LedStatus getStatus(boolean update);
+
+ int id();
+
+ int hatchId();
+
+ int parameterId();
+
+ String getBrief();
+ }
+
+ /**
+ * most likely used locally in parametersInstantiation_EM()
+ */
+ public class Group {
+
+ private final int hatchNo;
+ public final ParameterIn[] parameterIn = new ParameterIn[2];
+ public final ParameterOut[] parameterOut = new ParameterOut[2];
+ public boolean updateWhileRunning;
+
+ private Group(int hatchNo, boolean updateWhileRunning) {
+ if (hatchNo < 0 || hatchNo >= 10) {
+ throw new IllegalArgumentException("Hatch id must be in 0 to 9 range");
+ }
+ this.hatchNo = hatchNo;
+ this.updateWhileRunning = updateWhileRunning;
+ groups[hatchNo] = this;
+ }
+
+ public ParameterIn makeInParameter(int paramID, double defaultValue, INameFunction<?> name,
+ IStatusFunction<?> status) {
+ return new ParameterIn(paramID, defaultValue, name, status);
+ }
+
+ public ParameterOut makeOutParameter(int paramID, double defaultValue, INameFunction<?> name,
+ IStatusFunction<?> status) {
+ return new ParameterOut(paramID, defaultValue, name, status);
+ }
+
+ public void setToDefaults(boolean defaultIn, boolean defaultOut) {
+ if (defaultIn) {
+ if (this.parameterIn[0] != null) {
+ this.parameterIn[0].setDefault();
+ } else {
+ iParamsIn[hatchNo] = 0;
+ }
+ if (this.parameterIn[1] != null) {
+ this.parameterIn[1].setDefault();
+ } else {
+ iParamsIn[hatchNo + 10] = 0;
+ }
+ }
+ if (defaultOut) {
+ if (this.parameterOut[0] != null) {
+ this.parameterOut[0].setDefault();
+ } else {
+ iParamsOut[hatchNo] = 0;
+ }
+ if (this.parameterOut[1] != null) {
+ this.parameterOut[1].setDefault();
+ } else {
+ iParamsOut[hatchNo + 10] = 0;
+ }
+ }
+ }
+
+ /**
+ * Make a field out of this...
+ */
+ public class ParameterOut implements IParameter {
+
+ public final int id;
+ public final double defaultValue;
+ IStatusFunction status;
+ INameFunction name;
+
+ private ParameterOut(int paramID, double defaultValue, INameFunction<?> name, IStatusFunction<?> status) {
+ this.name = name == null ? NAME_FUNCTION_DEFAULT : name;
+ if (paramID < 0 || paramID > 2) {
+ throw new IllegalArgumentException("Parameter id must be in 0 to 1 range");
+ }
+ if (parameterOut[paramID] != null) {
+ throw new IllegalArgumentException("Parameter id already occupied");
+ }
+ this.id = hatchNo + 10 * paramID;
+ this.defaultValue = defaultValue;
+ this.status = status == null ? LED_STATUS_FUNCTION_DEFAULT : status;
+ parameterOutArrayList.add(this);
+ parameterOut[paramID] = this;
+ }
+
+ void setDefault() {
+ set(defaultValue);
+ }
+
+ @Override
+ public double get() {
+ return iParamsOut[id];
+ }
+
+ @Override
+ public double getDefault() {
+ return defaultValue;
+ }
+
+ public void set(double value) {
+ iParamsOut[id] = value;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void updateStatus() {
+ eParamsOutStatus[id] = status.apply(parent, this);
+ }
+
+ @Override
+ public LedStatus getStatus(boolean update) {
+ if (update) {
+ updateStatus();
+ }
+ return eParamsOutStatus[id];
+ }
+
+ @Override
+ public String getBrief() {
+ return name.apply(parent, this);
+ }
+
+ @Override
+ public int id() {
+ return id;
+ }
+
+ @Override
+ public int hatchId() {
+ return id % 10;
+ }
+
+ @Override
+ public int parameterId() {
+ return id / 10;
+ }
+ }
+
+ /**
+ * Make a field out of this...
+ */
+ public class ParameterIn implements IParameter {
+
+ public final int id;
+ public final double defaultValue;
+ IStatusFunction status;
+ INameFunction name;
+
+ private ParameterIn(int paramID, double defaultValue, INameFunction<?> name, IStatusFunction<?> status) {
+ this.name = name == null ? NAME_FUNCTION_DEFAULT : name;
+ this.id = hatchNo + 10 * paramID;
+ if (paramID < 0 || paramID > 2) {
+ throw new IllegalArgumentException("Parameter id must be in 0 to 1 range");
+ }
+ if (parameterIn[paramID] != null) {
+ throw new IllegalArgumentException("Parameter id already occupied");
+ }
+ this.defaultValue = defaultValue;
+ this.status = status == null ? LED_STATUS_FUNCTION_DEFAULT : status;
+ parameterInArrayList.add(this);
+ parameterIn[paramID] = this;
+ }
+
+ void setDefault() {
+ set(defaultValue);
+ }
+
+ @Override
+ public double get() {
+ return iParamsIn[id];
+ }
+
+ void set(double value) {
+ iParamsIn[id] = value;
+ }
+
+ @Override
+ public double getDefault() {
+ return defaultValue;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void updateStatus() {
+ eParamsInStatus[id] = status.apply(parent, this);
+ }
+
+ @Override
+ public LedStatus getStatus(boolean update) {
+ if (update) {
+ updateStatus();
+ }
+ return eParamsInStatus[id];
+ }
+
+ @Override
+ public String getBrief() {
+ return name.apply(parent, this);
+ }
+
+ @Override
+ public int id() {
+ return id;
+ }
+
+ @Override
+ public int hatchId() {
+ return id % 10;
+ }
+
+ @Override
+ public int parameterId() {
+ return id / 10;
+ }
+ }
+ }
+}
diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/SoundLoop.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/SoundLoop.java
new file mode 100644
index 0000000000..c337f5093e
--- /dev/null
+++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/SoundLoop.java
@@ -0,0 +1,59 @@
+package tectech.thing.metaTileEntity.multi.base;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.MovingSound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.World;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+
+@SideOnly(Side.CLIENT)
+public class SoundLoop extends MovingSound {
+
+ private final boolean whileActive;
+ private final boolean whileInactive;
+ private final int worldID;
+ private boolean fadeMe = false;
+
+ public SoundLoop(ResourceLocation p_i45104_1_, IGregTechTileEntity base, boolean stopWhenActive,
+ boolean stopWhenInactive) {
+ super(p_i45104_1_);
+ this.whileActive = stopWhenActive;
+ this.whileInactive = stopWhenInactive;
+ xPosF = base.getXCoord();
+ yPosF = base.getYCoord();
+ zPosF = base.getZCoord();
+ worldID = base.getWorld().provider.dimensionId;
+ repeat = true;
+ volume = 0.0625f;
+ }
+
+ @Override
+ public void update() {
+ if (donePlaying) {
+ return;
+ }
+ if (fadeMe) {
+ volume -= 0.0625f;
+ if (volume <= 0) {
+ volume = 0;
+ donePlaying = true;
+ }
+ } else if (volume < 1) {
+ volume += 0.0625f;
+ }
+ World world = Minecraft.getMinecraft().thePlayer.worldObj;
+ donePlaying = world.provider.dimensionId != worldID
+ || !world.checkChunksExist((int) xPosF, (int) yPosF, (int) zPosF, (int) xPosF, (int) yPosF, (int) zPosF);
+ if (donePlaying) return;
+ TileEntity tile = world.getTileEntity((int) xPosF, (int) yPosF, (int) zPosF);
+ if (!(tile instanceof IGregTechTileEntity)) {
+ donePlaying = true;
+ return;
+ }
+ fadeMe |= ((IGregTechTileEntity) tile).isActive() ? whileActive : whileInactive;
+ }
+}
diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/TTMultiblockBase.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/TTMultiblockBase.java
new file mode 100644
index 0000000000..22a2d38c0a
--- /dev/null
+++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/TTMultiblockBase.java
@@ -0,0 +1,2760 @@
+package tectech.thing.metaTileEntity.multi.base;
+
+import static gregtech.api.enums.GTValues.V;
+import static gregtech.api.enums.GTValues.VN;
+import static gregtech.api.enums.HatchElement.InputBus;
+import static gregtech.api.enums.HatchElement.InputHatch;
+import static gregtech.api.enums.HatchElement.Maintenance;
+import static gregtech.api.enums.HatchElement.Muffler;
+import static gregtech.api.enums.HatchElement.OutputBus;
+import static gregtech.api.enums.HatchElement.OutputHatch;
+import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY;
+import static gregtech.api.util.GTUtility.filterValidMTEs;
+import static java.lang.Math.min;
+import static tectech.thing.casing.BlockGTCasingsTT.texturePage;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.jetbrains.annotations.NotNull;
+import org.lwjgl.opengl.GL11;
+
+import com.google.common.collect.Iterables;
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import com.gtnewhorizon.structurelib.alignment.IAlignment;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.IStructureElement;
+import com.gtnewhorizon.structurelib.util.Vec3Impl;
+import com.gtnewhorizons.modularui.api.NumberFormatMUI;
+import com.gtnewhorizons.modularui.api.drawable.IDrawable;
+import com.gtnewhorizons.modularui.api.drawable.UITexture;
+import com.gtnewhorizons.modularui.api.math.Alignment;
+import com.gtnewhorizons.modularui.api.math.Color;
+import com.gtnewhorizons.modularui.api.math.Pos2d;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.api.widget.Widget;
+import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot;
+import com.gtnewhorizons.modularui.common.widget.ButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
+import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+import com.gtnewhorizons.modularui.common.widget.TextWidget;
+import com.gtnewhorizons.modularui.common.widget.textfield.NumericWidget;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.enums.Textures;
+import gregtech.api.gui.modularui.GTUITextures;
+import gregtech.api.interfaces.IHatchElement;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.modularui.IBindPlayerInventoryUI;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.BaseTileEntity;
+import gregtech.api.metatileentity.MetaTileEntity;
+import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.metatileentity.implementations.MTEHatchDynamo;
+import gregtech.api.metatileentity.implementations.MTEHatchEnergy;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.metatileentity.implementations.MTEHatchInputBus;
+import gregtech.api.metatileentity.implementations.MTEHatchMaintenance;
+import gregtech.api.metatileentity.implementations.MTEHatchMuffler;
+import gregtech.api.metatileentity.implementations.MTEHatchOutput;
+import gregtech.api.metatileentity.implementations.MTEHatchOutputBus;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.HatchElementBuilder;
+import gregtech.api.util.IGTHatchAdder;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.api.util.shutdown.ShutDownReason;
+import gregtech.api.util.shutdown.ShutDownReasonRegistry;
+import gregtech.api.util.shutdown.SimpleShutDownReason;
+import gregtech.common.Pollution;
+import gregtech.common.tileentities.machines.IDualInputHatch;
+import tectech.Reference;
+import tectech.TecTech;
+import tectech.loader.TecTechConfig;
+import tectech.thing.gui.TecTechUITextures;
+import tectech.thing.metaTileEntity.hatch.MTEHatchDataConnector;
+import tectech.thing.metaTileEntity.hatch.MTEHatchDataInput;
+import tectech.thing.metaTileEntity.hatch.MTEHatchDataOutput;
+import tectech.thing.metaTileEntity.hatch.MTEHatchDynamoMulti;
+import tectech.thing.metaTileEntity.hatch.MTEHatchEnergyMulti;
+import tectech.thing.metaTileEntity.hatch.MTEHatchParam;
+import tectech.thing.metaTileEntity.hatch.MTEHatchUncertainty;
+import tectech.thing.metaTileEntity.multi.base.render.TTRenderedExtendedFacingTexture;
+import tectech.util.CommonValues;
+import tectech.util.TTUtility;
+
+/**
+ * Created by danie_000 on 27.10.2016.
+ */
+public abstract class TTMultiblockBase extends MTEExtendedPowerMultiBlockBase<TTMultiblockBase>
+ implements IAlignment, IBindPlayerInventoryUI {
+ // region Client side variables (static - one per class)
+
+ // Front icon holders - static so it is default one for my blocks
+ // just add new static ones in your class and and override getTexture
+ protected static Textures.BlockIcons.CustomIcon ScreenOFF;
+ protected static Textures.BlockIcons.CustomIcon ScreenON;
+
+ /** Base ID for the LED window popup. LED 1 I0 will have ID 100, LED 1 I1 101... */
+ protected static int LED_WINDOW_BASE_ID = 100;
+
+ // Sound resource - same as with screen but override getActivitySound
+ public static final ResourceLocation activitySound = new ResourceLocation(Reference.MODID + ":fx_lo_freq");
+
+ @SideOnly(Side.CLIENT)
+ private SoundLoop activitySoundLoop;
+ // endregion
+
+ // region HATCHES ARRAYS - they hold info about found hatches, add hatches to them... (auto structure magic does it
+ // tho)
+
+ // HATCHES!!!, should be added and removed in check machine
+ protected ArrayList<MTEHatchParam> eParamHatches = new ArrayList<>();
+ protected ArrayList<MTEHatchUncertainty> eUncertainHatches = new ArrayList<>();
+ // multi amp hatches in/out
+ protected ArrayList<MTEHatchEnergyMulti> eEnergyMulti = new ArrayList<>();
+ protected ArrayList<MTEHatchDynamoMulti> eDynamoMulti = new ArrayList<>();
+ // data hatches
+ protected ArrayList<MTEHatchDataInput> eInputData = new ArrayList<>();
+ protected ArrayList<MTEHatchDataOutput> eOutputData = new ArrayList<>();
+
+ // endregion
+
+ // region parameters
+ public final Parameters parametrization;
+ // endregion
+
+ // region Control variables
+
+ // should explode on dismatle?, set it in constructor, if true machine will explode if invalidated structure while
+ // active
+ protected boolean eDismantleBoom = false;
+
+ // what is the amount of A required
+ public long eAmpereFlow = 1; // analogue of EU/t but for amperes used (so eu/t is actually eu*A/t) USE ONLY POSITIVE
+ // NUMBERS!
+
+ // set to what you need it to be in check recipe
+ // data required to operate
+ protected long eRequiredData = 0;
+
+ // Counter for the computation timeout. Will be initialized one to the max time and then only decreased.
+ protected int eComputationTimeout = MAX_COMPUTATION_TIMEOUT;
+
+ // Max timeout of computation in ticks
+ protected static int MAX_COMPUTATION_TIMEOUT = 100;
+
+ // are parameters correct - change in check recipe/output/update params etc. (maintenance status boolean)
+ protected boolean eParameters = true;
+
+ // what type of certainty inconvenience is used - can be used as in Computer - more info in uncertainty hatch
+ protected byte eCertainMode = 0, eCertainStatus = 0;
+
+ // minimal repair status to make the machine even usable (how much unfixed fixed stuff is needed)
+ // if u need to force some things to be fixed - u might need to override doRandomMaintenanceDamage
+ protected byte minRepairStatus = 3;
+
+ // whether there is a maintenance hatch in the multi and whether checks are necessary (for now only used in a
+ // transformer)
+ protected boolean hasMaintenanceChecks = true;
+
+ // is power pass cover present
+ public boolean ePowerPassCover = false;
+
+ // functionality toggles - changed by buttons in gui also
+ public boolean ePowerPass = false, eSafeVoid = false;
+
+ // endregion
+
+ // region READ ONLY unless u really need to change it
+
+ // max amperes machine can take in after computing it to the lowest tier (exchange packets to min tier count)
+ protected long eMaxAmpereFlow = 0, eMaxAmpereGen = 0;
+
+ // What is the max and minimal tier of eu hatches installed
+ private long maxEUinputMin = 0, maxEUinputMax = 0, maxEUoutputMin = 0, maxEUoutputMax = 0;
+
+ // read only unless you are making computation generator - read computer class
+ protected long eAvailableData = 0; // data being available
+
+ // just some info - private so hidden
+ private boolean explodedThisTick = false;
+
+ /** Flag if the new long power variable should be used */
+ protected boolean useLongPower = false;
+
+ // Locale-aware formatting of numbers.
+ protected static NumberFormatMUI numberFormat;
+ static {
+ numberFormat = new NumberFormatMUI();
+ numberFormat.setMaximumFractionDigits(8);
+ }
+
+ // endregion
+
+ protected TTMultiblockBase(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ parametrization = new Parameters(this);
+ parametersInstantiation_EM();
+ parametrization.setToDefaults(true, true);
+ }
+
+ protected TTMultiblockBase(String aName) {
+ super(aName);
+ parametrization = new Parameters(this);
+ parametersInstantiation_EM();
+ parametrization.setToDefaults(true, true);
+ }
+
+ // region SUPER STRUCT
+
+ /**
+ * Gets structure
+ *
+ * @return STATIC INSTANCE OF STRUCTURE
+ */
+ public abstract IStructureDefinition<? extends TTMultiblockBase> getStructure_EM();
+
+ @SuppressWarnings("unchecked")
+ private IStructureDefinition<TTMultiblockBase> getStructure_EM_Internal() {
+ return (IStructureDefinition<TTMultiblockBase>) getStructure_EM();
+ }
+
+ @Override
+ public IStructureDefinition<TTMultiblockBase> getStructureDefinition() {
+ return getStructure_EM_Internal();
+ }
+
+ public final boolean structureCheck_EM(String piece, int horizontalOffset, int verticalOffset, int depthOffset) {
+ IGregTechTileEntity baseMetaTileEntity = getBaseMetaTileEntity();
+ return getStructure_EM_Internal().check(
+ this,
+ piece,
+ baseMetaTileEntity.getWorld(),
+ getExtendedFacing(),
+ baseMetaTileEntity.getXCoord(),
+ baseMetaTileEntity.getYCoord(),
+ baseMetaTileEntity.getZCoord(),
+ horizontalOffset,
+ verticalOffset,
+ depthOffset,
+ !mMachine);
+ }
+
+ public final boolean structureBuild_EM(String piece, int horizontalOffset, int verticalOffset, int depthOffset,
+ ItemStack trigger, boolean hintsOnly) {
+ IGregTechTileEntity baseMetaTileEntity = getBaseMetaTileEntity();
+ return getStructure_EM_Internal().buildOrHints(
+ this,
+ trigger,
+ piece,
+ baseMetaTileEntity.getWorld(),
+ getExtendedFacing(),
+ baseMetaTileEntity.getXCoord(),
+ baseMetaTileEntity.getYCoord(),
+ baseMetaTileEntity.getZCoord(),
+ horizontalOffset,
+ verticalOffset,
+ depthOffset,
+ hintsOnly);
+ }
+ // endregion
+
+ // region METHODS TO OVERRIDE - general functionality, recipe check, output
+
+ /**
+ * Check structure here, also add hatches
+ *
+ * @param iGregTechTileEntity - the tile entity
+ * @param itemStack - what is in the controller input slot
+ * @return is structure valid
+ */
+ protected boolean checkMachine_EM(IGregTechTileEntity iGregTechTileEntity, ItemStack itemStack) {
+ return false;
+ }
+
+ /**
+ * Checks Recipes (when all machine is complete and can work)
+ * <p>
+ * can get/set Parameters here also
+ *
+ * @deprecated Use {@link #createProcessingLogic()} ()} or {@link #checkProcessing_EM()}
+ *
+ * @param itemStack item in the controller
+ * @return is recipe is valid
+ */
+ @Deprecated
+ public boolean checkRecipe_EM(ItemStack itemStack) {
+ return false;
+ }
+
+ @NotNull
+ protected CheckRecipeResult checkProcessing_EM() {
+ if (processingLogic == null) {
+ return checkRecipe_EM(getControllerSlot()) ? CheckRecipeResultRegistry.SUCCESSFUL
+ : CheckRecipeResultRegistry.NO_RECIPE;
+ }
+ return super.checkProcessing();
+ }
+
+ /**
+ * Put EM stuff from outputEM into EM output hatches here or do other stuff - it is basically on recipe succeded
+ * <p>
+ * based on "machine state" do output, this must move to outputEM to EM output hatches and can also modify output
+ * items/fluids/EM, remaining EM is NOT overflowed. (Well it can be overflowed if machine didn't finished,
+ * soft-hammered/disabled/not enough EU) Setting available data processing
+ */
+ public void outputAfterRecipe_EM() {}
+ // endregion
+
+ // region tooltip and scanner result
+
+ public ArrayList<String> getFullLedDescriptionIn(int hatchNo, int paramID) {
+ ArrayList<String> list = new ArrayList<>();
+ list.add(
+ EnumChatFormatting.WHITE + "ID: "
+ + EnumChatFormatting.AQUA
+ + hatchNo
+ + EnumChatFormatting.YELLOW
+ + ":"
+ + EnumChatFormatting.AQUA
+ + paramID
+ + EnumChatFormatting.YELLOW
+ + ":"
+ + EnumChatFormatting.AQUA
+ + "I "
+ + parametrization.getStatusIn(hatchNo, paramID).name.get());
+ list.add(
+ EnumChatFormatting.WHITE + "Value: "
+ + EnumChatFormatting.AQUA
+ + numberFormat.format(parametrization.getIn(hatchNo, paramID)));
+ try {
+ list.add(parametrization.groups[hatchNo].parameterIn[paramID].getBrief());
+ } catch (NullPointerException | IndexOutOfBoundsException e) {
+ list.add("Unused");
+ }
+ return list;
+ }
+
+ public ArrayList<String> getFullLedDescriptionOut(int hatchNo, int paramID) {
+ ArrayList<String> list = new ArrayList<>();
+ list.add(
+ EnumChatFormatting.WHITE + "ID: "
+ + EnumChatFormatting.AQUA
+ + hatchNo
+ + EnumChatFormatting.YELLOW
+ + ":"
+ + EnumChatFormatting.AQUA
+ + paramID
+ + EnumChatFormatting.YELLOW
+ + ":"
+ + EnumChatFormatting.AQUA
+ + "O "
+ + parametrization.getStatusOut(hatchNo, paramID).name.get());
+ list.add(
+ EnumChatFormatting.WHITE + "Value: "
+ + EnumChatFormatting.AQUA
+ + numberFormat.format(parametrization.getOut(hatchNo, paramID)));
+ try {
+ list.add(parametrization.groups[hatchNo].parameterOut[paramID].getBrief());
+ } catch (NullPointerException | IndexOutOfBoundsException e) {
+ list.add("Unused");
+ }
+ return list;
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addInfo("Nothing special just override me")
+ .toolTipFinisher(CommonValues.TEC_MARK_GENERAL);
+ return tt;
+ }
+
+ /**
+ * scanner gives it
+ */
+ @Override
+ public String[] getInfoData() { // TODO Do it
+ long storedEnergy = 0;
+ long maxEnergy = 0;
+ for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) {
+ storedEnergy += tHatch.getBaseMetaTileEntity()
+ .getStoredEU();
+ maxEnergy += tHatch.getBaseMetaTileEntity()
+ .getEUCapacity();
+ }
+ for (MTEHatchEnergyMulti tHatch : filterValidMTEs(eEnergyMulti)) {
+ storedEnergy += tHatch.getBaseMetaTileEntity()
+ .getStoredEU();
+ maxEnergy += tHatch.getBaseMetaTileEntity()
+ .getEUCapacity();
+ }
+
+ return new String[] { "Progress:",
+ EnumChatFormatting.GREEN + GTUtility.formatNumbers(mProgresstime / 20)
+ + EnumChatFormatting.RESET
+ + " s / "
+ + EnumChatFormatting.YELLOW
+ + GTUtility.formatNumbers(mMaxProgresstime / 20)
+ + EnumChatFormatting.RESET
+ + " s",
+ "Energy Hatches:",
+ EnumChatFormatting.GREEN + GTUtility.formatNumbers(storedEnergy)
+ + EnumChatFormatting.RESET
+ + " EU / "
+ + EnumChatFormatting.YELLOW
+ + GTUtility.formatNumbers(maxEnergy)
+ + EnumChatFormatting.RESET
+ + " EU",
+ (getPowerFlow() * eAmpereFlow <= 0 ? "Probably uses: " : "Probably makes: ") + EnumChatFormatting.RED
+ + GTUtility.formatNumbers(Math.abs(getPowerFlow()))
+ + EnumChatFormatting.RESET
+ + " EU/t at "
+ + EnumChatFormatting.RED
+ + GTUtility.formatNumbers(eAmpereFlow)
+ + EnumChatFormatting.RESET
+ + " A",
+ "Tier Rating: " + EnumChatFormatting.YELLOW
+ + VN[getMaxEnergyInputTier_EM()]
+ + EnumChatFormatting.RESET
+ + " / "
+ + EnumChatFormatting.GREEN
+ + VN[getMinEnergyInputTier_EM()]
+ + EnumChatFormatting.RESET
+ + " Amp Rating: "
+ + EnumChatFormatting.GREEN
+ + GTUtility.formatNumbers(eMaxAmpereFlow)
+ + EnumChatFormatting.RESET
+ + " A",
+ "Problems: " + EnumChatFormatting.RED
+ + (getIdealStatus() - getRepairStatus())
+ + EnumChatFormatting.RESET
+ + " Efficiency: "
+ + EnumChatFormatting.YELLOW
+ + mEfficiency / 100.0F
+ + EnumChatFormatting.RESET
+ + " %",
+ "PowerPass: " + EnumChatFormatting.BLUE
+ + ePowerPass
+ + EnumChatFormatting.RESET
+ + " SafeVoid: "
+ + EnumChatFormatting.BLUE
+ + eSafeVoid,
+ "Computation: " + EnumChatFormatting.GREEN
+ + GTUtility.formatNumbers(eAvailableData)
+ + EnumChatFormatting.RESET
+ + " / "
+ + EnumChatFormatting.YELLOW
+ + GTUtility.formatNumbers(eRequiredData)
+ + EnumChatFormatting.RESET };
+ }
+
+ /**
+ * should it work with scanner? HELL YES
+ */
+ @Override
+ public boolean isGivingInformation() {
+ return true;
+ }
+
+ // endregion
+
+ // region GUI/SOUND/RENDER
+
+ /**
+ * add more textures
+ */
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerIcons(IIconRegister aBlockIconRegister) {
+ ScreenOFF = new Textures.BlockIcons.CustomIcon("iconsets/EM_CONTROLLER");
+ ScreenON = new Textures.BlockIcons.CustomIcon("iconsets/EM_CONTROLLER_ACTIVE");
+ super.registerIcons(aBlockIconRegister);
+ }
+
+ /**
+ * actually use textures
+ */
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int colorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ return new ITexture[] { Textures.BlockIcons.casingTexturePages[texturePage][4],
+ new TTRenderedExtendedFacingTexture(aActive ? ScreenON : ScreenOFF) };
+ }
+ return new ITexture[] { Textures.BlockIcons.casingTexturePages[texturePage][4] };
+ }
+
+ /**
+ * should return your activity sound
+ */
+ @SideOnly(Side.CLIENT)
+ protected ResourceLocation getActivitySound() {
+ return activitySound;
+ }
+
+ /**
+ * plays the sounds auto magically
+ */
+ @SideOnly(Side.CLIENT)
+ protected void soundMagic(ResourceLocation activitySound) {
+ if (getBaseMetaTileEntity().isActive()) {
+ if (activitySoundLoop == null) {
+ activitySoundLoop = new SoundLoop(activitySound, getBaseMetaTileEntity(), false, true);
+ Minecraft.getMinecraft()
+ .getSoundHandler()
+ .playSound(activitySoundLoop);
+ }
+ } else {
+ if (activitySoundLoop != null) {
+ activitySoundLoop = null;
+ }
+ }
+ }
+
+ // endregion
+
+ // region Methods to maybe override (if u implement certain stuff)
+
+ /**
+ * is the thing inside controller a valid item to make the machine work
+ */
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ /**
+ * how much damage to apply to thing in controller - not sure how it does it
+ */
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ /**
+ * called when removing from map - not when unloading? //todo check
+ */
+ @Override
+ public void onRemoval() {
+ try {
+ if (ePowerPass && getEUVar() > V[3]
+ || eDismantleBoom && mMaxProgresstime > 0 && areChunksAroundLoaded_EM()) {
+ explodeMultiblock();
+ }
+ } catch (Exception e) {
+ if (TecTechConfig.DEBUG_MODE) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * prevents spontaneous explosions when the chunks unloading would cause them should cover 3 chunks radius
+ */
+ protected boolean areChunksAroundLoaded_EM() {
+ if (this.isValid() && getBaseMetaTileEntity().isServerSide()) {
+ IGregTechTileEntity base = getBaseMetaTileEntity();
+ return base.getWorld()
+ .doChunksNearChunkExist(base.getXCoord(), base.getYCoord(), base.getZCoord(), 3);
+ // todo check if it is actually checking if chunks are loaded
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * instantiate parameters in CONSTRUCTOR! CALLED ONCE on creation, don't call it in your classes
+ */
+ protected void parametersInstantiation_EM() {}
+
+ /**
+ * It is automatically called OFTEN update status of parameters in guis (and "machine state" if u wish) Called
+ * before check recipe, before outputting, and every second the machine is complete
+ * <p>
+ * good place to update parameter statuses, default implementation handles it well
+ *
+ * @param machineBusy is machine doing stuff
+ */
+ protected void parametersStatusesWrite_EM(boolean machineBusy) { // todo unimplement?
+ if (!machineBusy) {
+ for (Parameters.Group.ParameterIn parameterIn : parametrization.parameterInArrayList) {
+ if (parameterIn != null) {
+ parameterIn.updateStatus();
+ }
+ }
+ } else {
+ for (Parameters.Group hatch : parametrization.groups) {
+ if (hatch != null && hatch.updateWhileRunning) {
+ for (Parameters.Group.ParameterIn in : hatch.parameterIn) {
+ if (in != null) {
+ in.updateStatus();
+ }
+ }
+ }
+ }
+ }
+ for (Parameters.Group.ParameterOut parameterOut : parametrization.parameterOutArrayList) {
+ if (parameterOut != null) {
+ parameterOut.updateStatus();
+ }
+ }
+ }
+
+ /**
+ * For extra types of hatches initiation, LOOK HOW IT IS CALLED! in onPostTick
+ *
+ * @param mMachine was the machine considered complete at that point in onPostTick
+ */
+ protected void hatchInit_EM(boolean mMachine) {}
+
+ /**
+ * called when the multiblock is exploding - if u want to add more EXPLOSIONS, for ex. new types of hatches also
+ * have to explode
+ */
+ protected void extraExplosions_EM() {} // For that extra hatches explosions, and maybe some MOORE EXPLOSIONS
+
+ /**
+ * Get Available data, Override only on data outputters should return mAvailableData that is set in check recipe
+ *
+ * @return available data
+ */
+ protected long getAvailableData_EM() {
+ long result = 0;
+ IGregTechTileEntity baseMetaTileEntity = getBaseMetaTileEntity();
+ Vec3Impl pos = new Vec3Impl(
+ baseMetaTileEntity.getXCoord(),
+ baseMetaTileEntity.getYCoord(),
+ baseMetaTileEntity.getZCoord());
+ for (MTEHatchDataInput in : eInputData) {
+ if (in.q != null) {
+ Long value = in.q.contentIfNotInTrace(pos);
+ if (value != null) {
+ result += value;
+ }
+ }
+ }
+ return result;
+ }
+
+ protected long getPowerFlow() {
+ return useLongPower ? lEUt : mEUt;
+ }
+
+ protected void setPowerFlow(long lEUt) {
+ if (useLongPower) {
+ this.lEUt = lEUt;
+ } else {
+ mEUt = (int) Math.min(Integer.MAX_VALUE, lEUt);
+ }
+ }
+
+ @Override
+ protected long getActualEnergyUsage() {
+ return -(useLongPower ? lEUt : mEUt) * eAmpereFlow * 10_000 / Math.max(1_000, mEfficiency);
+ }
+
+ /**
+ * Extra hook on cyclic updates (not really needed for machines smaller than 1 chunk) BUT NEEDED WHEN - machine
+ * blocks are not touching each other or they don't implement IMachineBlockUpdateable (ex. air,stone,weird TE's)
+ */
+ protected boolean cyclicUpdate_EM() {
+ return mUpdate <= -1000; // set to false to disable cyclic update
+ // default is once per 50s; mUpdate is decremented every tick
+ }
+
+ /**
+ * get pollution per tick
+ *
+ * @param itemStack what is in controller
+ * @return how much pollution is produced
+ */
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ /**
+ * EM pollution per tick
+ *
+ * @param itemStack - item in controller
+ * @return how much excess matter is there
+ */
+ public float getExcessMassPerTick_EM(ItemStack itemStack) {
+ return 0f;
+ }
+
+ /**
+ * triggered if machine is not allowed to work after completing a recipe, override to make it not shutdown for
+ * instance (like turbines). bu just replacing it with blank - active transformer is doing it
+ * <p>
+ * CALLED DIRECTLY when soft hammered to offline state - usually should stop the machine unless some other mechanics
+ * should do it
+ */
+ protected void notAllowedToWork_stopMachine_EM() {
+ stopMachine();
+ }
+
+ /**
+ * store data
+ */
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setLong("eMaxGenEUmin", maxEUoutputMin);
+ aNBT.setLong("eMaxGenEUmax", maxEUoutputMax);
+ aNBT.setLong("eGenRating", eMaxAmpereGen);
+ aNBT.setLong("eMaxEUmin", maxEUinputMin);
+ aNBT.setLong("eMaxEUmax", maxEUinputMax);
+ aNBT.setLong("eRating", eAmpereFlow);
+ aNBT.setLong("eMaxA", eMaxAmpereFlow);
+ aNBT.setLong("eDataR", eRequiredData);
+ aNBT.setLong("eDataA", eAvailableData);
+ aNBT.setByte("eCertainM", eCertainMode);
+ aNBT.setByte("eCertainS", eCertainStatus);
+ aNBT.setByte("eMinRepair", minRepairStatus);
+ aNBT.setBoolean("eParam", eParameters);
+ aNBT.setBoolean("ePass", ePowerPass);
+ aNBT.setBoolean("ePowerPassCover", ePowerPassCover);
+ aNBT.setBoolean("eVoid", eSafeVoid);
+ aNBT.setBoolean("eBoom", eDismantleBoom);
+ aNBT.setBoolean("eOK", mMachine);
+ // Ensures compatibility
+ if (mOutputItems != null) {
+ aNBT.setInteger("mOutputItemsLength", mOutputItems.length);
+ for (int i = 0; i < mOutputItems.length; i++) {
+ if (mOutputItems[i] != null) {
+ NBTTagCompound tNBT = new NBTTagCompound();
+ mOutputItems[i].writeToNBT(tNBT);
+ aNBT.setTag("mOutputItem" + i, tNBT);
+ }
+ }
+ }
+
+ // Ensures compatibility
+ if (mOutputFluids != null) {
+ aNBT.setInteger("mOutputFluidsLength", mOutputFluids.length);
+ for (int i = 0; i < mOutputFluids.length; i++) {
+ if (mOutputFluids[i] != null) {
+ NBTTagCompound tNBT = new NBTTagCompound();
+ mOutputFluids[i].writeToNBT(tNBT);
+ aNBT.setTag("mOutputFluids" + i, tNBT);
+ }
+ }
+ }
+
+ aNBT.setInteger("eOutputStackCount", 0);
+ aNBT.removeTag("outputEM");
+
+ NBTTagCompound paramI = new NBTTagCompound();
+ for (int i = 0; i < parametrization.iParamsIn.length; i++) {
+ paramI.setDouble(Integer.toString(i), parametrization.iParamsIn[i]);
+ }
+ aNBT.setTag("eParamsInD", paramI);
+
+ NBTTagCompound paramO = new NBTTagCompound();
+ for (int i = 0; i < parametrization.iParamsOut.length; i++) {
+ paramO.setDouble(Integer.toString(i), parametrization.iParamsOut[i]);
+ }
+ aNBT.setTag("eParamsOutD", paramO);
+
+ NBTTagCompound paramIs = new NBTTagCompound();
+ for (int i = 0; i < parametrization.eParamsInStatus.length; i++) {
+ paramIs.setByte(Integer.toString(i), parametrization.eParamsInStatus[i].getOrdinalByte());
+ }
+ aNBT.setTag("eParamsInS", paramIs);
+
+ NBTTagCompound paramOs = new NBTTagCompound();
+ for (int i = 0; i < parametrization.eParamsOutStatus.length; i++) {
+ paramOs.setByte(Integer.toString(i), parametrization.eParamsOutStatus[i].getOrdinalByte());
+ }
+ aNBT.setTag("eParamsOutS", paramOs);
+ }
+
+ /**
+ * load data
+ */
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ maxEUoutputMin = aNBT.getLong("eMaxGenEUmin");
+ maxEUoutputMax = aNBT.getLong("eMaxGenEUmax");
+ eMaxAmpereGen = aNBT.getLong("eGenRating");
+ maxEUinputMin = aNBT.getLong("eMaxEUmin");
+ maxEUinputMax = aNBT.getLong("eMaxEUmax");
+ eAmpereFlow = aNBT.hasKey("eRating") ? aNBT.getLong("eRating") : 1;
+ eMaxAmpereFlow = aNBT.getLong("eMaxA");
+ eRequiredData = aNBT.getLong("eDataR");
+ eAvailableData = aNBT.getLong("eDataA");
+ eCertainMode = aNBT.getByte("eCertainM");
+ eCertainStatus = aNBT.getByte("eCertainS");
+ minRepairStatus = aNBT.hasKey("eMinRepair") ? aNBT.getByte("eMinRepair") : 3;
+ eParameters = !aNBT.hasKey("eParam") || aNBT.getBoolean("eParam");
+ ePowerPass = aNBT.getBoolean("ePass");
+ ePowerPassCover = aNBT.getBoolean("ePowerPassCover");
+ eSafeVoid = aNBT.getBoolean("eVoid");
+ eDismantleBoom = aNBT.getBoolean("eBoom");
+ mMachine = aNBT.getBoolean("eOK");
+
+ // Ensures compatibility
+ int aOutputItemsLength = aNBT.getInteger("mOutputItemsLength");
+ if (aOutputItemsLength > 0) {
+ mOutputItems = new ItemStack[aOutputItemsLength];
+ for (int i = 0; i < mOutputItems.length; i++) {
+ mOutputItems[i] = GTUtility.loadItem(aNBT, "mOutputItem" + i);
+ }
+ }
+
+ // Ensures compatibility
+ int aOutputFluidsLength = aNBT.getInteger("mOutputFluidsLength");
+ if (aOutputFluidsLength > 0) {
+ mOutputFluids = new FluidStack[aOutputFluidsLength];
+ for (int i = 0; i < mOutputFluids.length; i++) {
+ mOutputFluids[i] = GTUtility.loadFluid(aNBT, "mOutputFluids" + i);
+ }
+ }
+
+ if (aNBT.hasKey("eParamsIn") && aNBT.hasKey("eParamsOut") && aNBT.hasKey("eParamsB")) {
+ NBTTagCompound paramI = aNBT.getCompoundTag("eParamsIn");
+ NBTTagCompound paramO = aNBT.getCompoundTag("eParamsOut");
+ NBTTagCompound paramB = aNBT.getCompoundTag("eParamsB");
+ for (int i = 0; i < 10; i++) {
+ if (paramB.getBoolean(Integer.toString(i))) {
+ parametrization.iParamsIn[i] = Float.intBitsToFloat(paramI.getInteger(Integer.toString(i)));
+ parametrization.iParamsOut[i] = Float.intBitsToFloat(paramO.getInteger(Integer.toString(i)));
+ } else {
+ parametrization.iParamsIn[i] = paramI.getInteger(Integer.toString(i));
+ parametrization.iParamsOut[i] = paramO.getInteger(Integer.toString(i));
+ }
+ }
+ } else {
+ NBTTagCompound paramI = aNBT.getCompoundTag("eParamsInD");
+ for (int i = 0; i < parametrization.iParamsIn.length; i++) {
+ parametrization.iParamsIn[i] = paramI.getDouble(Integer.toString(i));
+ }
+ NBTTagCompound paramO = aNBT.getCompoundTag("eParamsOutD");
+ for (int i = 0; i < parametrization.iParamsOut.length; i++) {
+ parametrization.iParamsOut[i] = paramO.getDouble(Integer.toString(i));
+ }
+ }
+
+ NBTTagCompound paramIs = aNBT.getCompoundTag("eParamsInS");
+ for (int i = 0; i < parametrization.eParamsInStatus.length; i++) {
+ parametrization.eParamsInStatus[i] = LedStatus.getStatus(paramIs.getByte(Integer.toString(i)));
+ }
+
+ NBTTagCompound paramOs = aNBT.getCompoundTag("eParamsOutS");
+ for (int i = 0; i < parametrization.eParamsOutStatus.length; i++) {
+ parametrization.eParamsOutStatus[i] = LedStatus.getStatus(paramOs.getByte(Integer.toString(i)));
+ }
+ }
+
+ /**
+ * Override if needed but usually call super method at start! On machine stop - NOT called directly when soft
+ * hammered to offline state! - it SHOULD cause a full stop like power failure does
+ */
+ @Override
+ public void stopMachine(@Nonnull ShutDownReason reason) {
+ if (!ShutDownReasonRegistry.isRegistered(reason.getID())) {
+ throw new RuntimeException(String.format("Reason %s is not registered for registry", reason.getID()));
+ }
+ for (MTEHatchDataOutput data : eOutputData) {
+ data.q = null;
+ }
+
+ mOutputItems = null;
+ mOutputFluids = null;
+ mEfficiency = 0;
+ mEfficiencyIncrease = 0;
+ mProgresstime = 0;
+ mMaxProgresstime = 0;
+ eAvailableData = 0;
+ hatchesStatusUpdate_EM();
+ getBaseMetaTileEntity().disableWorking();
+ getBaseMetaTileEntity().setShutDownReason(reason);
+ getBaseMetaTileEntity().setShutdownStatus(true);
+ if (reason.wasCritical()) {
+ sendSound(INTERRUPT_SOUND_INDEX);
+ }
+ }
+
+ /**
+ * After recipe check failed helper method so i don't have to set that params to nothing at all times
+ */
+ protected void afterRecipeCheckFailed() {
+
+ for (MTEHatchDataOutput data : eOutputData) {
+ data.q = null;
+ }
+
+ mOutputItems = null;
+ mOutputFluids = null;
+ mEfficiency = 0;
+ mEfficiencyIncrease = 0;
+ mProgresstime = 0;
+ mMaxProgresstime = 0;
+ eAvailableData = 0;
+ }
+
+ /**
+ * cyclic check even when not working, called LESS frequently
+ */
+ private boolean cyclicUpdate() {
+ if (cyclicUpdate_EM()) {
+ mUpdate = 0;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * mining level...
+ */
+ @Override
+ public byte getTileEntityBaseType() {
+ return 3;
+ }
+
+ // endregion
+
+ // region internal
+
+ /**
+ * internal check machine
+ */
+ @Override
+ public final boolean checkMachine(IGregTechTileEntity iGregTechTileEntity, ItemStack itemStack) {
+ return checkMachine_EM(iGregTechTileEntity, itemStack);
+ }
+
+ /**
+ * internal check recipe
+ */
+ @Override
+ public final boolean checkRecipe(ItemStack itemStack) { // do recipe checks, based on "machine content and state"
+ hatchesStatusUpdate_EM();
+ startRecipeProcessing();
+ boolean result = checkRecipe_EM(itemStack); // if had no - set default params
+ endRecipeProcessing();
+ hatchesStatusUpdate_EM();
+ return result;
+ }
+
+ @NotNull
+ @Override
+ public final CheckRecipeResult checkProcessing() {
+ hatchesStatusUpdate_EM();
+ CheckRecipeResult result = checkProcessing_EM();
+ hatchesStatusUpdate_EM();
+ return result;
+ }
+
+ /**
+ * callback for updating parameters and new hatches
+ */
+ protected void hatchesStatusUpdate_EM() {
+ if (getBaseMetaTileEntity().isClientSide()) {
+ return;
+ }
+ boolean busy = mMaxProgresstime > 0;
+ if (busy) { // write from buffer to hatches only
+ for (MTEHatchParam hatch : filterValidMTEs(eParamHatches)) {
+ if (hatch.param < 0) {
+ continue;
+ }
+ int hatchId = hatch.param;
+ if (parametrization.groups[hatchId] != null && parametrization.groups[hatchId].updateWhileRunning) {
+ parametrization.iParamsIn[hatchId] = hatch.value0D;
+ parametrization.iParamsIn[hatchId + 10] = hatch.value1D;
+ }
+ hatch.input0D = parametrization.iParamsOut[hatchId];
+ hatch.input1D = parametrization.iParamsOut[hatchId + 10];
+ }
+ } else { // if has nothing to do update all
+ for (MTEHatchParam hatch : filterValidMTEs(eParamHatches)) {
+ if (hatch.param < 0) {
+ continue;
+ }
+ int hatchId = hatch.param;
+ parametrization.iParamsIn[hatchId] = hatch.value0D;
+ parametrization.iParamsIn[hatchId + 10] = hatch.value1D;
+ hatch.input0D = parametrization.iParamsOut[hatchId];
+ hatch.input1D = parametrization.iParamsOut[hatchId + 10];
+ }
+ }
+ for (MTEHatchUncertainty uncertainty : eUncertainHatches) {
+ eCertainStatus = uncertainty.update(eCertainMode);
+ }
+ eAvailableData = getAvailableData_EM();
+ parametersStatusesWrite_EM(busy);
+ }
+
+ @Deprecated
+ public final int getAmountOfOutputs() {
+ throw new NoSuchMethodError("Deprecated Do not use");
+ }
+ // endregion
+
+ // region TICKING functions
+
+ public void onFirstTick_EM(IGregTechTileEntity aBaseMetaTileEntity) {}
+
+ @Override
+ public final void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ isFacingValid(aBaseMetaTileEntity.getFrontFacing());
+ if (getBaseMetaTileEntity().isClientSide()) {
+ StructureLibAPI.queryAlignment((IAlignmentProvider) aBaseMetaTileEntity);
+ }
+ onFirstTick_EM(aBaseMetaTileEntity);
+ }
+
+ /**
+ * called every tick the machines is active
+ */
+ @Override
+ public boolean onRunningTick(ItemStack aStack) {
+ return onRunningTickCheck(aStack);
+ }
+
+ public boolean onRunningTickCheck_EM(ItemStack aStack) {
+ if (eRequiredData > eAvailableData) {
+ if (!checkComputationTimeout()) {
+ if (energyFlowOnRunningTick_EM(aStack, false)) {
+ stopMachine(SimpleShutDownReason.ofCritical("computation_loss"));
+ }
+ return false;
+ }
+ }
+ return energyFlowOnRunningTick_EM(aStack, true);
+ }
+
+ public boolean onRunningTickCheck(ItemStack aStack) {
+ if (eRequiredData > eAvailableData) {
+ if (!checkComputationTimeout()) {
+ if (energyFlowOnRunningTick(aStack, false)) {
+ stopMachine(SimpleShutDownReason.ofCritical("computation_loss"));
+ }
+ return false;
+ }
+ }
+ return energyFlowOnRunningTick(aStack, true);
+ }
+
+ /**
+ * CAREFUL!!! it calls most of the callbacks, like everything else in here
+ */
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ if (aBaseMetaTileEntity.isServerSide()) {
+ mTotalRunTime++;
+ explodedThisTick = false;
+ if (mEfficiency < 0) {
+ mEfficiency = 0;
+ }
+
+ if (--mUpdate == 0 || --mStartUpCheck == 0
+ || cyclicUpdate()
+ || aBaseMetaTileEntity.hasWorkJustBeenEnabled()) {
+ clearHatches_EM();
+
+ if (aBaseMetaTileEntity instanceof BaseTileEntity) {
+ ((BaseTileEntity) aBaseMetaTileEntity).ignoreUnloadedChunks = mMachine;
+ }
+ mMachine = checkMachine(aBaseMetaTileEntity, mInventory[1]);
+
+ if (!mMachine) {
+ if (ePowerPass && getEUVar() > V[3]
+ || eDismantleBoom && mMaxProgresstime > 0 && areChunksAroundLoaded_EM()) {
+ explodeMultiblock();
+ }
+ }
+
+ if (eUncertainHatches.size() > 1) {
+ mMachine = false;
+ }
+
+ if (mMachine) {
+ setupHatches_EM();
+
+ setupEnergyHatchesVariables_EM();
+
+ if (getEUVar() > maxEUStore()) {
+ setEUVar(maxEUStore());
+ }
+ } else {
+ maxEUinputMin = 0;
+ maxEUinputMax = 0;
+ eMaxAmpereFlow = 0;
+ setEUVar(0);
+ }
+ hatchInit_EM(mMachine);
+ }
+
+ if (mStartUpCheck < 0) { // E
+ if (mMachine) { // S
+ byte Tick = (byte) (aTick % 20);
+ if (CommonValues.MULTI_CHECK_AT == Tick) {
+ checkMaintenance();
+ }
+
+ if (getRepairStatus() >= minRepairStatus) { // S
+ if (CommonValues.MULTI_CHECK_AT == Tick) {
+ hatchesStatusUpdate_EM();
+ }
+
+ dischargeController_EM(aBaseMetaTileEntity);
+ chargeController_EM(aBaseMetaTileEntity);
+
+ if (mMaxProgresstime > 0 && doRandomMaintenanceDamage()) { // Start
+ if (onRunningTick(mInventory[1])) { // Compute EU
+ if (!polluteEnvironment(getPollutionPerTick(mInventory[1]))) {
+ stopMachine(ShutDownReasonRegistry.POLLUTION_FAIL);
+ }
+
+ if (mMaxProgresstime > 0 && ++mProgresstime >= mMaxProgresstime) { // progress increase
+ // and done
+ hatchesStatusUpdate_EM();
+
+ outputAfterRecipe_EM();
+
+ addClassicOutputs_EM();
+
+ updateSlots();
+ mProgresstime = 0;
+ mMaxProgresstime = 0;
+ mEfficiencyIncrease = 0;
+
+ if (aBaseMetaTileEntity.isAllowedToWork()) {
+ if (checkRecipe()) {
+ mEfficiency = Math.max(
+ 0,
+ min(
+ mEfficiency + mEfficiencyIncrease,
+ getMaxEfficiency(mInventory[1])
+ - (getIdealStatus() - getRepairStatus()) * 1000));
+ } else {
+ afterRecipeCheckFailed();
+ }
+ updateSlots();
+ } else {
+ notAllowedToWork_stopMachine_EM();
+ }
+ }
+ } // else {//failed to consume power/resources - inside on running tick
+ // stopMachine();
+ // }
+ } else if (CommonValues.RECIPE_AT == Tick || aBaseMetaTileEntity.hasWorkJustBeenEnabled()) {
+ if (aBaseMetaTileEntity.isAllowedToWork()) {
+ if (checkRecipe()) {
+ mEfficiency = Math.max(
+ 0,
+ min(
+ mEfficiency + mEfficiencyIncrease,
+ getMaxEfficiency(mInventory[1])
+ - (getIdealStatus() - getRepairStatus()) * 1000));
+ } else {
+ afterRecipeCheckFailed();
+ }
+ updateSlots();
+ } // else notAllowedToWork_stopMachine_EM(); //it is already stopped here
+ }
+ } else { // not repaired
+ stopMachine(ShutDownReasonRegistry.NO_REPAIR);
+ }
+ } else { // not complete
+ stopMachine(ShutDownReasonRegistry.STRUCTURE_INCOMPLETE);
+ }
+ }
+
+ aBaseMetaTileEntity.setErrorDisplayID(
+ aBaseMetaTileEntity.getErrorDisplayID() & -512 | (mWrench ? 0 : 1)
+ | (mScrewdriver ? 0 : 2)
+ | (mSoftHammer ? 0 : 4)
+ | (mHardHammer ? 0 : 8)
+ | (mSolderingTool ? 0 : 16)
+ | (mCrowbar ? 0 : 32)
+ | (mMachine ? 0 : 64)
+ | (eCertainStatus == 0 ? 0 : 128)
+ | (eParameters ? 0 : 256));
+ aBaseMetaTileEntity.setActive(mMaxProgresstime > 0);
+ boolean active = aBaseMetaTileEntity.isActive() && mPollution > 0;
+ setMufflers(active);
+ } else {
+ soundMagic(getActivitySound());
+ }
+ }
+
+ protected void addClassicOutputs_EM() {
+ if (mOutputItems != null) {
+ for (ItemStack tStack : mOutputItems) {
+ if (tStack != null) {
+ addOutput(tStack);
+ }
+ }
+ }
+ mOutputItems = null;
+
+ if (mOutputFluids != null) {
+ if (mOutputFluids.length == 1) {
+ for (FluidStack tStack : mOutputFluids) {
+ if (tStack != null) {
+ addOutput(tStack);
+ }
+ }
+ } else if (mOutputFluids.length > 1) {
+ addFluidOutputs(mOutputFluids);
+ }
+ }
+ mOutputFluids = null;
+ }
+
+ protected void clearHatches_EM() {
+ mDualInputHatches.clear();
+ mInputHatches.clear();
+ mInputBusses.clear();
+ mOutputHatches.clear();
+ mOutputBusses.clear();
+ mDynamoHatches.clear();
+ mEnergyHatches.clear();
+ mMufflerHatches.clear();
+ mMaintenanceHatches.clear();
+
+ for (MTEHatchDataConnector<?> hatch_data : filterValidMTEs(eOutputData)) {
+ hatch_data.id = -1;
+ }
+ for (MTEHatchDataConnector<?> hatch_data : filterValidMTEs(eInputData)) {
+ hatch_data.id = -1;
+ }
+
+ for (MTEHatchUncertainty hatch : filterValidMTEs(eUncertainHatches)) {
+ hatch.getBaseMetaTileEntity()
+ .setActive(false);
+ }
+ for (MTEHatchParam hatch : filterValidMTEs(eParamHatches)) {
+ hatch.getBaseMetaTileEntity()
+ .setActive(false);
+ }
+
+ eUncertainHatches.clear();
+ eEnergyMulti.clear();
+ eParamHatches.clear();
+ eDynamoMulti.clear();
+ eOutputData.clear();
+ eInputData.clear();
+ }
+
+ protected void setupHatches_EM() {
+ short id = 1;
+
+ for (MTEHatchDataConnector<?> hatch_data : filterValidMTEs(eOutputData)) {
+ hatch_data.id = id++;
+ }
+ id = 1;
+ for (MTEHatchDataConnector<?> hatch_data : filterValidMTEs(eInputData)) {
+ hatch_data.id = id++;
+ }
+
+ for (MTEHatchUncertainty hatch : filterValidMTEs(eUncertainHatches)) {
+ hatch.getBaseMetaTileEntity()
+ .setActive(true);
+ }
+ for (MTEHatchParam hatch : filterValidMTEs(eParamHatches)) {
+ hatch.getBaseMetaTileEntity()
+ .setActive(true);
+ }
+ }
+
+ protected void setupEnergyHatchesVariables_EM() {
+ if (!mEnergyHatches.isEmpty() || !eEnergyMulti.isEmpty()
+ || !mDynamoHatches.isEmpty()
+ || !eDynamoMulti.isEmpty()) {
+ maxEUinputMin = V[15];
+ maxEUinputMax = V[0];
+ maxEUoutputMin = V[15];
+ maxEUoutputMax = V[0];
+ for (MTEHatchEnergy hatch : filterValidMTEs(mEnergyHatches)) {
+ if (hatch.maxEUInput() < maxEUinputMin) {
+ maxEUinputMin = hatch.maxEUInput();
+ }
+ if (hatch.maxEUInput() > maxEUinputMax) {
+ maxEUinputMax = hatch.maxEUInput();
+ }
+ }
+ for (MTEHatchEnergyMulti hatch : filterValidMTEs(eEnergyMulti)) {
+ if (hatch.maxEUInput() < maxEUinputMin) {
+ maxEUinputMin = hatch.maxEUInput();
+ }
+ if (hatch.maxEUInput() > maxEUinputMax) {
+ maxEUinputMax = hatch.maxEUInput();
+ }
+ }
+ for (MTEHatchDynamo hatch : filterValidMTEs(mDynamoHatches)) {
+ if (hatch.maxEUOutput() < maxEUoutputMin) {
+ maxEUoutputMin = hatch.maxEUOutput();
+ }
+ if (hatch.maxEUOutput() > maxEUoutputMax) {
+ maxEUoutputMax = hatch.maxEUOutput();
+ }
+ }
+ for (MTEHatchDynamoMulti hatch : filterValidMTEs(eDynamoMulti)) {
+ if (hatch.maxEUOutput() < maxEUoutputMin) {
+ maxEUoutputMin = hatch.maxEUOutput();
+ }
+ if (hatch.maxEUOutput() > maxEUoutputMax) {
+ maxEUoutputMax = hatch.maxEUOutput();
+ }
+ }
+ eMaxAmpereFlow = 0;
+ eMaxAmpereGen = 0;
+ // counts only full amps
+ for (MTEHatchEnergy hatch : filterValidMTEs(mEnergyHatches)) {
+ eMaxAmpereFlow += hatch.maxEUInput() / maxEUinputMin;
+ }
+ for (MTEHatchEnergyMulti hatch : filterValidMTEs(eEnergyMulti)) {
+ eMaxAmpereFlow += hatch.maxEUInput() / maxEUinputMin * hatch.Amperes;
+ }
+ for (MTEHatchDynamo hatch : filterValidMTEs(mDynamoHatches)) {
+ eMaxAmpereGen += hatch.maxEUOutput() / maxEUoutputMin;
+ }
+ for (MTEHatchDynamoMulti hatch : filterValidMTEs(eDynamoMulti)) {
+ eMaxAmpereGen += hatch.maxEUOutput() / maxEUoutputMin * hatch.Amperes;
+ }
+ } else {
+ maxEUinputMin = 0;
+ maxEUinputMax = 0;
+ eMaxAmpereFlow = 0;
+ maxEUoutputMin = 0;
+ maxEUoutputMax = 0;
+ eMaxAmpereGen = 0;
+ }
+ }
+
+ protected void dischargeController_EM(IGregTechTileEntity aBaseMetaTileEntity) {
+ if (ePowerPass && getEUVar() > getMinimumStoredEU()) {
+ powerPass(aBaseMetaTileEntity);
+ }
+ }
+
+ protected final void powerPass(IGregTechTileEntity aBaseMetaTileEntity) {
+ long euVar;
+ for (MTEHatchDynamo tHatch : filterValidMTEs(mDynamoHatches)) {
+ euVar = tHatch.maxEUOutput() * tHatch.maxAmperesOut();
+ if (tHatch.getBaseMetaTileEntity()
+ .getStoredEU() <= tHatch.maxEUStore() - euVar
+ && aBaseMetaTileEntity
+ .decreaseStoredEnergyUnits(euVar + Math.max(euVar / 24576, tHatch.maxAmperesOut()), false)) {
+ tHatch.setEUVar(
+ tHatch.getBaseMetaTileEntity()
+ .getStoredEU() + euVar);
+ }
+ }
+ for (MTEHatchDynamoMulti tHatch : filterValidMTEs(eDynamoMulti)) {
+ euVar = tHatch.maxEUOutput() * tHatch.maxAmperesOut();
+ if (tHatch.getBaseMetaTileEntity()
+ .getStoredEU() <= tHatch.maxEUStore() - euVar
+ && aBaseMetaTileEntity
+ .decreaseStoredEnergyUnits(euVar + Math.max(euVar / 24576, tHatch.maxAmperesOut()), false)) {
+ tHatch.setEUVar(
+ tHatch.getBaseMetaTileEntity()
+ .getStoredEU() + euVar);
+ }
+ }
+ }
+
+ protected final void powerPass_EM(IGregTechTileEntity aBaseMetaTileEntity) {
+ long euVar;
+ for (MTEHatchDynamo tHatch : filterValidMTEs(mDynamoHatches)) {
+ euVar = tHatch.maxEUOutput();
+ if (tHatch.getBaseMetaTileEntity()
+ .getStoredEU() <= tHatch.maxEUStore() - euVar
+ && aBaseMetaTileEntity.decreaseStoredEnergyUnits(euVar + Math.max(euVar / 24576, 1), false)) {
+ tHatch.setEUVar(
+ tHatch.getBaseMetaTileEntity()
+ .getStoredEU() + euVar);
+ }
+ }
+ for (MTEHatchDynamoMulti tHatch : filterValidMTEs(eDynamoMulti)) {
+ euVar = tHatch.maxEUOutput() * tHatch.Amperes;
+ if (tHatch.getBaseMetaTileEntity()
+ .getStoredEU() <= tHatch.maxEUStore() - euVar
+ && aBaseMetaTileEntity
+ .decreaseStoredEnergyUnits(euVar + Math.max(euVar / 24576, tHatch.Amperes), false)) {
+ tHatch.setEUVar(
+ tHatch.getBaseMetaTileEntity()
+ .getStoredEU() + euVar);
+ }
+ }
+ }
+
+ protected void chargeController_EM(IGregTechTileEntity aBaseMetaTileEntity) {
+ powerInput();
+ }
+
+ protected final void powerInput() {
+ long euVar;
+ for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) {
+ if (getEUVar() > getMinimumStoredEU()) {
+ break;
+ }
+ euVar = Math.min(tHatch.maxEUInput() * tHatch.maxAmperesIn(), tHatch.getEUVar());
+ if (tHatch.getBaseMetaTileEntity()
+ .decreaseStoredEnergyUnits(euVar, false)) {
+ setEUVar(getEUVar() + euVar);
+ }
+ }
+ for (MTEHatchEnergyMulti tHatch : filterValidMTEs(eEnergyMulti)) {
+ if (getEUVar() > getMinimumStoredEU()) {
+ break;
+ }
+ euVar = Math.min(tHatch.maxEUInput() * tHatch.maxAmperesIn(), tHatch.getEUVar());
+ if (tHatch.getBaseMetaTileEntity()
+ .decreaseStoredEnergyUnits(euVar, false)) {
+ setEUVar(getEUVar() + euVar);
+ }
+ }
+ }
+
+ protected final void powerInput_EM() {
+ long euVar;
+ for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) {
+ if (getEUVar() > getMinimumStoredEU()) {
+ break;
+ }
+ euVar = tHatch.maxEUInput();
+ if (tHatch.getBaseMetaTileEntity()
+ .decreaseStoredEnergyUnits(euVar, false)) {
+ setEUVar(getEUVar() + euVar);
+ }
+ }
+ for (MTEHatchEnergyMulti tHatch : filterValidMTEs(eEnergyMulti)) {
+ if (getEUVar() > getMinimumStoredEU()) {
+ break;
+ }
+ euVar = tHatch.maxEUInput() * tHatch.Amperes;
+ if (tHatch.getBaseMetaTileEntity()
+ .decreaseStoredEnergyUnits(euVar, false)) {
+ setEUVar(getEUVar() + euVar);
+ }
+ }
+ }
+
+ // endregion
+
+ // region EFFICIENCY AND FIXING LIMITS
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getIdealStatus() {
+ return super.getIdealStatus() + 2;
+ }
+
+ @Override
+ public int getRepairStatus() {
+ return super.getRepairStatus() + (eCertainStatus == 0 ? 1 : 0) + (eParameters ? 1 : 0);
+ }
+
+ // endregion
+
+ // region ENERGY!!!!
+
+ // new method
+ public boolean energyFlowOnRunningTick_EM(ItemStack aStack, boolean allowProduction) {
+ long euFlow = getPowerFlow() * eAmpereFlow; // quick scope sign
+ if (allowProduction && euFlow > 0) {
+ addEnergyOutput_EM(getPowerFlow() * (long) mEfficiency / getMaxEfficiency(aStack), eAmpereFlow);
+ } else if (euFlow < 0) {
+ if (TecTechConfig.POWERLESS_MODE) {
+ return true;
+ }
+ if (!drainEnergyInput_EM(
+ getPowerFlow(),
+ getPowerFlow() * getMaxEfficiency(aStack) / Math.max(1000L, mEfficiency),
+ eAmpereFlow)) {
+ criticalStopMachine();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean energyFlowOnRunningTick(ItemStack aStack, boolean allowProduction) {
+ long euFlow = getPowerFlow() * eAmpereFlow; // quick scope sign
+ if (allowProduction && euFlow > 0) {
+ addEnergyOutput_EM(getPowerFlow() * (long) mEfficiency / getMaxEfficiency(aStack), eAmpereFlow);
+ } else if (euFlow < 0) {
+ if (TecTechConfig.POWERLESS_MODE) {
+ return true;
+ }
+ if (!drainEnergyInput(
+ getPowerFlow() * getMaxEfficiency(aStack) / Math.max(1000L, mEfficiency),
+ eAmpereFlow)) {
+ stopMachine(ShutDownReasonRegistry.POWER_LOSS);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public long maxEUStore() {
+ return Math.max(maxEUinputMin * (eMaxAmpereFlow << 3), maxEUoutputMin * (eMaxAmpereGen << 3));
+ }
+
+ @Override
+ public final long getMinimumStoredEU() {
+ return maxEUStore() >> 1;
+ }
+
+ @Override
+ public final long maxAmperesIn() {
+ return 0L;
+ }
+
+ @Override
+ public final long maxAmperesOut() {
+ return 0L;
+ }
+
+ @Deprecated
+ @Override
+ public final boolean addEnergyOutput(long eu) {
+ return addEnergyOutput_EM(eu, 1);
+ }
+
+ public boolean addEnergyOutput_EM(long EU, long Amperes) {
+ if (EU < 0) {
+ EU = -EU;
+ }
+ if (Amperes < 0) {
+ Amperes = -Amperes;
+ }
+ long euVar = EU * Amperes;
+ long diff;
+ for (MTEHatchDynamo tHatch : filterValidMTEs(mDynamoHatches)) {
+ if (tHatch.maxEUOutput() < EU) {
+ explodeMultiblock();
+ }
+ diff = tHatch.maxEUStore() - tHatch.getBaseMetaTileEntity()
+ .getStoredEU();
+ if (diff > 0) {
+ if (euVar > diff) {
+ tHatch.setEUVar(tHatch.maxEUStore());
+ euVar -= diff;
+ } else if (euVar <= diff) {
+ tHatch.setEUVar(
+ tHatch.getBaseMetaTileEntity()
+ .getStoredEU() + euVar);
+ return true;
+ }
+ }
+ }
+ for (MTEHatchDynamoMulti tHatch : filterValidMTEs(eDynamoMulti)) {
+ if (tHatch.maxEUOutput() < EU) {
+ explodeMultiblock();
+ }
+ diff = tHatch.maxEUStore() - tHatch.getBaseMetaTileEntity()
+ .getStoredEU();
+ if (diff > 0) {
+ if (euVar > diff) {
+ tHatch.setEUVar(tHatch.maxEUStore());
+ euVar -= diff;
+ } else if (euVar <= diff) {
+ tHatch.setEUVar(
+ tHatch.getBaseMetaTileEntity()
+ .getStoredEU() + euVar);
+ return true;
+ }
+ }
+ }
+ setEUVar(min(getEUVar() + euVar, maxEUStore()));
+ return false;
+ }
+
+ @Deprecated
+ @Override
+ public final boolean drainEnergyInput(long eu) {
+ return drainEnergyInput_EM(0, eu, 1);
+ }
+
+ public boolean drainEnergyInput_EM(long EUtTierVoltage, long EUtEffective, long Amperes) {
+ long EUuse = EUtEffective * Amperes;
+ if (EUuse == 0) {
+ return true;
+ }
+ if (maxEUinputMin == 0) {
+ return false;
+ }
+ if (EUuse < 0) {
+ EUuse = -EUuse;
+ }
+ if (EUuse > getEUVar() || // not enough power
+ (EUtTierVoltage == 0 ? EUuse > getMaxInputEnergy() : (EUtTierVoltage > maxEUinputMax) || // TIER IS
+ // BASED ON
+ // BEST HATCH!
+ // not total
+ // EUtEffective
+ // input
+ (EUtTierVoltage * Amperes - 1) / maxEUinputMin + 1 > eMaxAmpereFlow)) { // EUuse==0? --> (EUuse
+ // - 1) / maxEUinputMin
+ // + 1 = 1! //if
+ // not too much A
+ if (TecTechConfig.DEBUG_MODE) {
+ TecTech.LOGGER.debug("L1 " + EUuse + ' ' + getEUVar() + ' ' + (EUuse > getEUVar()));
+ TecTech.LOGGER.debug("L2 " + EUtEffective + ' ' + maxEUinputMax + ' ' + (EUtEffective > maxEUinputMax));
+ TecTech.LOGGER.debug("L3 " + Amperes + ' ' + getMaxInputEnergy());
+ TecTech.LOGGER.debug(
+ "L4 " + ((EUuse - 1) / maxEUinputMin + 1)
+ + ' '
+ + eMaxAmpereFlow
+ + ' '
+ + ((EUuse - 1) / maxEUinputMin + 1 > eMaxAmpereFlow));
+ }
+ return false;
+ }
+ // sub eu
+ setEUVar(getEUVar() - EUuse);
+ return true;
+ }
+
+ public boolean drainEnergyInput(long EUtEffective, long Amperes) {
+ long EUuse = EUtEffective * Amperes;
+ if (EUuse == 0) {
+ return true;
+ }
+ if (maxEUinputMin == 0) {
+ return false;
+ }
+ if (EUuse < 0) {
+ EUuse = -EUuse;
+ }
+ // not enough power
+ if (EUuse > getEUVar() || EUuse > getMaxInputEnergy()) { // EUuse==0? --> (EUuse - 1) / maxEUinputMin + 1 = 1!
+ // //if not too much
+ // A
+ return false;
+ }
+ // sub eu
+ setEUVar(getEUVar() - EUuse);
+ return true;
+ }
+
+ // new method
+ public final boolean overclockAndPutValuesIn_EM(long EU, int time) { // TODO revise
+ if (EU == 0L) {
+ setPowerFlow(0);
+ mMaxProgresstime = time;
+ return true;
+ }
+ long tempEUt = Math.max(EU, V[1]);
+ long tempTier = maxEUinputMax >> 2;
+ while (tempEUt < tempTier) {
+ tempEUt <<= 2;
+ time >>= 1;
+ EU = time == 0 ? EU >> 1 : EU << 2; // U know, if the time is less than 1 tick make the machine use less
+ // power
+ }
+ if (EU > Integer.MAX_VALUE || EU < Integer.MIN_VALUE) {
+ setPowerFlow(Integer.MAX_VALUE - 1);
+ mMaxProgresstime = Integer.MAX_VALUE - 1;
+ return false;
+ }
+ setPowerFlow(EU);
+ mMaxProgresstime = time == 0 ? 1 : time;
+ return true;
+ } // Use in EM check recipe return statement if you want overclocking
+
+ /**
+ * Use {@link #getMaxInputVoltage()}
+ */
+ @Deprecated
+ public final long getMaxInputVoltageSum() {
+ return getMaxInputVoltage();
+ }
+
+ /**
+ * Use {@link #getMaxInputEu()}
+ */
+ @Deprecated
+ public final long getMaxInputEnergy() {
+ return getMaxInputEu();
+ }
+
+ /**
+ * Use {@link #getMaxInputEu()}
+ */
+ @Deprecated
+ public final long getMaxInputEnergy_EM() {
+ return getMaxInputEu();
+ }
+
+ // new Method
+ public final int getMaxEnergyInputTier_EM() {
+ return TTUtility.getTier(maxEUinputMax);
+ }
+
+ // new Method
+ public final int getMinEnergyInputTier_EM() {
+ return TTUtility.getTier(maxEUinputMin);
+ }
+
+ public final long getMaxAmpereFlowAtMinTierOfEnergyHatches() {
+ return eAmpereFlow;
+ }
+
+ @Override
+ public List<MTEHatch> getExoticAndNormalEnergyHatchList() {
+ List<MTEHatch> list = new ArrayList<>();
+ list.addAll(mEnergyHatches);
+ list.addAll(eEnergyMulti);
+ return list;
+ }
+
+ @Override
+ public List<MTEHatch> getExoticEnergyHatches() {
+ List<MTEHatch> list = new ArrayList<>();
+ list.addAll(eEnergyMulti);
+ return list;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public final void explodeMultiblock() {
+ if (explodedThisTick) {
+ return;
+ }
+ explodedThisTick = true;
+ if (!TecTech.configTecTech.BOOM_ENABLE) {
+ TecTech.proxy.broadcast(
+ "Multi Explode BOOM! " + getBaseMetaTileEntity().getXCoord()
+ + ' '
+ + getBaseMetaTileEntity().getYCoord()
+ + ' '
+ + getBaseMetaTileEntity().getZCoord());
+ StackTraceElement[] ste = Thread.currentThread()
+ .getStackTrace();
+ TecTech.proxy.broadcast("Multi Explode BOOM! " + ste[2].toString());
+ return;
+ }
+ extraExplosions_EM();
+ Pollution.addPollution(getBaseMetaTileEntity(), 600000);
+ mInventory[1] = null;
+ @SuppressWarnings("unchecked")
+ Iterable<MetaTileEntity> allHatches = Iterables.concat(
+ mInputBusses,
+ mOutputBusses,
+ mInputHatches,
+ mOutputHatches,
+ mDynamoHatches,
+ mMufflerHatches,
+ mEnergyHatches,
+ mMaintenanceHatches,
+ eParamHatches,
+ eEnergyMulti,
+ eUncertainHatches,
+ eDynamoMulti,
+ eInputData,
+ eOutputData);
+ for (MetaTileEntity tTileEntity : allHatches) {
+ if (tTileEntity != null && tTileEntity.getBaseMetaTileEntity() != null) {
+ tTileEntity.getBaseMetaTileEntity()
+ .doExplosion(V[9]);
+ }
+ }
+ getBaseMetaTileEntity().doExplosion(V[15]);
+ }
+
+ @Override
+ public void doExplosion(long aExplosionPower) {
+ if (!TecTech.configTecTech.BOOM_ENABLE) {
+ TecTech.proxy.broadcast(
+ "Multi DoExplosion BOOM! " + getBaseMetaTileEntity().getXCoord()
+ + ' '
+ + getBaseMetaTileEntity().getYCoord()
+ + ' '
+ + getBaseMetaTileEntity().getZCoord());
+ StackTraceElement[] ste = Thread.currentThread()
+ .getStackTrace();
+ TecTech.proxy.broadcast("Multi DoExplosion BOOM! " + ste[2].toString());
+ return;
+ }
+ explodeMultiblock();
+ super.doExplosion(aExplosionPower);
+ } // Redirecting to explodemultiblock
+ // endregion
+
+ // region adder methods
+ @Override
+ public final boolean addToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatch) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ }
+ if (aMetaTileEntity instanceof IDualInputHatch) {
+ return mDualInputHatches.add((IDualInputHatch) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchInput) {
+ return mInputHatches.add((MTEHatchInput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchInputBus) {
+ return mInputBusses.add((MTEHatchInputBus) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutput) {
+ return mOutputHatches.add((MTEHatchOutput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutputBus) {
+ return mOutputBusses.add((MTEHatchOutputBus) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergy) {
+ return mEnergyHatches.add((MTEHatchEnergy) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamo) {
+ return mDynamoHatches.add((MTEHatchDynamo) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchMaintenance) {
+ return mMaintenanceHatches.add((MTEHatchMaintenance) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchMuffler) {
+ return mMufflerHatches.add((MTEHatchMuffler) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchParam) {
+ return eParamHatches.add((MTEHatchParam) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchUncertainty) {
+ return eUncertainHatches.add((MTEHatchUncertainty) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergyMulti) {
+ return eEnergyMulti.add((MTEHatchEnergyMulti) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamoMulti) {
+ return eDynamoMulti.add((MTEHatchDynamoMulti) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDataInput) {
+ return eInputData.add((MTEHatchDataInput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDataOutput) {
+ return eOutputData.add((MTEHatchDataOutput) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ public final boolean addClassicToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatch) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ }
+ if (aMetaTileEntity instanceof IDualInputHatch) {
+ return mDualInputHatches.add((IDualInputHatch) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchInput) {
+ return mInputHatches.add((MTEHatchInput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchInputBus) {
+ return mInputBusses.add((MTEHatchInputBus) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutput) {
+ return mOutputHatches.add((MTEHatchOutput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutputBus) {
+ return mOutputBusses.add((MTEHatchOutputBus) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergy) {
+ return mEnergyHatches.add((MTEHatchEnergy) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamo) {
+ return mDynamoHatches.add((MTEHatchDynamo) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchMaintenance) {
+ return mMaintenanceHatches.add((MTEHatchMaintenance) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchMuffler) {
+ return mMufflerHatches.add((MTEHatchMuffler) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchParam) {
+ return eParamHatches.add((MTEHatchParam) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchUncertainty) {
+ return eUncertainHatches.add((MTEHatchUncertainty) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergyMulti) {
+ return eEnergyMulti.add((MTEHatchEnergyMulti) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamoMulti) {
+ return eDynamoMulti.add((MTEHatchDynamoMulti) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDataInput) {
+ return eInputData.add((MTEHatchDataInput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDataOutput) {
+ return eOutputData.add((MTEHatchDataOutput) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ public final boolean addElementalToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatch) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ }
+
+ return false;
+ }
+
+ public final boolean addElementalMufflerToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+
+ return false;
+ }
+
+ @Override
+ public final boolean addMufflerToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchMuffler) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mMufflerHatches.add((MTEHatchMuffler) aMetaTileEntity);
+ }
+
+ return false;
+ }
+
+ @Override
+ public final boolean addInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof IDualInputHatch) {
+ ((IDualInputHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mDualInputHatches.add((IDualInputHatch) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchInput) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ ((MTEHatchInput) aMetaTileEntity).mRecipeMap = getRecipeMap();
+ return mInputHatches.add((MTEHatchInput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchInputBus) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ ((MTEHatchInputBus) aMetaTileEntity).mRecipeMap = getRecipeMap();
+ return mInputBusses.add((MTEHatchInputBus) aMetaTileEntity);
+ }
+
+ return false;
+ }
+
+ @Override
+ public final boolean addOutputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutput) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mOutputHatches.add((MTEHatchOutput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutputBus) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mOutputBusses.add((MTEHatchOutputBus) aMetaTileEntity);
+ }
+
+ return false;
+ }
+
+ @Deprecated
+ @Override
+ public final boolean addEnergyInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergy) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mEnergyHatches.add((MTEHatchEnergy) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergyMulti) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eEnergyMulti.add((MTEHatchEnergyMulti) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ @Deprecated
+ @Override
+ public final boolean addDynamoToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamo) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mDynamoHatches.add((MTEHatchDynamo) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamoMulti) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eDynamoMulti.add((MTEHatchDynamoMulti) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ // New Method
+ public final boolean addEnergyIOToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergy) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mEnergyHatches.add((MTEHatchEnergy) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchEnergyMulti) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eEnergyMulti.add((MTEHatchEnergyMulti) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamo) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mDynamoHatches.add((MTEHatchDynamo) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDynamoMulti) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eDynamoMulti.add((MTEHatchDynamoMulti) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ // NEW METHOD
+ public final boolean addElementalInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+
+ return false;
+ }
+
+ // NEW METHOD
+ public final boolean addElementalOutputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+
+ return false;
+ }
+
+ // NEW METHOD
+ public final boolean addParametrizerToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchParam) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eParamHatches.add((MTEHatchParam) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ // NEW METHOD
+ public final boolean addUncertainToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchUncertainty) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eUncertainHatches.add((MTEHatchUncertainty) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean addMaintenanceToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchMaintenance) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mMaintenanceHatches.add((MTEHatchMaintenance) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchParam) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eParamHatches.add((MTEHatchParam) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchUncertainty) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eUncertainHatches.add((MTEHatchUncertainty) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ // NEW METHOD
+ public final boolean addClassicMaintenanceToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchMaintenance) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return mMaintenanceHatches.add((MTEHatchMaintenance) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ // NEW METHOD
+ public final boolean addDataConnectorToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchDataInput) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eInputData.add((MTEHatchDataInput) aMetaTileEntity);
+ }
+ if (aMetaTileEntity instanceof MTEHatchDataOutput) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ return eOutputData.add((MTEHatchDataOutput) aMetaTileEntity);
+ }
+ return false;
+ }
+ // endregion
+
+ protected static <T extends TTMultiblockBase> IStructureElement<T> classicHatches(int casingIndex, int dot,
+ Block casingBlock, int casingMeta) {
+ return HatchElementBuilder.<T>builder()
+ .atLeast(
+ InputBus,
+ InputHatch,
+ OutputHatch,
+ OutputBus,
+ Maintenance,
+ Muffler,
+ HatchElement.EnergyMulti,
+ HatchElement.DynamoMulti,
+ HatchElement.InputData,
+ HatchElement.OutputData,
+ HatchElement.Uncertainty)
+ .casingIndex(casingIndex)
+ .dot(dot)
+ .buildAndChain(casingBlock, casingMeta);
+ }
+
+ protected static <T extends TTMultiblockBase> IStructureElement<T> allHatches(int casingIndex, int dot,
+ Block casingBlock, int casingMeta) {
+ return HatchElementBuilder.<T>builder()
+ .atLeast(
+ InputBus,
+ InputHatch,
+ OutputHatch,
+ OutputBus,
+ Maintenance,
+ Muffler,
+ HatchElement.EnergyMulti,
+ HatchElement.DynamoMulti,
+ HatchElement.InputData,
+ HatchElement.OutputData,
+ HatchElement.Uncertainty)
+ .casingIndex(casingIndex)
+ .dot(dot)
+ .buildAndChain(casingBlock, casingMeta);
+ }
+
+ public enum HatchElement implements IHatchElement<TTMultiblockBase> {
+
+ Param(TTMultiblockBase::addParametrizerToMachineList, MTEHatchParam.class) {
+
+ @Override
+ public long count(TTMultiblockBase t) {
+ return t.eParamHatches.size();
+ }
+ },
+ Uncertainty(TTMultiblockBase::addUncertainToMachineList, MTEHatchUncertainty.class) {
+
+ @Override
+ public long count(TTMultiblockBase t) {
+ return t.eUncertainHatches.size();
+ }
+ },
+ EnergyMulti(TTMultiblockBase::addEnergyInputToMachineList, MTEHatchEnergyMulti.class) {
+
+ @Override
+ public long count(TTMultiblockBase t) {
+ return t.eEnergyMulti.size();
+ }
+ },
+ DynamoMulti(TTMultiblockBase::addDynamoToMachineList, MTEHatchDynamoMulti.class) {
+
+ @Override
+ public long count(TTMultiblockBase t) {
+ return t.eDynamoMulti.size();
+ }
+ },
+ InputData(TTMultiblockBase::addDataConnectorToMachineList, MTEHatchDataInput.class) {
+
+ @Override
+ public long count(TTMultiblockBase t) {
+ return t.eInputData.size();
+ }
+ },
+ OutputData(TTMultiblockBase::addDataConnectorToMachineList, MTEHatchDataOutput.class) {
+
+ @Override
+ public long count(TTMultiblockBase t) {
+ return t.eOutputData.size();
+ }
+ },;
+
+ private final List<Class<? extends IMetaTileEntity>> mteClasses;
+ private final IGTHatchAdder<TTMultiblockBase> adder;
+
+ @SafeVarargs
+ HatchElement(IGTHatchAdder<TTMultiblockBase> adder, Class<? extends IMetaTileEntity>... mteClasses) {
+ this.mteClasses = Collections.unmodifiableList(Arrays.asList(mteClasses));
+ this.adder = adder;
+ }
+
+ @Override
+ public List<? extends Class<? extends IMetaTileEntity>> mteClasses() {
+ return mteClasses;
+ }
+
+ public IGTHatchAdder<? super TTMultiblockBase> adder() {
+ return adder;
+ }
+ }
+
+ /**
+ * Check if the computation timeout is still active
+ *
+ * @return True if the timeout is still active or false if the machine should fail
+ */
+ protected boolean checkComputationTimeout() {
+ if (eComputationTimeout > 0) {
+ return --eComputationTimeout > 0;
+ }
+ return false;
+ }
+
+ // region ModularUI
+
+ @Override
+ public int getGUIWidth() {
+ return 198;
+ }
+
+ @Override
+ public int getGUIHeight() {
+ return 192;
+ }
+
+ @Override
+ public void bindPlayerInventoryUI(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ builder.bindPlayerInventory(buildContext.getPlayer(), new Pos2d(7, 109), getGUITextureSet().getItemSlot());
+ }
+
+ public boolean isPowerPassButtonEnabled() {
+ return true;
+ }
+
+ public boolean isSafeVoidButtonEnabled() {
+ return true;
+ }
+
+ public boolean isAllowedToWorkButtonEnabled() {
+ return true;
+ }
+
+ @Override
+ public void addGregTechLogo(ModularWindow.Builder builder) {
+ builder.widget(
+ new DrawableWidget().setDrawable(TecTechUITextures.PICTURE_TECTECH_LOGO_DARK)
+ .setSize(18, 18)
+ .setPos(173, 74));
+ }
+
+ private static byte LEDCounter = 0;
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ if (doesBindPlayerInventory()) {
+ builder.widget(
+ new DrawableWidget().setDrawable(TecTechUITextures.BACKGROUND_SCREEN_BLUE)
+ .setPos(4, 4)
+ .setSize(190, 91));
+ } else {
+ builder.widget(
+ new DrawableWidget().setDrawable(TecTechUITextures.BACKGROUND_SCREEN_BLUE_NO_INVENTORY)
+ .setPos(4, 4)
+ .setSize(190, 171));
+ }
+ final SlotWidget inventorySlot = new SlotWidget(new BaseSlot(inventoryHandler, 1) {
+
+ @Override
+ public int getSlotStackLimit() {
+ return getInventoryStackLimit();
+ }
+ });
+ if (doesBindPlayerInventory()) {
+ builder
+ .widget(
+ inventorySlot.setBackground(getGUITextureSet().getItemSlot(), TecTechUITextures.OVERLAY_SLOT_MESH)
+ .setPos(173, 167))
+ .widget(
+ new DrawableWidget().setDrawable(TecTechUITextures.PICTURE_HEAT_SINK_SMALL)
+ .setPos(173, 185)
+ .setSize(18, 6));
+ }
+
+ final DynamicPositionedColumn screenElements = new DynamicPositionedColumn();
+ drawTexts(screenElements, inventorySlot);
+ builder.widget(screenElements.setPos(7, 8));
+
+ Widget powerPassButton = createPowerPassButton();
+ builder.widget(powerPassButton)
+ .widget(new FakeSyncWidget.BooleanSyncer(() -> ePowerPass, val -> ePowerPass = val))
+ .widget(new FakeSyncWidget.BooleanSyncer(() -> ePowerPassCover, val -> ePowerPassCover = val));
+ Widget safeVoidButton = createSafeVoidButton();
+ builder.widget(safeVoidButton)
+ .widget(new FakeSyncWidget.BooleanSyncer(() -> eSafeVoid, val -> eSafeVoid = val));
+ Widget powerSwitchButton = createPowerSwitchButton();
+ builder.widget(powerSwitchButton)
+ .widget(new FakeSyncWidget.BooleanSyncer(() -> getBaseMetaTileEntity().isAllowedToWork(), val -> {
+ if (val) getBaseMetaTileEntity().enableWorking();
+ else getBaseMetaTileEntity().disableWorking();
+ }));
+
+ builder.widget(new DrawableWidget() {
+
+ @Override
+ public void draw(float partialTicks) {
+ super.draw(partialTicks);
+ LEDCounter = (byte) ((1 + LEDCounter) % 6);
+ }
+ }.setDrawable(TecTechUITextures.PICTURE_PARAMETER_BLANK)
+ .setPos(5, doesBindPlayerInventory() ? 96 : 176)
+ .setSize(166, 12));
+ for (int hatch = 0; hatch < 10; hatch++) {
+ for (int param = 0; param < 2; param++) {
+ int ledID = hatch + param * 10;
+ buildContext
+ .addSyncedWindow(LED_WINDOW_BASE_ID + ledID, (player) -> createLEDConfigurationWindow(ledID));
+ addParameterLED(builder, hatch, param, true);
+ addParameterLED(builder, hatch, param, false);
+ }
+ }
+
+ if (doesBindPlayerInventory()) {
+ builder.widget(
+ new DrawableWidget().setDrawable(TecTechUITextures.PICTURE_UNCERTAINTY_MONITOR_MULTIMACHINE)
+ .setPos(173, 96)
+ .setSize(18, 18));
+ for (int i = 0; i < 9; i++) {
+ final int index = i;
+ builder.widget(new DrawableWidget().setDrawable(() -> {
+ UITexture valid = TecTechUITextures.PICTURE_UNCERTAINTY_VALID[index];
+ UITexture invalid = TecTechUITextures.PICTURE_UNCERTAINTY_INVALID[index];
+ switch (eCertainMode) {
+ case 1: // ooo oxo ooo
+ if (index == 4) return eCertainStatus == 0 ? valid : invalid;
+ break;
+ case 2: // ooo xox ooo
+ if (index == 3) return (eCertainStatus & 1) == 0 ? valid : invalid;
+ if (index == 5) return (eCertainStatus & 2) == 0 ? valid : invalid;
+ break;
+ case 3: // oxo xox oxo
+ if (index == 1) return (eCertainStatus & 1) == 0 ? valid : invalid;
+ if (index == 3) return (eCertainStatus & 2) == 0 ? valid : invalid;
+ if (index == 5) return (eCertainStatus & 4) == 0 ? valid : invalid;
+ if (index == 7) return (eCertainStatus & 8) == 0 ? valid : invalid;
+ break;
+ case 4: // xox ooo xox
+ if (index == 0) return (eCertainStatus & 1) == 0 ? valid : invalid;
+ if (index == 2) return (eCertainStatus & 2) == 0 ? valid : invalid;
+ if (index == 6) return (eCertainStatus & 4) == 0 ? valid : invalid;
+ if (index == 8) return (eCertainStatus & 8) == 0 ? valid : invalid;
+ break;
+ case 5: // xox oxo xox
+ if (index == 0) return (eCertainStatus & 1) == 0 ? valid : invalid;
+ if (index == 2) return (eCertainStatus & 2) == 0 ? valid : invalid;
+ if (index == 4) return (eCertainStatus & 4) == 0 ? valid : invalid;
+ if (index == 6) return (eCertainStatus & 8) == 0 ? valid : invalid;
+ if (index == 8) return (eCertainStatus & 16) == 0 ? valid : invalid;
+ break;
+ }
+ return null;
+ })
+ .setPos(174 + (index % 3) * 6, 97 + (index / 3) * 6)
+ .setSize(4, 4));
+ }
+ builder.widget(new FakeSyncWidget.ByteSyncer(() -> eCertainMode, val -> eCertainMode = val))
+ .widget(new FakeSyncWidget.ByteSyncer(() -> eCertainStatus, val -> eCertainStatus = val));
+ }
+ }
+
+ protected ButtonWidget createPowerPassButton() {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (isPowerPassButtonEnabled() || ePowerPassCover) {
+ TecTech.proxy.playSound(getBaseMetaTileEntity(), "fx_click");
+ ePowerPass = !ePowerPass;
+ if (!isAllowedToWorkButtonEnabled()) { // TRANSFORMER HACK
+ if (ePowerPass) {
+ getBaseMetaTileEntity().enableWorking();
+ } else {
+ getBaseMetaTileEntity().disableWorking();
+ }
+ }
+ }
+ })
+ .setPlayClickSound(false)
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ ret.add(TecTechUITextures.BUTTON_STANDARD_16x16);
+ if (!isPowerPassButtonEnabled() && !ePowerPassCover) {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_POWER_PASS_DISABLED);
+ } else {
+ if (ePowerPass) {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_POWER_PASS_ON);
+ } else {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_POWER_PASS_OFF);
+ }
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .setPos(174, doesBindPlayerInventory() ? 116 : 140)
+ .setSize(16, 16);
+ if (isPowerPassButtonEnabled()) {
+ button.addTooltip("Power Pass")
+ .setTooltipShowUpDelay(TOOLTIP_DELAY);
+ }
+ return (ButtonWidget) button;
+ }
+
+ protected ButtonWidget createSafeVoidButton() {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (isSafeVoidButtonEnabled()) {
+ TecTech.proxy.playSound(getBaseMetaTileEntity(), "fx_click");
+ eSafeVoid = !eSafeVoid;
+ }
+ })
+ .setPlayClickSound(false)
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ ret.add(TecTechUITextures.BUTTON_STANDARD_16x16);
+ if (!isSafeVoidButtonEnabled()) {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_SAFE_VOID_DISABLED);
+ } else {
+ if (eSafeVoid) {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_SAFE_VOID_ON);
+ } else {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_SAFE_VOID_OFF);
+ }
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .setPos(174, doesBindPlayerInventory() ? 132 : 156)
+ .setSize(16, 16);
+ if (isSafeVoidButtonEnabled()) {
+ button.addTooltip("Safe Void")
+ .setTooltipShowUpDelay(TOOLTIP_DELAY);
+ }
+ return (ButtonWidget) button;
+ }
+
+ protected ButtonWidget createPowerSwitchButton() {
+ Widget button = new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (isAllowedToWorkButtonEnabled()) {
+ TecTech.proxy.playSound(getBaseMetaTileEntity(), "fx_click");
+ if (getBaseMetaTileEntity().isAllowedToWork()) {
+ getBaseMetaTileEntity().disableWorking();
+ } else {
+ getBaseMetaTileEntity().enableWorking();
+ }
+ }
+ })
+ .setPlayClickSound(false)
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ ret.add(TecTechUITextures.BUTTON_STANDARD_16x16);
+ if (!isAllowedToWorkButtonEnabled()) {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_POWER_SWITCH_DISABLED);
+ } else {
+ if (getBaseMetaTileEntity().isAllowedToWork()) {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_POWER_SWITCH_ON);
+ } else {
+ ret.add(TecTechUITextures.OVERLAY_BUTTON_POWER_SWITCH_OFF);
+ }
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .setPos(174, doesBindPlayerInventory() ? 148 : 172)
+ .setSize(16, 16);
+ if (isAllowedToWorkButtonEnabled()) {
+ button.addTooltip("Power Switch")
+ .setTooltipShowUpDelay(TOOLTIP_DELAY);
+ }
+ return (ButtonWidget) button;
+ }
+
+ private ModularWindow createLEDConfigurationWindow(int ledID) {
+ return ModularWindow.builder(100, 40)
+ .setBackground(TecTechUITextures.BACKGROUND_SCREEN_BLUE)
+ .setPos(
+ (screenSize, mainWindow) -> new Pos2d(
+ (screenSize.width / 2 - mainWindow.getSize().width / 2) - 110,
+ (screenSize.height / 2 - mainWindow.getSize().height / 2)))
+ .widget(
+ ButtonWidget.closeWindowButton(true)
+ .setPos(85, 3))
+ .widget(
+ new NumericWidget().setGetter(() -> parametrization.iParamsIn[ledID])
+ .setSetter(val -> parametrization.iParamsIn[ledID] = val)
+ .setIntegerOnly(false)
+ .modifyNumberFormat(format -> format.setMaximumFractionDigits(8))
+ .setTextColor(Color.LIGHT_BLUE.normal)
+ .setTextAlignment(Alignment.CenterLeft)
+ .setFocusOnGuiOpen(true)
+ .setBackground(GTUITextures.BACKGROUND_TEXT_FIELD)
+ .setPos(5, 20)
+ .setSize(90, 15))
+ .widget(
+ new TextWidget((ledID % 10) + ":" + (ledID / 10) + ":I").setDefaultColor(Color.WHITE.normal)
+ .setTextAlignment(Alignment.Center)
+ .setPos(5, 5))
+ .build();
+ }
+
+ private void addParameterLED(ModularWindow.Builder builder, int hatch, int param, boolean input) {
+ final int parameterIndex = hatch + param * 10;
+ final int posIndex = hatch * 2 + param;
+ ButtonWidget ledWidget = new ButtonWidget() {
+
+ @Override
+ public void draw(float partialTicks) {
+ IDrawable texture = null;
+ final LedStatus status = input ? parametrization.eParamsInStatus[parameterIndex]
+ : parametrization.eParamsOutStatus[parameterIndex];
+ switch (status) {
+ case STATUS_WTF: {
+ int c = LEDCounter;
+ if (c > 4) {
+ c = TecTech.RANDOM.nextInt(5);
+ }
+ switch (c) {
+ case 0:
+ texture = TecTechUITextures.PICTURE_PARAMETER_BLUE[posIndex];
+ break;
+ case 1:
+ texture = TecTechUITextures.PICTURE_PARAMETER_CYAN[posIndex];
+ break;
+ case 2:
+ texture = TecTechUITextures.PICTURE_PARAMETER_GREEN[posIndex];
+ break;
+ case 3:
+ texture = TecTechUITextures.PICTURE_PARAMETER_ORANGE[posIndex];
+ break;
+ case 4:
+ texture = TecTechUITextures.PICTURE_PARAMETER_RED[posIndex];
+ break;
+ }
+ break;
+ }
+ case STATUS_WRONG: // fallthrough
+ if (LEDCounter < 2) {
+ texture = TecTechUITextures.PICTURE_PARAMETER_BLUE[posIndex];
+ break;
+ } else if (LEDCounter < 4) {
+ texture = TecTechUITextures.PICTURE_PARAMETER_RED[posIndex];
+ break;
+ }
+ case STATUS_OK: // ok
+ texture = TecTechUITextures.PICTURE_PARAMETER_GREEN[posIndex];
+ break;
+ case STATUS_TOO_LOW: // too low blink
+ if (LEDCounter < 3) {
+ texture = TecTechUITextures.PICTURE_PARAMETER_BLUE[posIndex];
+ break;
+ }
+ case STATUS_LOW: // too low
+ texture = TecTechUITextures.PICTURE_PARAMETER_CYAN[posIndex];
+ break;
+ case STATUS_TOO_HIGH: // too high blink
+ if (LEDCounter < 3) {
+ texture = TecTechUITextures.PICTURE_PARAMETER_RED[posIndex];
+ break;
+ }
+ case STATUS_HIGH: // too high
+ texture = TecTechUITextures.PICTURE_PARAMETER_ORANGE[posIndex];
+ break;
+ case STATUS_NEUTRAL:
+ if (LEDCounter < 3) {
+ GL11.glColor4f(.85f, .9f, .95f, .5F);
+ } else {
+ GL11.glColor4f(.8f, .9f, 1f, .5F);
+ }
+ texture = TecTechUITextures.PICTURE_PARAMETER_GRAY;
+ break;
+ case STATUS_UNDEFINED:
+ if (LEDCounter < 3) {
+ GL11.glColor4f(.5f, .1f, .15f, .5F);
+ } else {
+ GL11.glColor4f(0f, .1f, .2f, .5F);
+ }
+ texture = TecTechUITextures.PICTURE_PARAMETER_GRAY;
+ break;
+ case STATUS_UNUSED:
+ default:
+ // no-op
+ break;
+ }
+ setBackground(texture);
+ super.draw(partialTicks);
+ GL11.glColor4f(1f, 1f, 1f, 1f);
+ }
+ }.setOnClick((clickData, widget) -> {
+ if (!widget.isClient() && input
+ && parametrization.eParamsInStatus[parameterIndex] != LedStatus.STATUS_UNUSED) {
+ // We don't use CloseAllButMain here in case MB implementation adds their own window
+ for (int i = 0; i < parametrization.eParamsInStatus.length; i++) {
+ if (widget.getContext()
+ .isWindowOpen(LED_WINDOW_BASE_ID + i)) {
+ widget.getContext()
+ .closeWindow(LED_WINDOW_BASE_ID + i);
+ }
+ }
+ widget.getContext()
+ .openSyncedWindow(LED_WINDOW_BASE_ID + parameterIndex);
+ }
+ });
+ builder.widget(ledWidget.dynamicTooltip(() -> {
+ if (input) {
+ return getFullLedDescriptionIn(hatch, param);
+ } else {
+ return getFullLedDescriptionOut(hatch, param);
+ }
+ })
+ .setPos(12 + posIndex * 8, (doesBindPlayerInventory() ? 97 : 177) + (input ? 0 : 1) * 6)
+ .setSize(6, 4));
+ if (input) {
+ builder
+ .widget(
+ new FakeSyncWidget.ByteSyncer(
+ () -> parametrization.eParamsInStatus[parameterIndex].getOrdinalByte(),
+ val -> parametrization.eParamsInStatus[parameterIndex] = LedStatus.getStatus(val))
+ .setOnClientUpdate(val -> ledWidget.notifyTooltipChange()))
+ .widget(
+ new FakeSyncWidget.DoubleSyncer(
+ () -> parametrization.iParamsIn[parameterIndex],
+ val -> parametrization.iParamsIn[parameterIndex] = val)
+ .setOnClientUpdate(val -> ledWidget.notifyTooltipChange()));
+ } else {
+ builder
+ .widget(
+ new FakeSyncWidget.ByteSyncer(
+ () -> parametrization.eParamsOutStatus[parameterIndex].getOrdinalByte(),
+ val -> parametrization.eParamsOutStatus[parameterIndex] = LedStatus.getStatus(val))
+ .setOnClientUpdate(val -> ledWidget.notifyTooltipChange()))
+ .widget(
+ new FakeSyncWidget.DoubleSyncer(
+ () -> parametrization.iParamsOut[parameterIndex],
+ val -> parametrization.iParamsOut[parameterIndex] = val)
+ .setOnClientUpdate(val -> ledWidget.notifyTooltipChange()));
+ }
+ }
+
+ // endregion
+}
diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/render/TTRenderedExtendedFacingTexture.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/render/TTRenderedExtendedFacingTexture.java
new file mode 100644
index 0000000000..8d41fcb0ff
--- /dev/null
+++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/render/TTRenderedExtendedFacingTexture.java
@@ -0,0 +1,25 @@
+package tectech.thing.metaTileEntity.multi.base.render;
+
+import gregtech.api.enums.Dyes;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.common.render.GTRenderedTexture;
+
+public class TTRenderedExtendedFacingTexture extends GTRenderedTexture {
+
+ public TTRenderedExtendedFacingTexture(IIconContainer aIcon, short[] aRGBa, boolean allowAlpha, boolean glow,
+ boolean stdOrient, boolean extFacing) {
+ super(aIcon, aRGBa, allowAlpha, glow, stdOrient, extFacing);
+ }
+
+ public TTRenderedExtendedFacingTexture(IIconContainer aIcon, short[] aRGBa, boolean aAllowAlpha) {
+ this(aIcon, aRGBa, aAllowAlpha, false, false, true);
+ }
+
+ public TTRenderedExtendedFacingTexture(IIconContainer aIcon, short[] aRGBa) {
+ this(aIcon, aRGBa, true);
+ }
+
+ public TTRenderedExtendedFacingTexture(IIconContainer aIcon) {
+ this(aIcon, Dyes._NULL.mRGBa);
+ }
+}