aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/bartworks/common/tileentities
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bartworks/common/tileentities')
-rw-r--r--src/main/java/bartworks/common/tileentities/classic/TileEntityDimIDBridge.java24
-rw-r--r--src/main/java/bartworks/common/tileentities/classic/TileEntityHeatedWaterPump.java375
-rw-r--r--src/main/java/bartworks/common/tileentities/classic/TileEntityRotorBlock.java41
-rw-r--r--src/main/java/bartworks/common/tileentities/debug/MTECreativeScanner.java70
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTEBioVat.java834
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTECircuitAssemblyLine.java672
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTEDeepEarthHeatingPump.java336
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTEElectricImplosionCompressor.java565
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTEHighTempGasCooledReactor.java619
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTELESU.java590
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTEManualTrafo.java363
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTEThoriumHighTempReactor.java416
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/MTEWindmill.java637
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaBlastFurnace.java430
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaChemicalReactor.java278
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaDistillTower.java446
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaOilCracker.java465
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaVacuumFreezer.java533
-rw-r--r--src/main/java/bartworks/common/tileentities/multis/mega/MegaMultiBlockBase.java212
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/GT_MetaTileEntity_RadioHatch.java494
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/MTEAcidGenerator.java155
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/MTEBioLab.java405
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/MTECompressedFluidHatch.java57
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/MTEDiode.java125
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/MTEEnergyDistributor.java72
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/MTEGiantOutputHatch.java41
-rw-r--r--src/main/java/bartworks/common/tileentities/tiered/MTEHumongousInputHatch.java41
27 files changed, 9296 insertions, 0 deletions
diff --git a/src/main/java/bartworks/common/tileentities/classic/TileEntityDimIDBridge.java b/src/main/java/bartworks/common/tileentities/classic/TileEntityDimIDBridge.java
new file mode 100644
index 0000000000..6b00b65054
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/classic/TileEntityDimIDBridge.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.classic;
+
+import net.minecraft.tileentity.TileEntity;
+
+public class TileEntityDimIDBridge extends TileEntity {
+
+ @Override
+ public boolean canUpdate() {
+ return false;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/classic/TileEntityHeatedWaterPump.java b/src/main/java/bartworks/common/tileentities/classic/TileEntityHeatedWaterPump.java
new file mode 100644
index 0000000000..3f973e8eea
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/classic/TileEntityHeatedWaterPump.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.classic;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.tileentity.TileEntityFurnace;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidEvent;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import net.minecraftforge.fluids.IFluidTank;
+
+import com.gtnewhorizons.modularui.api.ModularUITextures;
+import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable;
+import com.gtnewhorizons.modularui.api.forge.InvWrapper;
+import com.gtnewhorizons.modularui.api.screen.ITileWithModularUI;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.widget.ProgressBar;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+
+import bartworks.API.ITileAddsInformation;
+import bartworks.API.ITileDropsContent;
+import bartworks.API.ITileHasDifferentTextureSides;
+import bartworks.API.modularUI.BWUITextures;
+import bartworks.MainMod;
+import bartworks.common.configs.ConfigHandler;
+import gregtech.api.util.GTUtility;
+import gregtech.common.Pollution;
+
+public class TileEntityHeatedWaterPump extends TileEntity implements ITileDropsContent, IFluidHandler, IFluidTank,
+ ITileWithModularUI, ITileAddsInformation, ITileHasDifferentTextureSides {
+
+ public static final int FUELSLOT = 0;
+ public static final Fluid WATER = FluidRegistry.WATER;
+ public ItemStack fuelstack;
+ public FluidStack outputstack = new FluidStack(FluidRegistry.WATER, 0);
+ public int fuel;
+ public byte tick;
+ public int maxfuel;
+ public ItemStack fakestack = new ItemStack(Blocks.water);
+
+ @Override
+ public void writeToNBT(NBTTagCompound compound) {
+ NBTTagCompound subItemStack = new NBTTagCompound();
+ if (this.fuelstack != null) {
+ this.fuelstack.writeToNBT(subItemStack);
+ }
+ compound.setTag("ItemStack", subItemStack);
+ NBTTagCompound subFluidStack = new NBTTagCompound();
+ this.outputstack.writeToNBT(subFluidStack);
+ compound.setTag("FluidStack", subFluidStack);
+ compound.setInteger("fuel", this.fuel);
+ compound.setInteger("maxfuel", this.maxfuel);
+ compound.setByte("tick", this.tick);
+ super.writeToNBT(compound);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound compound) {
+ this.tick = compound.getByte("tick");
+ this.fuel = compound.getInteger("fuel");
+ this.maxfuel = compound.getInteger("maxfuel");
+ this.outputstack = FluidStack.loadFluidStackFromNBT(compound.getCompoundTag("FluidStack"));
+ if (!compound.getCompoundTag("ItemStack")
+ .equals(new NBTTagCompound()))
+ this.fuelstack = ItemStack.loadItemStackFromNBT(compound.getCompoundTag("ItemStack"));
+ super.readFromNBT(compound);
+ }
+
+ private boolean checkPreUpdate() {
+ return (this.fuelstack == null || this.fuelstack.stackSize <= 0) && this.fuel <= 0;
+ }
+
+ private void fixUnderlflow() {
+ if (this.fuel < 0) this.fuel = 0;
+ }
+
+ private void handleRefuel() {
+ if (this.fuelstack != null && this.fuel == 0) {
+ this.fuel = this.maxfuel = TileEntityFurnace.getItemBurnTime(this.fuelstack);
+ --this.fuelstack.stackSize;
+ if (this.fuelstack.stackSize <= 0) this.fuelstack = fuelstack.getItem()
+ .getContainerItem(fuelstack);
+ }
+ }
+
+ private void handleWaterGeneration() {
+ if (this.fuel > 0) {
+ ++this.tick;
+ --this.fuel;
+ if (this.tick % 20 == 0) {
+ if (this.outputstack.amount <= 8000 - ConfigHandler.mbWaterperSec)
+ this.outputstack.amount += ConfigHandler.mbWaterperSec;
+ this.tick = 0;
+ }
+ }
+ }
+
+ @Override
+ public void updateEntity() {
+ if (this.worldObj.isRemote) return;
+
+ this.pushWaterToAdjacentTiles();
+ this.fakestack.setStackDisplayName(this.outputstack.amount + "L Water");
+ if (this.checkPreUpdate()) return;
+
+ this.fixUnderlflow();
+ this.handleRefuel();
+ this.handleWaterGeneration();
+ this.causePollution();
+ }
+
+ private void pushWaterToAdjacentTiles() {
+ Arrays.stream(ForgeDirection.values(), 0, 6) // All but Unknown
+ .forEach(
+ direction -> Optional
+ .ofNullable(
+ this.worldObj.getTileEntity(
+ this.xCoord + direction.offsetX,
+ this.yCoord + direction.offsetY,
+ this.zCoord + direction.offsetZ))
+ .ifPresent(te -> {
+ if (te instanceof IFluidHandler tank) {
+ if (tank.canFill(direction.getOpposite(), this.outputstack.getFluid())) {
+ int drainage = tank.fill(direction.getOpposite(), this.outputstack, false);
+ if (drainage > 0) {
+ tank.fill(direction.getOpposite(), this.outputstack, true);
+ this.drain(drainage, true);
+ }
+ }
+ } else if (te instanceof IFluidTank tank) {
+ int drainage = tank.fill(this.outputstack, false);
+ if (drainage > 0) {
+ tank.fill(this.outputstack, true);
+ this.drain(drainage, true);
+ }
+ }
+ }));
+ }
+
+ private void causePollution() {
+ Optional.ofNullable(this.worldObj)
+ .ifPresent(e -> {
+ if (e.getTotalWorldTime() % 20 == 0) {
+ Optional.ofNullable(e.getChunkFromBlockCoords(this.xCoord, this.zCoord))
+ .ifPresent(c -> Pollution.addPollution(c, ConfigHandler.pollutionHeatedWaterPumpSecond));
+ }
+ });
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int side) {
+ return new int[] { 0 };
+ }
+
+ @Override
+ public boolean canInsertItem(int p_102007_1_, ItemStack p_102007_2_, int p_102007_3_) {
+ return TileEntityFurnace.getItemBurnTime(p_102007_2_) > 0;
+ }
+
+ @Override
+ public boolean canExtractItem(int p_102008_1_, ItemStack p_102008_2_, int p_102008_3_) {
+ return false;
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return 2;
+ }
+
+ @Override
+ public ItemStack getStackInSlot(int slotIn) {
+ if (slotIn == 0) return this.fuelstack;
+ return this.fakestack;
+ }
+
+ @Override
+ public ItemStack decrStackSize(int slot, int ammount) {
+ if (slot != TileEntityHeatedWaterPump.FUELSLOT || this.fuelstack == null || ammount > this.fuelstack.stackSize)
+ return null;
+
+ return this.fuelstack.splitStack(ammount);
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(int index) {
+ return null;
+ }
+
+ @Override
+ public void setInventorySlotContents(int slot, ItemStack stack) {
+ if (slot == TileEntityHeatedWaterPump.FUELSLOT) this.fuelstack = stack;
+ else this.fakestack = stack;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return null;
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return false;
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return 64;
+ }
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer player) {
+ return true;
+ }
+
+ @Override
+ public void openInventory() {}
+
+ @Override
+ public void closeInventory() {}
+
+ @Override
+ public boolean isItemValidForSlot(int index, ItemStack stack) {
+ return TileEntityFurnace.getItemBurnTime(stack) > 0 && index == TileEntityHeatedWaterPump.FUELSLOT;
+ }
+
+ @Override
+ public FluidStack getFluid() {
+ return this.outputstack.amount > 0 ? this.outputstack : null;
+ }
+
+ @Override
+ public int getFluidAmount() {
+ return this.outputstack.amount;
+ }
+
+ @Override
+ public int getCapacity() {
+ return 8000;
+ }
+
+ @Override
+ public FluidTankInfo getInfo() {
+ return new FluidTankInfo(this);
+ }
+
+ @Override
+ public int fill(FluidStack resource, boolean doFill) {
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(int maxDrain, boolean doDrain) {
+ int actualdrain = maxDrain;
+ if (actualdrain > this.outputstack.amount) actualdrain = this.outputstack.amount;
+ FluidStack ret = new FluidStack(TileEntityHeatedWaterPump.WATER, actualdrain);
+ if (ret.amount == 0) ret = null;
+ if (doDrain) {
+ this.outputstack.amount -= actualdrain;
+ FluidEvent.fireEvent(
+ new FluidEvent.FluidDrainingEvent(
+ this.outputstack,
+ this.getWorldObj(),
+ this.xCoord,
+ this.yCoord,
+ this.zCoord,
+ this,
+ actualdrain));
+ }
+ return ret;
+ }
+
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
+ if (resource != null && resource.getFluid() == TileEntityHeatedWaterPump.WATER
+ && this.drain(resource.amount, false) != null) return this.drain(resource.amount, doDrain);
+ return null;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
+ return this.drain(maxDrain, doDrain);
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid) {
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid) {
+ return fluid == null || fluid == TileEntityHeatedWaterPump.WATER;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from) {
+ return new FluidTankInfo[] { this.getInfo() };
+ }
+
+ @Override
+ public String[] getInfoData() {
+ return new String[] {
+ StatCollector.translateToLocal("tooltip.tile.waterpump.0.name") + " "
+ + GTUtility.formatNumbers(ConfigHandler.mbWaterperSec)
+ + String.format(
+ StatCollector.translateToLocal("tooltip.tile.waterpump.1.name"),
+ ConfigHandler.pollutionHeatedWaterPumpSecond),
+ StatCollector.translateToLocal("tooltip.tile.waterpump.2.name") };
+ }
+
+ @Override
+ public void registerBlockIcons(IIconRegister par1IconRegister) {
+ ITileHasDifferentTextureSides.texture[ForgeDirection.UP.ordinal()] = par1IconRegister
+ .registerIcon(MainMod.MOD_ID + ":heatedWaterPumpTop");
+ ITileHasDifferentTextureSides.texture[ForgeDirection.DOWN.ordinal()] = par1IconRegister
+ .registerIcon(MainMod.MOD_ID + ":heatedWaterPumpDown");
+ for (int i = 2; i < 7; i++) {
+ ITileHasDifferentTextureSides.texture[i] = par1IconRegister
+ .registerIcon(MainMod.MOD_ID + ":heatedWaterPumpSide");
+ }
+ }
+
+ @Override
+ public ModularWindow createWindow(UIBuildContext buildContext) {
+ ModularWindow.Builder builder = ModularWindow.builder(176, 166);
+ builder.setBackground(ModularUITextures.VANILLA_BACKGROUND);
+ builder.bindPlayerInventory(buildContext.getPlayer());
+ final IItemHandlerModifiable invWrapper = new InvWrapper(this);
+
+ builder.widget(
+ new SlotWidget(invWrapper, 0).setFilter(stack -> TileEntityFurnace.getItemBurnTime(stack) > 0)
+ .setPos(55, 52))
+ .widget(
+ SlotWidget.phantom(invWrapper, 1)
+ .disableInteraction()
+ .setPos(85, 32))
+ .widget(
+ new ProgressBar().setProgress(() -> (float) this.fuel / this.maxfuel)
+ .setTexture(BWUITextures.PROGRESSBAR_FUEL, 14)
+ .setDirection(ProgressBar.Direction.UP)
+ .setPos(56, 36)
+ .setSize(14, 14));
+
+ return builder.build();
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/classic/TileEntityRotorBlock.java b/src/main/java/bartworks/common/tileentities/classic/TileEntityRotorBlock.java
new file mode 100644
index 0000000000..78c7f34710
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/classic/TileEntityRotorBlock.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.classic;
+
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.entity.player.EntityPlayer;
+
+import bartworks.client.gui.GuiContainerRotorBlock;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import ic2.core.block.kineticgenerator.container.ContainerWindKineticGenerator;
+import ic2.core.block.kineticgenerator.tileentity.TileEntityWindKineticGenerator;
+
+public class TileEntityRotorBlock extends TileEntityWindKineticGenerator {
+
+ public int getGrindPower() {
+ return super.getKuOutput();
+ }
+
+ @Override
+ public int getKuOutput() {
+ return 0;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public GuiScreen getGui(EntityPlayer entityPlayer, boolean isAdmin) {
+ return new GuiContainerRotorBlock(new ContainerWindKineticGenerator(entityPlayer, this));
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/debug/MTECreativeScanner.java b/src/main/java/bartworks/common/tileentities/debug/MTECreativeScanner.java
new file mode 100644
index 0000000000..a1ccd7d4e3
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/debug/MTECreativeScanner.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.debug;
+
+import net.minecraft.util.StatCollector;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+import bartworks.util.BWTooltipReference;
+import gregtech.api.enums.MachineType;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.MetaTileEntity;
+import gregtech.common.tileentities.machines.basic.MTEScanner;
+
+public class MTECreativeScanner extends MTEScanner {
+
+ public MTECreativeScanner(int aID, String aName, String aNameRegional, int aTier) {
+ super(aID, aName, aNameRegional, aTier);
+ }
+
+ public MTECreativeScanner(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ }
+
+ @Override
+ public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTECreativeScanner(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ public String[] getDescription() {
+ return ArrayUtils.addAll(
+ MachineType.SCANNER.tooltipDescription(),
+ StatCollector.translateToLocal("gt.blockmachines.creativeScanner.desc.1"),
+ BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get());
+ }
+
+ @Override
+ public long maxEUStore() {
+ return 0;
+ }
+
+ @Override
+ protected boolean hasEnoughEnergyToCheckRecipe() {
+ return true;
+ }
+
+ @Override
+ protected boolean drainEnergyForProcess(long aEUt) {
+ return true;
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ this.mProgresstime = this.mMaxProgresstime;
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEBioVat.java b/src/main/java/bartworks/common/tileentities/multis/MTEBioVat.java
new file mode 100644
index 0000000000..b982c0d886
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTEBioVat.java
@@ -0,0 +1,834 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static bartworks.util.BWUtil.ofGlassTiered;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.isAir;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlockAnyMeta;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_GLOW;
+import static gregtech.api.util.GTStructureUtility.ofHatchAdder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.API.SideReference;
+import bartworks.API.recipe.BartWorksRecipeMaps;
+import bartworks.MainMod;
+import bartworks.common.configs.ConfigHandler;
+import bartworks.common.items.ItemLabParts;
+import bartworks.common.loaders.FluidLoader;
+import bartworks.common.net.RendererPacket;
+import bartworks.common.tileentities.tiered.GT_MetaTileEntity_RadioHatch;
+import bartworks.util.BWUtil;
+import bartworks.util.BioCulture;
+import bartworks.util.Coords;
+import bartworks.util.MathUtils;
+import bartworks.util.ResultWrongSievert;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.metatileentity.implementations.MTEHatchOutput;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.api.util.ParallelHelper;
+
+public class MTEBioVat extends MTEEnhancedMultiBlockBase<MTEBioVat> {
+
+ public static final HashMap<Coords, Integer> staticColorMap = new HashMap<>();
+
+ private static final byte TIMERDIVIDER = 20;
+
+ private final HashSet<EntityPlayerMP> playerMPHashSet = new HashSet<>();
+ private final ArrayList<GT_MetaTileEntity_RadioHatch> mRadHatches = new ArrayList<>();
+ private int height = 1;
+ private Fluid mFluid = FluidRegistry.LAVA;
+ private BioCulture mCulture;
+ private ItemStack mStack;
+ private boolean needsVisualUpdate = true;
+ private byte mGlassTier;
+ private int mSievert;
+ private int mNeededSievert;
+ private int mCasing = 0;
+ private int mExpectedMultiplier = 0;
+ private int mTimes = 0;
+ private boolean isVisibleFluid = false;
+
+ public MTEBioVat(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MTEBioVat(String aName) {
+ super(aName);
+ }
+
+ private static final int CASING_INDEX = 49;
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition<MTEBioVat> STRUCTURE_DEFINITION = StructureDefinition.<MTEBioVat>builder()
+ .addShape(
+ STRUCTURE_PIECE_MAIN,
+ transpose(
+ new String[][] { { "ccccc", "ccccc", "ccccc", "ccccc", "ccccc" },
+ { "ggggg", "gaaag", "gaaag", "gaaag", "ggggg" }, { "ggggg", "gaaag", "gaaag", "gaaag", "ggggg" },
+ { "cc~cc", "ccccc", "ccccc", "ccccc", "ccccc" }, }))
+ .addElement(
+ 'c',
+ ofChain(
+ ofHatchAdder(MTEBioVat::addMaintenanceToMachineList, CASING_INDEX, 1),
+ ofHatchAdder(MTEBioVat::addOutputToMachineList, CASING_INDEX, 1),
+ ofHatchAdder(MTEBioVat::addInputToMachineList, CASING_INDEX, 1),
+ ofHatchAdder(MTEBioVat::addRadiationInputToMachineList, CASING_INDEX, 1),
+ ofHatchAdder(MTEBioVat::addEnergyInputToMachineList, CASING_INDEX, 1),
+ onElementPass(e -> e.mCasing++, ofBlock(GregTechAPI.sBlockCasings4, 1))))
+ .addElement('a', ofChain(isAir(), ofBlockAnyMeta(FluidLoader.bioFluidBlock)))
+ .addElement(
+ 'g',
+ ofGlassTiered((byte) 1, (byte) 127, (byte) 0, (te, v) -> te.mGlassTier = v, te -> te.mGlassTier, 1))
+ .build();
+
+ @Override
+ public IStructureDefinition<MTEBioVat> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected IAlignmentLimits getInitialAlignmentLimits() {
+ return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped();
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Bacterial Vat")
+ .addInfo("Controller block for the Bacterial Vat")
+ .addInfo("For maximum efficiency boost keep the Output Hatch always half filled!")
+ .addSeparator()
+ .beginStructureBlock(5, 4, 5, false)
+ .addController("Front bottom center")
+ .addCasingInfoMin("Clean Stainless Steel Casings", 19, false)
+ .addOtherStructurePart("Glass", "Hollow two middle layers", 2)
+ .addStructureInfo("The glass can be any glass, i.e. Tinkers Construct Clear Glass")
+ .addStructureInfo("Some Recipes need more advanced Glass Types")
+ .addMaintenanceHatch("Any casing", 1)
+ .addOtherStructurePart("Radio Hatch", "Any casing", 1)
+ .addInputBus("Any casing", 1)
+ .addOutputBus("Any casing", 1)
+ .addInputHatch("Any casing", 1)
+ .addOutputHatch("Any casing", 1)
+ .addEnergyHatch("Any casing", 1)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ public static int[] specialValueUnpack(int aSpecialValue) {
+ int[] ret = new int[4];
+ ret[0] = aSpecialValue & 0xF; // = glass tier
+ ret[1] = aSpecialValue >>> 4 & 0b11; // = special value
+ ret[2] = aSpecialValue >>> 6 & 0b1; // boolean exact svt | 1 = true | 0 = false
+ ret[3] = aSpecialValue >>> 7 & Integer.MAX_VALUE; // = sievert
+ return ret;
+ }
+
+ private int getInputCapacity() {
+ return this.mInputHatches.stream()
+ .mapToInt(MTEHatchInput::getCapacity)
+ .sum();
+ }
+
+ private int getOutputCapacity() {
+ return this.mOutputHatches.stream()
+ .mapToInt(MTEHatchOutput::getCapacity)
+ .sum();
+ }
+
+ @Override
+ public int getCapacity() {
+ int ret = 0;
+ ret += this.getInputCapacity();
+ // ret += getOutputCapacity();
+ return ret;
+ }
+
+ @Override
+ public int fill(FluidStack resource, boolean doFill) {
+ return super.fill(resource, doFill);
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return BartWorksRecipeMaps.bacterialVatRecipes;
+ }
+
+ /**
+ * Calculates the expected output multiplier based on the output hatch
+ *
+ * @param recipeFluidOutput the recipe fluid output
+ * @param needEqual if the recipeFluidOutput should be equal to the fluid in the output hatch
+ * @return the expected output multiplier
+ */
+ private int getExpectedMultiplier(@Nullable FluidStack recipeFluidOutput, boolean needEqual) {
+ FluidStack storedFluidOutputs = this.getStoredFluidOutputs();
+ if (storedFluidOutputs == null) return 1;
+ if (!needEqual || storedFluidOutputs.isFluidEqual(recipeFluidOutput)) {
+ return this.calcMod(storedFluidOutputs.amount) + 1;
+ }
+ return 1;
+ }
+
+ private int calcMod(double x) {
+ double y = this.getOutputCapacity() / 2D, z = ConfigHandler.bioVatMaxParallelBonus;
+
+ int ret = MathUtils.ceilInt((-1D / y * Math.pow(x - y, 2D) + y) / y * z);
+ return MathUtils.clamp(1, ret, ConfigHandler.bioVatMaxParallelBonus);
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic() {
+
+ @NotNull
+ @Override
+ protected CheckRecipeResult validateRecipe(@NotNull GTRecipe recipe) {
+ if (!BWUtil.areStacksEqualOrNull((ItemStack) recipe.mSpecialItems, MTEBioVat.this.getControllerSlot()))
+ return CheckRecipeResultRegistry.NO_RECIPE;
+ int[] conditions = MTEBioVat.specialValueUnpack(recipe.mSpecialValue);
+ MTEBioVat.this.mNeededSievert = conditions[3];
+
+ if (MTEBioVat.this.mGlassTier < conditions[0]) {
+ return CheckRecipeResultRegistry.insufficientMachineTier(conditions[0]);
+ }
+
+ if (conditions[2] == 0) {
+ if (MTEBioVat.this.mSievert < MTEBioVat.this.mNeededSievert) {
+ return ResultWrongSievert.insufficientSievert(MTEBioVat.this.mNeededSievert);
+ }
+ } else if (MTEBioVat.this.mSievert != conditions[3]) {
+ return ResultWrongSievert.wrongSievert(conditions[3]);
+ }
+
+ return CheckRecipeResultRegistry.SUCCESSFUL;
+ }
+
+ @NotNull
+ @Override
+ protected ParallelHelper createParallelHelper(@NotNull GTRecipe recipe) {
+ return super.createParallelHelper(recipeWithMultiplier(recipe, inputFluids));
+ }
+ };
+ }
+
+ protected GTRecipe recipeWithMultiplier(GTRecipe recipe, FluidStack[] fluidInputs) {
+ GTRecipe tRecipe = recipe.copy();
+ int multiplier = getExpectedMultiplier(recipe.getFluidOutput(0), true);
+ mExpectedMultiplier = multiplier;
+ // Calculate max multiplier limited by input fluids
+ long fluidAmount = 0;
+ for (FluidStack fluid : fluidInputs) {
+ if (recipe.mFluidInputs[0].isFluidEqual(fluid)) {
+ fluidAmount += fluid.amount;
+ }
+ }
+ multiplier = (int) Math.min(multiplier, fluidAmount / recipe.mFluidInputs[0].amount);
+ // In case multiplier is 0
+ multiplier = Math.max(multiplier, 1);
+ mTimes = multiplier;
+ tRecipe.mFluidInputs[0].amount *= multiplier;
+ tRecipe.mFluidOutputs[0].amount *= multiplier;
+ return tRecipe;
+ }
+
+ @Override
+ protected void setupProcessingLogic(ProcessingLogic logic) {
+ super.setupProcessingLogic(logic);
+ logic.setSpecialSlotItem(this.getControllerSlot());
+ }
+
+ public FluidStack getStoredFluidOutputs() {
+ // Only one output Hatch
+ assert this.mOutputHatches.size() == 1;
+ return this.mOutputHatches.get(0)
+ .getFluid();
+ }
+
+ private boolean addRadiationInputToMachineList(IGregTechTileEntity aTileEntity, int CasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null || !(aMetaTileEntity instanceof GT_MetaTileEntity_RadioHatch)) {
+ return false;
+ } else {
+ ((GT_MetaTileEntity_RadioHatch) aMetaTileEntity).updateTexture(CasingIndex);
+ return this.mRadHatches.add((GT_MetaTileEntity_RadioHatch) aMetaTileEntity);
+ }
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) {
+ this.mRadHatches.clear();
+ this.mGlassTier = 0;
+ this.mCasing = 0;
+
+ if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 2, 3, 0)) return false;
+
+ return this.mCasing >= 19 && this.mRadHatches.size() <= 1
+ && this.mOutputHatches.size() == 1
+ && this.mMaintenanceHatches.size() == 1
+ && this.mInputHatches.size() > 0
+ && this.mEnergyHatches.size() > 0;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ private void sendAllRequiredRendererPackets() {
+ int height = this.reCalculateHeight();
+ if (this.mFluid != null && height > 1 && this.reCalculateFluidAmmount() > 0) {
+ for (int x = -1; x < 2; x++) for (int y = 1; y < height; y++)
+ for (int z = -1; z < 2; z++) this.sendPackagesOrRenewRenderer(x, y, z, this.mCulture);
+ }
+ }
+
+ private void sendPackagesOrRenewRenderer(int x, int y, int z, BioCulture lCulture) {
+ int xDir = this.getXDir();
+ int zDir = this.getZDir();
+
+ MTEBioVat.staticColorMap.remove(
+ new Coords(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord(),
+ this.getBaseMetaTileEntity()
+ .getWorld().provider.dimensionId));
+ MTEBioVat.staticColorMap.put(
+ new Coords(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord(),
+ this.getBaseMetaTileEntity()
+ .getWorld().provider.dimensionId),
+ lCulture == null ? BioCulture.NULLCULTURE.getColorRGB() : lCulture.getColorRGB());
+
+ if (SideReference.Side.Server) {
+ MainMod.BW_Network_instance.sendPacketToAllPlayersInRange(
+ this.getBaseMetaTileEntity()
+ .getWorld(),
+ new RendererPacket(
+ new Coords(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord(),
+ this.getBaseMetaTileEntity()
+ .getWorld().provider.dimensionId),
+ lCulture == null ? BioCulture.NULLCULTURE.getColorRGB() : lCulture.getColorRGB(),
+ true),
+ this.getBaseMetaTileEntity()
+ .getXCoord(),
+ this.getBaseMetaTileEntity()
+ .getZCoord());
+ MainMod.BW_Network_instance.sendPacketToAllPlayersInRange(
+ this.getBaseMetaTileEntity()
+ .getWorld(),
+ new RendererPacket(
+ new Coords(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord(),
+ this.getBaseMetaTileEntity()
+ .getWorld().provider.dimensionId),
+ lCulture == null ? BioCulture.NULLCULTURE.getColorRGB() : lCulture.getColorRGB(),
+ false),
+ this.getBaseMetaTileEntity()
+ .getXCoord(),
+ this.getBaseMetaTileEntity()
+ .getZCoord());
+ }
+ this.needsVisualUpdate = true;
+ }
+
+ private void check_Chunk() {
+ World aWorld = this.getBaseMetaTileEntity()
+ .getWorld();
+ if (!aWorld.isRemote) {
+
+ for (Object tObject : aWorld.playerEntities) {
+ if (!(tObject instanceof EntityPlayerMP tPlayer)) {
+ break;
+ }
+ Chunk tChunk = aWorld.getChunkFromBlockCoords(
+ this.getBaseMetaTileEntity()
+ .getXCoord(),
+ this.getBaseMetaTileEntity()
+ .getZCoord());
+ if (tPlayer.getServerForPlayer()
+ .getPlayerManager()
+ .isPlayerWatchingChunk(tPlayer, tChunk.xPosition, tChunk.zPosition)) {
+ if (!this.playerMPHashSet.contains(tPlayer)) {
+ this.playerMPHashSet.add(tPlayer);
+ this.sendAllRequiredRendererPackets();
+ }
+ } else {
+ this.playerMPHashSet.remove(tPlayer);
+ }
+ }
+ }
+ }
+
+ private void placeFluid() {
+ this.isVisibleFluid = true;
+ int xDir = this.getXDir();
+ int zDir = this.getZDir();
+ this.height = this.reCalculateHeight();
+ if (this.mFluid != null && this.height > 1 && this.reCalculateFluidAmmount() > 0) for (int x = -1; x < 2; x++) {
+ for (int y = 0; y < this.height; y++) {
+ for (int z = -1; z < 2; z++) {
+ if (this.getBaseMetaTileEntity()
+ .getWorld()
+ .getBlock(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord())
+ .equals(Blocks.air))
+ this.getBaseMetaTileEntity()
+ .getWorld()
+ .setBlock(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord(),
+ FluidLoader.bioFluidBlock);
+ }
+ }
+ }
+ }
+
+ private void removeFluid(int xDir, int zDir) {
+ this.isVisibleFluid = false;
+
+ for (int x = -1; x < 2; x++) {
+ for (int y = 1; y < 3; y++) {
+ for (int z = -1; z < 2; z++) {
+ if (this.getBaseMetaTileEntity()
+ .getWorld()
+ .getBlock(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord())
+ .equals(FluidLoader.bioFluidBlock))
+ this.getBaseMetaTileEntity()
+ .getWorld()
+ .setBlockToAir(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord());
+ MTEBioVat.staticColorMap.remove(
+ new Coords(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord()),
+ this.getBaseMetaTileEntity()
+ .getWorld().provider.dimensionId);
+ }
+ }
+ }
+ }
+
+ private int reCalculateFluidAmmount() {
+ return this.getStoredFluids()
+ .stream()
+ .mapToInt(fluidStack -> fluidStack.amount)
+ .sum();
+ }
+
+ private int reCalculateHeight() {
+ return this.reCalculateFluidAmmount() > this.getCapacity() / 4 - 1
+ ? this.reCalculateFluidAmmount() >= this.getCapacity() / 2 ? 3 : 2
+ : 1;
+ }
+
+ public void doAllVisualThings() {
+ if (this.getBaseMetaTileEntity()
+ .isServerSide()) {
+ if (this.mMachine) {
+ ItemStack aStack = this.mInventory[1];
+ BioCulture lCulture = null;
+ int xDir = this.getXDir();
+ int zDir = this.getZDir();
+
+ if (this.getBaseMetaTileEntity()
+ .getTimer() % 200 == 0) {
+ this.check_Chunk();
+ }
+
+ if (this.needsVisualUpdate && this.getBaseMetaTileEntity()
+ .getTimer() % MTEBioVat.TIMERDIVIDER == 0) {
+ for (int x = -1; x < 2; x++)
+ for (int y = 1; y < 3; y++) for (int z = -1; z < 2; z++) this.getBaseMetaTileEntity()
+ .getWorld()
+ .setBlockToAir(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord());
+ }
+
+ this.height = this.reCalculateHeight();
+ if (this.mFluid != null && this.height > 1 && this.reCalculateFluidAmmount() > 0) {
+ if (!BWUtil.areStacksEqualOrNull(aStack, this.mStack)
+ || this.needsVisualUpdate && this.getBaseMetaTileEntity()
+ .getTimer() % MTEBioVat.TIMERDIVIDER == 1) {
+ for (int x = -1; x < 2; x++) {
+ for (int y = 1; y < this.height; y++) {
+ for (int z = -1; z < 2; z++) {
+ if (aStack == null
+ || aStack.getItem() instanceof ItemLabParts && aStack.getItemDamage() == 0) {
+ if (this.mCulture == null || aStack == null
+ || aStack.getTagCompound() == null
+ || this.mCulture.getID() != aStack.getTagCompound()
+ .getInteger("ID")) {
+ lCulture = aStack == null || aStack.getTagCompound() == null ? null
+ : BioCulture.getBioCulture(
+ aStack.getTagCompound()
+ .getString("Name"));
+ this.sendPackagesOrRenewRenderer(x, y, z, lCulture);
+ }
+ }
+ }
+ }
+ }
+ this.mStack = aStack;
+ this.mCulture = lCulture;
+ }
+ if (this.needsVisualUpdate && this.getBaseMetaTileEntity()
+ .getTimer() % MTEBioVat.TIMERDIVIDER == 1) {
+ if (this.getBaseMetaTileEntity()
+ .isClientSide()) new Throwable().printStackTrace();
+ this.placeFluid();
+ this.needsVisualUpdate = false;
+ }
+ }
+ } else {
+ this.onRemoval();
+ }
+ }
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+ if (this.height != this.reCalculateHeight()) this.needsVisualUpdate = true;
+ this.doAllVisualThings();
+ if (this.getBaseMetaTileEntity()
+ .isServerSide() && this.mRadHatches.size() == 1) {
+ this.mSievert = this.mRadHatches.get(0)
+ .getSievert();
+ if (this.getBaseMetaTileEntity()
+ .isActive() && this.mNeededSievert > this.mSievert) this.mOutputFluids = null;
+ }
+ if (aBaseMetaTileEntity.isServerSide() && this.mMaxProgresstime <= 0) {
+ this.mTimes = 0;
+ this.mMaxProgresstime = 0;
+ }
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ aNBT.setInteger("mFluidHeight", this.height);
+ if (this.mCulture != null && !this.mCulture.getName()
+ .isEmpty()) aNBT.setString("mCulture", this.mCulture.getName());
+ else if ((this.mCulture == null || this.mCulture.getName()
+ .isEmpty()) && !aNBT.getString("mCulture")
+ .isEmpty()) {
+ aNBT.removeTag("mCulture");
+ }
+ if (this.mFluid != null) aNBT.setString("mFluid", this.mFluid.getName());
+ aNBT.setInteger("mSievert", this.mSievert);
+ aNBT.setInteger("mNeededSievert", this.mNeededSievert);
+ aNBT.setBoolean("isVisibleFluid", this.isVisibleFluid);
+ super.saveNBTData(aNBT);
+ }
+
+ @Override
+ public void onRemoval() {
+ if (this.isVisibleFluid) {
+ int xDir = this.getXDir();
+ int zDir = this.getZDir();
+ this.removeFluid(xDir, zDir);
+ this.sendRenderPackets(xDir, zDir);
+ } else if (this.getBaseMetaTileEntity()
+ .getWorld()
+ .getWorldTime() % 20 == 7) {
+ this.sendRenderPackets();
+ }
+
+ super.onRemoval();
+ }
+
+ private int getXDir() {
+ return this.getBaseMetaTileEntity()
+ .getBackFacing().offsetX * 2;
+ }
+
+ private int getZDir() {
+ return this.getBaseMetaTileEntity()
+ .getBackFacing().offsetZ * 2;
+ }
+
+ private void sendRenderPackets() {
+ int xDir = this.getXDir();
+ int zDir = this.getZDir();
+ this.sendRenderPackets(xDir, zDir);
+ }
+
+ private void sendRenderPackets(int xDir, int zDir) {
+ if (SideReference.Side.Server) {
+ for (int x = -1; x < 2; x++) {
+ for (int y = 1; y < 3; y++) {
+ for (int z = -1; z < 2; z++) {
+ MainMod.BW_Network_instance.sendPacketToAllPlayersInRange(
+ this.getBaseMetaTileEntity()
+ .getWorld(),
+ new RendererPacket(
+ new Coords(
+ xDir + x
+ + this.getBaseMetaTileEntity()
+ .getXCoord(),
+ y + this.getBaseMetaTileEntity()
+ .getYCoord(),
+ zDir + z
+ + this.getBaseMetaTileEntity()
+ .getZCoord(),
+ this.getBaseMetaTileEntity()
+ .getWorld().provider.dimensionId),
+ this.mCulture == null ? BioCulture.NULLCULTURE.getColorRGB()
+ : this.mCulture.getColorRGB(),
+ true),
+ this.getBaseMetaTileEntity()
+ .getXCoord(),
+ this.getBaseMetaTileEntity()
+ .getZCoord());
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ this.height = aNBT.getInteger("mFluidHeight");
+ this.mCulture = BioCulture.getBioCulture(aNBT.getString("mCulture"));
+ if (!aNBT.getString("mFluid")
+ .isEmpty()) this.mFluid = FluidRegistry.getFluid(aNBT.getString("mFluid"));
+ this.mSievert = aNBT.getInteger("mSievert");
+ this.mNeededSievert = aNBT.getInteger("mNeededSievert");
+ super.loadNBTData(aNBT);
+ this.isVisibleFluid = aNBT.getBoolean("isVisibleFluid");
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEBioVat(this.mName);
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) };
+ }
+
+ @Override
+ public void construct(ItemStack itemStack, boolean b) {
+ this.buildPiece(STRUCTURE_PIECE_MAIN, itemStack, b, 2, 3, 0);
+ }
+
+ @Override
+ public String[] getInfoData() {
+ final String[] baseInfoData = super.getInfoData();
+ final String[] infoData = new String[baseInfoData.length + 2];
+ System.arraycopy(baseInfoData, 0, infoData, 0, baseInfoData.length);
+ // See https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/11923
+ // here we must check the machine is well-formed as otherwise getExpectedMultiplier might error out!
+ infoData[infoData.length - 2] = StatCollector.translateToLocal("BW.infoData.BioVat.expectedProduction") + ": "
+ + EnumChatFormatting.GREEN
+ + (this.mMachine
+ ? (this.mMaxProgresstime <= 0 ? this.getExpectedMultiplier(null, false) : this.mExpectedMultiplier)
+ * 100
+ : -1)
+ + EnumChatFormatting.RESET
+ + " %";
+ infoData[infoData.length - 1] = StatCollector.translateToLocal("BW.infoData.BioVat.production") + ": "
+ + EnumChatFormatting.GREEN
+ + (this.mMaxProgresstime <= 0 ? 0 : this.mTimes) * 100
+ + EnumChatFormatting.RESET
+ + " %";
+ return infoData;
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (aPlayer.isSneaking()) {
+ batchMode = !batchMode;
+ if (batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTECircuitAssemblyLine.java b/src/main/java/bartworks/common/tileentities/multis/MTECircuitAssemblyLine.java
new file mode 100644
index 0000000000..80f851167d
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTECircuitAssemblyLine.java
@@ -0,0 +1,672 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS;
+import static bartworks.util.BWUtil.ofGlassTieredMixed;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.*;
+import static gregtech.api.enums.HatchElement.Energy;
+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.OutputBus;
+import static gregtech.api.enums.SoundResource.IC2_MACHINES_MAGNETIZER_LOOP;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE_GLOW;
+import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+import static gregtech.api.util.GTUtility.filterValidMTEs;
+import static gregtech.api.util.GTUtility.getColoredTierNameFromTier;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+
+import bartworks.API.modularUI.BWUITextures;
+import bartworks.API.recipe.BartWorksRecipeMaps;
+import bartworks.system.material.CircuitGeneration.BWMetaItems;
+import bartworks.system.material.CircuitGeneration.CircuitImprintLoader;
+import bartworks.util.BWTooltipReference;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.SoundResource;
+import gregtech.api.enums.Textures;
+import gregtech.api.gui.modularui.GTUITextures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.metatileentity.implementations.MTEHatchInputBus;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.RecipeMaps;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+import gregtech.api.recipe.check.SimpleCheckRecipeResult;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTLanguageManager;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
+public class MTECircuitAssemblyLine extends MTEEnhancedMultiBlockBase<MTECircuitAssemblyLine>
+ implements ISurvivalConstructable {
+
+ private static final int CASING_INDEX = 16;
+
+ private static final String STRUCTURE_PIECE_FIRST = "first";
+ private static final String STRUCTURE_PIECE_NEXT = "next";
+ private static final String STRUCTURE_PIECE_NEXT_HINT = "next_hint";
+ private static final String STRUCTURE_PIECE_LAST = "last";
+
+ private static final int MINIMUM_CIRCUIT_ASSEMBLER_LENGTH = 5;
+ protected static final String IMPRINT_KEY = "Type";
+ protected static final String LENGTH_KEY = "Length";
+ protected static final String RUNNING_MODE_KEY = "RunningMode";
+
+ private int length;
+ private int mode;
+ private String imprintedItemName;
+ private ItemStack imprintedStack;
+
+ private static final IStructureDefinition<MTECircuitAssemblyLine> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTECircuitAssemblyLine>builder()
+ .addShape(
+ STRUCTURE_PIECE_FIRST,
+ transpose(new String[][] { { "~", "G", "G" }, { "g", "l", "g" }, { "b", "i", "b" }, }))
+ .addShape(
+ STRUCTURE_PIECE_NEXT,
+ transpose(new String[][] { { "G", "G", "G" }, { "g", "l", "g" }, { "b", "I", "b" }, }))
+ .addShape(
+ STRUCTURE_PIECE_NEXT_HINT,
+ transpose(new String[][] { { "G", "G", "G" }, { "g", "l", "g" }, { "b", "i", "b" }, }))
+ .addShape(
+ STRUCTURE_PIECE_LAST,
+ transpose(new String[][] { { "G", "G", "G" }, { "g", "l", "g" }, { "b", "o", "b" }, }))
+ .addElement(
+ 'G',
+ buildHatchAdder(MTECircuitAssemblyLine.class).atLeast(Energy)
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(GregTechAPI.sBlockCasings3, 10))
+ .addElement('g', ofGlassTieredMixed((byte) 4, (byte) 127, 5))
+ .addElement('l', ofBlock(GregTechAPI.sBlockCasings2, 5)) // assembling line casings
+ .addElement(
+ 'b',
+ buildHatchAdder(MTECircuitAssemblyLine.class).atLeast(InputHatch, Maintenance)
+ .casingIndex(CASING_INDEX)
+ .dot(2)
+ .disallowOnly(ForgeDirection.EAST, ForgeDirection.WEST)
+ .buildAndChain(GregTechAPI.sBlockCasings2, 0))
+ .addElement('i', InputBus.newAny(CASING_INDEX, 3, ForgeDirection.DOWN))
+ .addElement(
+ 'I',
+ buildHatchAdder(MTECircuitAssemblyLine.class).atLeast(InputHatch, InputBus, OutputBus)
+ .casingIndex(CASING_INDEX)
+ .dot(2)
+ .disallowOnly(ForgeDirection.EAST, ForgeDirection.WEST)
+ .buildAndChain(GregTechAPI.sBlockCasings2, 0))
+ .addElement('o', OutputBus.newAny(CASING_INDEX, 2, ForgeDirection.DOWN))
+ .build();
+
+ @Override
+ public IStructureDefinition<MTECircuitAssemblyLine> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Circuit Assembler/Circuit Assembly Line")
+ .addInfo("Controller block for the Circuit Assembly Line")
+ .addInfo("Change Mode with Screwdriver")
+ .addInfo("Does not lose efficiency when overclocked")
+ .addInfo(
+ "--------- " + EnumChatFormatting.GOLD
+ + StatCollector.translateToLocal("chat.cal.mode.0")
+ + EnumChatFormatting.GRAY
+ + " --------")
+ .addInfo("Imprint this machine with a Circuit Imprint,")
+ .addInfo("by putting the imprint in the controller")
+ .addInfo("Every Circuit Assembly Line can only be imprinted ONCE")
+ .addInfo(
+ "--------- " + EnumChatFormatting.GOLD
+ + StatCollector.translateToLocal("chat.cal.mode.1")
+ + EnumChatFormatting.GRAY
+ + " --------")
+ .addInfo(
+ "Does Circuit Assembler recipes, Minimum Length: " + EnumChatFormatting.RED
+ + MINIMUM_CIRCUIT_ASSEMBLER_LENGTH
+ + EnumChatFormatting.GRAY)
+ .addInfo("Recipe tier in Circuit Assembler mode is at most Energy Hatch tier - 1.")
+ .addInfo("This mode supports Crafting Input Buffer/Bus and allows bus separation")
+ .addInfo("")
+ .addSeparator()
+ .addInfo(BWTooltipReference.TT_BLUEPRINT)
+ .beginVariableStructureBlock(2, 7, 3, 3, 3, 3, false)
+ .addStructureInfo("From Bottom to Top, Left to Right")
+ .addStructureInfo(
+ "Layer 1 - Solid Steel Machine Casing, Input bus (Last Output bus), Solid Steel Machine Casing")
+ .addStructureInfo(
+ "Layer 2 - " + getColoredTierNameFromTier((byte) 4)
+ + "+ Tier Glass, Assembling Line Casing, "
+ + getColoredTierNameFromTier((byte) 4)
+ + "+ Tier Glass")
+ .addStructureInfo("Layer 3 - Grate Machine Casing")
+ .addStructureInfo("Up to 7 repeating slices, last is Output Bus")
+ .addController("Layer 3 first slice front")
+ .addOtherStructurePart(
+ "1x " + StatCollector.translateToLocal("GT5U.MBTT.EnergyHatch"),
+ "Any layer 3 casing",
+ 1)
+ .addInputHatch("Any layer 1 casing", 2)
+ .addInputBus("As specified on layer 1", 3, 4)
+ .addOutputBus("As specified in final slice on layer 1", 4)
+ .addOtherStructurePart(getColoredTierNameFromTier((byte) 4) + "+ Tier Glass", "As specified on layer 2", 5)
+ .addMaintenanceHatch("Any layer 1 casing", 2)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS);
+ return tt;
+ }
+
+ public String getTypeForDisplay() {
+
+ if (!isImprinted()) return "";
+ return GTLanguageManager.getTranslation(
+ GTLanguageManager.getTranslateableItemStackName(CircuitImprintLoader.getStackFromTag(this.type)));
+ }
+
+ private NBTTagCompound type = new NBTTagCompound();
+
+ public MTECircuitAssemblyLine(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ private MTECircuitAssemblyLine(String aName) {
+ super(aName);
+ }
+
+ public boolean isImprinted() {
+ return !this.type.hasNoTags();
+ }
+
+ private boolean imprintMachine(ItemStack itemStack) {
+ if (isImprinted()) return true;
+ if (!GTUtility.isStackValid(itemStack)) return false;
+ if (itemStack.getItem() instanceof BWMetaItems.BW_GT_MetaGenCircuits && itemStack.getItemDamage() == 0
+ && itemStack.getTagCompound() != null) {
+ this.type = itemStack.getTagCompound();
+ itemStack.stackSize -= 1;
+ if (itemStack == getControllerSlot() && itemStack.stackSize <= 0) {
+ mInventory[getControllerSlotIndex()] = null;
+ }
+ this.getBaseMetaTileEntity()
+ .issueBlockUpdate();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) {
+ super.startSoundLoop(aIndex, aX, aY, aZ);
+ if (aIndex == 20) {
+ GTUtility.doSoundAtClient(IC2_MACHINES_MAGNETIZER_LOOP, 10, 1.0F, aX, aY, aZ);
+ }
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ this.type = aNBT.getCompoundTag(IMPRINT_KEY);
+ this.imprintedItemName = this.type == null ? ""
+ : GTLanguageManager.getTranslateableItemStackName(ItemStack.loadItemStackFromNBT(this.type));
+ mode = aNBT.getInteger(RUNNING_MODE_KEY);
+ if (aNBT.hasKey(LENGTH_KEY)) {
+ length = aNBT.getInteger(LENGTH_KEY);
+ }
+ super.loadNBTData(aNBT);
+ }
+
+ @Override
+ public void setItemNBT(NBTTagCompound aNBT) {
+ if (isImprinted()) aNBT.setTag(IMPRINT_KEY, this.type);
+ aNBT.setInteger(RUNNING_MODE_KEY, mode);
+ super.saveNBTData(aNBT);
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ if (isImprinted()) aNBT.setTag(IMPRINT_KEY, this.type);
+ aNBT.setInteger(RUNNING_MODE_KEY, mode);
+ aNBT.setInteger(LENGTH_KEY, length);
+ super.saveNBTData(aNBT);
+ }
+
+ @Override
+ public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
+ if (mode == 0 && !isImprinted() && getBaseMetaTileEntity().isServerSide()) {
+ ItemStack heldItem = aPlayer.getHeldItem();
+ if (imprintMachine(heldItem)) {
+ if (heldItem.stackSize <= 0) {
+ aPlayer.inventory.setInventorySlotContents(aPlayer.inventory.currentItem, null);
+ }
+ return;
+ }
+ }
+ super.onLeftclick(aBaseMetaTileEntity, aPlayer);
+ }
+
+ @Override
+ public final void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (getBaseMetaTileEntity().isServerSide()) {
+ this.mode = (this.mode + 1) % 2;
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("chat.cal.mode." + this.mode));
+ }
+ super.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ);
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ if (this.mode == 0) return BartWorksRecipeMaps.circuitAssemblyLineRecipes;
+ return RecipeMaps.circuitAssemblerRecipes;
+ }
+
+ @Nonnull
+ @Override
+ public Collection<RecipeMap<?>> getAvailableRecipeMaps() {
+ return Arrays.asList(BartWorksRecipeMaps.circuitAssemblyLineRecipes, RecipeMaps.circuitAssemblerRecipes);
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic() {
+
+ @Override
+ @Nonnull
+ protected CheckRecipeResult validateRecipe(@Nonnull GTRecipe recipe) {
+ // limit CA mode recipes to hatch tier - 1
+ if (MTECircuitAssemblyLine.this.mode == 1
+ && recipe.mEUt > MTECircuitAssemblyLine.this.getMaxInputVoltage() / 4) {
+ return CheckRecipeResultRegistry.NO_RECIPE;
+ }
+ return CheckRecipeResultRegistry.SUCCESSFUL;
+ }
+ }.enablePerfectOverclock();
+ }
+
+ @NotNull
+ @Override
+ public CheckRecipeResult checkProcessing() {
+ if (mode == 0) {
+ if (!isImprinted() && !this.imprintMachine(this.getControllerSlot()))
+ return SimpleCheckRecipeResult.ofFailure("no_imprint");
+ if (this.imprintedItemName == null || this.imprintedStack == null) {
+ this.imprintedStack = new ItemStack(BWMetaItems.getCircuitParts(), 1, 0);
+ this.imprintedStack.setTagCompound(this.type);
+ this.imprintedItemName = GTLanguageManager.getTranslateableItemStackName(this.imprintedStack);
+ }
+ } else if (length < MINIMUM_CIRCUIT_ASSEMBLER_LENGTH) {
+ return SimpleCheckRecipeResult.ofFailure("not_enough_length");
+ }
+
+ return super.checkProcessing();
+ }
+
+ @Override
+ protected void setupProcessingLogic(ProcessingLogic logic) {
+ super.setupProcessingLogic(logic);
+ logic.setSpecialSlotItem(this.imprintedStack);
+ }
+
+ @Override
+ protected SoundResource getProcessStartSound() {
+ return SoundResource.IC2_MACHINES_MAGNETIZER_LOOP;
+ }
+
+ @Override
+ public ArrayList<ItemStack> getStoredInputs() {
+ if (mode == 0) {
+ ArrayList<ItemStack> rList = new ArrayList<>();
+ for (MTEHatchInputBus tHatch : filterValidMTEs(mInputBusses)) {
+ tHatch.mRecipeMap = this.getRecipeMap();
+ for (int i = 0; i < tHatch.getBaseMetaTileEntity()
+ .getSizeInventory(); i++) {
+ if (tHatch.getBaseMetaTileEntity()
+ .getStackInSlot(i) != null) {
+ rList.add(
+ tHatch.getBaseMetaTileEntity()
+ .getStackInSlot(i));
+ break;
+ }
+ }
+ }
+ return rList;
+ }
+
+ return super.getStoredInputs();
+ }
+
+ @Override
+ public boolean addInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity instanceof MTEHatchInput) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ ((MTEHatchInput) aMetaTileEntity).mRecipeMap = this.getRecipeMap();
+ return this.mInputHatches.add((MTEHatchInput) aMetaTileEntity);
+ } else if (aMetaTileEntity instanceof MTEHatchInputBus) {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ ((MTEHatchInputBus) aMetaTileEntity).mRecipeMap = this.getRecipeMap();
+ return this.mInputBusses.add((MTEHatchInputBus) aMetaTileEntity);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean addInputHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null || !(aMetaTileEntity instanceof MTEHatchInput)) {
+ return false;
+ } else {
+ ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex);
+ ((MTEHatchInput) aMetaTileEntity).mRecipeMap = this.getRecipeMap();
+ return this.mInputHatches.add((MTEHatchInput) aMetaTileEntity);
+ }
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTECircuitAssemblyLine(this.mName);
+ }
+
+ private String[] infoDataBuffer;
+
+ @Override
+ public String[] getInfoData() {
+ if (this.infoDataBuffer != null) return this.infoDataBuffer;
+
+ String[] oldInfo = super.getInfoData();
+ this.infoDataBuffer = new String[oldInfo.length + 1];
+ System.arraycopy(oldInfo, 0, this.infoDataBuffer, 0, oldInfo.length);
+ this.infoDataBuffer[oldInfo.length] = StatCollector.translateToLocal("tooltip.cal.imprintedWith") + " "
+ + EnumChatFormatting.YELLOW
+ + this.getTypeForDisplay();
+ return this.infoDataBuffer;
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) };
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ if (!this.checkPiece(STRUCTURE_PIECE_FIRST, 0, 0, 0)) {
+ return false;
+ }
+ return this.checkMachine(true) || this.checkMachine(false);
+ }
+
+ private boolean checkMachine(boolean leftToRight) {
+
+ for (int i = 1; i < 7; ++i) {
+ if (!this.checkPiece(STRUCTURE_PIECE_NEXT, leftToRight ? -i : i, 0, 0)) {
+ return false;
+ }
+ length = i + 1;
+
+ if (!this.mOutputBusses.isEmpty()) {
+ return this.mEnergyHatches.size() == 1 && this.mMaintenanceHatches.size() == 1;
+ }
+ }
+
+ return false;
+ }
+
+ public void construct(ItemStack stackSize, boolean hintsOnly) {
+ this.buildPiece(STRUCTURE_PIECE_FIRST, stackSize, hintsOnly, 0, 0, 0);
+ int tLength = Math.min(stackSize.stackSize + 1, 7);
+
+ for (int i = 1; i < tLength; ++i) {
+ this.buildPiece(STRUCTURE_PIECE_NEXT, stackSize, hintsOnly, -i, 0, 0);
+ }
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) {
+ if (this.mMachine) return -1;
+ int built;
+ built = survivialBuildPiece(STRUCTURE_PIECE_FIRST, stackSize, 0, 0, 0, elementBudget, env, false, true);
+ if (built >= 0) return built;
+ int tLength = Math.min(stackSize.stackSize + 1, 7);
+
+ for (int i = 1; i < tLength - 1; ++i) {
+ built = survivialBuildPiece(
+ STRUCTURE_PIECE_NEXT_HINT,
+ stackSize,
+ -i,
+ 0,
+ 0,
+ elementBudget,
+ env,
+ false,
+ true);
+ if (built >= 0) return built;
+ }
+ return survivialBuildPiece(
+ STRUCTURE_PIECE_LAST,
+ stackSize,
+ -(tLength - 1),
+ 0,
+ 0,
+ elementBudget,
+ env,
+ false,
+ true);
+ }
+
+ @Override
+ public void addAdditionalTooltipInformation(ItemStack stack, List<String> tooltip) {
+ if (stack.hasTagCompound() && stack.stackTagCompound.hasKey(IMPRINT_KEY)) {
+ tooltip.add(
+ StatCollector.translateToLocal("tooltip.cal.imprintedWith") + " "
+ + EnumChatFormatting.YELLOW
+ + StatCollector.translateToLocal(
+ GTLanguageManager.getTranslateableItemStackName(
+ ItemStack.loadItemStackFromNBT(stack.stackTagCompound.getCompoundTag("Type")))));
+ }
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ super.addUIWidgets(builder, buildContext);
+ builder
+ .widget(new FakeSyncWidget.StringSyncer(() -> this.imprintedItemName, val -> this.imprintedItemName = val));
+ builder.widget(
+ new CycleButtonWidget().setToggle(() -> mode == 1, val -> mode = val ? 1 : 0)
+ .setTextureGetter(
+ state -> state == 1 ? BWUITextures.OVERLAY_BUTTON_ASSEMBLER_MODE
+ : BWUITextures.OVERLAY_BUTTON_LINE_MODE)
+ .setBackground(GTUITextures.BUTTON_STANDARD)
+ .setPos(80, 91)
+ .setSize(16, 16)
+ .dynamicTooltip(
+ () -> Collections.singletonList(StatCollector.translateToLocal("chat.cal.mode." + mode)))
+ .setUpdateTooltipEveryTick(true)
+ .setTooltipShowUpDelay(TOOLTIP_DELAY));
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ protected boolean supportsSlotAutomation(int aSlot) {
+ return aSlot == getControllerSlotIndex();
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (!aPlayer.isSneaking()) {
+ if (mode == 0) return false;
+ inputSeparation = !inputSeparation;
+ GTUtility.sendChatToPlayer(
+ aPlayer,
+ StatCollector.translateToLocal("GT5U.machines.separatebus") + " " + inputSeparation);
+ return true;
+ } else {
+ batchMode = !batchMode;
+ if (batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+ }
+
+ @Override
+ public boolean supportsInputSeparation() {
+ return mode != 0;
+ }
+
+ @Override
+ public boolean supportsSingleRecipeLocking() {
+ return true;
+ }
+
+ @Override
+ public boolean isInputSeparationEnabled() {
+ return mode == 1 && super.isInputSeparationEnabled();
+ }
+
+ @Override
+ public void getWailaBody(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor,
+ IWailaConfigHandler config) {
+ super.getWailaBody(itemStack, currenttip, accessor, config);
+ NBTTagCompound tag = accessor.getNBTData();
+ currenttip.add(
+ StatCollector.translateToLocal("GT5U.machines.oreprocessor1") + " "
+ + EnumChatFormatting.WHITE
+ + StatCollector.translateToLocal("chat.cal.mode." + tag.getInteger(RUNNING_MODE_KEY)));
+ if (tag.hasKey("ImprintedWith") && tag.getInteger(RUNNING_MODE_KEY) == 0) currenttip.add(
+ StatCollector.translateToLocal("tooltip.cal.imprintedWith") + " "
+ + EnumChatFormatting.YELLOW
+ + tag.getString("ImprintedWith"));
+ }
+
+ @Override
+ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y,
+ int z) {
+ super.getWailaNBTData(player, tile, tag, world, x, y, z);
+ String imprintedWith = this.getTypeForDisplay();
+ if (!imprintedWith.isEmpty()) tag.setString("ImprintedWith", imprintedWith);
+ tag.setInteger(RUNNING_MODE_KEY, mode);
+ }
+
+ @Override
+ protected boolean supportsCraftingMEBuffer() {
+ return mode != 0;
+ }
+
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEDeepEarthHeatingPump.java b/src/main/java/bartworks/common/tileentities/multis/MTEDeepEarthHeatingPump.java
new file mode 100644
index 0000000000..fca10c20fd
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTEDeepEarthHeatingPump.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS;
+import static gregtech.api.enums.GTValues.VN;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidRegistry;
+
+import bartworks.common.configs.ConfigHandler;
+import gregtech.api.enums.GTValues;
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Materials;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.util.GTModHandler;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.common.tileentities.machines.multi.MTEDrillerBase;
+import ic2.core.block.reactor.tileentity.TileEntityNuclearReactorElectric;
+
+public class MTEDeepEarthHeatingPump extends MTEDrillerBase {
+
+ private static float nulearHeatMod = 2f;
+ private byte mMode;
+ private byte mTier;
+
+ public MTEDeepEarthHeatingPump(int aID, int tier, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ this.mTier = (byte) tier;
+ }
+
+ public MTEDeepEarthHeatingPump(String aName, byte mTier) {
+ super(aName);
+ this.mTier = mTier;
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public void onConfigLoad() {
+ try {
+ Class c = TileEntityNuclearReactorElectric.class;
+ Field f = c.getDeclaredField("huOutputModifier");
+ f.setAccessible(true);
+ MTEDeepEarthHeatingPump.nulearHeatMod = f.getFloat(f);
+ } catch (SecurityException | IllegalArgumentException | ExceptionInInitializerError | NullPointerException
+ | IllegalAccessException | NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ super.onConfigLoad();
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ aNBT.setByte("mTier", this.mTier);
+ aNBT.setByte("mMode", this.mMode);
+ super.saveNBTData(aNBT);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ this.mTier = aNBT.getByte("mTier");
+ this.mMode = aNBT.getByte("mMode");
+ super.loadNBTData(aNBT);
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEDeepEarthHeatingPump(this.mName, this.mTier);
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ String casings = this.getCasingBlockItem()
+ .get(0)
+ .getDisplayName();
+ tt.addMachineType("Geothermal Heat Pump")
+ .addInfo("Consumes " + GTValues.V[this.mTier + 2] + "EU/t")
+ .addInfo("Has 4 Modes, use the Screwdriver to change them:");
+ if (ConfigHandler.DEHPDirectSteam) {
+ tt.addInfo("0 Idle, 1 Steam, 2 Superheated Steam (requires Distilled Water), 3 Retract")
+ .addInfo("Explodes when it runs out of Water/Distilled Water")
+ .addInfo(
+ "Converts " + (long) (this.mTier * 1200 * 20)
+ + "L/s Water(minus 10% per Maintenance Problem) to Steam")
+ .addInfo(
+ "Converts " + (long) (this.mTier * 600 * 20)
+ + "L/s Distilled Water(minus 10% per Maintenance Problem) to SuperheatedSteam");
+
+ } else {
+ tt.addInfo("0 Idle, 1 & 2 Coolant Heating Mode (no Difference between them), 3 Retract")
+ .addInfo("Explodes when it runs out of Coolant")
+ .addInfo(
+ "Heats up " + (long) (this.mTier * 24 * (double) MTEDeepEarthHeatingPump.nulearHeatMod) * 20
+ + "L/s Coolant(minus 10% per Maintenance Problem)");
+ }
+ tt.addSeparator()
+ .beginStructureBlock(3, 7, 3, false)
+ .addController("Front bottom")
+ .addOtherStructurePart(casings, "form the 3x1x3 Base")
+ .addOtherStructurePart(casings, "1x3x1 pillar above the center of the base (2 minimum total)")
+ .addOtherStructurePart(
+ this.getFrameMaterial().mName + " Frame Boxes",
+ "Each pillar's side and 1x3x1 on top")
+ .addEnergyHatch(VN[this.getMinTier()] + "+, Any base casing")
+ .addMaintenanceHatch("Any base casing")
+ .addInputBus("Mining Pipes, optional, any base casing")
+ .addInputHatch("Any base casing")
+ .addOutputHatch("Any base casing")
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ protected ItemList getCasingBlockItem() {
+ return ItemList.Casing_HeatProof;
+ }
+
+ @Override
+ protected Materials getFrameMaterial() {
+ return Materials.Tungsten;
+ }
+
+ @Override
+ protected int getCasingTextureIndex() {
+ return 11;
+ }
+
+ @Override
+ protected int getMinTier() {
+ return 2 + this.mTier;
+ }
+
+ @Override
+ protected boolean checkHatches() {
+ return !this.mMaintenanceHatches.isEmpty() && !this.mOutputHatches.isEmpty() && !this.mInputHatches.isEmpty();
+ }
+
+ private long getFluidFromHatches(Fluid f) {
+ long ret = 0;
+ for (MTEHatchInput ih : this.mInputHatches) {
+ if (ih.getFluid()
+ .getFluid()
+ .equals(f)) ret += ih.getFluidAmount();
+ }
+ return ret;
+ }
+
+ private long getWaterFromHatches(boolean onlyDistilled) {
+ Fluid toConsume1 = FluidRegistry.WATER;
+ Fluid toConsume2 = GTModHandler.getDistilledWater(1L)
+ .getFluid();
+ if (onlyDistilled) toConsume1 = toConsume2;
+ long ret = 0;
+ for (MTEHatchInput ih : this.mInputHatches) {
+ if (ih.getFluid()
+ .getFluid()
+ .equals(toConsume1)
+ || ih.getFluid()
+ .getFluid()
+ .equals(toConsume2))
+ ret += ih.getFluidAmount();
+ }
+ return ret;
+ }
+
+ @Override
+ protected boolean workingUpward(ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, int zPipe,
+ int yHead, int oldYHead) {
+ if (this.mMode != 3) {
+ this.isPickingPipes = false;
+ try {
+ Field workState = this.getClass()
+ .getField("workState");
+ workState.setInt(this, 0);
+ } catch (NoSuchFieldError | NoSuchFieldException | IllegalAccessException ignored) {}
+ return true;
+ }
+ return super.workingUpward(aStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead);
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (this.getBaseMetaTileEntity()
+ .getWorld().isRemote) return;
+ ++this.mMode;
+ if (this.mMode >= 4) this.mMode = 0;
+ GTUtility.sendChatToPlayer(aPlayer, "Mode: " + this.mMode);
+ super.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ);
+ }
+
+ @Override
+ protected boolean workingDownward(ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, int zPipe,
+ int yHead, int oldYHead) {
+ if (this.mMode == 3) {
+ this.isPickingPipes = true;
+ try {
+ Field workState = this.getClass()
+ .getSuperclass()
+ .getDeclaredField("workState");
+ workState.setInt(this, 2);
+ } catch (NoSuchFieldError | NoSuchFieldException | IllegalAccessException ignored) {}
+ return true;
+ }
+
+ if (this.tryLowerPipeState(false) == 0) {
+ return true;
+ }
+ if (this.waitForPipes()) {
+ return false;
+ }
+ if (this.mMode == 0) {
+ this.mMode = 1;
+ }
+ if (ConfigHandler.DEHPDirectSteam) {
+ if (this.mMode == 1) {
+ long steamProduced = this.mTier * 600 * 2L * this.mEfficiency / 10000L;
+ long waterConsume = (steamProduced + 160) / 160;
+
+ if (this.getWaterFromHatches(false) - waterConsume > 0) {
+ this.consumeFluid(FluidRegistry.WATER, waterConsume);
+ this.addOutput(GTModHandler.getSteam(steamProduced));
+ } else {
+ this.explodeMultiblock();
+ return false;
+ }
+ } else if (this.mMode == 2) {
+ long steamProduced = this.mTier * 300 * 2L * this.mEfficiency / 10000L;
+ long waterConsume = (steamProduced + 160) / 160;
+
+ if (this.getWaterFromHatches(true) - waterConsume > 0) {
+ this.consumeFluid(
+ GTModHandler.getDistilledWater(1)
+ .getFluid(),
+ waterConsume);
+ this.addOutput(FluidRegistry.getFluidStack("ic2superheatedsteam", (int) steamProduced));
+ } else {
+ this.explodeMultiblock();
+ return false;
+ }
+ }
+ } else if (this.mMode == 1 || this.mMode == 2) {
+ long coolantConverted = (long) (this.mTier * 24
+ * (double) MTEDeepEarthHeatingPump.nulearHeatMod
+ * this.mEfficiency
+ / 10000L);
+ if (this.getFluidFromHatches(FluidRegistry.getFluid("ic2coolant")) - coolantConverted > 0) {
+ this.consumeFluid(FluidRegistry.getFluid("ic2coolant"), coolantConverted);
+ this.addOutput(FluidRegistry.getFluidStack("ic2hotcoolant", (int) coolantConverted));
+ } else {
+ this.explodeMultiblock();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean consumeFluid(Fluid fluid, long ammount) {
+ if (ammount > Integer.MAX_VALUE) {
+ int[] tmp = new int[(int) (ammount / Integer.MAX_VALUE)];
+ Arrays.fill(tmp, (int) (ammount / Integer.MAX_VALUE));
+ for (int i = 0; i < tmp.length; i++) {
+ for (MTEHatchInput ih : this.mInputHatches) {
+ if (fluid.equals(FluidRegistry.WATER) ? ih.getFluid()
+ .getFluid()
+ .equals(fluid)
+ || ih.getFluid()
+ .getFluid()
+ .equals(
+ GTModHandler.getDistilledWater(1)
+ .getFluid())
+ : ih.getFluid()
+ .getFluid()
+ .equals(fluid))
+ tmp[i] -= ih.drain((int) ammount, true).amount;
+ if (tmp[i] <= 0) break;
+ }
+ }
+
+ return tmp[tmp.length - 1] <= 0;
+ }
+
+ long tmp = ammount;
+ for (MTEHatchInput ih : this.mInputHatches) {
+ if (fluid.equals(FluidRegistry.WATER) ? ih.getFluid()
+ .getFluid()
+ .equals(fluid)
+ || ih.getFluid()
+ .getFluid()
+ .equals(
+ GTModHandler.getDistilledWater(1)
+ .getFluid())
+ : ih.getFluid()
+ .getFluid()
+ .equals(fluid))
+ tmp -= ih.drain((int) ammount, true).amount;
+ if (tmp <= 0) return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void setElectricityStats() {
+ try {
+ this.mEUt = this.isPickingPipes ? 60 : Math.toIntExact(GTValues.V[this.getMinTier()]);
+ } catch (ArithmeticException e) {
+ e.printStackTrace();
+ this.mEUt = Integer.MAX_VALUE - 7;
+ }
+ this.mProgresstime = 0;
+ this.mMaxProgresstime = 1;
+ this.mEfficiency = this.getCurrentEfficiency(null);
+ this.mEfficiencyIncrease = 10000;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEElectricImplosionCompressor.java b/src/main/java/bartworks/common/tileentities/multis/MTEElectricImplosionCompressor.java
new file mode 100644
index 0000000000..4b99f97ec5
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTEElectricImplosionCompressor.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.common.loaders.ItemRegistry.BW_BLOCKS;
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static bartworks.util.BWTooltipReference.TT;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.isAir;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.HatchElement.Energy;
+import static gregtech.api.enums.HatchElement.ExoticEnergy;
+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.OutputBus;
+import static gregtech.api.enums.HatchElement.OutputHatch;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR_GLOW;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.ChunkCoordinates;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.jetbrains.annotations.NotNull;
+
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
+import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.IStructureElement;
+import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment;
+import com.gtnewhorizon.structurelib.structure.ITierConverter;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureUtility;
+
+import bartworks.API.recipe.BartWorksRecipeMaps;
+import bartworks.MainMod;
+import bartworks.client.renderer.EICPistonVisualizer;
+import bartworks.common.configs.ConfigHandler;
+import bartworks.common.net.EICPacket;
+import bartworks.util.Coords;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import fox.spiteful.avaritia.blocks.LudicrousBlocks;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.Mods;
+import gregtech.api.enums.SoundResource;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.api.util.OverclockCalculator;
+
+public class MTEElectricImplosionCompressor extends MTEExtendedPowerMultiBlockBase<MTEElectricImplosionCompressor>
+ implements ISurvivalConstructable {
+
+ private static final boolean pistonEnabled = !ConfigHandler.disablePistonInEIC;
+ private Boolean piston = true;
+ private static final SoundResource sound = SoundResource.RANDOM_EXPLODE;
+ private final ArrayList<ChunkCoordinates> chunkCoordinates = new ArrayList<>(5);
+ private int mBlockTier = 0;
+ private int mCasing;
+
+ public MTEElectricImplosionCompressor(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MTEElectricImplosionCompressor(String aName) {
+ super(aName);
+ }
+
+ private static final int CASING_INDEX = 16;
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition<MTEElectricImplosionCompressor> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEElectricImplosionCompressor>builder()
+ .addShape(
+ STRUCTURE_PIECE_MAIN,
+ transpose(
+ new String[][] { { "ccc", "cec", "ccc" }, { "ttt", "tft", "ttt" }, { "ttt", "tft", "ttt" },
+ { "nnn", "nnn", "nnn" }, { "nNn", "NNN", "nNn" }, { "nnn", "nnn", "nnn" }, { "t~t", "tft", "ttt" },
+ { "ttt", "tft", "ttt" }, { "CCC", "CeC", "CCC" }, }))
+ .addElement('c', ofChain(ofBlock(GregTechAPI.sBlockCasings2, 0), ofBlock(GregTechAPI.sBlockCasings3, 4)))
+ .addElement('t', ofBlock(BW_BLOCKS[2], 1))
+ .addElement('f', ofBlock(BW_BLOCKS[2], 0))
+ .addElement(
+ 'n',
+ StructureUtility.ofBlocksTiered(
+ tieredBlockConverter(),
+ getAllBlockTiers(),
+ 0,
+ MTEElectricImplosionCompressor::setBlockTier,
+ MTEElectricImplosionCompressor::getBlockTier))
+ .addElement(
+ 'C',
+ buildHatchAdder(MTEElectricImplosionCompressor.class)
+ .atLeast(InputBus, OutputBus, Maintenance, InputHatch, OutputHatch)
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(
+ onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings2, 0)),
+ onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings3, 4))))
+ .addElement(
+ 'e',
+ buildHatchAdder(MTEElectricImplosionCompressor.class).atLeast(Energy.or(ExoticEnergy))
+ .casingIndex(CASING_INDEX)
+ .dot(2)
+ .buildAndChain(
+ onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings2, 0)),
+ onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings3, 4))))
+ .addElement('N', new IStructureElement<>() {
+
+ // Much of this based on StructureUtility.ofBlocksTiered
+ private final List<Pair<Block, Integer>> tiers = getAllBlockTiers();
+
+ @Override
+ public boolean check(MTEElectricImplosionCompressor te, World world, int x, int y, int z) {
+ if (!te.piston && !world.isAirBlock(x, y, z)) return false;
+ if (te.piston) {
+ Block candidate = world.getBlock(x, y, z);
+ int candidateMeta = world.getBlockMetadata(x, y, z);
+ return getTierOfBlock(candidate, candidateMeta) != -1;
+ }
+ return true;
+ }
+
+ private Pair<Block, Integer> getTier(ItemStack trigger) {
+ return this.tiers.get(Math.min(Math.max(trigger.stackSize, 1), this.tiers.size()) - 1);
+ }
+
+ @Override
+ public boolean spawnHint(MTEElectricImplosionCompressor te, World world, int x, int y, int z,
+ ItemStack itemStack) {
+ Pair<Block, Integer> tier = this.getTier(itemStack);
+ if (te.piston) StructureLibAPI.hintParticle(world, x, y, z, tier.getKey(), tier.getValue());
+ return true;
+ }
+
+ @Override
+ public boolean placeBlock(MTEElectricImplosionCompressor te, World world, int x, int y, int z,
+ ItemStack itemStack) {
+ Pair<Block, Integer> tier = this.getTier(itemStack);
+ if (te.piston) world.setBlock(x, y, z, tier.getKey(), tier.getValue(), 3);
+ else world.setBlockToAir(x, y, z);
+ return true;
+ }
+
+ @Override
+ public BlocksToPlace getBlocksToPlace(MTEElectricImplosionCompressor t, World world, int x, int y, int z,
+ ItemStack trigger, AutoPlaceEnvironment env) {
+ return BlocksToPlace.createEmpty();
+ }
+
+ @Override
+ public PlaceResult survivalPlaceBlock(MTEElectricImplosionCompressor t, World world, int x, int y, int z,
+ ItemStack trigger, AutoPlaceEnvironment env) {
+ return isAir().survivalPlaceBlock(t, world, x, y, z, trigger, env);
+ }
+ })
+ .build();
+
+ public static List<Pair<Block, Integer>> getAllBlockTiers() {
+ return new ArrayList<>() {
+
+ private static final long serialVersionUID = 8171991663102417651L;
+
+ {
+ this.add(Pair.of(GregTechAPI.sBlockMetal5, 2));
+ if (Mods.Avaritia.isModLoaded()) {
+ this.add(Pair.of(LudicrousBlocks.resource_block, 1));
+ }
+ this.add(Pair.of(GregTechAPI.sBlockMetal9, 4));
+ this.add(Pair.of(GregTechAPI.sBlockMetal9, 3));
+ this.add(Pair.of(GregTechAPI.sBlockMetal9, 8));
+ }
+
+ };
+ }
+
+ public static ITierConverter<Integer> tieredBlockConverter() {
+ return MTEElectricImplosionCompressor::getTierOfBlock;
+ }
+
+ private static int getTierOfBlock(Block block, int meta) {
+ if (block == null) {
+ return -1;
+ }
+ if (block == GregTechAPI.sBlockMetal5 && meta == 2) {
+ return 1; // Neutronium
+ }
+ if (block == LudicrousBlocks.resource_block && meta == 1) {
+ return 2; // Infinity
+ }
+ if (block == GregTechAPI.sBlockMetal9) {
+ return switch (meta) {
+ case 4 -> 3; // Transcendent Metal
+ case 3 -> 4; // SpaceTime
+ case 8 -> 5; // Universium
+ default -> -1;
+ };
+ }
+ return -1;
+ }
+
+ private void setBlockTier(int tier) {
+ this.mBlockTier = tier;
+ }
+
+ private int getBlockTier() {
+ return this.mBlockTier;
+ }
+
+ @Override
+ public IStructureDefinition<MTEElectricImplosionCompressor> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected IAlignmentLimits getInitialAlignmentLimits() {
+ return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped();
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Implosion Compressor")
+ .addInfo("Explosions are fun")
+ .addInfo("Controller block for the Electric Implosion Compressor")
+ .addInfo("Uses electricity instead of Explosives")
+ .addInfo("Can parallel up to 4^(Tier - 1)")
+ .addInfo("Tier is determined by containment block")
+ .addInfo("Valid blocks: Neutronium, Infinity, Transcendent Metal, Spacetime, Universium")
+ .addInfo("Minimum allowed energy hatch tier is one below recipe tier")
+ .addInfo("Supports " + TT + " energy hatches")
+ .addSeparator()
+ .beginStructureBlock(3, 9, 3, false)
+ .addController("Front 3rd layer center")
+ .addCasingInfoMin("Solid Steel Machine Casing", 8, false)
+ .addStructureInfo("Casings can be replaced with Explosion Warning Signs")
+ .addOtherStructurePart("Transformer-Winding Blocks", "Outer layer 2,3,7,8")
+ .addOtherStructurePart("Nickel-Zinc-Ferrite Blocks", "Inner layer 2,3,7,8")
+ .addOtherStructurePart("Containment Blocks", "Layer 4,5,6")
+ .addMaintenanceHatch("Any bottom casing", 1)
+ .addInputBus("Any bottom casing", 1)
+ .addInputHatch("Any bottom casing", 1)
+ .addOutputBus("Any bottom casing", 1)
+ .addEnergyHatch("Bottom middle and/or top middle", 2)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return BartWorksRecipeMaps.electricImplosionCompressorRecipes;
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic() {
+
+ @NotNull
+ @Override
+ protected CheckRecipeResult validateRecipe(@Nonnull GTRecipe recipe) {
+ long voltage = MTEElectricImplosionCompressor.this.getAverageInputVoltage();
+ // Only allow a minimum of T-1 energy hatch
+ if (recipe.mEUt > voltage * 4) {
+ return CheckRecipeResultRegistry.insufficientPower(recipe.mEUt);
+ }
+ return CheckRecipeResultRegistry.SUCCESSFUL;
+ }
+
+ @NotNull
+ @Override
+ protected OverclockCalculator createOverclockCalculator(@NotNull GTRecipe recipe) {
+ // For overclocking we'll allow all power to be used
+ return super.createOverclockCalculator(recipe)
+ .setEUt(MTEElectricImplosionCompressor.this.getMaxInputEu())
+ .setAmperage(1);
+ }
+ }.setMaxParallelSupplier(() -> (int) Math.pow(4, Math.max(this.mBlockTier - 1, 0)));
+ }
+
+ private void updateChunkCoordinates() {
+ this.chunkCoordinates.clear();
+
+ for (int x = -1; x <= 1; x++) for (int z = -1; z <= 1; z++) {
+ if (Math.abs(x) != 1 || Math.abs(z) != 1) {
+ int[] abc = { x, -2, z + 1 };
+ int[] xyz = { 0, 0, 0 };
+ this.getExtendedFacing()
+ .getWorldOffset(abc, xyz);
+ xyz[0] += this.getBaseMetaTileEntity()
+ .getXCoord();
+ xyz[1] += this.getBaseMetaTileEntity()
+ .getYCoord();
+ xyz[2] += this.getBaseMetaTileEntity()
+ .getZCoord();
+ this.chunkCoordinates.add(new ChunkCoordinates(xyz[0], xyz[1], xyz[2]));
+ }
+ }
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ super.onFirstTick(aBaseMetaTileEntity);
+ this.updateChunkCoordinates();
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+
+ if (pistonEnabled && aBaseMetaTileEntity.isActive() && aTick % 20 == 0) {
+ if (aBaseMetaTileEntity.isClientSide()) this.animatePiston(aBaseMetaTileEntity);
+ else if (aBaseMetaTileEntity.hasMufflerUpgrade()) MainMod.BW_Network_instance.sendPacketToAllPlayersInRange(
+ aBaseMetaTileEntity.getWorld(),
+ new EICPacket(
+ new Coords(
+ aBaseMetaTileEntity.getXCoord(),
+ aBaseMetaTileEntity.getYCoord(),
+ aBaseMetaTileEntity.getZCoord()),
+ true),
+ aBaseMetaTileEntity.getXCoord(),
+ aBaseMetaTileEntity.getZCoord());
+ }
+ }
+
+ @Override
+ public void setExtendedFacing(ExtendedFacing newExtendedFacing) {
+ super.setExtendedFacing(newExtendedFacing); // Will call stopMachine
+
+ this.updateChunkCoordinates();
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public void stopMachine() {
+ this.resetPiston(this.mBlockTier);
+ super.stopMachine();
+ }
+
+ private void resetPiston(int tier) {
+ if (!pistonEnabled) return;
+ IGregTechTileEntity aBaseMetaTileEntity = this.getBaseMetaTileEntity();
+ if (!aBaseMetaTileEntity.isServerSide()) return;
+ if (!this.piston) {
+ List<Pair<Block, Integer>> tiers = getAllBlockTiers();
+ Pair<Block, Integer> tieredBlock = tiers.get(Math.min(tier, tiers.size()) - 1);
+ this.chunkCoordinates.forEach(c -> {
+ // Don't replace real blocks in case user has placed something (e.g. tier upgrade)
+ if (aBaseMetaTileEntity.getWorld()
+ .isAirBlock(c.posX, c.posY, c.posZ)) {
+ aBaseMetaTileEntity.getWorld()
+ .setBlock(c.posX, c.posY, c.posZ, tieredBlock.getKey(), tieredBlock.getValue(), 3);
+ }
+ });
+ this.piston = !this.piston;
+ }
+ }
+
+ private void activatePiston() {
+ if (!pistonEnabled) return;
+ IGregTechTileEntity aBaseMetaTileEntity = this.getBaseMetaTileEntity();
+ if (!aBaseMetaTileEntity.isServerSide()) return;
+ if (this.piston) {
+ this.chunkCoordinates.forEach(
+ c -> aBaseMetaTileEntity.getWorld()
+ .setBlockToAir(c.posX, c.posY, c.posZ));
+ this.piston = !this.piston;
+ }
+ }
+
+ private void animatePiston(IGregTechTileEntity aBaseMetaTileEntity) {
+ if (!aBaseMetaTileEntity.getWorld().isRemote) return;
+
+ if (!this.getBaseMetaTileEntity()
+ .hasMufflerUpgrade())
+ GTUtility.doSoundAtClient(
+ sound,
+ 10,
+ 1f,
+ 1f,
+ this.chunkCoordinates.get(0).posX,
+ this.chunkCoordinates.get(0).posY,
+ this.chunkCoordinates.get(0).posZ);
+ this.spawnVisualPistonBlocks(
+ aBaseMetaTileEntity.getWorld(),
+ this.chunkCoordinates.get(2).posX,
+ this.chunkCoordinates.get(2).posY,
+ this.chunkCoordinates.get(2).posZ,
+ 10);
+ }
+
+ @SideOnly(Side.CLIENT)
+ private void spawnVisualPistonBlocks(World world, int x, int y, int z, int age) {
+ EICPistonVisualizer pistonVisualizer = new EICPistonVisualizer(world, x, y, z, age);
+ Minecraft.getMinecraft().effectRenderer.addEffect(pistonVisualizer);
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setBoolean("piston", this.piston);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ if (aNBT.hasKey("piston")) this.piston = aNBT.getBoolean("piston");
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) {
+ int pistonTier = this.mBlockTier;
+ this.mCasing = 0;
+ int mMaxHatchTier = 0;
+ this.setBlockTier(0);
+ boolean isOK = this.checkPiece(STRUCTURE_PIECE_MAIN, 1, 6, 0);
+
+ List<MTEHatch> energyHatches = this.getExoticAndNormalEnergyHatchList();
+ for (MTEHatch hatch : energyHatches) {
+ mMaxHatchTier = Math.max(mMaxHatchTier, hatch.mTier);
+ }
+
+ isOK = isOK && this.mMaintenanceHatches.size() == 1 && energyHatches.size() >= 1;
+ if (isOK) {
+ this.activatePiston();
+ return true;
+ }
+ this.resetPiston(pistonTier);
+ return false;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEElectricImplosionCompressor(this.mName);
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) };
+ }
+
+ @Override
+ public void construct(ItemStack itemStack, boolean b) {
+ this.buildPiece(STRUCTURE_PIECE_MAIN, itemStack, b, 1, 6, 0);
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) {
+ if (this.mMachine) return -1;
+ return this.survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 1, 6, 0, elementBudget, env, false, true);
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (aPlayer.isSneaking()) {
+ batchMode = !batchMode;
+ if (batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEHighTempGasCooledReactor.java b/src/main/java/bartworks/common/tileentities/multis/MTEHighTempGasCooledReactor.java
new file mode 100644
index 0000000000..73f6593d4f
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTEHighTempGasCooledReactor.java
@@ -0,0 +1,619 @@
+/*
+ * Copyright (C) 2022 kuba6000 This program is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details. You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.API.recipe.BartWorksRecipeMaps.htgrFakeRecipes;
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_VIA_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.GTValues.AuthorKuba;
+import static gregtech.api.util.GTRecipeBuilder.HOURS;
+import static gregtech.api.util.GTStructureUtility.ofHatchAdder;
+import static gregtech.api.util.GTUtility.filterValidMTEs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.common.items.SimpleSubItemClass;
+import bartworks.system.material.WerkstoffLoader;
+import bartworks.util.MathUtils;
+import cpw.mods.fml.common.registry.GameRegistry;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.GTValues;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.enums.Textures;
+import gregtech.api.enums.TierEU;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.metatileentity.implementations.MTEHatchOutputBus;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTLanguageManager;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+
+public class MTEHighTempGasCooledReactor extends MTEEnhancedMultiBlockBase<MTEHighTempGasCooledReactor> {
+
+ private static final int BASECASINGINDEX = 181;
+
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition<MTEHighTempGasCooledReactor> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEHighTempGasCooledReactor>builder()
+ .addShape(
+ STRUCTURE_PIECE_MAIN,
+ transpose(
+ new String[][] {
+ { " BBBBBBB ", " BBBBBBBBB ", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB",
+ "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", " BBBBBBBBB ", " BBBBBBB " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " bbb~bbb ", " bbbbbbbbb ", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb",
+ "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", " bbbbbbbbb ", " bbbbbbb " }, }))
+ .addElement('c', onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings8, 5)))
+ .addElement(
+ 'b',
+ ofChain(
+ ofHatchAdder(MTEHighTempGasCooledReactor::addOutputToMachineList, BASECASINGINDEX, 1),
+ ofHatchAdder(MTEHighTempGasCooledReactor::addMaintenanceToMachineList, BASECASINGINDEX, 1),
+ ofHatchAdder(MTEHighTempGasCooledReactor::addEnergyInputToMachineList, BASECASINGINDEX, 1),
+ onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings8, 5))))
+ .addElement(
+ 'B',
+ ofChain(
+ ofHatchAdder(MTEHighTempGasCooledReactor::addInputToMachineList, BASECASINGINDEX, 2),
+ onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings8, 5))))
+ // ofHatchAdderOptional(GT_TileEntity_HTGR::addInputToMachineList, BASECASINGINDEX, 2,
+ // GregTechAPI.sBlockCasings8, 5))
+ .build();
+
+ private static final int HELIUM_NEEDED = 730000;
+ public static final int powerUsage = (int) TierEU.RECIPE_LuV;
+ private static final int maxcapacity = 720000;
+ private static final int mincapacity = maxcapacity / 10;
+ private int HeliumSupply;
+ private int fueltype = -1, fuelsupply = 0;
+ private boolean empty;
+ private int emptyticksnodiff = 0;
+ private int coolanttaking = 0;
+ private int mCasing = 0;
+
+ public MTEHighTempGasCooledReactor(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ private MTEHighTempGasCooledReactor(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public IStructureDefinition<MTEHighTempGasCooledReactor> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Breeder Reactor")
+ .addInfo("Controller block for the High Temperature Gas-cooled Reactor (HTGR)")
+ .addInfo(AuthorKuba)
+ .addInfo("You can clear internal buffer by changing the mode with a screwdriver")
+ .addInfo("Needs a constant supply of coolant while running")
+ .addInfo("Needs at least 72k Fuel pebbles to start operation (can hold up to 720k pebbles)")
+ .addInfo("Consumes up to 2.5% of total Fuel Pellets per Operation depending on efficiency")
+ .addInfo("Efficiency is calculated exponentially depending on the amount of pebbles in the internal buffer")
+ .addInfo("and affects total recipe time (at 100% eff, -50% total recipe time")
+ .addInfo(
+ "Reactor will take 4 000L/s of coolant multiplied by efficiency and by fuel coolant value (check tooltips)")
+ .addInfo("Uses " + GTUtility.formatNumbers(powerUsage) + " EU/t")
+ .addInfo("One Operation takes 1 hour")
+ .addSeparator()
+ .beginStructureBlock(11, 12, 11, true)
+ .addController("Front bottom center")
+ .addCasingInfoMin("Europium Reinforced Radiation Proof Casings", 500, false)
+ .addStructureInfo("Corners and the 2 touching blocks are air (cylindric)")
+ .addInputBus("Any top layer casing", 2)
+ .addInputHatch("Any top layer casing", 2)
+ .addOutputBus("Any bottom layer casing", 1)
+ .addOutputHatch("Any bottom layer casing", 1)
+ .addEnergyHatch("Any bottom layer casing", 1)
+ .addMaintenanceHatch("Any bottom layer casing", 1)
+ .toolTipFinisher(MULTIBLOCK_ADDED_VIA_BARTWORKS.apply(EnumChatFormatting.GOLD + "kuba6000"));
+ return tt;
+ }
+
+ @Override
+ protected IAlignmentLimits getInitialAlignmentLimits() {
+ return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped();
+ }
+
+ @Override
+ public void construct(ItemStack stackSize, boolean hintsOnly) {
+ this.buildPiece("main", stackSize, hintsOnly, 5, 11, 0);
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) {
+ this.mCasing = 0;
+ return this.checkPiece("main", 5, 11, 0) && this.mCasing >= 500
+ && this.mMaintenanceHatches.size() == 1
+ && this.mInputHatches.size() > 0
+ && this.mOutputHatches.size() > 0
+ && this.mInputBusses.size() > 0
+ && this.mOutputBusses.size() > 0
+ && this.mEnergyHatches.size() > 0;
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ this.HeliumSupply = aNBT.getInteger("HeliumSupply");
+ this.fueltype = aNBT.getInteger("fueltype");
+ this.fuelsupply = aNBT.getInteger("fuelsupply");
+ this.empty = aNBT.getBoolean("EmptyMode");
+ this.coolanttaking = aNBT.getInteger("coolanttaking");
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setInteger("HeliumSupply", this.HeliumSupply);
+ aNBT.setInteger("fueltype", this.fueltype);
+ aNBT.setInteger("fuelsupply", this.fuelsupply);
+ aNBT.setBoolean("EmptyMode", this.empty);
+ aNBT.setInteger("coolanttaking", this.coolanttaking);
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+ if (aBaseMetaTileEntity.isServerSide() && !this.empty) {
+ boolean updateneeded = false;
+ if (this.HeliumSupply < MTEHighTempGasCooledReactor.HELIUM_NEEDED) {
+ for (FluidStack fluidStack : this.getStoredFluids()) {
+ if (fluidStack.isFluidEqual(Materials.Helium.getGas(1))) {
+ int toget = Math
+ .min(MTEHighTempGasCooledReactor.HELIUM_NEEDED - this.HeliumSupply, fluidStack.amount);
+ fluidStack.amount -= toget;
+ this.HeliumSupply += toget;
+ updateneeded = true;
+ }
+ }
+ }
+ if (this.fuelsupply < maxcapacity) {
+ this.startRecipeProcessing();
+ for (ItemStack itemStack : this.getStoredInputs()) {
+ int type = -1;
+ if (itemStack == null || itemStack.getItem() != HTGRMaterials.aHTGR_Materials) continue;
+ int damage = HTGRMaterials.aHTGR_Materials.getDamage(itemStack);
+ if ((damage + 1) % HTGRMaterials.MATERIALS_PER_FUEL != HTGRMaterials.USABLE_FUEL_INDEX + 1)
+ continue; // is fuel
+ type = damage / HTGRMaterials.MATERIALS_PER_FUEL;
+ if (this.fueltype == -1) this.fueltype = type;
+ if (this.fueltype != type) continue;
+ int toget = Math.min(maxcapacity - this.fuelsupply, itemStack.stackSize);
+ this.fuelsupply += toget;
+ itemStack.stackSize -= toget;
+ updateneeded = true;
+ }
+ this.endRecipeProcessing();
+ }
+ if (updateneeded) this.updateSlots();
+ }
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ // Only for visual
+ return htgrFakeRecipes;
+ }
+
+ @Override
+ protected boolean filtersFluid() {
+ return false;
+ }
+
+ @Override
+ public boolean checkRecipe(ItemStack controllerStack) {
+
+ if (this.empty) {
+ if (this.HeliumSupply > 0 || this.fuelsupply > 0) {
+ this.mEfficiency = 10000;
+ this.mMaxProgresstime = 100;
+ return true;
+ }
+ return false;
+ }
+ if (this.HeliumSupply < MTEHighTempGasCooledReactor.HELIUM_NEEDED || this.fuelsupply < mincapacity)
+ return false;
+
+ double eff = Math.min(Math.pow((double) this.fuelsupply / (double) mincapacity, 2D), 100D) / 100D
+ - (this.getIdealStatus() - this.getRepairStatus()) / 10D;
+
+ if (eff <= 0) return false;
+
+ int toReduce = MathUtils.floorInt(this.fuelsupply * 0.025D * eff);
+
+ final int originalToReduce = toReduce;
+ int burnedballs = toReduce / 64;
+ if (burnedballs > 0) toReduce -= burnedballs * 64;
+
+ int meta = this.fueltype * HTGRMaterials.MATERIALS_PER_FUEL + HTGRMaterials.BURNED_OUT_FUEL_INDEX;
+
+ ItemStack[] toOutput = { new ItemStack(HTGRMaterials.aHTGR_Materials, burnedballs, meta),
+ new ItemStack(HTGRMaterials.aHTGR_Materials, toReduce, meta + 1) };
+ if (!this.canOutputAll(toOutput)) return false;
+
+ this.fuelsupply -= originalToReduce;
+ this.mOutputItems = toOutput;
+
+ // this.updateSlots(); // not needed ?
+
+ this.coolanttaking = (int) (4000D * (this.fueltype * 0.5D + 1) * eff);
+
+ this.mEfficiency = (int) (eff * 10000D);
+ this.mEfficiencyIncrease = 0;
+ this.mEUt = -powerUsage;
+ this.mMaxProgresstime = (int) (72000 * (1d - eff / 2d));
+ return true;
+ }
+
+ private int runningtick = 0;
+
+ @Override
+ public boolean onRunningTick(ItemStack aStack) {
+ this.runningtick++;
+
+ if (this.empty) {
+ if (this.emptyticksnodiff > 20 && this.emptyticksnodiff % 20 != 0) {
+ this.emptyticksnodiff++;
+ return true;
+ }
+ if (this.HeliumSupply > 0) {
+ this.addOutput(Materials.Helium.getGas(this.HeliumSupply));
+ this.HeliumSupply = 0;
+ }
+ if (this.fuelsupply > 0) {
+ ItemStack iStack = new ItemStack(
+ HTGRMaterials.aHTGR_Materials,
+ this.fuelsupply,
+ HTGRMaterials.MATERIALS_PER_FUEL * this.fueltype + HTGRMaterials.USABLE_FUEL_INDEX);
+ boolean storedAll = false;
+ for (MTEHatchOutputBus tHatch : filterValidMTEs(mOutputBusses)) {
+ if (tHatch.storeAll(iStack)) {
+ storedAll = true;
+ break;
+ }
+ }
+ if (!storedAll) {
+ if (this.fuelsupply == iStack.stackSize) this.emptyticksnodiff++;
+ else {
+ this.fuelsupply = iStack.stackSize;
+ this.emptyticksnodiff = 0;
+ }
+ } else {
+ this.fuelsupply = 0;
+ this.fueltype = -1;
+ this.coolanttaking = 0;
+ }
+ }
+ return true;
+ }
+ // USE DA POWAH
+ if (!this.drainEnergyInput(-this.mEUt)) {
+ this.criticalStopMachine();
+ return false;
+ }
+
+ if (this.runningtick % 20 == 0) {
+ int takecoolant = this.coolanttaking;
+ int drainedamount = 0;
+
+ for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) {
+ FluidStack tLiquid = tHatch.getFluid();
+ if (tLiquid != null && tLiquid.isFluidEqual(FluidRegistry.getFluidStack("ic2coolant", 1))) {
+ FluidStack drained = tHatch.drain(takecoolant, true);
+ takecoolant -= drained.amount;
+ drainedamount += drained.amount;
+ if (takecoolant <= 0) break;
+ }
+ }
+
+ if (drainedamount > 0) this.addOutput(FluidRegistry.getFluidStack("ic2hotcoolant", drainedamount));
+
+ this.updateSlots();
+
+ if (takecoolant > 0) this.stopMachine();
+ }
+
+ return true;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEHighTempGasCooledReactor(this.mName);
+ }
+
+ @Override
+ public String[] getInfoData() {
+ return new String[] { "Mode:", this.empty ? "Emptying" : "Normal", "Progress:",
+ GTUtility.formatNumbers(this.mProgresstime / 20) + "s / "
+ + GTUtility.formatNumbers(this.mMaxProgresstime / 20)
+ + "s",
+ "Fuel type:",
+ this.fueltype == -1 ? "NONE" : "TRISO (" + HTGRMaterials.sHTGR_Fuel[this.fueltype].sEnglish + ")",
+ "Fuel amount:", GTUtility.formatNumbers(this.fuelsupply) + " pcs.", "Helium-Level:",
+ GTUtility.formatNumbers(this.HeliumSupply) + "L / "
+ + GTUtility.formatNumbers(MTEHighTempGasCooledReactor.HELIUM_NEEDED)
+ + "L",
+ "Coolant:", GTUtility.formatNumbers(this.coolanttaking) + "L/s", "Problems:",
+ String.valueOf(this.getIdealStatus() - this.getRepairStatus()) };
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side,
+ ForgeDirection forgeDirection, int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == forgeDirection) {
+ if (aActive) return new ITexture[] {
+ Textures.BlockIcons.getCasingTextureForId(MTEHighTempGasCooledReactor.BASECASINGINDEX),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] {
+ Textures.BlockIcons.getCasingTextureForId(MTEHighTempGasCooledReactor.BASECASINGINDEX),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] {
+ Textures.BlockIcons.getCasingTextureForId(MTEHighTempGasCooledReactor.BASECASINGINDEX) };
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (this.mMaxProgresstime > 0) {
+ GTUtility.sendChatToPlayer(aPlayer, "HTGR mode cannot be changed while the machine is running.");
+ return;
+ }
+ this.empty = !this.empty;
+ GTUtility.sendChatToPlayer(
+ aPlayer,
+ "HTGR is now running in " + (this.empty ? "emptying mode." : "normal Operation"));
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+
+ public static class HTGRMaterials {
+
+ private static class CustomHTGRSimpleSubItemClass extends SimpleSubItemClass {
+
+ HashMap<Integer, String> tooltip = null;
+
+ public CustomHTGRSimpleSubItemClass(HashMap<Integer, String> tooltip, String... tex) {
+ super(tex);
+ this.tooltip = tooltip;
+ }
+
+ @Override
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List aList, boolean p_77624_4_) {
+ if (this.tooltip.containsKey(this.getDamage(p_77624_1_)))
+ aList.add(this.tooltip.get(this.getDamage(p_77624_1_)));
+ aList.add("Material for High Temperature Gas-cooled Reactor");
+ super.addInformation(p_77624_1_, p_77624_2_, aList, p_77624_4_);
+ }
+ }
+
+ private static class Base_ {
+
+ public String sName;
+ public String sEnglish;
+
+ public Base_(String a, String b) {
+ this.sName = a;
+ this.sEnglish = b;
+ }
+ }
+
+ public static class Fuel_ {
+
+ public String sName;
+ public String sEnglish;
+ public ItemStack mainItem;
+ public ItemStack secondaryItem;
+ public ItemStack[] recycledItems = { GTValues.NI, GTValues.NI, GTValues.NI, GTValues.NI, GTValues.NI,
+ GTValues.NI };
+ public FluidStack recycledFluid;
+ public int[] recycleChances;
+ public String tooltip;
+
+ public Fuel_(String sName, String sEnglish, ItemStack mainItem, ItemStack secondaryItem,
+ FluidStack recycledFluid, ItemStack[] recycledItems, int[] recycleChances, String tooltip) {
+ this.sName = sName;
+ this.sEnglish = sEnglish;
+ this.mainItem = mainItem;
+ this.secondaryItem = secondaryItem;
+ this.recycledFluid = recycledFluid;
+ System.arraycopy(recycledItems, 0, this.recycledItems, 0, recycledItems.length);
+ this.recycleChances = recycleChances;
+ this.tooltip = tooltip;
+ }
+ }
+
+ private static class LangEntry_ {
+
+ public String sName;
+ public String sEnglish;
+
+ public LangEntry_(String a, String b) {
+ this.sName = a;
+ this.sEnglish = b;
+ }
+ }
+
+ public static final Base_[] sHTGR_Bases = { new Base_("HTGRFuelMixture", "HTGR fuel mixture"),
+ new Base_("BISOPebbleCompound", "BISO pebble compound"),
+ new Base_("TRISOPebbleCompound", "TRISO pebble compound"), new Base_("TRISOBall", "TRISO ball"),
+ new Base_("TRISOPebble", "TRISO pebble"), new Base_("BurnedOutTRISOBall", "Burned out TRISO Ball"),
+ new Base_("BurnedOutTRISOPebble", "Burned out TRISO Pebble"), };
+ public static final int MATERIALS_PER_FUEL = sHTGR_Bases.length;
+ static final int USABLE_FUEL_INDEX = 4;
+ static final int BURNED_OUT_FUEL_INDEX = 5;
+ public static final Fuel_[] sHTGR_Fuel = { new Fuel_(
+ "Thorium",
+ "Thorium",
+ WerkstoffLoader.Thorium232.get(OrePrefixes.dust, 64),
+ Materials.Uranium235.getDust(4),
+ GTValues.NF,
+ new ItemStack[] { Materials.Silicon.getDust(1), Materials.Graphite.getDust(1), Materials.Carbon.getDust(1),
+ Materials.Lutetium.getDust(1), WerkstoffLoader.Thorium232.get(OrePrefixes.dust, 1) },
+ new int[] { 9900 / 4, 9900 / 4, 9900 / 4, 9900 / 4, 162 / 4 },
+ "Multiplies coolant by 1"),
+ new Fuel_(
+ "Uranium",
+ "Uranium",
+ Materials.Uranium.getDust(64),
+ Materials.Uranium235.getDust(8),
+ FluidRegistry.getFluidStack("krypton", 4),
+ new ItemStack[] { Materials.Silicon.getDust(1), Materials.Graphite.getDust(1),
+ Materials.Carbon.getDust(1), Materials.Lead.getDust(1), Materials.Uranium.getDust(1) },
+ new int[] { 9900 / 4, 9900 / 4, 9900 / 4, 5000 / 4, 5000 / 4 },
+ "Multiplies coolant by 1.5"),
+ new Fuel_(
+ "Plutonium",
+ "Plutonium",
+ Materials.Plutonium.getDust(64),
+ Materials.Plutonium241.getDust(4),
+ FluidRegistry.getFluidStack("xenon", 4),
+ new ItemStack[] { Materials.Silicon.getDust(1), Materials.Graphite.getDust(1),
+ Materials.Carbon.getDust(1), Materials.Lead.getDust(1), Materials.Plutonium.getDust(1) },
+ new int[] { 9900 / 4, 9900 / 4, 9900 / 4, 5000 / 4, 5000 / 4 },
+ "Multiplies coolant by 2"), };
+ public static final CustomHTGRSimpleSubItemClass aHTGR_Materials;
+ static final ArrayList<LangEntry_> aHTGR_Localizations = new ArrayList<>();
+
+ static {
+ String[] sHTGR_Materials = new String[sHTGR_Bases.length * sHTGR_Fuel.length];
+ HashMap<Integer, String> tooltip = new HashMap<>();
+ int i = 0;
+ for (Fuel_ fuel : sHTGR_Fuel) for (Base_ base : sHTGR_Bases) {
+ sHTGR_Materials[i] = "HTGR" + base.sName + fuel.sName;
+ aHTGR_Localizations.add(
+ new LangEntry_("item." + sHTGR_Materials[i] + ".name", base.sEnglish + " (" + fuel.sEnglish + ")"));
+ if ((i + 1) % MATERIALS_PER_FUEL == USABLE_FUEL_INDEX + 1 && fuel.tooltip != null
+ && !fuel.tooltip.isEmpty()) tooltip.put(i, fuel.tooltip);
+ i++;
+ }
+ aHTGR_Materials = new CustomHTGRSimpleSubItemClass(tooltip, sHTGR_Materials);
+ }
+
+ public static void registeraTHR_Materials() {
+ for (LangEntry_ iName : aHTGR_Localizations)
+ GTLanguageManager.addStringLocalization(iName.sName, iName.sEnglish);
+ GameRegistry.registerItem(MTEHighTempGasCooledReactor.HTGRMaterials.aHTGR_Materials, "bw.HTGRMaterials");
+ }
+
+ public static void register_fake_THR_Recipes() {
+
+ int i = 0;
+ for (@SuppressWarnings("unused")
+ Fuel_ fuel : sHTGR_Fuel) {
+
+ GTValues.RA.stdBuilder()
+ .itemInputs(new ItemStack(MTEHighTempGasCooledReactor.HTGRMaterials.aHTGR_Materials, 64, i + 4))
+ .itemOutputs(new ItemStack(MTEHighTempGasCooledReactor.HTGRMaterials.aHTGR_Materials, 1, i + 5))
+ .duration(1 * HOURS)
+ .eut(powerUsage)
+ .ignoreCollision()
+ .noOptimize()
+ .fake()
+ .addTo(htgrFakeRecipes);
+
+ i += MATERIALS_PER_FUEL;
+ }
+ }
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTELESU.java b/src/main/java/bartworks/common/tileentities/multis/MTELESU.java
new file mode 100644
index 0000000000..a039aa593c
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTELESU.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.IIcon;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizons.modularui.api.NumberFormatMUI;
+import com.gtnewhorizons.modularui.api.drawable.Text;
+import com.gtnewhorizons.modularui.api.forge.ItemStackHandler;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot;
+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.ProgressBar;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+import com.gtnewhorizons.modularui.common.widget.TextWidget;
+
+import bartworks.API.modularUI.BWUITextures;
+import bartworks.MainMod;
+import bartworks.common.configs.ConfigHandler;
+import bartworks.common.loaders.ItemRegistry;
+import bartworks.util.BWTooltipReference;
+import bartworks.util.ConnectedBlocksChecker;
+import cpw.mods.fml.common.FMLCommonHandler;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.enums.Dyes;
+import gregtech.api.enums.GTValues;
+import gregtech.api.gui.modularui.GTUITextures;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEMultiBlockBase;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTUtility;
+
+public class MTELESU extends MTEMultiBlockBase {
+
+ private static final byte TEXID_SIDE = 0;
+ private static final byte TEXID_CHARGING = 1;
+ private static final byte TEXID_IDLE = 2;
+ private static final byte TEXID_EMPTY = 3;
+ private static final IIcon[] iIcons = new IIcon[4];
+ private static final IIconContainer[] iIconContainers = new IIconContainer[4];
+ private static final ITexture[][] iTextures = new ITexture[4][1];
+ public ConnectedBlocksChecker connectedcells;
+ public final ItemStack[] circuits = new ItemStack[5];
+ private final ItemStackHandler circuitsInventoryHandler = new ItemStackHandler(this.circuits) {
+
+ @Override
+ public int getSlotLimit(int slot) {
+ return 1;
+ }
+ };
+ private long mStorage;
+
+ protected static final NumberFormatMUI numberFormat = new NumberFormatMUI();
+
+ public MTELESU(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ this.mStorage = ConfigHandler.energyPerCell;
+ }
+
+ public MTELESU(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public boolean isEnetOutput() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnetInput() {
+ return true;
+ }
+
+ @Override
+ public long maxEUStore() {
+ return this.mStorage >= Long.MAX_VALUE - 1 || this.mStorage < 0 ? Long.MAX_VALUE - 1 : this.mStorage;
+ }
+
+ @Override
+ public long maxAmperesIn() {
+ int ret = 0;
+ for (int i = 0; i < 5; ++i) if (this.circuits[i] != null && this.circuits[i].getItem()
+ .equals(
+ GTUtility.getIntegratedCircuit(0)
+ .getItem()))
+ ret += this.circuits[i].getItemDamage();
+ return ret > 0 ? ret : 1;
+ }
+
+ @Override
+ public long maxAmperesOut() {
+ return this.maxAmperesIn();
+ }
+
+ @Override
+ public long maxEUInput() {
+
+ for (int i = 1; i < GTValues.V.length; i++) {
+ if (this.maxEUOutput() <= GTValues.V[i] && this.maxEUOutput() > GTValues.V[i - 1])
+ return Math.min(GTValues.V[i], 32768L);
+ }
+
+ return 8;
+ }
+
+ @Override
+ public long maxEUOutput() {
+ return Math.min(Math.max(this.mStorage / ConfigHandler.energyPerCell, 1L), 32768L);
+ }
+
+ @Override
+ public int rechargerSlotStartIndex() {
+ return 0;
+ }
+
+ @Override
+ public int rechargerSlotCount() {
+ return 1;
+ }
+
+ @Override
+ public int dechargerSlotStartIndex() {
+ return 1;
+ }
+
+ @Override
+ public int dechargerSlotCount() {
+ return 1;
+ }
+
+ @Override
+ public boolean isTeleporterCompatible() {
+ return true;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTELESU(this.mName);
+ }
+
+ @Override
+ public String[] getDescription() {
+ ArrayList<String> e = new ArrayList<>();
+ String[] dsc = StatCollector.translateToLocal("tooltip.tile.lesu.0.name")
+ .split(";");
+ Collections.addAll(e, dsc);
+ e.add(
+ StatCollector.translateToLocal("tooltip.tile.lesu.1.name") + " "
+ + GTUtility.formatNumbers(ConfigHandler.energyPerCell)
+ + "EU");
+ dsc = StatCollector.translateToLocal("tooltip.tile.lesu.2.name")
+ .split(";");
+ Collections.addAll(e, dsc);
+ e.add(EnumChatFormatting.RED + StatCollector.translateToLocal("tooltip.tile.lesu.3.name"));
+ e.add(BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get());
+ return e.toArray(new String[0]);
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerIcons(IIconRegister aBlockIconRegister) {
+
+ for (int i = 0; i < MTELESU.iTextures.length; i++) {
+ MTELESU.iIcons[i] = aBlockIconRegister.registerIcon(MainMod.MOD_ID + ":LESU_CASING_" + i);
+ int finalI = i;
+ MTELESU.iIconContainers[i] = new IIconContainer() {
+
+ @Override
+ public IIcon getIcon() {
+ return MTELESU.iIcons[finalI];
+ }
+
+ @Override
+ public IIcon getOverlayIcon() {
+ return MTELESU.iIcons[finalI];
+ }
+
+ @Override
+ public ResourceLocation getTextureFile() {
+ return new ResourceLocation(MainMod.MOD_ID + ":LESU_CASING_" + finalI);
+ }
+ };
+ }
+ }
+
+ public boolean isClientSide() {
+ if (this.getWorld() != null) return this.getWorld().isRemote ? FMLCommonHandler.instance()
+ .getSide() == Side.CLIENT
+ : FMLCommonHandler.instance()
+ .getEffectiveSide() == Side.CLIENT;
+ return FMLCommonHandler.instance()
+ .getEffectiveSide() == Side.CLIENT;
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+
+ ITexture[] ret = {};
+
+ if (this.isClientSide()) {
+
+ for (int i = 0; i < MTELESU.iTextures.length; i++) {
+ MTELESU.iTextures[i][0] = TextureFactory
+ .of(MTELESU.iIconContainers[i], Dyes.getModulation(0, Dyes.MACHINE_METAL.mRGBa));
+ }
+
+ if (side == facing && this.getBaseMetaTileEntity()
+ .getUniversalEnergyStored() <= 0) ret = MTELESU.iTextures[MTELESU.TEXID_EMPTY];
+ else if (side == facing && !aActive) ret = MTELESU.iTextures[MTELESU.TEXID_IDLE];
+ else if (side == facing && aActive) ret = MTELESU.iTextures[MTELESU.TEXID_CHARGING];
+ else ret = MTELESU.iTextures[MTELESU.TEXID_SIDE];
+ }
+
+ return ret;
+ }
+
+ @Override
+ public boolean canInsertItem(int p_102007_1_, ItemStack p_102007_2_, int p_102007_3_) {
+ return true;
+ }
+
+ @Override
+ public boolean canExtractItem(int p_102008_1_, ItemStack p_102008_2_, int p_102008_3_) {
+ return true;
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return 6;
+ }
+
+ @Override
+ public ItemStack getStackInSlot(int slotIn) {
+ if (slotIn > 1) return this.circuits[slotIn - 2];
+ return this.mInventory[slotIn];
+ }
+
+ @Override
+ public void setInventorySlotContents(int index, ItemStack stack) {
+ if (index < 2) this.mInventory[index] = stack;
+ else this.circuits[index - 2] = stack;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return "L.E.S.U.";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return true;
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return 1;
+ }
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer player) {
+ return true;
+ }
+
+ @Override
+ public boolean isItemValidForSlot(int index, ItemStack stack) {
+
+ return switch (index) {
+ case 0, 1 -> true;
+ default -> stack != null && stack.getItem()
+ .equals(
+ GTUtility.getIntegratedCircuit(0)
+ .getItem());
+ };
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public boolean checkRecipe(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public boolean isInputFacing(ForgeDirection side) {
+ return side != this.getBaseMetaTileEntity()
+ .getFrontFacing();
+ }
+
+ @Override
+ public boolean isOutputFacing(ForgeDirection side) {
+ return side == this.getBaseMetaTileEntity()
+ .getFrontFacing();
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ this.checkMachine(aBaseMetaTileEntity, null);
+ super.onFirstTick(aBaseMetaTileEntity);
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ if (aBaseMetaTileEntity.isServerSide()) {
+ this.mMaxProgresstime = 1;
+ if (aTick % 20 == 0) this.checkMachine(aBaseMetaTileEntity, null);
+ }
+ }
+
+ @Override
+ public long getMinimumStoredEU() {
+ return 0;
+ }
+
+ @Override
+ public boolean onRunningTick(ItemStack aStack) {
+ this.mMaxProgresstime = 1;
+ return true;
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ aNBT.setIntArray("customCircuitInv", GTUtility.stacksToIntArray(this.circuits));
+ super.saveNBTData(aNBT);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ int[] stacks = aNBT.getIntArray("customCircuitInv");
+ for (int i = 0; i < stacks.length; i++) {
+ this.circuits[i] = GTUtility.intToStack(stacks[i]);
+ }
+ super.loadNBTData(aNBT);
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) {
+ long startingTime = System.nanoTime();
+ this.connectedcells = new ConnectedBlocksChecker();
+ this.connectedcells.get_connected(
+ aBaseMetaTileEntity.getWorld(),
+ aBaseMetaTileEntity.getXCoord(),
+ aBaseMetaTileEntity.getYCoord(),
+ aBaseMetaTileEntity.getZCoord(),
+ ItemRegistry.BW_BLOCKS[1]);
+
+ if (this.connectedcells.get_meta_of_sideblocks(
+ aBaseMetaTileEntity.getWorld(),
+ this.getBaseMetaTileEntity()
+ .getMetaTileID(),
+ new int[] { aBaseMetaTileEntity.getXCoord(), aBaseMetaTileEntity.getYCoord(),
+ aBaseMetaTileEntity.getZCoord() },
+ true)) {
+ this.getBaseMetaTileEntity()
+ .disableWorking();
+ this.getBaseMetaTileEntity()
+ .setActive(false);
+ this.mStorage = 0;
+ this.mMaxProgresstime = 0;
+ this.mProgresstime = 0;
+ return false;
+ }
+
+ this.mEfficiency = this.getMaxEfficiency(null);
+ this.mStorage = ConfigHandler.energyPerCell * this.connectedcells.hashset.size() >= Long.MAX_VALUE - 1
+ || ConfigHandler.energyPerCell * this.connectedcells.hashset.size() < 0 ? Long.MAX_VALUE - 1
+ : ConfigHandler.energyPerCell * this.connectedcells.hashset.size();
+ this.mMaxProgresstime = 1;
+ this.mProgresstime = 0;
+
+ this.getBaseMetaTileEntity()
+ .enableWorking();
+ this.getBaseMetaTileEntity()
+ .setActive(true);
+
+ long finishedTime = System.nanoTime();
+ // System.out.println("LESU LookUp: "+((finishedTime - startingTime) / 1000000)+"ms");
+ if (finishedTime - startingTime > 5000000) MainMod.LOGGER.warn(
+ "LESU LookUp took longer than 5ms!(" + (finishedTime - startingTime)
+ + "ns / "
+ + (finishedTime - startingTime) / 1000000
+ + "ms) Owner:"
+ + this.getBaseMetaTileEntity()
+ .getOwnerName()
+ + " Check at x:"
+ + this.getBaseMetaTileEntity()
+ .getXCoord()
+ + " y:"
+ + this.getBaseMetaTileEntity()
+ .getYCoord()
+ + " z:"
+ + this.getBaseMetaTileEntity()
+ .getZCoord()
+ + " DIM-ID: "
+ + this.getBaseMetaTileEntity()
+ .getWorld().provider.dimensionId);
+ return true;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ public World getWorld() {
+ return this.getBaseMetaTileEntity()
+ .getWorld();
+ }
+
+ @Override
+ public void addGregTechLogo(ModularWindow.Builder builder) {
+ builder.widget(
+ new DrawableWidget().setDrawable(GTUITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT_GRAY)
+ .setSize(17, 17)
+ .setPos(105, 51));
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ builder.widget(
+ new DrawableWidget().setDrawable(GTUITextures.PICTURE_SCREEN_BLACK)
+ .setPos(7, 4)
+ .setSize(118, 67))
+ .widget(new SlotWidget(new BaseSlot(this.inventoryHandler, 1) {
+
+ @Override
+ public int getSlotStackLimit() {
+ return 1;
+ }
+ }).setBackground(
+ this.getGUITextureSet()
+ .getItemSlot(),
+ GTUITextures.OVERLAY_SLOT_IN)
+ .setPos(127, 13))
+ .widget(new SlotWidget(new BaseSlot(this.inventoryHandler, 0) {
+
+ @Override
+ public int getSlotStackLimit() {
+ return 1;
+ }
+ }).setBackground(
+ this.getGUITextureSet()
+ .getItemSlot(),
+ GTUITextures.OVERLAY_SLOT_CHARGER)
+ .setPos(127, 49));
+ for (int i = 0; i < 4; i++) {
+ builder.widget(
+ new SlotWidget(this.circuitsInventoryHandler, i).setBackground(
+ this.getGUITextureSet()
+ .getItemSlot(),
+ GTUITextures.OVERLAY_SLOT_INT_CIRCUIT)
+ .setPos(151, 4 + i * 18));
+ }
+
+ final DynamicPositionedColumn screenElements = new DynamicPositionedColumn();
+ this.drawTexts(screenElements);
+ builder.widget(screenElements);
+
+ builder.widget(
+ new DrawableWidget().setDrawable(BWUITextures.PICTURE_STORED_EU_FRAME)
+ .setPos(7, 72)
+ .setSize(118, 7))
+ .widget(
+ new ProgressBar().setProgress(
+ () -> (float) this.getBaseMetaTileEntity()
+ .getStoredEU() / this.getBaseMetaTileEntity()
+ .getEUCapacity())
+ .setDirection(ProgressBar.Direction.RIGHT)
+ .setTexture(BWUITextures.PROGRESSBAR_STORED_EU_116, 116)
+ .setPos(8, 73)
+ .setSize(116, 5));
+ }
+
+ private long clientEU;
+ private long clientMaxEU;
+ private long clientMaxIn;
+ private long clientMaxOut;
+ private long clientAmps;
+
+ private void drawTexts(DynamicPositionedColumn screenElements) {
+ screenElements.setSpace(0)
+ .setPos(11, 8);
+
+ screenElements.widget(
+ new TextWidget().setStringSupplier(() -> "EU: " + numberFormat.format(this.clientEU))
+ .setDefaultColor(this.COLOR_TEXT_WHITE.get()))
+ .widget(
+ new FakeSyncWidget.LongSyncer(
+ () -> this.getBaseMetaTileEntity()
+ .getStoredEU(),
+ val -> clientEU = val))
+ .widget(
+ new TextWidget().setStringSupplier(() -> "MAX: " + numberFormat.format(clientMaxEU))
+ .setDefaultColor(this.COLOR_TEXT_WHITE.get()))
+ .widget(
+ new FakeSyncWidget.LongSyncer(
+ () -> this.getBaseMetaTileEntity()
+ .isActive()
+ ? this.getBaseMetaTileEntity()
+ .getOutputVoltage() * ConfigHandler.energyPerCell
+ : 0,
+ val -> clientMaxEU = val))
+ .widget(
+ new TextWidget().setStringSupplier(() -> "MAX EU/t IN: " + numberFormat.format(clientMaxIn))
+ .setDefaultColor(this.COLOR_TEXT_WHITE.get()))
+ .widget(
+ new FakeSyncWidget.LongSyncer(
+ () -> this.getBaseMetaTileEntity()
+ .getInputVoltage(),
+ val -> clientMaxIn = val))
+ .widget(
+ new TextWidget().setStringSupplier(() -> "EU/t OUT: " + numberFormat.format(clientMaxOut))
+ .setDefaultColor(this.COLOR_TEXT_WHITE.get()))
+ .widget(
+ new FakeSyncWidget.LongSyncer(
+ () -> this.getBaseMetaTileEntity()
+ .getOutputVoltage(),
+ val -> clientMaxOut = val))
+ .widget(
+ new TextWidget().setStringSupplier(() -> "AMP/t IN/OUT: " + numberFormat.format(clientAmps))
+ .setDefaultColor(this.COLOR_TEXT_WHITE.get()))
+ .widget(
+ new FakeSyncWidget.LongSyncer(
+ () -> this.getBaseMetaTileEntity()
+ .getInputAmperage(),
+ val -> clientAmps = val))
+ .widget(
+ new TextWidget(Text.localised("tooltip.LESU.0.name")).setDefaultColor(Color.YELLOW.getRGB())
+ .setEnabled(widget -> this.maxEUStore() >= Long.MAX_VALUE - 1))
+ .widget(
+ new TextWidget(Text.localised("tooltip.LESU.1.name")).setDefaultColor(Color.RED.getRGB())
+ .setEnabled(
+ widget -> !this.getBaseMetaTileEntity()
+ .isActive()));
+ }
+
+ @Override
+ public boolean getDefaultHasMaintenanceChecks() {
+ return false;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEManualTrafo.java b/src/main/java/bartworks/common/tileentities/multis/MTEManualTrafo.java
new file mode 100644
index 0000000000..2533fd5213
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTEManualTrafo.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.common.loaders.ItemRegistry.BW_BLOCKS;
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.GTValues.V;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW;
+import static gregtech.api.util.GTStructureUtility.ofHatchAdder;
+import static gregtech.api.util.GTStructureUtility.ofHatchAdderOptional;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatchDynamo;
+import gregtech.api.metatileentity.implementations.MTEHatchEnergy;
+import gregtech.api.metatileentity.implementations.MTETieredMachineBlock;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+
+public class MTEManualTrafo extends MTEEnhancedMultiBlockBase<MTEManualTrafo> {
+
+ private byte mode;
+ private int mTiers;
+ private boolean upstep = true;
+
+ public MTEManualTrafo(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MTEManualTrafo(String aName) {
+ super(aName);
+ }
+
+ private static final int CASING_INDEX = 2;
+ private static final String STRUCTURE_PIECE_BASE = "base";
+ private static final String STRUCTURE_PIECE_LAYER = "layer";
+ private static final String STRUCTURE_PIECE_TOP = "top";
+ private static final String STRUCTURE_PIECE_TAP_LAYER = "taplayer";
+ private static final IStructureDefinition<MTEManualTrafo> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEManualTrafo>builder()
+ .addShape(STRUCTURE_PIECE_BASE, transpose(new String[][] { { "b~b", "bbb", "bbb" } }))
+ .addShape(STRUCTURE_PIECE_LAYER, transpose(new String[][] { { "ttt", "tft", "ttt" } }))
+ .addShape(STRUCTURE_PIECE_TOP, transpose(new String[][] { { "ooo", "ooo", "ooo" } }))
+ .addShape(
+ STRUCTURE_PIECE_TAP_LAYER,
+ transpose(new String[][] { { " TTT ", "TtttT", "TtftT", "TtttT", " TTT " } }))
+ .addElement(
+ 'b',
+ ofChain(
+ ofHatchAdder(MTEManualTrafo::addEnergyInputToMachineList, CASING_INDEX, 1),
+ ofHatchAdder(MTEManualTrafo::addMaintenanceToMachineList, CASING_INDEX, 1),
+ ofBlock(GregTechAPI.sBlockCasings1, 2)))
+ .addElement(
+ 'o',
+ ofHatchAdderOptional(
+ MTEManualTrafo::addDynamoToMachineList,
+ CASING_INDEX,
+ 2,
+ GregTechAPI.sBlockCasings1,
+ 2))
+ .addElement('t', ofBlock(BW_BLOCKS[2], 1))
+ .addElement('f', ofBlock(BW_BLOCKS[2], 0))
+ .addElement('T', new IStructureElementNoPlacement<MTEManualTrafo>() {
+
+ @Override
+ public boolean check(MTEManualTrafo te, World world, int x, int y, int z) {
+ if (world.isAirBlock(x, y, z)) return true;
+ TileEntity tileEntity = world.getTileEntity(x, y, z);
+ if (tileEntity == null || !(tileEntity instanceof IGregTechTileEntity)) return true;
+ IMetaTileEntity mte = ((IGregTechTileEntity) tileEntity).getMetaTileEntity();
+ if (mte instanceof MTEHatchDynamo || mte instanceof MTEHatchEnergy) {
+ int intier = te.mEnergyHatches.get(0).mTier;
+ if (((MTETieredMachineBlock) mte).mTier == intier + (te.upstep ? te.mTiers : -te.mTiers)) {
+ te.addToMachineList((IGregTechTileEntity) tileEntity, CASING_INDEX);
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean spawnHint(MTEManualTrafo te, World world, int x, int y, int z, ItemStack itemStack) {
+ StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), 2 /* aDots: 3 */);
+ return true;
+ }
+ })
+ .build();
+
+ @Override
+ public IStructureDefinition<MTEManualTrafo> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Transformer")
+ .addInfo("Controller block for the Manual Trafo")
+ .addInfo("Operates in 4 diffrent modes:")
+ .addInfo("Mode 1: Circuit 0 in controller: Direct-Upstep")
+ .addInfo("Mode 2: Circuit 1 in controller: Direct-Downstep")
+ .addInfo("Mode 3: Circuit 2 in controller: Tapped-Upstep (currently disabled)")
+ .addInfo("Mode 4: Circuit 2 in controller: Tapped-Downstep (currently disabled)")
+ .addSeparator()
+ .beginVariableStructureBlock(3, 3, 3, 10, 3, 3, false)
+ .addController("Front bottom center")
+ .addCasingInfoMin("MV Machine Casing", 0, false)
+ .addOtherStructurePart("Transformer-Winding Blocks", "1 Layer for each tier transformed")
+ .addOtherStructurePart("Nickel-Zinc-Ferrite Blocks", "Middle of Transformer-Winding Blocks")
+ .addMaintenanceHatch("Any bottom layer casing", 1)
+ .addEnergyHatch("Any bottom layer casing", 1)
+ .addDynamoHatch("Any top layer casing", 2)
+ .addStructureInfo("---------TAPPED MODE---------")
+ .addEnergyHatch("Touching Transformer-Winding Blocks", 3)
+ .addDynamoHatch("Touching Transformer-Winding Blocks", 3)
+ .addStructureInfo("Hatches touching Transformer-Winding Blocks must be tiered from bottom to top")
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ if (!this.getBaseMetaTileEntity()
+ .isAllowedToWork()) this.stopMachine();
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+ }
+
+ @Override
+ public boolean onRunningTick(ItemStack aStack) {
+ if (!this.getBaseMetaTileEntity()
+ .isAllowedToWork()) {
+ this.stopMachine();
+ return false;
+ }
+
+ this.mProgresstime = 0;
+ this.mMaxProgresstime = 1;
+
+ if (this.getBaseMetaTileEntity()
+ .getTimer() % 40 == 0) if (this.mEfficiency < this.getMaxEfficiency(null)) this.mEfficiency += 100;
+ else this.mEfficiency = this.getMaxEfficiency(null);
+
+ if (this.mode > 1) {
+ return false; // this.onRunningTickTabbedMode(); Tapped mode is disable
+ }
+
+ return this.drainEnergyInput(this.getInputTier() * 2 * this.mEnergyHatches.size()) && this.addEnergyOutput(
+ this.getInputTier() * 2 * this.mEnergyHatches.size() * this.mEfficiency / this.getMaxEfficiency(null));
+ }
+
+ public boolean onRunningTickTabbedMode() {
+ boolean ret = false;
+ for (MTEHatchDynamo E : this.mDynamoHatches) {
+ for (MTEHatchEnergy I : this.mEnergyHatches) {
+
+ long vtt = I.getEUVar() >= V[E.mTier] / 2 && E.getEUVar() < E.maxEUStore() ? I.getEUVar() : 0;
+
+ if (vtt == 0) continue;
+
+ long vtp = E.getEUVar() + vtt;
+ long avt = Math.min(vtp, E.maxEUStore());
+ E.setEUVar(avt);
+ I.setEUVar(I.getEUVar() - vtt);
+ ret = true;
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ public long getInputTier() {
+ if (this.mEnergyHatches.size() > 0) return GTUtility.getTier(
+ this.mEnergyHatches.get(0)
+ .getBaseMetaTileEntity()
+ .getInputVoltage());
+ return 0L;
+ }
+
+ @Override
+ public long getOutputTier() {
+ if (this.mDynamoHatches.size() > 0) return GTUtility.getTier(
+ this.mDynamoHatches.get(0)
+ .getBaseMetaTileEntity()
+ .getOutputVoltage());
+ return 0L;
+ }
+
+ @Override
+ public boolean checkRecipe(ItemStack itemStack) {
+
+ if (!this.getBaseMetaTileEntity()
+ .isAllowedToWork()) {
+ this.stopMachine();
+ return false;
+ }
+ if (itemStack == null || !itemStack.getUnlocalizedName()
+ .startsWith("gt.integrated_circuit")) this.mode = 0;
+ else this.mode = (byte) Math.min(3, itemStack.getItemDamage());
+ this.upstep = this.mode % 2 == 0;
+ this.mProgresstime = 0;
+ this.mMaxProgresstime = 1;
+ this.mEfficiency = Math.max(this.mEfficiency, 100);
+ return this.upstep ? this.getOutputTier() - this.getInputTier() == this.mTiers
+ : this.getInputTier() - this.getOutputTier() == this.mTiers;
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) {
+
+ if (itemStack == null || !itemStack.getUnlocalizedName()
+ .startsWith("gt.integrated_circuit")) this.mode = 0;
+ else this.mode = (byte) Math.min(3, itemStack.getItemDamage());
+
+ this.upstep = this.mode % 2 == 0;
+ boolean tapmode = this.mode > 1;
+
+ if (!this.checkPiece(STRUCTURE_PIECE_BASE, 1, 0, 0) || this.mEnergyHatches.size() == 0) return false;
+
+ byte intier = this.mEnergyHatches.get(0).mTier;
+ for (MTEHatchEnergy in : this.mEnergyHatches) if (in.mTier != intier) return false;
+
+ int mHeight;
+ for (mHeight = 1; mHeight <= 8; mHeight++) {
+ if (tapmode) {
+ this.mTiers = mHeight;
+ if (!this.checkPiece(STRUCTURE_PIECE_TAP_LAYER, 2, mHeight, 1)) break;
+ } else if (!this.checkPiece(STRUCTURE_PIECE_LAYER, 1, mHeight, 0)) break;
+ }
+ if (!this.checkPiece(STRUCTURE_PIECE_TOP, 1, mHeight, 0)) return false;
+ this.mTiers = mHeight - 1;
+
+ if (this.mDynamoHatches.size() == 0 || this.mMaintenanceHatches.size() != 1 || this.mTiers == 0) return false;
+
+ byte outtier = this.mDynamoHatches.get(0).mTier;
+ for (MTEHatchDynamo out : this.mDynamoHatches) {
+ if (out.mTier != outtier) return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEManualTrafo(this.mName);
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound ntag) {
+ super.saveNBTData(ntag);
+ ntag.setInteger("mTiers", this.mTiers);
+ ntag.setByte("mMode", this.mode);
+ ntag.setBoolean("upstep", this.upstep);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound ntag) {
+ super.loadNBTData(ntag);
+ this.mTiers = ntag.getInteger("mTiers");
+ this.mode = ntag.getByte("mMode");
+ this.upstep = ntag.getBoolean("upstep");
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) };
+ }
+
+ @Override
+ public void construct(ItemStack itemStack, boolean b) {
+ if (this.mInventory[1] == null || !this.mInventory[1].getUnlocalizedName()
+ .startsWith("gt.integrated_circuit")) this.mode = 0;
+ else this.mode = (byte) Math.min(3, this.mInventory[1].getItemDamage());
+ int mHeight = Math.min(itemStack.stackSize, 8);
+ boolean tapmode = this.mode > 1;
+ this.buildPiece(STRUCTURE_PIECE_BASE, itemStack, b, 1, 0, 0);
+ for (int i = 0; i < mHeight; i++) {
+ if (tapmode) this.buildPiece(STRUCTURE_PIECE_TAP_LAYER, itemStack, b, 2, i + 1, 1);
+ else this.buildPiece(STRUCTURE_PIECE_LAYER, itemStack, b, 1, i + 1, 0);
+ }
+ this.buildPiece(STRUCTURE_PIECE_TOP, itemStack, b, 1, mHeight + 1, 0);
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEThoriumHighTempReactor.java b/src/main/java/bartworks/common/tileentities/multis/MTEThoriumHighTempReactor.java
new file mode 100644
index 0000000000..064bc351fd
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTEThoriumHighTempReactor.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.util.GTStructureUtility.ofHatchAdder;
+import static gregtech.api.util.GTUtility.filterValidMTEs;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.common.items.SimpleSubItemClass;
+import bartworks.util.MathUtils;
+import cpw.mods.fml.common.registry.GameRegistry;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.Textures;
+import gregtech.api.enums.TierEU;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+
+public class MTEThoriumHighTempReactor extends MTEEnhancedMultiBlockBase<MTEThoriumHighTempReactor> {
+
+ private static final int BASECASINGINDEX = 44;
+
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition<MTEThoriumHighTempReactor> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEThoriumHighTempReactor>builder()
+ .addShape(
+ STRUCTURE_PIECE_MAIN,
+ transpose(
+ new String[][] {
+ { " BBBBBBB ", " BBBBBBBBB ", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB",
+ "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", " BBBBBBBBB ", " BBBBBBB " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c",
+ "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " },
+ { " bbb~bbb ", " bbbbbbbbb ", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb",
+ "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", " bbbbbbbbb ", " bbbbbbb " }, }))
+ .addElement('c', onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings3, 12)))
+ .addElement(
+ 'b',
+ ofChain(
+ ofHatchAdder(MTEThoriumHighTempReactor::addOutputToMachineList, BASECASINGINDEX, 1),
+ ofHatchAdder(MTEThoriumHighTempReactor::addMaintenanceToMachineList, BASECASINGINDEX, 1),
+ ofHatchAdder(MTEThoriumHighTempReactor::addEnergyInputToMachineList, BASECASINGINDEX, 1),
+ onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings3, 12))))
+ .addElement(
+ 'B',
+ ofChain(
+ ofHatchAdder(MTEThoriumHighTempReactor::addInputToMachineList, BASECASINGINDEX, 2),
+ onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings3, 12))))
+ // ofHatchAdderOptional(GT_TileEntity_THTR::addInputToMachineList, BASECASINGINDEX, 2,
+ // GregTechAPI.sBlockCasings3, 12))
+ .build();
+
+ private static final int HELIUM_NEEDED = 730000;
+ private static final int powerUsage = (int) TierEU.RECIPE_IV / 2;
+ private static final int maxcapacity = 675000;
+ private static final int mincapacity = 100000;
+ private int HeliumSupply;
+ private int fuelsupply;
+ private boolean empty;
+ private int coolanttaking = 0;
+ private int mCasing = 0;
+
+ public MTEThoriumHighTempReactor(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ private MTEThoriumHighTempReactor(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public IStructureDefinition<MTEThoriumHighTempReactor> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("High Temperature Reactor")
+ .addInfo("Controller block for the Thorium High Temperature Reactor (THTR)")
+ .addInfo("Needs to be primed with " + GTUtility.formatNumbers(HELIUM_NEEDED) + " of helium")
+ .addInfo("Needs a constant supply of coolant while running")
+ .addInfo("Needs at least 100k Fuel pebbles to start operation (can hold up to 675k pebbles)")
+ .addInfo("Consumes up to 0.5% of total Fuel Pellets per Operation depending on efficiency")
+ .addInfo("Efficiency decreases exponentially if the internal buffer is not completely filled")
+ .addInfo("Reactor will take 4 800L/t of coolant multiplied by efficiency")
+ .addInfo("Uses " + GTUtility.formatNumbers(powerUsage) + " EU/t")
+ .addInfo("One Operation takes 9 hours")
+ .addSeparator()
+ .beginStructureBlock(11, 12, 11, true)
+ .addController("Front bottom center")
+ .addCasingInfoMin("Radiation Proof Casings", 500, false)
+ .addStructureInfo("Corners and the 2 touching blocks are air (cylindric)")
+ .addInputBus("Any top layer casing", 2)
+ .addInputHatch("Any top layer casing", 2)
+ .addOutputBus("Any bottom layer casing", 1)
+ .addOutputHatch("Any bottom layer casing", 1)
+ .addEnergyHatch("Any bottom layer casing", 1)
+ .addMaintenanceHatch("Any bottom layer casing", 1)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ protected IAlignmentLimits getInitialAlignmentLimits() {
+ return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped();
+ }
+
+ @Override
+ public void construct(ItemStack stackSize, boolean hintsOnly) {
+ this.buildPiece(STRUCTURE_PIECE_MAIN, stackSize, hintsOnly, 5, 11, 0);
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) {
+ this.mCasing = 0;
+ return this.checkPiece(STRUCTURE_PIECE_MAIN, 5, 11, 0) && this.mCasing >= 500
+ && this.mMaintenanceHatches.size() == 1
+ && this.mInputHatches.size() > 0
+ && this.mOutputHatches.size() > 0
+ && this.mInputBusses.size() > 0
+ && this.mOutputBusses.size() > 0
+ && this.mEnergyHatches.size() > 0;
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ this.HeliumSupply = aNBT.getInteger("HeliumSupply");
+ this.fuelsupply = aNBT.getInteger("fuelsupply");
+ this.coolanttaking = aNBT.getInteger("coolanttaking");
+ this.empty = aNBT.getBoolean("EmptyMode");
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setInteger("HeliumSupply", this.HeliumSupply);
+ aNBT.setInteger("fuelsupply", this.fuelsupply);
+ aNBT.setInteger("coolanttaking", this.coolanttaking);
+ aNBT.setBoolean("EmptyMode", this.empty);
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+ if (aBaseMetaTileEntity.isServerSide() && !this.empty) {
+ if (this.HeliumSupply < MTEThoriumHighTempReactor.HELIUM_NEEDED) {
+ for (FluidStack fluidStack : this.getStoredFluids()) {
+ if (fluidStack.isFluidEqual(Materials.Helium.getGas(1))) {
+ int toget = Math
+ .min(MTEThoriumHighTempReactor.HELIUM_NEEDED - this.HeliumSupply, fluidStack.amount);
+ fluidStack.amount -= toget;
+ this.HeliumSupply += toget;
+ if (MTEThoriumHighTempReactor.HELIUM_NEEDED == this.HeliumSupply && fluidStack.amount == 0)
+ fluidStack = null;
+ }
+ }
+ }
+ if (this.fuelsupply < maxcapacity) {
+ this.startRecipeProcessing();
+ for (ItemStack itemStack : this.getStoredInputs()) {
+ if (GTUtility.areStacksEqual(
+ itemStack,
+ new ItemStack(THTRMaterials.aTHTR_Materials, 1, THTRMaterials.MATERIAL_FUEL_INDEX))) {
+ int toget = Math.min(maxcapacity - this.fuelsupply, itemStack.stackSize);
+ if (toget == 0) continue;
+ itemStack.stackSize -= toget;
+ this.fuelsupply += toget;
+ }
+ }
+ this.endRecipeProcessing();
+ this.updateSlots();
+ }
+ }
+ }
+
+ @Override
+ public boolean checkRecipe(ItemStack controllerStack) {
+
+ if (this.empty) {
+ if (this.HeliumSupply > 0 || this.fuelsupply > 0) {
+ this.mEfficiency = 10000;
+ this.mMaxProgresstime = 100;
+ return true;
+ }
+ return false;
+ }
+ if (this.HeliumSupply < MTEThoriumHighTempReactor.HELIUM_NEEDED || this.fuelsupply < mincapacity) return false;
+
+ double eff = Math
+ .min(Math.pow((this.fuelsupply - mincapacity) / ((maxcapacity - mincapacity) / 10D), 2D) + 1, 100D) / 100D
+ - (this.getIdealStatus() - this.getRepairStatus()) / 10D;
+ if (eff <= 0D) return false;
+
+ int toReduce = MathUtils.floorInt(this.fuelsupply * 0.005D * eff);
+
+ final int originalToReduce = toReduce;
+ int burnedballs = toReduce / 64;
+ if (burnedballs > 0) toReduce -= burnedballs * 64;
+
+ int meta = THTRMaterials.MATERIAL_USED_FUEL_INDEX;
+
+ ItemStack[] toOutput = { new ItemStack(THTRMaterials.aTHTR_Materials, burnedballs, meta),
+ new ItemStack(THTRMaterials.aTHTR_Materials, toReduce, meta + 1) };
+ if (!this.canOutputAll(toOutput)) return false;
+
+ this.fuelsupply -= originalToReduce;
+ this.mOutputItems = toOutput;
+
+ // this.updateSlots(); not needed ?
+
+ this.coolanttaking = (int) (4800D * eff);
+ this.mEfficiency = (int) (eff * 10000D);
+ this.mEUt = -powerUsage;
+ this.mMaxProgresstime = 648000;
+ return true;
+ }
+
+ @Override
+ public boolean onRunningTick(ItemStack aStack) {
+
+ if (this.empty) {
+ this.addOutput(Materials.Helium.getGas(this.HeliumSupply));
+ this.addOutput(
+ new ItemStack(THTRMaterials.aTHTR_Materials, this.fuelsupply, THTRMaterials.MATERIAL_FUEL_INDEX));
+ this.HeliumSupply = 0;
+ this.fuelsupply = 0;
+ this.updateSlots();
+ return true;
+ }
+
+ if (!super.onRunningTick(aStack)) return false;
+
+ int takecoolant = this.coolanttaking;
+ int drainedamount = 0;
+
+ for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) {
+ FluidStack tLiquid = tHatch.getFluid();
+ if (tLiquid != null && tLiquid.isFluidEqual(FluidRegistry.getFluidStack("ic2coolant", 1))) {
+ FluidStack drained = tHatch.drain(takecoolant, true);
+ takecoolant -= drained.amount;
+ drainedamount += drained.amount;
+ if (takecoolant <= 0) break;
+ }
+ }
+
+ if (drainedamount > 0) this.addOutput(FluidRegistry.getFluidStack("ic2hotcoolant", drainedamount));
+
+ this.updateSlots();
+
+ return true;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEThoriumHighTempReactor(this.mName);
+ }
+
+ @Override
+ public String[] getInfoData() {
+ return new String[] { "Progress:",
+ GTUtility.formatNumbers(this.mProgresstime / 20) + "secs /"
+ + GTUtility.formatNumbers(this.mMaxProgresstime / 20)
+ + "secs",
+ "TRISO-Pebbles:",
+ GTUtility.formatNumbers(this.fuelsupply) + "pcs. / " + GTUtility.formatNumbers(this.fuelsupply) + "psc.",
+ "Helium-Level:",
+ GTUtility.formatNumbers(this.HeliumSupply) + "L / "
+ + GTUtility.formatNumbers(MTEThoriumHighTempReactor.HELIUM_NEEDED)
+ + "L",
+ "Coolant/t:", GTUtility.formatNumbers(this.mProgresstime == 0 ? 0 : this.coolanttaking) + "L/t",
+ "Problems:", String.valueOf(this.getIdealStatus() - this.getRepairStatus()) };
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] {
+ Textures.BlockIcons.getCasingTextureForId(MTEThoriumHighTempReactor.BASECASINGINDEX),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] {
+ Textures.BlockIcons.getCasingTextureForId(MTEThoriumHighTempReactor.BASECASINGINDEX),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(MTEThoriumHighTempReactor.BASECASINGINDEX) };
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (this.mMaxProgresstime > 0) {
+ GTUtility.sendChatToPlayer(aPlayer, "THTR mode cannot be changed while the machine is running.");
+ return;
+ }
+ this.empty = !this.empty;
+ GTUtility.sendChatToPlayer(
+ aPlayer,
+ "THTR is now running in " + (this.empty ? "emptying mode." : "normal Operation"));
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+
+ public static class THTRMaterials {
+
+ public static final SimpleSubItemClass aTHTR_Materials = new SimpleSubItemClass(
+ "BISOPelletCompound", // 0
+ "BISOPelletBall", // 1
+ "TRISOPelletCompound", // 2
+ "TRISOPelletBall", // 3
+ "TRISOPellet", // 4
+ "BurnedOutTRISOPelletBall", // 5
+ "BurnedOutTRISOPellet" // 6
+ );
+ public static final int MATERIAL_FUEL_INDEX = 4;
+ public static final int MATERIAL_USED_FUEL_INDEX = 5;
+
+ public static void registeraTHR_Materials() {
+ GameRegistry.registerItem(MTEThoriumHighTempReactor.THTRMaterials.aTHTR_Materials, "bw.THTRMaterials");
+ }
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEWindmill.java b/src/main/java/bartworks/common/tileentities/multis/MTEWindmill.java
new file mode 100644
index 0000000000..e60c147b70
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/MTEWindmill.java
@@ -0,0 +1,637 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlockAnyMeta;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofTileAdder;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.GTValues.V;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.init.Blocks;
+import net.minecraft.init.Items;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.tileentity.TileEntityDispenser;
+import net.minecraft.util.IIcon;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.IStructureElement;
+import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement;
+import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+import com.gtnewhorizons.modularui.api.drawable.ItemDrawable;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+import com.gtnewhorizons.modularui.common.widget.TextWidget;
+
+import bartworks.API.modularUI.BWUITextures;
+import bartworks.MainMod;
+import bartworks.common.items.ItemStonageRotors;
+import bartworks.common.loaders.ItemRegistry;
+import bartworks.common.tileentities.classic.TileEntityRotorBlock;
+import cpw.mods.fml.common.FMLCommonHandler;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.enums.Textures;
+import gregtech.api.gui.modularui.GUITextureSet;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.modularui.IGetTitleColor;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase;
+import gregtech.api.objects.ItemData;
+import gregtech.api.recipe.RecipeMaps;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTOreDictUnificator;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.common.items.IDMetaTool01;
+import gregtech.common.items.MetaGeneratedTool01;
+
+public class MTEWindmill extends MTEEnhancedMultiBlockBase<MTEWindmill>
+ implements ISurvivalConstructable, IGetTitleColor {
+
+ private static final IIcon[] iIcons = new IIcon[2];
+ private static final IIconContainer[] iIconContainers = new IIconContainer[2];
+ private static final ITexture[] iTextures = new ITexture[3];
+
+ private TileEntityRotorBlock rotorBlock;
+ private int mDoor = 0;
+ private int mHardenedClay = 0;
+ private int mMulti = 16;
+
+ public MTEWindmill(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ private MTEWindmill(String aName) {
+ super(aName);
+ }
+
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition<MTEWindmill> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEWindmill>builder()
+ .addShape(
+ STRUCTURE_PIECE_MAIN,
+ transpose(
+ new String[][] { { " ", " ", " ", " p ", " ", " ", " " },
+ { " ", " ", " ppp ", " p p ", " ppp ", " ", " " },
+ { " ", " ppppp ", " p p ", " p p ", " p p ", " ppppp ", " " },
+ { " ppppp ", "p p", "p p", "p p", "p p", "p p", " ppppp " },
+ { " ppspp ", "p p", "p p", "p p", "p p", "p p", " ppppp " },
+ { " ppppp ", "p p", "p p", "p p", "p p", "p p", " ppppp " },
+ { " ", " ppppp ", " p p ", " p p ", " p p ", " ppppp ", " " },
+ { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " },
+ { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " },
+ { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " },
+ { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " },
+ { " bb~bb ", "bbbbbbb", "bbbbbbb", "bbbbbbb", "bbbbbbb", "bbbbbbb", " bbbbb " }, }))
+ .addElement('p', ofBlockAnyMeta(Blocks.planks))
+ .addElement(
+ 'c',
+ ofChain(
+ onElementPass(t -> t.mHardenedClay++, ofBlock(Blocks.hardened_clay, 0)),
+ ofTileAdder(MTEWindmill::addDispenserToOutputSet, Blocks.hardened_clay, 0),
+ onElementPass(t -> t.mDoor++, new IStructureElementNoPlacement<MTEWindmill>() {
+
+ private final IStructureElement<MTEWindmill> delegate = ofBlock(Blocks.wooden_door, 0);
+
+ @Override
+ public boolean check(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z) {
+ return this.delegate.check(gt_tileEntity_windmill, world, x, y, z);
+ }
+
+ @Override
+ public boolean spawnHint(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z,
+ ItemStack trigger) {
+ return this.delegate.spawnHint(gt_tileEntity_windmill, world, x, y, z, trigger);
+ }
+ })))
+ .addElement('b', ofBlock(Blocks.brick_block, 0))
+ .addElement('s', new IStructureElement<MTEWindmill>() {
+
+ @Override
+ public boolean check(MTEWindmill t, World world, int x, int y, int z) {
+ TileEntity tileEntity = world.getTileEntity(x, y, z);
+ return t.setRotorBlock(tileEntity);
+ }
+
+ @Override
+ public boolean spawnHint(MTEWindmill t, World world, int x, int y, int z, ItemStack trigger) {
+ StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), 0);
+ return true;
+ }
+
+ @Override
+ public boolean placeBlock(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z,
+ ItemStack trigger) {
+ return false;
+ }
+
+ @Override
+ public BlocksToPlace getBlocksToPlace(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z,
+ ItemStack trigger, AutoPlaceEnvironment env) {
+ return BlocksToPlace.create(new ItemStack(ItemRegistry.ROTORBLOCK));
+ }
+ })
+ .build();
+
+ @Override
+ public IStructureDefinition<MTEWindmill> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected IAlignmentLimits getInitialAlignmentLimits() {
+ return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped();
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Windmill")
+ .addInfo("Controller block for the Windmill")
+ .addInfo("A primitive Grinder powered by Kinetic energy")
+ .addInfo("Speed and output will be affected by wind speed, recipe and rotor")
+ .addInfo("Please use the Primitive Rotor")
+ .addInfo("Macerates 16 items at a time")
+ .addInfo("The structure is too complex!")
+ .addInfo("Follow the StructureLib hologram projector to build the main structure.")
+ .addSeparator()
+ .beginStructureBlock(7, 12, 7, false)
+ .addController("Front bottom center")
+ .addCasingInfoMin("Hardened Clay block", 40, false)
+ .addOtherStructurePart("Dispenser", "Any Hardened Clay block")
+ .addOtherStructurePart("0-1 Wooden door", "Any Hardened Clay block")
+ .addStructureHint("Primitive Kinetic Shaftbox", 1)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ private final Set<TileEntityDispenser> tileEntityDispensers = new HashSet<>();
+
+ @Override
+ public boolean onRunningTick(ItemStack aStack) {
+ if (this.mMaxProgresstime > 0) this.mProgresstime += this.rotorBlock.getGrindPower();
+ if (!this.rotorBlock.rotorSlot.isEmpty()) this.setRotorDamage(this.rotorBlock, this.rotorBlock.getGrindPower());
+ return this.rotorBlock.getGrindPower() > 0;
+ }
+
+ @Override
+ public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side,
+ ItemStack aStack) {
+ return true;
+ }
+
+ @Override
+ public boolean doRandomMaintenanceDamage() {
+ return true;
+ }
+
+ private float[] multiplierRecipe(ItemStack itemStack) {
+ // will return max and min value of the multiplier, the average of these is used to calculate the multiplier.
+ final Item item = itemStack.getItem();
+ if (item == Items.wheat) {
+ return new float[] { 1.13f, 1.5f };
+ }
+ final Block block = Block.getBlockFromItem(item);
+ if (item == Items.bone || block == Blocks.glowstone || block == Blocks.pumpkin) {
+ return new float[] { 0.8f, 1f };
+ }
+ if (block == Blocks.gravel || block == Blocks.cobblestone
+ || block == Blocks.stone
+ || block == Blocks.sandstone
+ || block == Blocks.clay
+ || block == Blocks.hardened_clay
+ || block == Blocks.stained_hardened_clay
+ || block == Blocks.wool
+ || block == Blocks.netherrack
+ || block == Blocks.log
+ || block == Blocks.log2) {
+ return new float[] { 1f, 1.5f };
+ }
+ final ItemData association = GTOreDictUnificator.getAssociation(itemStack);
+ final OrePrefixes prefix = association == null ? null : association.mPrefix;
+ if (prefix == null || association.mMaterial == null
+ || association.mMaterial.mMaterial == null
+ || association.mMaterial.mMaterial.getDust(1) == null) {
+ return new float[] { 1f, 1f };
+ }
+ if (OrePrefixes.ore == prefix || OrePrefixes.oreNetherrack == prefix
+ || OrePrefixes.oreEndstone == prefix
+ || OrePrefixes.oreBlackgranite == prefix
+ || OrePrefixes.oreRedgranite == prefix
+ || OrePrefixes.oreMarble == prefix
+ || OrePrefixes.oreBasalt == prefix) {
+ return new float[] { 0.5f, 1f };
+ }
+ if (OrePrefixes.stone == prefix || OrePrefixes.stoneBricks == prefix
+ || OrePrefixes.stoneChiseled == prefix
+ || OrePrefixes.stoneCobble == prefix
+ || OrePrefixes.stoneCracked == prefix
+ || OrePrefixes.stoneMossy == prefix
+ || OrePrefixes.stoneMossyBricks == prefix
+ || OrePrefixes.stoneSmooth == prefix
+ || OrePrefixes.cobblestone == prefix) {
+ return new float[] { 1f, 1.5f };
+ }
+ return new float[] { 1f, 1f };
+ }
+
+ @Override
+ public boolean checkRecipe(ItemStack itemStack) {
+ if (itemStack == null || itemStack.getItem() == null) return false;
+
+ if (this.mOutputItems == null) this.mOutputItems = new ItemStack[2];
+
+ GTRecipe tRecipe = RecipeMaps.maceratorRecipes
+ .findRecipe(this.getBaseMetaTileEntity(), false, false, V[1], null, itemStack);
+ if (tRecipe == null) {
+ return false;
+ }
+
+ if (tRecipe.getOutput(0) != null) {
+ // Decrease input stack by appropriate amount (Not always 1)
+ for (int i = 0; i < this.mMulti; i++) {
+ if (!tRecipe.isRecipeInputEqual(true, null, itemStack)) {
+ this.mMulti = i;
+ break;
+ }
+ }
+ this.updateSlots();
+ this.mOutputItems[0] = tRecipe.getOutput(0);
+ float[] mRecipe = this.multiplierRecipe(itemStack);
+ float multiper = Math.min(
+ mRecipe[1],
+ Math.max(
+ mRecipe[0],
+ 2f * (float) Math.sqrt((float) 1 / (this.rotorBlock.getWindStrength() + 1))
+ * this.OutputMultiplier(this.rotorBlock)
+ * (mRecipe[0] + mRecipe[1])));
+ int amount = (int) Math.floor(multiper * (this.mOutputItems[0].stackSize * this.mMulti));
+
+ // Split ItemStack --by gtpp
+ List<ItemStack> splitStacks = new ArrayList<>();
+ while (amount > this.mOutputItems[0].getMaxStackSize()) {
+ ItemStack tmp = this.mOutputItems[0].copy();
+ tmp.stackSize = this.mOutputItems[0].getMaxStackSize();
+ amount -= this.mOutputItems[0].getMaxStackSize();
+ splitStacks.add(tmp);
+ }
+ ItemStack tmp = this.mOutputItems[0].copy();
+ tmp.stackSize = amount;
+ splitStacks.add(tmp);
+ this.mOutputItems = splitStacks.toArray(new ItemStack[splitStacks.size()]);
+ }
+ this.mMaxProgresstime = tRecipe.mDuration * 2 * 100 * this.mMulti / this.getSpeed(this.rotorBlock);
+ this.mMulti = 16;
+ return true;
+ }
+
+ @Override
+ public void stopMachine() {
+ this.getBaseMetaTileEntity()
+ .disableWorking();
+ }
+
+ public boolean addDispenserToOutputSet(TileEntity aTileEntity) {
+ if (aTileEntity instanceof TileEntityDispenser) {
+ this.tileEntityDispensers.add((TileEntityDispenser) aTileEntity);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean setRotorBlock(TileEntity aTileEntity) {
+ if (aTileEntity instanceof TileEntityRotorBlock) {
+ this.rotorBlock = (TileEntityRotorBlock) aTileEntity;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean addOutput(ItemStack aStack) {
+ if (GTUtility.isStackInvalid(aStack)) return false;
+
+ for (TileEntityDispenser tHatch : this.tileEntityDispensers) {
+ for (int i = tHatch.getSizeInventory() - 1; i >= 0; i--) {
+ if (tHatch.getStackInSlot(i) == null || GTUtility.areStacksEqual(tHatch.getStackInSlot(i), aStack)
+ && aStack.stackSize + tHatch.getStackInSlot(i).stackSize <= 64) {
+ if (GTUtility.areStacksEqual(tHatch.getStackInSlot(i), aStack)) {
+ ItemStack merge = tHatch.getStackInSlot(i)
+ .copy();
+ merge.stackSize = aStack.stackSize + tHatch.getStackInSlot(i).stackSize;
+ tHatch.setInventorySlotContents(i, merge);
+ } else {
+ tHatch.setInventorySlotContents(i, aStack.copy());
+ }
+
+ if (GTUtility.areStacksEqual(tHatch.getStackInSlot(i), aStack)) {
+ aStack = null;
+ return true;
+ }
+ tHatch.setInventorySlotContents(i, null);
+ aStack = null;
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) {
+
+ this.tileEntityDispensers.clear();
+ this.mDoor = 0;
+ this.mHardenedClay = 0;
+
+ return this.checkPiece(STRUCTURE_PIECE_MAIN, 3, 11, 0) && !this.tileEntityDispensers.isEmpty()
+ && this.mDoor <= 2
+ && this.mHardenedClay >= 40;
+ }
+
+ @Override
+ public int getCurrentEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public void updateSlots() {
+ if (this.mInventory[1] != null && this.mInventory[1].stackSize <= 0) {
+ this.mInventory[1] = null;
+ }
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEWindmill(this.mName);
+ }
+
+ @Override
+ public String[] getInfoData() {
+ return new String[] { "Progress:",
+ this.mProgresstime + " Grindings of " + this.mMaxProgresstime + " needed Grindings", "GrindPower:",
+ this.rotorBlock.getGrindPower() + "KU/t" };
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void registerIcons(IIconRegister aBlockIconRegister) {
+ MTEWindmill.iIcons[0] = Blocks.brick_block.getIcon(0, 0);
+ MTEWindmill.iIconContainers[0] = new IIconContainer() {
+
+ @Override
+ public IIcon getIcon() {
+ return MTEWindmill.iIcons[0];
+ }
+
+ @Override
+ public IIcon getOverlayIcon() {
+ return null;
+ }
+
+ @Override
+ public ResourceLocation getTextureFile() {
+ return new ResourceLocation("brick");
+ }
+ };
+
+ MTEWindmill.iIcons[1] = aBlockIconRegister.registerIcon(MainMod.MOD_ID + ":windmill_top");
+ MTEWindmill.iIconContainers[1] = new IIconContainer() {
+
+ @Override
+ public IIcon getIcon() {
+ return MTEWindmill.iIcons[1];
+ }
+
+ @Override
+ public IIcon getOverlayIcon() {
+ return null;
+ }
+
+ @Override
+ public ResourceLocation getTextureFile() {
+ return new ResourceLocation(MainMod.MOD_ID + ":windmill_top");
+ }
+ };
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+
+ ITexture[] ret = new ITexture[6];
+
+ if (this.isClientSide()) {
+
+ if (facing == side || side == ForgeDirection.DOWN) {
+ MTEWindmill.iTextures[0] = TextureFactory.of(MTEWindmill.iIconContainers[0]);
+ Arrays.fill(ret, MTEWindmill.iTextures[0]);
+ } else if (side == ForgeDirection.UP) {
+ MTEWindmill.iTextures[1] = TextureFactory.of(MTEWindmill.iIconContainers[1]);
+ Arrays.fill(ret, MTEWindmill.iTextures[1]);
+ } else {
+ MTEWindmill.iTextures[2] = TextureFactory.of(Textures.BlockIcons.COVER_WOOD_PLATE);
+ Arrays.fill(ret, MTEWindmill.iTextures[2]);
+ }
+ }
+ return ret;
+ }
+
+ public boolean isClientSide() {
+ if (this.getBaseMetaTileEntity()
+ .getWorld() != null)
+ return this.getBaseMetaTileEntity()
+ .getWorld().isRemote
+ ? FMLCommonHandler.instance()
+ .getSide() == Side.CLIENT
+ : FMLCommonHandler.instance()
+ .getEffectiveSide() == Side.CLIENT;
+ return FMLCommonHandler.instance()
+ .getEffectiveSide() == Side.CLIENT;
+ }
+
+ @Override
+ public void construct(ItemStack itemStack, boolean b) {
+ this.buildPiece(STRUCTURE_PIECE_MAIN, itemStack, b, 3, 11, 0);
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) {
+ if (this.mMachine) return -1;
+ return this.survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 3, 11, 0, elementBudget, env, false, true);
+ }
+
+ public float OutputMultiplier(TileEntityRotorBlock rotorBlock) {
+ try {
+ return ((ItemStonageRotors) rotorBlock.rotorSlot.get()
+ .getItem()).getmRotor();
+ } catch (Exception e) {
+ return 1f;
+ }
+ }
+
+ public int getSpeed(TileEntityRotorBlock rotorBlock) {
+ try {
+ return ((ItemStonageRotors) rotorBlock.rotorSlot.get()
+ .getItem()).getSpeed();
+ } catch (Exception e) {
+ return 1;
+ }
+ }
+
+ public void setRotorDamage(TileEntityRotorBlock rotorBlock, int damage) {
+ try {
+ ((ItemStonageRotors) rotorBlock.rotorSlot.get()
+ .getItem()).damageItemStack(rotorBlock.rotorSlot.get(), damage);
+ } catch (Exception e) {
+ rotorBlock.rotorSlot.damage(damage, false);
+ }
+ }
+
+ @Override
+ public GUITextureSet getGUITextureSet() {
+ return new GUITextureSet().setMainBackground(BWUITextures.BACKGROUND_BROWN)
+ .setItemSlot(BWUITextures.SLOT_BROWN)
+ .setTitleTab(
+ BWUITextures.TAB_TITLE_BROWN,
+ BWUITextures.TAB_TITLE_DARK_BROWN,
+ BWUITextures.TAB_TITLE_ANGULAR_BROWN);
+ }
+
+ @Override
+ public void addGregTechLogo(ModularWindow.Builder builder) {
+ builder.widget(
+ new DrawableWidget().setDrawable(BWUITextures.PICTURE_BW_LOGO_47X21)
+ .setSize(47, 21)
+ .setPos(123, 59));
+ }
+
+ @Override
+ public int getTitleColor() {
+ return this.COLOR_TITLE_WHITE.get();
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ builder.widget(
+ new SlotWidget(this.inventoryHandler, 1).setBackground(
+ this.getGUITextureSet()
+ .getItemSlot())
+ .setPos(59, 35))
+ .widget(new DrawableWidget() {
+
+ private static final int DIVIDER = 125;
+
+ @Override
+ public void onScreenUpdate() {
+ super.onScreenUpdate();
+ if (MTEWindmill.this.mMaxProgresstime > 0) {
+ if (System.currentTimeMillis() / DIVIDER % 40 == 30)
+ this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[3]);
+ else if (System.currentTimeMillis() / DIVIDER % 40 == 20)
+ this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[2]);
+ else if (System.currentTimeMillis() / DIVIDER % 40 == 10)
+ this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[1]);
+ else if (System.currentTimeMillis() / DIVIDER % 40 == 0)
+ this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[0]);
+ } else {
+ this.setDrawable(BWUITextures.PICTURE_WINDMILL_EMPTY);
+ }
+ }
+ }.setDrawable(BWUITextures.PICTURE_WINDMILL_EMPTY)
+ .setPos(85, 27)
+ .setSize(32, 32))
+ .widget(new FakeSyncWidget.IntegerSyncer(() -> this.mMaxProgresstime, val -> this.mMaxProgresstime = val))
+ .widget(
+ new ItemDrawable(
+ () -> this.mMachine && !this.getBaseMetaTileEntity()
+ .isActive()
+ ? MetaGeneratedTool01.INSTANCE
+ .getToolWithStats(IDMetaTool01.SOFTMALLET.ID, 1, null, null, null)
+ : null).asWidget()
+ .setPos(66, 66))
+ .widget(
+ new FakeSyncWidget.BooleanSyncer(
+ () -> this.getBaseMetaTileEntity()
+ .isActive(),
+ val -> this.getBaseMetaTileEntity()
+ .setActive(val)))
+ .widget(
+ new TextWidget(GTUtility.trans("138", "Incomplete Structure."))
+ .setDefaultColor(this.COLOR_TEXT_WHITE.get())
+ .setMaxWidth(150)
+ .setEnabled(widget -> !this.mMachine)
+ .setPos(92, 22))
+ .widget(new FakeSyncWidget.BooleanSyncer(() -> this.mMachine, val -> this.mMachine = val));
+ }
+
+ @Override
+ public boolean getDefaultHasMaintenanceChecks() {
+ return false;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaBlastFurnace.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaBlastFurnace.java
new file mode 100644
index 0000000000..8d5ea073db
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaBlastFurnace.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis.mega;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.withChannel;
+import static gregtech.api.enums.HatchElement.*;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+import static gregtech.api.util.GTStructureUtility.ofCoil;
+import static gregtech.api.util.GTUtility.filterValidMTEs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.structure.IItemSource;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.API.BorosilicateGlass;
+import bartworks.common.configs.ConfigHandler;
+import bartworks.util.BWUtil;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.GTValues;
+import gregtech.api.enums.HeatingCoilLevel;
+import gregtech.api.enums.Materials;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.metatileentity.implementations.MTEHatchMuffler;
+import gregtech.api.metatileentity.implementations.MTEHatchOutput;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.RecipeMaps;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.api.util.OverclockCalculator;
+
+public class MTEMegaBlastFurnace extends MegaMultiBlockBase<MTEMegaBlastFurnace> implements ISurvivalConstructable {
+
+ private static final int CASING_INDEX = 11;
+ private static final IStructureDefinition<MTEMegaBlastFurnace> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEMegaBlastFurnace>builder()
+ .addShape("main", createShape())
+ .addElement('=', StructureElementAirNoHint.getInstance())
+ .addElement(
+ 't',
+ buildHatchAdder(MTEMegaBlastFurnace.class)
+ .atLeast(
+ OutputHatch.withAdder(MTEMegaBlastFurnace::addOutputHatchToTopList)
+ .withCount(t -> t.mPollutionOutputHatches.size()))
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(GregTechAPI.sBlockCasings1, CASING_INDEX))
+ .addElement('m', Muffler.newAny(CASING_INDEX, 2))
+ .addElement(
+ 'C',
+ withChannel("coil", ofCoil(MTEMegaBlastFurnace::setCoilLevel, MTEMegaBlastFurnace::getCoilLevel)))
+ .addElement(
+ 'g',
+ withChannel(
+ "glass",
+ BorosilicateGlass
+ .ofBoroGlass((byte) 0, (byte) 1, Byte.MAX_VALUE, (te, t) -> te.glassTier = t, te -> te.glassTier)))
+ .addElement(
+ 'b',
+ buildHatchAdder(MTEMegaBlastFurnace.class)
+ .atLeast(InputHatch, OutputHatch, InputBus, OutputBus, Maintenance, Energy.or(ExoticEnergy))
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(GregTechAPI.sBlockCasings1, CASING_INDEX))
+ .build();
+
+ private static String[][] createShape() {
+ String[][] raw = new String[20][];
+
+ raw[0] = new String[15];
+ String topCasing = "ttttttttttttttt";
+ String middleTopCasing = "tttttttmttttttt";
+ raw[0][0] = topCasing;
+ for (int i = 1; i < 15; i++) {
+ raw[0][i] = topCasing;
+ }
+ raw[0][7] = middleTopCasing;
+
+ raw[1] = new String[15];
+ String allGlass = "ggggggggggggggg";
+ String allCoil = "gCCCCCCCCCCCCCg";
+ String middleLine = "gC===========Cg";
+ raw[1][0] = allGlass;
+ raw[1][1] = allCoil;
+ raw[1][13] = allCoil;
+ raw[1][14] = allGlass;
+ for (int i = 2; i < 13; i++) {
+ raw[1][i] = middleLine;
+ }
+ for (int i = 2; i < 19; i++) {
+ raw[i] = raw[1];
+ }
+ String bottomCasing = "bbbbbbbbbbbbbbb";
+ raw[19] = new String[15];
+ for (int i = 0; i < 15; i++) {
+ raw[19][i] = bottomCasing;
+ }
+
+ raw[17] = Arrays.copyOf(raw[17], raw[17].length);
+ raw[17][0] = "ggggggg~ggggggg";
+
+ return transpose(raw);
+ }
+
+ private HeatingCoilLevel mCoilLevel;
+ protected final ArrayList<MTEHatchOutput> mPollutionOutputHatches = new ArrayList<>();
+ protected final FluidStack[] pollutionFluidStacks = { Materials.CarbonDioxide.getGas(1000),
+ Materials.CarbonMonoxide.getGas(1000), Materials.SulfurDioxide.getGas(1000) };
+ private int mHeatingCapacity;
+ private byte glassTier;
+ private final static int polPtick = ConfigHandler.basePollutionMBFSecond / 20 * ConfigHandler.megaMachinesMax;
+
+ public MTEMegaBlastFurnace(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MTEMegaBlastFurnace(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEMegaBlastFurnace(this.mName);
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Blast Furnace")
+ .addInfo("Controller block for the Mega Blast Furnace")
+ .addInfo("You can use some fluids to reduce recipe time. Place the circuit in the Input Bus")
+ .addInfo("Each 900K over the min. Heat required reduces power consumption by 5% (multiplicatively)")
+ .addInfo("Each 1800K over the min. Heat allows for an overclock to be upgraded to a perfect overclock.")
+ .addInfo("That means the EBF will reduce recipe time by a factor 4 instead of 2 (giving 100% efficiency).")
+ .addInfo("Additionally gives +100K for every tier past MV")
+ .addInfo(
+ GTValues.TIER_COLORS[8] + GTValues.VN[8]
+ + EnumChatFormatting.GRAY
+ + "-tier glass required for "
+ + EnumChatFormatting.BLUE
+ + "Tec"
+ + EnumChatFormatting.DARK_BLUE
+ + "Tech"
+ + EnumChatFormatting.GRAY
+ + " Laser Hatches.")
+ .addPollutionAmount(20 * this.getPollutionPerTick(null))
+ .addSeparator()
+ .beginStructureBlock(15, 20, 15, true)
+ .addController("3rd layer center")
+ .addCasingInfoRange("Heat Proof Machine Casing", 0, 279, false)
+ .addOtherStructurePart("864x Heating Coils", "Inner 13x18x13 (Hollow)")
+ .addOtherStructurePart("1007x Borosilicate Glass", "Outer 15x18x15")
+ .addStructureInfo("The glass tier limits the Energy Input tier")
+ .addEnergyHatch("Any bottom layer casing")
+ .addMaintenanceHatch("Any bottom layer casing")
+ .addMufflerHatch("Top middle")
+ .addInputBus("Any bottom layer casing")
+ .addInputHatch("Any bottom layer casing")
+ .addOutputBus("Any bottom layer casing")
+ .addOutputHatch("Gasses, Any top layer casing")
+ .addStructureInfo("Recovery amount scales with Muffler Hatch tier")
+ .addOutputHatch("Platline fluids, Any bottom layer casing")
+ .addStructureHint("This Mega Multiblock is too big to have its structure hologram displayed fully.")
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ this.glassTier = aNBT.getByte("glasTier");
+ if (!aNBT.hasKey(INPUT_SEPARATION_NBT_KEY)) {
+ this.inputSeparation = aNBT.getBoolean("isBussesSeparate");
+ }
+ if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) {
+ this.batchMode = aNBT.getBoolean("mUseMultiparallelMode");
+ }
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (!aPlayer.isSneaking()) {
+ this.inputSeparation = !this.inputSeparation;
+ GTUtility.sendChatToPlayer(
+ aPlayer,
+ StatCollector.translateToLocal("GT5U.machines.separatebus") + " " + this.inputSeparation);
+ return true;
+ }
+ this.batchMode = !this.batchMode;
+ if (this.batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { casingTexturePages[0][CASING_INDEX] };
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setByte("glasTier", this.glassTier);
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack aStack) {
+ return polPtick;
+ }
+
+ public boolean addOutputHatchToTopList(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 this.mPollutionOutputHatches.add((MTEHatchOutput) aMetaTileEntity);
+ }
+ return false;
+ }
+
+ @Override
+ protected String[] getExtendedInfoData() {
+ return new String[] { StatCollector.translateToLocal("GT5U.EBF.heat") + ": "
+ + EnumChatFormatting.GREEN
+ + GTUtility.formatNumbers(this.mHeatingCapacity)
+ + EnumChatFormatting.RESET
+ + " K" };
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic() {
+
+ @Nonnull
+ @Override
+ protected OverclockCalculator createOverclockCalculator(@Nonnull GTRecipe recipe) {
+ return super.createOverclockCalculator(recipe).setRecipeHeat(recipe.mSpecialValue)
+ .setMachineHeat(MTEMegaBlastFurnace.this.mHeatingCapacity)
+ .setHeatOC(true)
+ .setHeatDiscount(true);
+ }
+
+ @Override
+ protected @Nonnull CheckRecipeResult validateRecipe(@Nonnull GTRecipe recipe) {
+ return recipe.mSpecialValue <= MTEMegaBlastFurnace.this.mHeatingCapacity
+ ? CheckRecipeResultRegistry.SUCCESSFUL
+ : CheckRecipeResultRegistry.insufficientHeat(recipe.mSpecialValue);
+ }
+ }.setMaxParallel(ConfigHandler.megaMachinesMax);
+ }
+
+ @Override
+ public IStructureDefinition<MTEMegaBlastFurnace> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ public void construct(ItemStack stackSize, boolean hintsOnly) {
+ this.buildPiece("main", stackSize, hintsOnly, 7, 17, 0);
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) {
+ if (this.mMachine) return -1;
+ int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5);
+ this.glassTier = 0;
+ this.setCoilLevel(HeatingCoilLevel.None);
+ return this.survivialBuildPiece("main", stackSize, 7, 17, 0, realBudget, source, actor, false, true);
+ }
+
+ public void setCoilLevel(HeatingCoilLevel aCoilLevel) {
+ this.mCoilLevel = aCoilLevel;
+ }
+
+ public HeatingCoilLevel getCoilLevel() {
+ return this.mCoilLevel;
+ }
+
+ @Override
+ public boolean addOutput(FluidStack aLiquid) {
+ if (aLiquid == null) return false;
+ FluidStack tLiquid = aLiquid.copy();
+ boolean isOutputPollution = false;
+ for (FluidStack pollutionFluidStack : this.pollutionFluidStacks) {
+ if (!tLiquid.isFluidEqual(pollutionFluidStack)) continue;
+
+ isOutputPollution = true;
+ break;
+ }
+ ArrayList<MTEHatchOutput> tOutputHatches;
+ if (isOutputPollution) {
+ tOutputHatches = this.mPollutionOutputHatches;
+ int pollutionReduction = 0;
+ for (MTEHatchMuffler tHatch : filterValidMTEs(mMufflerHatches)) {
+ pollutionReduction = 100 - tHatch.calculatePollutionReduction(100);
+ break;
+ }
+ tLiquid.amount = tLiquid.amount * pollutionReduction / 100;
+ } else {
+ tOutputHatches = this.mOutputHatches;
+ }
+ return dumpFluid(tOutputHatches, tLiquid, true) || dumpFluid(tOutputHatches, tLiquid, false);
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity iGregTechTileEntity, ItemStack itemStack) {
+ this.mHeatingCapacity = 0;
+ this.glassTier = 0;
+
+ this.setCoilLevel(HeatingCoilLevel.None);
+
+ this.mPollutionOutputHatches.clear();
+
+ if (!this.checkPiece("main", 7, 17, 0) || this.getCoilLevel() == HeatingCoilLevel.None
+ || this.mMaintenanceHatches.size() != 1) return false;
+
+ if (this.glassTier < 8) {
+ for (int i = 0; i < this.mExoticEnergyHatches.size(); ++i) {
+ MTEHatch hatch = this.mExoticEnergyHatches.get(i);
+ if (hatch.getConnectionType() == MTEHatch.ConnectionType.LASER) {
+ return false;
+ }
+ if (this.glassTier < hatch.mTier) {
+ return false;
+ }
+ }
+ for (int i = 0; i < this.mEnergyHatches.size(); ++i) {
+ if (this.glassTier < this.mEnergyHatches.get(i).mTier) {
+ return false;
+ }
+ }
+ }
+
+ this.mHeatingCapacity = (int) this.getCoilLevel()
+ .getHeat() + 100 * (BWUtil.getTier(this.getMaxInputEu()) - 2);
+
+ return true;
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return RecipeMaps.blastFurnaceRecipes;
+ }
+
+ @Override
+ public int getRecipeCatalystPriority() {
+ return -2;
+ }
+
+ @Override
+ public boolean supportsInputSeparation() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaChemicalReactor.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaChemicalReactor.java
new file mode 100644
index 0000000000..e1366cec7d
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaChemicalReactor.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis.mega;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.HatchElement.*;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.structure.IItemSource;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.API.BorosilicateGlass;
+import bartworks.common.configs.ConfigHandler;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.GTValues;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.RecipeMaps;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+
+public class MTEMegaChemicalReactor extends MegaMultiBlockBase<MTEMegaChemicalReactor>
+ implements ISurvivalConstructable {
+
+ private byte glassTier;
+
+ public MTEMegaChemicalReactor(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MTEMegaChemicalReactor(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public MultiblockTooltipBuilder createTooltip() {
+ final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Chemical Reactor")
+ .addInfo("Controller block for the Chemical Reactor")
+ .addInfo("What molecule do you want to synthesize")
+ .addInfo("Or you want to replace something in this molecule")
+ .addInfo(
+ GTValues.TIER_COLORS[8] + GTValues.VN[8]
+ + EnumChatFormatting.GRAY
+ + "-tier glass required for "
+ + EnumChatFormatting.BLUE
+ + "Tec"
+ + EnumChatFormatting.DARK_BLUE
+ + "Tech"
+ + EnumChatFormatting.GRAY
+ + " Laser Hatches.")
+ .addInfo("The structure is too complex!")
+ .addInfo("Follow the Structure Lib hologram projector to build the main structure.")
+ .addSeparator()
+ .beginStructureBlock(5, 5, 9, false)
+ .addController("Front center")
+ .addStructureInfo("46x Chemically Inert Machine Casing (minimum)")
+ .addStructureInfo("7x Fusion Coil Block")
+ .addStructureInfo("28x PTFE Pipe Casing")
+ .addStructureInfo("64x Borosilicate Glass Block (any tier)")
+ .addStructureInfo("The glass tier limits the Energy Input tier")
+ .addEnergyHatch("Hint block ", 3)
+ .addMaintenanceHatch("Hint block ", 2)
+ .addInputHatch("Hint block ", 1)
+ .addInputBus("Hint block ", 1)
+ .addOutputBus("Hint block ", 1)
+ .addOutputHatch("Hint block ", 1)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEMegaChemicalReactor(this.mName);
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { casingTexturePages[1][48], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { casingTexturePages[1][48], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { casingTexturePages[1][48] };
+ }
+
+ @Override
+ public boolean supportsSingleRecipeLocking() {
+ return true;
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return RecipeMaps.multiblockChemicalReactorRecipes;
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) {
+ this.batchMode = aNBT.getBoolean("mUseMultiparallelMode");
+ }
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ inputSeparation = !inputSeparation;
+ GTUtility.sendChatToPlayer(
+ aPlayer,
+ StatCollector.translateToLocal("GT5U.machines.separatebus") + " " + inputSeparation);
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (aPlayer.isSneaking()) {
+ this.batchMode = !this.batchMode;
+ if (this.batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic().enablePerfectOverclock()
+ .setMaxParallel(ConfigHandler.megaMachinesMax);
+ }
+
+ @Override
+ public void construct(ItemStack aStack, boolean aHintsOnly) {
+ this.buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 2, 2, 0);
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) {
+ if (this.mMachine) return -1;
+ int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5);
+ return this
+ .survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 2, 2, 0, realBudget, source, actor, false, true);
+ }
+ // -------------- TEC TECH COMPAT ----------------
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ this.glassTier = 0;
+
+ if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 2, 2, 0) || this.mMaintenanceHatches.size() != 1) return false;
+
+ if (this.glassTier < 8) {
+ for (int i = 0; i < this.mExoticEnergyHatches.size(); ++i) {
+ MTEHatch hatch = this.mExoticEnergyHatches.get(i);
+ if (hatch.getConnectionType() == MTEHatch.ConnectionType.LASER) {
+ return false;
+ }
+ if (this.glassTier < hatch.mTier) {
+ return false;
+ }
+ }
+ for (int i = 0; i < this.mEnergyHatches.size(); ++i) {
+ if (this.glassTier < this.mEnergyHatches.get(i).mTier) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private static final int CASING_INDEX = 176;
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition<MTEMegaChemicalReactor> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEMegaChemicalReactor>builder()
+ .addShape(
+ STRUCTURE_PIECE_MAIN,
+ transpose(
+ new String[][] { { "ttttt", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "ttttt" },
+ { "tgggt", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", "teeet" },
+ { "tg~gt", " gcg ", " gcg ", " gcg ", " gcg ", " gcg ", " gcg ", " gcg ", "teret" },
+ { "tgggt", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", "teeet" },
+ { "ttttt", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "ttttt" }, }))
+ .addElement('p', ofBlock(GregTechAPI.sBlockCasings8, 1))
+ .addElement('t', ofBlock(GregTechAPI.sBlockCasings8, 0))
+ .addElement(
+ 'd',
+ buildHatchAdder(MTEMegaChemicalReactor.class).atLeast(InputBus, InputHatch, OutputBus, OutputHatch)
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(GregTechAPI.sBlockCasings8, 0))
+ .addElement('r', Maintenance.newAny(CASING_INDEX, 2))
+ .addElement(
+ 'e',
+ buildHatchAdder(MTEMegaChemicalReactor.class)
+ .atLeast(Energy.or(ExoticEnergy), InputHatch, InputBus, OutputHatch, OutputBus)
+ .casingIndex(CASING_INDEX)
+ .dot(3)
+ .buildAndChain(GregTechAPI.sBlockCasings8, 0))
+ .addElement('c', ofChain(ofBlock(GregTechAPI.sBlockCasings4, 7), ofBlock(GregTechAPI.sBlockCasings5, 13)))
+ .addElement(
+ 'g',
+ BorosilicateGlass
+ .ofBoroGlass((byte) 0, (byte) 1, Byte.MAX_VALUE, (te, t) -> te.glassTier = t, te -> te.glassTier))
+ .build();
+
+ @Override
+ public IStructureDefinition<MTEMegaChemicalReactor> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsInputSeparation() {
+ return true;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaDistillTower.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaDistillTower.java
new file mode 100644
index 0000000000..382b64fb47
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaDistillTower.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis.mega;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.HatchElement.*;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_GLOW;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.structure.IItemSource;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.IStructureElementCheckOnly;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.common.configs.ConfigHandler;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.IHatchElement;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.fluid.IFluidStore;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEHatchOutput;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.RecipeMaps;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.common.tileentities.machines.MTEHatchOutputME;
+
+public class MTEMegaDistillTower extends MegaMultiBlockBase<MTEMegaDistillTower> implements ISurvivalConstructable {
+
+ protected static final int CASING_INDEX = 49;
+ protected static final String STRUCTURE_PIECE_BASE = "base";
+ protected static final String STRUCTURE_PIECE_LAYER = "layer";
+ protected static final String STRUCTURE_PIECE_TOP_HINT = "top";
+ private static final IStructureDefinition<MTEMegaDistillTower> STRUCTURE_DEFINITION;
+
+ static {
+ IHatchElement<MTEMegaDistillTower> layeredOutputHatch = OutputHatch
+ .withCount(MTEMegaDistillTower::getCurrentLayerOutputHatchCount)
+ .withAdder(MTEMegaDistillTower::addLayerOutputHatch);
+ STRUCTURE_DEFINITION = StructureDefinition.<MTEMegaDistillTower>builder()
+ .addShape(
+ STRUCTURE_PIECE_BASE,
+ transpose(
+ new String[][] { { "bbbbbbb~bbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb",
+ "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb",
+ "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb",
+ "bbbbbbbbbbbbbbb" }, }))
+ .addShape(
+ STRUCTURE_PIECE_LAYER,
+ transpose(
+ new String[][] {
+ { "lllllllllllllll", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl",
+ "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl",
+ "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl",
+ "lcccccccccccccl", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" }, }))
+ .addShape(
+ STRUCTURE_PIECE_TOP_HINT,
+ transpose(
+ new String[][] {
+ { "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll",
+ "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll",
+ "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll",
+ "lllllllllllllll", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" },
+ { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "l=============l", "l=============l", "l=============l",
+ "l=============l", "lllllllllllllll" }, }))
+ .addElement('=', StructureElementAirNoHint.getInstance())
+ .addElement(
+ 'b',
+ buildHatchAdder(MTEMegaDistillTower.class)
+ .atLeast(InputHatch, OutputHatch, InputBus, OutputBus, Maintenance, Energy.or(ExoticEnergy))
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(
+ onElementPass(MTEMegaDistillTower::onCasingFound, ofBlock(GregTechAPI.sBlockCasings4, 1))))
+ .addElement(
+ 'l',
+ buildHatchAdder(MTEMegaDistillTower.class)
+ .atLeast(layeredOutputHatch, Maintenance, Energy.or(ExoticEnergy))
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(
+ onElementPass(MTEMegaDistillTower::onCasingFound, ofBlock(GregTechAPI.sBlockCasings4, 1))))
+ .addElement('c', (IStructureElementCheckOnly<MTEMegaDistillTower>) (t, world, x, y, z) -> {
+ if (world.isAirBlock(x, y, z)) {
+ if (t.mTopState < 1) {
+ t.mTopState = 0;
+ return true;
+ }
+ // definitely top - cannot be air
+ return false;
+ }
+ // from here on we must be looking at a top layer, since it's not air
+ if (t.mTopState == 0)
+ // must be air but failed, so no
+ return false;
+ t.mTopState = 1;
+ // hatch adder
+ TileEntity tileEntity = world.getTileEntity(x, y, z);
+ if (tileEntity instanceof IGregTechTileEntity entity && t.addLayerOutputHatch(entity, CASING_INDEX)) {
+ t.onTopLayerFound(false);
+ return true;
+ }
+ // block adder
+ if (world.getBlock(x, y, z) == GregTechAPI.sBlockCasings4 && world.getBlockMetadata(x, y, z) == 1) {
+ t.onTopLayerFound(true);
+ return true;
+ }
+ return false;
+ })
+ .build();
+ }
+
+ protected final List<List<MTEHatchOutput>> mOutputHatchesByLayer = new ArrayList<>();
+ protected int mHeight;
+ protected int mCasing;
+ protected boolean mTopLayerFound;
+
+ // -1 => maybe top, maybe not, 0 => definitely not top, 1 => definitely top
+ private int mTopState = -1;
+
+ public MTEMegaDistillTower(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ private MTEMegaDistillTower(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEMegaDistillTower(this.mName);
+ }
+
+ protected void onCasingFound() {
+ this.mCasing++;
+ }
+
+ protected int getCurrentLayerOutputHatchCount() {
+ return this.mOutputHatchesByLayer.size() < this.mHeight || this.mHeight <= 0 ? 0
+ : this.mOutputHatchesByLayer.get(this.mHeight - 1)
+ .size();
+ }
+
+ protected boolean addLayerOutputHatch(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null || aTileEntity.isDead() || !(aTileEntity.getMetaTileEntity() instanceof MTEHatchOutput))
+ return false;
+ while (this.mOutputHatchesByLayer.size() < this.mHeight) this.mOutputHatchesByLayer.add(new ArrayList<>());
+ MTEHatchOutput tHatch = (MTEHatchOutput) aTileEntity.getMetaTileEntity();
+ tHatch.updateTexture(aBaseCasingIndex);
+ return this.mOutputHatchesByLayer.get(this.mHeight - 1)
+ .add(tHatch);
+ }
+
+ protected void onTopLayerFound(boolean aIsCasing) {
+ this.mTopLayerFound = true;
+ if (aIsCasing) this.onCasingFound();
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) };
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return RecipeMaps.distillationTowerRecipes;
+ }
+
+ @Override
+ public int getRecipeCatalystPriority() {
+ return -1;
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Distillery")
+ .addInfo("Controller block for the Distillation Tower")
+ .addInfo("Fluids are only put out at the correct height")
+ .addInfo("The correct height equals the slot number in the NEI recipe")
+ .addSeparator()
+ .beginVariableStructureBlock(15, 15, 16, 56, 15, 15, true)
+ .addController("Front bottom")
+ .addOtherStructurePart("Clean Stainless Steel Machine Casing", "15 x h - 5 (minimum)")
+ .addEnergyHatch("Any casing")
+ .addMaintenanceHatch("Any casing")
+ .addInputHatch("Any bottom layer casing")
+ .addOutputBus("Any bottom layer casing")
+ .addOutputHatch("2-11x Output Hatches (One per Output Layer except bottom layer)")
+ .addStructureInfo("An \"Output Layer\" consists of 5 layers!")
+ .addStructureHint("The interior of this Mega Multiblock's hologram is empty, it should be all air.")
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public IStructureDefinition<MTEMegaDistillTower> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ // reset
+ this.mOutputHatchesByLayer.forEach(List::clear);
+ this.mHeight = 1;
+ this.mTopLayerFound = false;
+ this.mTopState = -1;
+
+ // check base
+ if (!this.checkPiece(STRUCTURE_PIECE_BASE, 7, 0, 0)) return false;
+
+ // check each layer
+ while (this.mHeight < 12) {
+ if (!checkPiece(STRUCTURE_PIECE_LAYER, 7, mHeight * 5, 0)) {
+ return false;
+ }
+ if (this.mOutputHatchesByLayer.size() < this.mHeight || this.mOutputHatchesByLayer.get(this.mHeight - 1)
+ .isEmpty())
+ // layer without output hatch
+ return false;
+ if (mTopLayerFound) {
+ break;
+ }
+ this.mTopState = -1;
+ // not top
+ this.mHeight++;
+ }
+
+ // validate final invariants...
+ return this.mCasing >= 75 * this.mHeight + 10 && this.mHeight >= 2
+ && this.mTopLayerFound
+ && this.mMaintenanceHatches.size() == 1;
+ }
+
+ @Override
+ public void construct(ItemStack stackSize, boolean hintsOnly) {
+ this.buildPiece(STRUCTURE_PIECE_BASE, stackSize, hintsOnly, 7, 0, 0);
+ int tTotalHeight = Math.min(12, stackSize.stackSize + 2); // min 2 output layer, so at least 1 + 2 height
+ for (int i = 1; i < tTotalHeight - 1; i++) {
+ this.buildPiece(STRUCTURE_PIECE_LAYER, stackSize, hintsOnly, 7, 5 * i, 0);
+ }
+ this.buildPiece(STRUCTURE_PIECE_TOP_HINT, stackSize, hintsOnly, 7, 5 * (tTotalHeight - 1), 0);
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) {
+ if (this.mMachine) return -1;
+ int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5);
+ this.mHeight = 0;
+ int built = this
+ .survivialBuildPiece(STRUCTURE_PIECE_BASE, stackSize, 7, 0, 0, realBudget, source, actor, false, true);
+ if (built >= 0) return built;
+ int tTotalHeight = Math.min(12, stackSize.stackSize + 2); // min 2 output layer, so at least 1 + 2 height
+ for (int i = 1; i < tTotalHeight - 1; i++) {
+ this.mHeight = i;
+ built = this.survivialBuildPiece(
+ STRUCTURE_PIECE_LAYER,
+ stackSize,
+ 7,
+ 5 * this.mHeight,
+ 0,
+ realBudget,
+ source,
+ actor,
+ false,
+ true);
+ if (built >= 0) return built;
+ }
+ this.mHeight = tTotalHeight - 1;
+ return this.survivialBuildPiece(
+ STRUCTURE_PIECE_TOP_HINT,
+ stackSize,
+ 7,
+ 5 * this.mHeight,
+ 0,
+ realBudget,
+ source,
+ actor,
+ false,
+ true);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) {
+ this.batchMode = aNBT.getBoolean("mUseMultiparallelMode");
+ }
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (aPlayer.isSneaking()) {
+ this.batchMode = !this.batchMode;
+ if (this.batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic().setMaxParallel(ConfigHandler.megaMachinesMax);
+ }
+
+ @Override
+ public boolean canDumpFluidToME() {
+
+ // All fluids can be dumped to ME only if each layer contains a ME Output Hatch.
+ for (List<MTEHatchOutput> tLayerOutputHatches : this.mOutputHatchesByLayer) {
+
+ boolean foundMEHatch = false;
+
+ for (IFluidStore tHatch : tLayerOutputHatches) {
+ if (tHatch instanceof MTEHatchOutputME tMEHatch) {
+ if (tMEHatch.canAcceptFluid()) {
+ foundMEHatch = true;
+ break;
+ }
+ }
+ }
+
+ // Exit if we didn't find a valid hatch on this layer.
+ if (!foundMEHatch) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void addFluidOutputs(FluidStack[] mOutputFluids2) {
+ for (int i = 0; i < mOutputFluids2.length && i < this.mOutputHatchesByLayer.size(); i++) {
+ FluidStack tStack = mOutputFluids2[i].copy();
+ if (!dumpFluid(this.mOutputHatchesByLayer.get(i), tStack, true))
+ dumpFluid(this.mOutputHatchesByLayer.get(i), tStack, false);
+ }
+ }
+
+ @Override
+ public List<? extends IFluidStore> getFluidOutputSlots(FluidStack[] toOutput) {
+ return this.getFluidOutputSlotsByLayer(toOutput, this.mOutputHatchesByLayer);
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaOilCracker.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaOilCracker.java
new file mode 100644
index 0000000000..4720b0b37c
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaOilCracker.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2022 SKYCATV587 Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The
+ * above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+ * Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis.mega;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.withChannel;
+import static gregtech.api.enums.HatchElement.*;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+import static gregtech.api.util.GTStructureUtility.ofCoil;
+import static gregtech.api.util.GTUtility.filterValidMTEs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.structure.IItemSource;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.API.BorosilicateGlass;
+import bartworks.common.configs.ConfigHandler;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.GTValues;
+import gregtech.api.enums.HeatingCoilLevel;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.metatileentity.implementations.MTEHatchMultiInput;
+import gregtech.api.metatileentity.implementations.MTEHatchOutput;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.RecipeMaps;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.maps.OilCrackerBackend;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch;
+import gregtech.common.tileentities.machines.MTEHatchInputME;
+
+public class MTEMegaOilCracker extends MegaMultiBlockBase<MTEMegaOilCracker> implements ISurvivalConstructable {
+
+ private static final int CASING_INDEX = 49;
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition<MTEMegaOilCracker> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEMegaOilCracker>builder()
+ .addShape(
+ STRUCTURE_PIECE_MAIN,
+ transpose(
+ new String[][] {
+ { " p p ", "ppgggggggggpp", " pgggggggggp ", " pgggpppgggp ", " pgggpMpgggp ",
+ " pgggpppgggp ", " pgggggggggp ", "ppgggggggggpp", " p p " },
+ { " p p ", "pgggggggggggp", " g c c c c g ", " g c c c c g ", " g c c c c g ",
+ " g c c c c g ", " g c c c c g ", "pgggggggggggp", " p p " },
+ { " p p ", "pgggggggggggp", " g c c c c g ", " p c c p ", " p c c c c p ",
+ " p c c p ", " g c c c c g ", "pgggggggggggp", " p p " },
+ { " p p ", "pgggggggggggp", " g c c c c g ", " p c c c c p ", " l c c c c r ",
+ " p c c c c p ", " g c c c c g ", "pgggggggggggp", " p p " },
+ { " p p ", "pgggggggggggp", " g c c c c g ", " p c c p ", " p c c c c p ",
+ " p c c p ", " g c c c c g ", "pgggggggggggp", " p p " },
+ { " p p ", "pgggggggggggp", " g c c c c g ", " g c c c c g ", " g c c c c g ",
+ " g c c c c g ", " g c c c c g ", "pgggggggggggp", " p p " },
+ { "ppmmmm~mmmmpp", "ppppppppppppp", "ppppppppppppp", "ppppppppppppp", "ppppppppppppp",
+ "ppppppppppppp", "ppppppppppppp", "ppppppppppppp", "ppmmmmmmmmmpp" }, }))
+ .addElement('c', withChannel("coil", ofCoil(MTEMegaOilCracker::setCoilLevel, MTEMegaOilCracker::getCoilLevel)))
+
+ .addElement('p', ofBlock(GregTechAPI.sBlockCasings4, 1))
+ .addElement(
+ 'l',
+ InputHatch.withAdder(MTEMegaOilCracker::addLeftHatchToMachineList)
+ .newAny(CASING_INDEX, 2))
+ .addElement(
+ 'r',
+ OutputHatch.withAdder(MTEMegaOilCracker::addRightHatchToMachineList)
+ .newAny(CASING_INDEX, 3))
+ .addElement(
+ 'm',
+ buildHatchAdder(MTEMegaOilCracker.class).atLeast(Energy.or(ExoticEnergy), Maintenance, InputBus)
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(GregTechAPI.sBlockCasings4, 1))
+ .addElement(
+ 'M',
+ InputHatch.withAdder(MTEMegaOilCracker::addMiddleInputToMachineList)
+ .newAny(CASING_INDEX, 4))
+ .addElement(
+ 'g',
+ withChannel(
+ "glass",
+ BorosilicateGlass
+ .ofBoroGlass((byte) 0, (byte) 1, Byte.MAX_VALUE, (te, t) -> te.glassTier = t, te -> te.glassTier)))
+ .build();
+ private byte glassTier;
+ private HeatingCoilLevel heatLevel;
+ protected final List<MTEHatchInput> mMiddleInputHatches = new ArrayList<>();
+ protected int mInputOnSide = -1;
+ protected int mOutputOnSide = -1;
+
+ public MTEMegaOilCracker(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MTEMegaOilCracker(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public MultiblockTooltipBuilder createTooltip() {
+ final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Cracker")
+ .addInfo("Controller block for the Mega Oil Cracking")
+ .addInfo("Thermally cracks heavy hydrocarbons into lighter fractions")
+ .addInfo("More efficient than the Chemical Reactor")
+ .addInfo("Gives different benefits whether it hydro or steam-cracks:")
+ .addInfo("Hydro - Consumes 20% less Hydrogen and outputs 25% more cracked fluid")
+ .addInfo("Steam - Outputs 50% more cracked fluid")
+ .addInfo("(Values compared to cracking in the Chemical Reactor)")
+ .addInfo("Place the appropriate circuit in the controller or an input bus")
+ .addInfo(
+ GTValues.TIER_COLORS[8] + GTValues.VN[8]
+ + EnumChatFormatting.GRAY
+ + "-tier glass required for "
+ + EnumChatFormatting.BLUE
+ + "Tec"
+ + EnumChatFormatting.DARK_BLUE
+ + "Tech"
+ + EnumChatFormatting.GRAY
+ + " Laser Hatches.")
+ .addSeparator()
+ .beginStructureBlock(13, 7, 9, true)
+ .addController("Front bottom")
+ .addStructureInfo("The glass tier limits the Energy Input tier")
+ .addInfo("Gets 10% EU/t reduction per coil tier, up to a maximum of 50%")
+ .addEnergyHatch("Hint block", 1)
+ .addMaintenanceHatch("Hint block", 1)
+ .addInputHatch("Hint block", 2, 3)
+ .addOutputHatch("Hint block", 2, 3)
+ .addInputHatch("Steam/Hydrogen ONLY, Hint block", 4)
+ .addInputBus("Optional, for programmed circuit automation. Hint block", 1)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEMegaOilCracker(this.mName);
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ if (side == facing) {
+ if (aActive) return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_OIL_CRACKER_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_OIL_CRACKER_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_OIL_CRACKER)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_OIL_CRACKER_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ return new ITexture[] { casingTexturePages[0][CASING_INDEX] };
+ }
+
+ @Override
+ public RecipeMap<OilCrackerBackend> getRecipeMap() {
+ return RecipeMaps.crackingRecipes;
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic() {
+
+ @Override
+ @Nonnull
+ public CheckRecipeResult process() {
+ this.setEuModifier(1.0F - Math.min(0.1F * (MTEMegaOilCracker.this.heatLevel.getTier() + 1), 0.5F));
+ return super.process();
+ }
+ }.setMaxParallel(ConfigHandler.megaMachinesMax);
+ }
+
+ public HeatingCoilLevel getCoilLevel() {
+ return this.heatLevel;
+ }
+
+ public void setCoilLevel(HeatingCoilLevel aCoilLevel) {
+ this.heatLevel = aCoilLevel;
+ }
+
+ @Override
+ public void construct(ItemStack aStack, boolean aHintsOnly) {
+ this.buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 6, 6, 0);
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) {
+ if (this.mMachine) return -1;
+ int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5);
+ return this
+ .survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 6, 6, 0, realBudget, source, actor, false, true);
+ }
+ // -------------- TEC TECH COMPAT ----------------
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ this.glassTier = 0;
+ this.mInputOnSide = -1;
+ this.mOutputOnSide = -1;
+ this.mMiddleInputHatches.clear();
+
+ if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 6, 6, 0) || this.mMaintenanceHatches.size() != 1) return false;
+
+ if (this.glassTier < 8) {
+ for (int i = 0; i < this.mExoticEnergyHatches.size(); ++i) {
+ MTEHatch hatch = this.mExoticEnergyHatches.get(i);
+ if (hatch.getConnectionType() == MTEHatch.ConnectionType.LASER) {
+ return false;
+ }
+ if (this.glassTier < hatch.mTier) {
+ return false;
+ }
+ }
+ for (int i = 0; i < this.mEnergyHatches.size(); ++i) {
+ if (this.glassTier < this.mEnergyHatches.get(i).mTier) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private boolean addLeftHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchInput) {
+ if (this.mInputOnSide == 1) {
+ return false;
+ }
+ this.mInputOnSide = 0;
+ this.mOutputOnSide = 1;
+ MTEHatchInput tHatch = (MTEHatchInput) aMetaTileEntity;
+ tHatch.updateTexture(aBaseCasingIndex);
+ tHatch.mRecipeMap = this.getRecipeMap();
+ return this.mInputHatches.add(tHatch);
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutput) {
+ if (this.mOutputOnSide == 1) {
+ return false;
+ }
+ this.mInputOnSide = 1;
+ this.mOutputOnSide = 0;
+ MTEHatchOutput tHatch = (MTEHatchOutput) aMetaTileEntity;
+ tHatch.updateTexture(aBaseCasingIndex);
+ return this.mOutputHatches.add(tHatch);
+ }
+ return false;
+ }
+
+ private boolean addRightHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchInput) {
+ if (this.mInputOnSide == 0) {
+ return false;
+ }
+ this.mInputOnSide = 1;
+ this.mOutputOnSide = 0;
+ MTEHatchInput tHatch = (MTEHatchInput) aMetaTileEntity;
+ tHatch.updateTexture(aBaseCasingIndex);
+ tHatch.mRecipeMap = this.getRecipeMap();
+ return this.mInputHatches.add(tHatch);
+ }
+ if (aMetaTileEntity instanceof MTEHatchOutput) {
+ if (this.mOutputOnSide == 0) {
+ return false;
+ }
+ this.mInputOnSide = 0;
+ this.mOutputOnSide = 1;
+ MTEHatchOutput tHatch = (MTEHatchOutput) aMetaTileEntity;
+ tHatch.updateTexture(aBaseCasingIndex);
+ return this.mOutputHatches.add(tHatch);
+ }
+ return false;
+ }
+
+ private boolean addMiddleInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) {
+ if (aTileEntity == null) {
+ return false;
+ }
+ IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) {
+ return false;
+ }
+ if (aMetaTileEntity instanceof MTEHatchInput tHatch) {
+ tHatch.updateTexture(aBaseCasingIndex);
+ tHatch.mRecipeMap = this.getRecipeMap();
+ return this.mMiddleInputHatches.add(tHatch);
+ }
+ return false;
+ }
+
+ @Override
+ public ArrayList<FluidStack> getStoredFluids() {
+ final ArrayList<FluidStack> rList = new ArrayList<>();
+ Map<Fluid, FluidStack> inputsFromME = new HashMap<>();
+ for (final MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) {
+ tHatch.mRecipeMap = getRecipeMap();
+ if (tHatch instanceof MTEHatchInputME meHatch) {
+ for (FluidStack tFluid : meHatch.getStoredFluids()) {
+ if (tFluid != null && !getRecipeMap().getBackend()
+ .isValidCatalystFluid(tFluid)) {
+ inputsFromME.put(tFluid.getFluid(), tFluid);
+ }
+ }
+ } else if (tHatch instanceof MTEHatchMultiInput) {
+ for (final FluidStack tFluid : ((MTEHatchMultiInput) tHatch).getStoredFluid()) {
+ if (tFluid != null && !getRecipeMap().getBackend()
+ .isValidCatalystFluid(tFluid)) {
+ rList.add(tFluid);
+ }
+ }
+ } else {
+ if (tHatch.getFillableStack() != null) {
+ if (!getRecipeMap().getBackend()
+ .isValidCatalystFluid(tHatch.getFillableStack())) rList.add(tHatch.getFillableStack());
+ }
+ }
+ }
+ for (final MTEHatchInput tHatch : filterValidMTEs(mMiddleInputHatches)) {
+ tHatch.mRecipeMap = getRecipeMap();
+ if (tHatch instanceof MTEHatchInputME meHatch) {
+ for (FluidStack tFluid : meHatch.getStoredFluids()) {
+ if (tFluid != null && getRecipeMap().getBackend()
+ .isValidCatalystFluid(tFluid)) {
+ inputsFromME.put(tFluid.getFluid(), tFluid);
+ }
+ }
+ } else if (tHatch instanceof MTEHatchMultiInput) {
+ for (final FluidStack tFluid : ((MTEHatchMultiInput) tHatch).getStoredFluid()) {
+ if (tFluid != null && getRecipeMap().getBackend()
+ .isValidCatalystFluid(tFluid)) {
+ rList.add(tFluid);
+ }
+ }
+ } else {
+ if (tHatch.getFillableStack() != null) {
+ final FluidStack tStack = tHatch.getFillableStack();
+ if (getRecipeMap().getBackend()
+ .isValidCatalystFluid(tStack)) {
+ rList.add(tStack);
+ }
+ }
+ }
+ }
+ if (!inputsFromME.isEmpty()) {
+ rList.addAll(inputsFromME.values());
+ }
+ return rList;
+ }
+
+ @Override
+ public IStructureDefinition<MTEMegaOilCracker> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (aPlayer.isSneaking()) {
+ batchMode = !batchMode;
+ if (batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+
+ @Override
+ protected void startRecipeProcessing() {
+ for (MTEHatchInput hatch : filterValidMTEs(mMiddleInputHatches)) {
+ if (hatch instanceof IRecipeProcessingAwareHatch aware) {
+ aware.startRecipeProcessing();
+ }
+ }
+ super.startRecipeProcessing();
+ }
+
+ @Override
+ protected void endRecipeProcessing() {
+ super.endRecipeProcessing();
+ for (MTEHatchInput hatch : filterValidMTEs(mMiddleInputHatches)) {
+ if (hatch instanceof IRecipeProcessingAwareHatch aware) {
+ setResultIfFailure(aware.endRecipeProcessing(this));
+ }
+ }
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaVacuumFreezer.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaVacuumFreezer.java
new file mode 100644
index 0000000000..e47782d980
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaVacuumFreezer.java
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.multis.mega;
+
+import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.enums.HatchElement.*;
+import static gregtech.api.enums.HatchElement.ExoticEnergy;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
+import com.gtnewhorizon.structurelib.structure.IItemSource;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+
+import bartworks.common.configs.ConfigHandler;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.MaterialsUEVplus;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.recipe.RecipeMaps;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.api.util.OverclockCalculator;
+import gregtech.api.util.shutdown.ShutDownReasonRegistry;
+import gregtech.common.blocks.BlockCasingsAbstract;
+
+public class MTEMegaVacuumFreezer extends MegaMultiBlockBase<MTEMegaVacuumFreezer> implements ISurvivalConstructable {
+
+ public MTEMegaVacuumFreezer(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MTEMegaVacuumFreezer(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEMegaVacuumFreezer(this.mName);
+ }
+
+ private int mCasingFrostProof = 0;
+ private int mTier = 1;
+
+ private static class SubspaceCoolingFluid {
+
+ public Materials material;
+ public int perfectOverclocks;
+ // Consumption per second of runtime
+ public long amount;
+
+ public SubspaceCoolingFluid(Materials material, int perfectOverclocks, long amount) {
+ this.material = material;
+ this.perfectOverclocks = perfectOverclocks;
+ this.amount = amount;
+ }
+
+ public FluidStack getStack() {
+ FluidStack stack = material.getFluid(amount);
+ // FUCK THIS FUCK THIS FUCK THIS
+ if (stack == null) {
+ return material.getMolten(amount);
+ }
+ return stack;
+ }
+ }
+
+ private static final ArrayList<SubspaceCoolingFluid> SUBSPACE_COOLING_FLUIDS = new ArrayList<>(
+ Arrays.asList(
+ new SubspaceCoolingFluid(MaterialsUEVplus.SpaceTime, 1, 7500),
+ new SubspaceCoolingFluid(MaterialsUEVplus.Space, 2, 5000),
+ new SubspaceCoolingFluid(MaterialsUEVplus.Eternity, 3, 2500)));
+
+ private SubspaceCoolingFluid currentCoolingFluid = null;
+
+ private static final int CASING_INDEX = 17;
+ private static final int CASING_INDEX_T2 = ((BlockCasingsAbstract) GregTechAPI.sBlockCasings8).getTextureIndex(14);
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final String STRUCTURE_PIECE_MAIN_T2 = "main_t2";
+
+ private static final String[][] structure = transpose(
+ new String[][] {
+ { "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA",
+ "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA",
+ "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAA~AAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA",
+ "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA",
+ "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA" } });
+ private static final String[][] structure_tier2 = new String[][] {
+ { "AAAAAAAAAAAAAAA", "ABBBBBBBBBBBBBA", "ABAAAAAAAAAAABA", "ABABBBBBBBBBABA", "ABABAAAAAAABABA",
+ "ABABABBBBBABABA", "ABABABAAABABABA", "ABABABA~ABABABA", "ABABABAAABABABA", "ABABABBBBBABABA",
+ "ABABAAAAAAABABA", "ABABBBBBBBBBABA", "ABAAAAAAAAAAABA", "ABBBBBBBBBBBBBA", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "B B", "B B", "B B",
+ "B B", "B B", "B B", "B B", "B B",
+ "B B", "B B", "B B", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "B B",
+ "B B", "B B", "B B", "B B", "B B",
+ "B B", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A",
+ "B B", "B B", "B B", "B B", "B B",
+ "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A",
+ "B B", "A A", "A A", "A A", "B B",
+ "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A",
+ "B B", "A A", "A A", "A A", "B B",
+ "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A",
+ "B B", "A A", "A A", "A A", "B B",
+ "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A",
+ "B B", "B B", "B B", "B B", "B B",
+ "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "B B",
+ "B B", "B B", "B B", "B B", "B B",
+ "B B", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "A A", "A A", "A A",
+ "A A", "A A", "A A", "A A", "A A",
+ "A A", "A A", "A A", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "B B", "B B", "B B", "B B",
+ "B B", "B B", "B B", "B B", "B B",
+ "B B", "B B", "B B", "B B", "AAAAAAAAAAAAAAA" },
+ { "AAAAAAAAAAAAAAA", "ABBBBBBBBBBBBBA", "ABAAAAAAAAAAABA", "ABABBBBBBBBBABA", "ABABAAAAAAABABA",
+ "ABABABBBBBABABA", "ABABABAAABABABA", "ABABABAAABABABA", "ABABABAAABABABA", "ABABABBBBBABABA",
+ "ABABAAAAAAABABA", "ABABBBBBBBBBABA", "ABAAAAAAAAAAABA", "ABBBBBBBBBBBBBA", "AAAAAAAAAAAAAAA" } };
+
+ private static final IStructureDefinition<MTEMegaVacuumFreezer> STRUCTURE_DEFINITION = StructureDefinition
+ .<MTEMegaVacuumFreezer>builder()
+ .addShape(STRUCTURE_PIECE_MAIN, structure)
+ .addShape(STRUCTURE_PIECE_MAIN_T2, structure_tier2)
+ .addElement(
+ 'A',
+ buildHatchAdder(MTEMegaVacuumFreezer.class)
+ .atLeast(Energy.or(ExoticEnergy), InputHatch, InputBus, OutputHatch, OutputBus, Maintenance)
+ .casingIndex(CASING_INDEX)
+ .dot(1)
+ .buildAndChain(onElementPass(x -> x.mCasingFrostProof++, ofBlock(GregTechAPI.sBlockCasings2, 1))))
+ // Infinity Cooled Casing
+ .addElement('B', ofBlock(GregTechAPI.sBlockCasings8, 14))
+ .build();
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Vacuum Freezer")
+ .addInfo("Controller Block for the Mega Vacuum Freezer")
+ .addInfo("Cools hot ingots and cells")
+ .addSeparator()
+ .addInfo("Upgrade to Tier 2 to unlock " + EnumChatFormatting.LIGHT_PURPLE + "Subspace Cooling.")
+ .addInfo(
+ "To activate " + EnumChatFormatting.LIGHT_PURPLE
+ + "Subspace Cooling "
+ + EnumChatFormatting.GRAY
+ + "supply a coolant while running recipes.")
+ .addInfo(
+ EnumChatFormatting.RED + "7500 L/s "
+ + EnumChatFormatting.DARK_PURPLE
+ + "Molten SpaceTime"
+ + EnumChatFormatting.GRAY
+ + ": "
+ + EnumChatFormatting.RED
+ + "1"
+ + EnumChatFormatting.GRAY
+ + " perfect overclock.")
+ .addInfo(
+ EnumChatFormatting.RED + "5000 L/s "
+ + EnumChatFormatting.DARK_PURPLE
+ + "Spatially Enlarged Fluid"
+ + EnumChatFormatting.GRAY
+ + ": "
+ + EnumChatFormatting.RED
+ + "2"
+ + EnumChatFormatting.GRAY
+ + " perfect overclocks.")
+ .addInfo(
+ EnumChatFormatting.RED + "2500 L/s "
+ + EnumChatFormatting.DARK_PURPLE
+ + "Molten Eternity"
+ + EnumChatFormatting.GRAY
+ + ": "
+ + EnumChatFormatting.RED
+ + "3"
+ + EnumChatFormatting.GRAY
+ + " perfect overclocks.")
+ .addSeparator()
+ .addInfo(
+ EnumChatFormatting.LIGHT_PURPLE + "Reinforcing the structure allows the injection of exotic coolants,")
+ .addInfo(
+ EnumChatFormatting.LIGHT_PURPLE
+ + "enabling the capture of heat energy in miniature tears in spacetime,")
+ .addInfo(EnumChatFormatting.LIGHT_PURPLE + "massively increasing the efficiency of the cooling process.")
+ .addSeparator()
+ .beginStructureBlock(15, 15, 15, true)
+ .addController("Front center")
+ .addEnergyHatch("Any Frost Proof Machine Casing", 1)
+ .addMaintenanceHatch("Any Frost Proof Machine Casing", 1)
+ .addInputHatch("Any Frost Proof Machine Casing", 1)
+ .addOutputHatch("Any Frost Proof Machine Casing", 1)
+ .addInputBus("Any Frost Proof Machine Casing", 1)
+ .addOutputBus("Any Frost Proof Machine Casing", 1)
+ .addStructureInfo(
+ EnumChatFormatting.BLUE + "Base Multi (Tier "
+ + EnumChatFormatting.DARK_PURPLE
+ + 1
+ + EnumChatFormatting.BLUE
+ + "):")
+ .addCasingInfoMinColored(
+ "Frost Proof Machine Casing",
+ EnumChatFormatting.GRAY,
+ 800,
+ EnumChatFormatting.GOLD,
+ false)
+ .addStructureInfo(
+ EnumChatFormatting.BLUE + "Tier "
+ + EnumChatFormatting.DARK_PURPLE
+ + 2
+ + EnumChatFormatting.BLUE
+ + " (Upgrades from Tier "
+ + EnumChatFormatting.DARK_PURPLE
+ + 1
+ + EnumChatFormatting.BLUE
+ + "):")
+ .addCasingInfoMinColored(
+ "Frost Proof Machine Casing",
+ EnumChatFormatting.GRAY,
+ 700,
+ EnumChatFormatting.GOLD,
+ false)
+ .addCasingInfoExactlyColored(
+ "Infinity Cooled Casing",
+ EnumChatFormatting.GRAY,
+ 384,
+ EnumChatFormatting.GOLD,
+ false)
+ .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS);
+ return tt;
+ }
+
+ @Override
+ public IStructureDefinition<MTEMegaVacuumFreezer> getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ public void construct(ItemStack aStack, boolean aHintsOnly) {
+ if (aStack.stackSize == 1) {
+ this.buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 7, 7, 0);
+ } else {
+ this.buildPiece(STRUCTURE_PIECE_MAIN_T2, aStack, aHintsOnly, 7, 7, 0);
+ }
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) {
+ if (this.mMachine) return -1;
+ int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5);
+ if (stackSize.stackSize == 1) {
+ return this
+ .survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 7, 7, 0, realBudget, source, actor, false, true);
+ } else {
+ return this.survivialBuildPiece(
+ STRUCTURE_PIECE_MAIN_T2,
+ stackSize,
+ 7,
+ 7,
+ 0,
+ realBudget,
+ source,
+ actor,
+ false,
+ true);
+ }
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return RecipeMaps.vacuumFreezerRecipes;
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) {
+ this.batchMode = aNBT.getBoolean("mUseMultiparallelMode");
+ }
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ if (aPlayer.isSneaking()) {
+ this.batchMode = !this.batchMode;
+ if (this.batchMode) {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn"));
+ } else {
+ GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff"));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public SubspaceCoolingFluid findSubspaceCoolingFluid() {
+ // Loop over all hatches and find the first match with a valid fluid
+ for (MTEHatchInput hatch : mInputHatches) {
+ Optional<SubspaceCoolingFluid> fluid = SUBSPACE_COOLING_FLUIDS.stream()
+ .filter(candidate -> drain(hatch, candidate.getStack(), false))
+ .findFirst();
+ if (fluid.isPresent()) return fluid.get();
+ }
+ return null;
+ }
+
+ @Override
+ protected ProcessingLogic createProcessingLogic() {
+ return new ProcessingLogic() {
+
+ @Nonnull
+ @Override
+ protected OverclockCalculator createOverclockCalculator(@Nonnull GTRecipe recipe) {
+ // Check if the freezer is T2
+ if (mTier == 1) return super.createOverclockCalculator(recipe);
+
+ // First try to detect the current fluid used for subspace cooling.
+ currentCoolingFluid = findSubspaceCoolingFluid();
+
+ return super.createOverclockCalculator(recipe)
+ .setMachineHeat(currentCoolingFluid == null ? 0 : currentCoolingFluid.perfectOverclocks * 1800)
+ .setRecipeHeat(0)
+ .setHeatOC(true)
+ .setHeatDiscount(false);
+ }
+ }.setMaxParallel(ConfigHandler.megaMachinesMax);
+ }
+
+ @Override
+ protected void runMachine(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.runMachine(aBaseMetaTileEntity, aTick);
+ // Every second while running, consume subspace coolant fluid
+ if (mMaxProgresstime > 0 && aTick % 20 == 0) {
+ // Subspace cooling only allowed for T2 freezer
+ if (mTier == 2) {
+ // Try to drain the coolant fluid if it exists. If failed, stop the machine with an error
+ if (this.currentCoolingFluid != null) {
+ FluidStack fluid = this.currentCoolingFluid.getStack();
+ for (MTEHatchInput hatch : mInputHatches) {
+ if (drain(hatch, fluid, false)) {
+ drain(hatch, fluid, true);
+ return;
+ }
+ }
+ // If we exited this loop without returning from the function, no matching fluid was found, so
+ // stop the machine - we ran out of coolant
+ stopMachine(ShutDownReasonRegistry.outOfFluid(fluid));
+ }
+ }
+ }
+ }
+
+ // -------------- TEC TECH COMPAT ----------------
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ this.mCasingFrostProof = 0;
+ this.mTier = 1;
+ // If check for T1 fails, also do a check for T2 structure
+ if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 7, 7, 0)) {
+ // Reset mCasing in between checks, so they don't count again
+ this.mCasingFrostProof = 0;
+ if (!this.checkPiece(STRUCTURE_PIECE_MAIN_T2, 7, 7, 0)) {
+ return false;
+ }
+ // Structure is Tier 2
+ this.mTier = 2;
+ }
+ return this.mMaintenanceHatches.size() == 1 && this.mCasingFrostProof >= 700;
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
+ int aColorIndex, boolean aActive, boolean aRedstone) {
+ ITexture[] rTexture;
+ if (side == facing) {
+ if (aActive) {
+ rTexture = new ITexture[] { casingTexturePages[0][17], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ } else {
+ rTexture = new ITexture[] { casingTexturePages[0][17], TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_VACUUM_FREEZER)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_VACUUM_FREEZER_GLOW)
+ .extFacing()
+ .glow()
+ .build() };
+ }
+ } else {
+ rTexture = new ITexture[] { casingTexturePages[0][17] };
+ }
+ return rTexture;
+ }
+
+ @Override
+ public String[] getInfoData() {
+ ArrayList<String> info = new ArrayList<>(Arrays.asList(super.getInfoData()));
+ info.add("Tier: " + mTier);
+ if (mTier == 2) {
+ if (currentCoolingFluid != null) {
+ info.add(
+ "Subspace cooling: " + EnumChatFormatting.GREEN
+ + "Active ("
+ + currentCoolingFluid.getStack()
+ .getLocalizedName()
+ + ")");
+ } else {
+ info.add("Subspace cooling: " + EnumChatFormatting.RED + "Inactive");
+ }
+ }
+ return info.toArray(new String[] {});
+ }
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsVoidProtection() {
+ return true;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MegaMultiBlockBase.java b/src/main/java/bartworks/common/tileentities/multis/mega/MegaMultiBlockBase.java
new file mode 100644
index 0000000000..bac811ede8
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/multis/mega/MegaMultiBlockBase.java
@@ -0,0 +1,212 @@
+package bartworks.common.tileentities.multis.mega;
+
+import static gregtech.api.util.GTUtility.filterValidMTEs;
+
+import java.util.Arrays;
+
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment;
+import com.gtnewhorizon.structurelib.structure.IStructureElement;
+
+import bartworks.util.BWTooltipReference;
+import bartworks.util.BWUtil;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.metatileentity.implementations.MTEHatchEnergy;
+import gregtech.api.metatileentity.implementations.MTEHatchMuffler;
+import gregtech.api.util.GTUtility;
+
+public abstract class MegaMultiBlockBase<T extends MegaMultiBlockBase<T>> extends MTEExtendedPowerMultiBlockBase<T> {
+
+ protected MegaMultiBlockBase(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public MegaMultiBlockBase(String aName) {
+ super(aName);
+ }
+
+ protected String[] getExtendedInfoData() {
+ return new String[0];
+ }
+
+ protected long[] getCurrentInfoData() {
+ long storedEnergy = 0, maxEnergy = 0;
+ for (MTEHatch hatch : this.getExoticAndNormalEnergyHatchList()) {
+ storedEnergy += hatch.getBaseMetaTileEntity()
+ .getStoredEU();
+ maxEnergy += hatch.getBaseMetaTileEntity()
+ .getEUCapacity();
+ }
+ return new long[] { storedEnergy, maxEnergy };
+ }
+
+ @Override
+ public String[] getInfoData() {
+ int mPollutionReduction = 0;
+
+ for (MTEHatchMuffler tHatch : filterValidMTEs(mMufflerHatches)) {
+ mPollutionReduction = Math.max(tHatch.calculatePollutionReduction(100), mPollutionReduction);
+ }
+
+ long[] ttHatches = this.getCurrentInfoData();
+ long storedEnergy = ttHatches[0];
+ long maxEnergy = ttHatches[1];
+
+ for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) {
+ storedEnergy += tHatch.getBaseMetaTileEntity()
+ .getStoredEU();
+ maxEnergy += tHatch.getBaseMetaTileEntity()
+ .getEUCapacity();
+ }
+
+ long nominalV = this.getMaxInputEu();
+ String tName = BWUtil.getTierNameFromVoltage(nominalV);
+ if ("MAX+".equals(tName)) tName = EnumChatFormatting.OBFUSCATED + "MAX+";
+
+ String[] extendedInfo = this.getExtendedInfoData();
+
+ String[] baseInfo = {
+ StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": "
+ + EnumChatFormatting.GREEN
+ + GTUtility.formatNumbers(this.mProgresstime / 20)
+ + EnumChatFormatting.RESET
+ + " s / "
+ + EnumChatFormatting.YELLOW
+ + GTUtility.formatNumbers(this.mMaxProgresstime / 20)
+ + EnumChatFormatting.RESET
+ + " s",
+ StatCollector.translateToLocal("GT5U.multiblock.energy") + ": "
+ + EnumChatFormatting.GREEN
+ + GTUtility.formatNumbers(storedEnergy)
+ + EnumChatFormatting.RESET
+ + " EU / "
+ + EnumChatFormatting.YELLOW
+ + GTUtility.formatNumbers(maxEnergy)
+ + EnumChatFormatting.RESET
+ + " EU",
+ StatCollector.translateToLocal("GT5U.multiblock.usage") + ": "
+ + EnumChatFormatting.RED
+ + GTUtility.formatNumbers(-this.lEUt)
+ + EnumChatFormatting.RESET
+ + " EU/t",
+ StatCollector.translateToLocal("GT5U.multiblock.mei") + ": "
+ + EnumChatFormatting.YELLOW
+ + GTUtility.formatNumbers(this.getMaxInputVoltage())
+ + EnumChatFormatting.RESET
+ + " EU/t(*"
+ + GTUtility.formatNumbers(this.getMaxInputAmps())
+ + "A) = "
+ + EnumChatFormatting.YELLOW
+ + GTUtility.formatNumbers(nominalV)
+ + EnumChatFormatting.RESET,
+ StatCollector.translateToLocal("GT5U.machines.tier") + ": "
+ + EnumChatFormatting.YELLOW
+ + tName
+ + EnumChatFormatting.RESET,
+ StatCollector.translateToLocal("GT5U.multiblock.problems") + ": "
+ + EnumChatFormatting.RED
+ + (this.getIdealStatus() - this.getRepairStatus())
+ + EnumChatFormatting.RESET
+ + " "
+ + StatCollector.translateToLocal("GT5U.multiblock.efficiency")
+ + ": "
+ + EnumChatFormatting.YELLOW
+ + this.mEfficiency / 100.0F
+ + EnumChatFormatting.RESET
+ + " %",
+ StatCollector.translateToLocal("GT5U.multiblock.pollution") + ": "
+ + EnumChatFormatting.GREEN
+ + mPollutionReduction
+ + EnumChatFormatting.RESET
+ + " %" };
+
+ String[] combinedInfo = Arrays.copyOf(baseInfo, baseInfo.length + extendedInfo.length + 1);
+
+ System.arraycopy(extendedInfo, 0, combinedInfo, baseInfo.length, extendedInfo.length);
+
+ combinedInfo[combinedInfo.length - 1] = BWTooltipReference.BW;
+
+ return combinedInfo;
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack itemStack) {
+ return true;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack itemStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack itemStack) {
+ return false;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack itemStack) {
+ return 10000;
+ }
+
+ @Override
+ protected void setProcessingLogicPower(ProcessingLogic logic) {
+ logic.setAvailableVoltage(this.getMaxInputEu());
+ logic.setAvailableAmperage(1);
+ }
+
+ protected static class StructureElementAirNoHint<T> implements IStructureElement<T> {
+
+ private static final StructureElementAirNoHint<?> INSTANCE = new StructureElementAirNoHint<>();
+
+ @SuppressWarnings("unchecked")
+ public static <T> IStructureElement<T> getInstance() {
+ return (IStructureElement<T>) INSTANCE;
+ }
+
+ private StructureElementAirNoHint() {}
+
+ @Override
+ public boolean check(T o, World world, int x, int y, int z) {
+ return world.isAirBlock(x, y, z);
+ }
+
+ @Override
+ public boolean spawnHint(T o, World world, int x, int y, int z, ItemStack trigger) {
+ if (world.blockExists(x, y, z) && !world.isAirBlock(x, y, z))
+ // hint if this is obstructed. in case *someone* ever finish the transparent rendering
+ StructureLibAPI
+ .hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), StructureLibAPI.HINT_BLOCK_META_AIR);
+ return true;
+ }
+
+ @Override
+ public boolean placeBlock(T o, World world, int x, int y, int z, ItemStack trigger) {
+ world.setBlockToAir(x, y, z);
+ return true;
+ }
+
+ @Override
+ public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger,
+ AutoPlaceEnvironment env) {
+ return BlocksToPlace.createEmpty();
+ }
+
+ @Override
+ public PlaceResult survivalPlaceBlock(T o, World world, int x, int y, int z, ItemStack trigger,
+ AutoPlaceEnvironment env) {
+ if (this.check(o, world, x, y, z)) return PlaceResult.SKIP;
+ if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return PlaceResult.REJECT;
+ world.setBlock(x, y, z, Blocks.air, 0, 2);
+ return PlaceResult.ACCEPT;
+ }
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/GT_MetaTileEntity_RadioHatch.java b/src/main/java/bartworks/common/tileentities/tiered/GT_MetaTileEntity_RadioHatch.java
new file mode 100644
index 0000000000..8e752711ea
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/GT_MetaTileEntity_RadioHatch.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import static gregtech.api.enums.GTValues.ticksBetweenSounds;
+
+import java.util.Collections;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizons.modularui.api.ModularUITextures;
+import com.gtnewhorizons.modularui.api.drawable.ItemDrawable;
+import com.gtnewhorizons.modularui.api.drawable.shapes.Rectangle;
+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.math.Size;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.widget.ButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.ProgressBar;
+import com.gtnewhorizons.modularui.common.widget.ProgressBar.Direction;
+import com.gtnewhorizons.modularui.common.widget.TextWidget;
+import com.gtnewhorizons.modularui.common.widget.textfield.NumericWidget;
+
+import bartworks.API.modularUI.BWUITextures;
+import bartworks.API.recipe.BartWorksRecipeMaps;
+import bartworks.MainMod;
+import bartworks.util.BWColorUtil;
+import bartworks.util.BWTooltipReference;
+import bartworks.util.MathUtils;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.Textures;
+import gregtech.api.gui.modularui.GTUIInfos;
+import gregtech.api.gui.modularui.GTUITextures;
+import gregtech.api.gui.modularui.GUITextureSet;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.modularui.IAddGregtechLogo;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.interfaces.tileentity.RecipeMapWorkable;
+import gregtech.api.metatileentity.BaseMetaTileEntity;
+import gregtech.api.metatileentity.implementations.MTEHatch;
+import gregtech.api.objects.ItemData;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTOreDictUnificator;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTUtility;
+import gregtech.common.items.IDMetaTool01;
+import gregtech.common.items.MetaGeneratedTool01;
+
+public class GT_MetaTileEntity_RadioHatch extends MTEHatch implements RecipeMapWorkable, IAddGregtechLogo {
+
+ private final int cap;
+ public int sievert;
+ private long timer = 1;
+ private long decayTime = 1;
+ private short[] colorForGUI = { 0x02, 0x02, 0x02 };
+ private byte mass;
+ private String material;
+ private byte coverage;
+ private ItemStack lastUsedItem = null;
+ private boolean lastFail = false;
+ private GTRecipe lastRecipe = null;
+
+ public GT_MetaTileEntity_RadioHatch(int aID, String aName, String aNameRegional, int aTier) {
+ super(
+ aID,
+ aName,
+ aNameRegional,
+ aTier,
+ 1,
+ new String[] { StatCollector.translateToLocal("tooltip.tile.radhatch.0.name"),
+ StatCollector.translateToLocal("tooltip.tile.tiereddsc.3.name") + " "
+ + (aTier - 2)
+ + " "
+ + (aTier - 2 >= 2 ? StatCollector.translateToLocal("tooltip.bw.kg.1.name")
+ : StatCollector.translateToLocal("tooltip.bw.kg.0.name")),
+ StatCollector.translateToLocal("tooltip.tile.radhatch.1.name"),
+ BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get() });
+ this.cap = aTier - 2;
+ }
+
+ public GT_MetaTileEntity_RadioHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, 1, aDescription, aTextures);
+ this.cap = aTier - 2;
+ }
+
+ public int getSievert() {
+ return this.sievert - MathUtils.ceilInt(this.sievert / 100f * this.coverage);
+ }
+
+ public short[] getColorForGUI() {
+ if (this.colorForGUI != null) return this.colorForGUI;
+ return this.colorForGUI = new short[] { 0xFA, 0xFA, 0xFF };
+ }
+
+ public byte getMass() {
+ return this.mass;
+ }
+
+ public byte getCoverage() {
+ return this.coverage;
+ }
+
+ public void setCoverage(short coverage) {
+ byte nu;
+ if (coverage > 100) nu = 100;
+ else if (coverage < 0) nu = 0;
+ else nu = (byte) coverage;
+ this.coverage = nu;
+ }
+
+ @Override
+ public ITexture[] getTexturesActive(ITexture aBaseTexture) {
+ return new ITexture[] { aBaseTexture, TextureFactory.of(Textures.BlockIcons.OVERLAY_PIPE_IN) };
+ }
+
+ @Override
+ public ITexture[] getTexturesInactive(ITexture aBaseTexture) {
+ return new ITexture[] { aBaseTexture, TextureFactory.of(Textures.BlockIcons.OVERLAY_PIPE_IN) };
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new GT_MetaTileEntity_RadioHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
+ GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer);
+ return true;
+ }
+
+ public void updateSlots() {
+ if (this.mInventory[0] != null && this.mInventory[0].stackSize <= 0) this.mInventory[0] = null;
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) {
+ BaseMetaTileEntity myMetaTileEntity = (BaseMetaTileEntity) this.getBaseMetaTileEntity();
+ if (myMetaTileEntity.isServerSide()) {
+
+ if (this.mass > 0) {
+ ++this.timer;
+ }
+
+ if (this.mass > 0 && (this.decayTime == 0 || this.decayTime > 0 && this.timer % this.decayTime == 0)) {
+ this.mass--;
+ if (this.mass == 0) {
+ this.material = StatCollector.translateToLocal("tooltip.bw.empty.name");
+ this.sievert = 0;
+ }
+ this.timer = 1;
+ }
+
+ if (myMetaTileEntity.mTickTimer > myMetaTileEntity.mLastSoundTick + ticksBetweenSounds
+ && this.sievert > 0) {
+ this.sendLoopStart((byte) 1);
+ myMetaTileEntity.mLastSoundTick = myMetaTileEntity.mTickTimer;
+ }
+
+ if (this.mass == 0) {
+ ItemStack lStack = this.mInventory[0];
+
+ if (lStack == null) {
+ this.colorForGUI = new short[] { 0x37, 0x37, 0x37 };
+ return;
+ }
+ ItemData itemData = GTOreDictUnificator.getAssociation(lStack);
+ if (itemData != null) {
+ Materials mat = itemData.mMaterial.mMaterial;
+ this.colorForGUI = new short[] { mat.getRGBA()[0], mat.getRGBA()[1], mat.getRGBA()[2] };
+ } else {
+ this.colorForGUI = new short[] { 0x37, 0x37, 0x37 };
+ }
+
+ if (this.lastFail && GTUtility.areStacksEqual(this.lastUsedItem, lStack, true)) {
+ return;
+ }
+
+ if (!this.lastFail && this.lastUsedItem != null && this.lastRecipe != null) {
+ if (GTUtility.areStacksEqual(this.lastUsedItem, lStack, true)) {
+ this.mass = (byte) this.lastRecipe.mDuration;
+ this.decayTime = this.lastRecipe.mSpecialValue;
+ this.sievert = this.lastRecipe.mEUt;
+ this.material = this.lastUsedItem.getDisplayName();
+ lStack.stackSize--;
+ this.updateSlots();
+ } else {
+ this.lastRecipe = null;
+ }
+ }
+
+ if (this.lastRecipe == null || this.lastFail) {
+ this.lastRecipe = BartWorksRecipeMaps.radioHatchRecipes.findRecipe(
+ this.getBaseMetaTileEntity(),
+ false,
+ Integer.MAX_VALUE - 7,
+ null,
+ this.mInventory[0]);
+ if (this.lastRecipe == null) {
+ this.lastFail = true;
+ this.lastUsedItem = this.mInventory[0] == null ? null : this.mInventory[0].copy();
+ } else {
+ if (this.lastRecipe.mDuration > this.cap) {
+ this.lastFail = true;
+ this.lastUsedItem = this.mInventory[0].copy();
+ return;
+ }
+ this.lastFail = false;
+ this.lastUsedItem = this.mInventory[0].copy();
+ this.mass = (byte) this.lastRecipe.mDuration;
+ this.decayTime = this.lastRecipe.mSpecialValue;
+ this.sievert = this.lastRecipe.mEUt;
+ this.material = lStack.getDisplayName();
+ lStack.stackSize--;
+ this.updateSlots();
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean isGivingInformation() {
+ return true;
+ }
+
+ @Override
+ public String[] getInfoData() {
+ if (this.sievert != 0) return new String[] {
+ StatCollector.translateToLocal("tooltip.tile.radhatch.2.name") + " "
+ + StatCollector.translateToLocal(this.material),
+ StatCollector.translateToLocal("tooltip.tile.radhatch.3.name") + " " + this.sievert,
+ StatCollector.translateToLocal("tooltip.tile.radhatch.4.name") + " " + this.mass,
+ StatCollector.translateToLocal("tooltip.tile.radhatch.5.name") + " "
+ + (this.decayTime - this.timer % (this.decayTime * 60))
+ + StatCollector.translateToLocal("tooltip.tile.radhatch.6.name")
+ + "/"
+ + (this.decayTime - this.timer % this.decayTime) / 20
+ + StatCollector.translateToLocal("tooltip.tile.radhatch.7.name")
+ + "/"
+ + (this.decayTime - this.timer % this.decayTime) / 20 / 60
+ + StatCollector.translateToLocal("tooltip.tile.radhatch.8.name")
+ + "/"
+ + (this.decayTime - this.timer % this.decayTime) / 20 / 60 / 60
+ + StatCollector.translateToLocal("tooltip.tile.radhatch.9.name") };
+ return new String[] {
+ StatCollector.translateToLocal("tooltip.tile.radhatch.2.name") + " "
+ + StatCollector.translateToLocal("tooltip.bw.empty.name"),
+ StatCollector.translateToLocal("tooltip.tile.radhatch.3.name") + " " + "0",
+ StatCollector.translateToLocal("tooltip.tile.radhatch.4.name") + " " + "0" };
+ }
+
+ @Override
+ public boolean isSimpleMachine() {
+ return true;
+ }
+
+ @Override
+ public boolean isFacingValid(ForgeDirection facing) {
+ return true;
+ }
+
+ @Override
+ public boolean isAccessAllowed(EntityPlayer aPlayer) {
+ return true;
+ }
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return true;
+ }
+
+ @Override
+ public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side,
+ ItemStack aStack) {
+ return false;
+ }
+
+ @Override
+ public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side,
+ ItemStack aStack) {
+ return side == this.getBaseMetaTileEntity()
+ .getFrontFacing() && BartWorksRecipeMaps.radioHatchRecipes.containsInput(aStack);
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ aNBT.setByte("mMass", this.mass);
+ aNBT.setByte("mSv", (byte) (this.sievert - 100));
+ aNBT.setByte("mCoverage", this.coverage);
+ aNBT.setInteger("mTextColor", BWColorUtil.getColorFromRGBArray(this.getColorForGUI()));
+ if (this.material != null && !this.material.isEmpty()) aNBT.setString("mMaterial", this.material);
+ aNBT.setLong("timer", this.timer);
+ aNBT.setLong("decay", this.decayTime);
+ super.saveNBTData(aNBT);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ this.timer = aNBT.getLong("timer");
+ this.mass = aNBT.getByte("mMass");
+ this.sievert = aNBT.getByte("mSv") + 100;
+ this.coverage = aNBT.getByte("mCoverage");
+ this.colorForGUI = BWColorUtil.splitColorToRBGArray(aNBT.getInteger("mTextColor"));
+ this.material = aNBT.getString("mMaterial");
+ this.decayTime = aNBT.getLong("decay");
+ super.loadNBTData(aNBT);
+ }
+
+ @Override
+ public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) {
+ super.startSoundLoop(aIndex, aX, aY, aZ);
+ ResourceLocation rl = new ResourceLocation(MainMod.MOD_ID, "hatch.RadOn");
+ if (aIndex == 1) {
+ GTUtility.doSoundAtClient(rl, 10, 1.0F, aX, aY, aZ);
+ }
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ // Only for visual
+ return BartWorksRecipeMaps.radioHatchRecipes;
+ }
+
+ private static final int RADIATION_SHUTTER_WINDOW_ID = 999;
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ buildContext.addSyncedWindow(RADIATION_SHUTTER_WINDOW_ID, this::createShutterWindow);
+
+ this.getBaseMetaTileEntity()
+ .add1by1Slot(builder);
+ builder.widget(
+ new DrawableWidget().setBackground(BWUITextures.PICTURE_SIEVERT_CONTAINER)
+ .setPos(61, 9)
+ .setSize(56, 24))
+ .widget(
+ new ProgressBar().setProgress(() -> this.getSievert() / 148f)
+ .setDirection(Direction.RIGHT)
+ .setTexture(BWUITextures.PROGRESSBAR_SIEVERT, 24)
+ .setPos(65, 13)
+ .setSize(48, 16))
+ .widget(
+ new DrawableWidget().setBackground(BWUITextures.PICTURE_DECAY_TIME_INSIDE)
+ .setPos(124, 18)
+ .setSize(16, 48))
+ .widget(new DrawableWidget() {
+
+ @Override
+ public void draw(float partialTicks) {
+ if (GT_MetaTileEntity_RadioHatch.this.decayTime > 0) {
+ int height = MathUtils.ceilInt(
+ 48 * ((GT_MetaTileEntity_RadioHatch.this.decayTime
+ - GT_MetaTileEntity_RadioHatch.this.timer % GT_MetaTileEntity_RadioHatch.this.decayTime)
+ / (float) GT_MetaTileEntity_RadioHatch.this.decayTime));
+ new Rectangle()
+ .setColor(
+ Color.argb(
+ GT_MetaTileEntity_RadioHatch.this.colorForGUI[0],
+ GT_MetaTileEntity_RadioHatch.this.colorForGUI[1],
+ GT_MetaTileEntity_RadioHatch.this.colorForGUI[2],
+ 255))
+ .draw(new Pos2d(0, 48 - height), new Size(16, height), partialTicks);
+ }
+ }
+ }.dynamicTooltip(
+ () -> Collections.singletonList(
+ StatCollector.translateToLocalFormatted(
+ "tooltip.tile.radhatch.10.name",
+ this.timer <= 1 ? 0 : (this.decayTime - this.timer) / 20,
+ this.timer <= 1 ? 0 : this.decayTime / 20)))
+ .setPos(124, 18)
+ .setSize(16, 48)
+ .attachSyncer(
+ new FakeSyncWidget.LongSyncer(() -> this.decayTime, val -> this.decayTime = val),
+ builder,
+ (widget, val) -> widget.notifyTooltipChange())
+ .attachSyncer(
+ new FakeSyncWidget.LongSyncer(() -> this.timer, val -> this.timer = val),
+ builder,
+ (widget, val) -> widget.notifyTooltipChange()))
+ .widget(new FakeSyncWidget.ShortSyncer(() -> this.colorForGUI[0], val -> this.colorForGUI[0] = val))
+ .widget(new FakeSyncWidget.ShortSyncer(() -> this.colorForGUI[1], val -> this.colorForGUI[1] = val))
+ .widget(new FakeSyncWidget.ShortSyncer(() -> this.colorForGUI[2], val -> this.colorForGUI[2] = val))
+ .widget(
+ new DrawableWidget().setBackground(BWUITextures.PICTURE_DECAY_TIME_CONTAINER)
+ .setPos(120, 14)
+ .setSize(24, 56))
+ .widget(
+ new TextWidget()
+ .setStringSupplier(
+ () -> StatCollector.translateToLocalFormatted("BW.NEI.display.radhatch.1", this.mass))
+ .setTextAlignment(Alignment.Center)
+ .setPos(65, 62))
+ .widget(new FakeSyncWidget.ByteSyncer(() -> this.mass, val -> this.mass = val))
+ .widget(
+ new TextWidget()
+ .setStringSupplier(
+ () -> StatCollector.translateToLocalFormatted("BW.NEI.display.radhatch.0", this.getSievert()))
+ .setTextAlignment(Alignment.Center)
+ .setPos(60, 72))
+ .widget(new FakeSyncWidget.IntegerSyncer(() -> this.sievert, val -> this.sievert = val))
+ .widget(new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (!widget.isClient()) {
+ widget.getContext()
+ .openSyncedWindow(RADIATION_SHUTTER_WINDOW_ID);
+ }
+ })
+ .addTooltip("Radiation Shutter")
+ .setBackground(GTUITextures.BUTTON_STANDARD)
+ .setPos(153, 5)
+ .setSize(18, 18))
+ .widget(
+ new ItemDrawable(
+ MetaGeneratedTool01.INSTANCE.getToolWithStats(IDMetaTool01.SCREWDRIVER.ID, 1, null, null, null))
+ .asWidget()
+ .setPos(154, 6));
+ }
+
+ private ModularWindow createShutterWindow(EntityPlayer player) {
+ ModularWindow.Builder builder = ModularWindow.builder(176, 107);
+ builder.setBackground(ModularUITextures.VANILLA_BACKGROUND);
+ builder.setGuiTint(this.getGUIColorization());
+
+ builder.widget(
+ new TextWidget("Radiation Shutter Control").setDefaultColor(this.COLOR_TITLE.get())
+ .setPos(10, 9))
+ .widget(
+ new DrawableWidget().setDrawable(BWUITextures.PICTURE_RADIATION_SHUTTER_FRAME)
+ .setPos(14, 27)
+ .setSize(55, 54))
+ .widget(
+ new DrawableWidget()
+ .setDrawable(() -> this.coverage < 100 ? BWUITextures.PICTURE_RADIATION_SHUTTER_INSIDE : null)
+ .setPos(16, 29)
+ .setSize(51, 50)
+ .attachSyncer(
+ new FakeSyncWidget.ByteSyncer(this::getCoverage, this::setCoverage),
+ builder,
+ (widget, val) -> widget.setPos(16, 29 + this.coverage / 2)
+ .setSize(51, 50 - this.coverage / 2)))
+ .widget(
+ new NumericWidget().setSetter(val -> this.coverage = (byte) val)
+ .setGetter(() -> this.coverage)
+ .setBounds(0, 100)
+ .setScrollValues(1, 5, 50)
+ .setTextColor(Color.WHITE.dark(1))
+ .setTextAlignment(Alignment.CenterLeft)
+ .setBackground(GTUITextures.BACKGROUND_TEXT_FIELD.withOffset(-1, -1, 2, 2))
+ .setPos(86, 27)
+ .setSize(30, 12))
+ .widget(
+ ButtonWidget.closeWindowButton(true)
+ .setPos(176 - 15, 3));
+
+ return builder.build();
+ }
+
+ @Override
+ public void addGregTechLogo(ModularWindow.Builder builder) {
+ builder.widget(
+ new DrawableWidget().setDrawable(BWUITextures.PICTURE_BW_LOGO_47X21)
+ .setSize(47, 21)
+ .setPos(10, 53));
+ }
+
+ @Override
+ public GUITextureSet getGUITextureSet() {
+ return new GUITextureSet().setMainBackground(GTUITextures.BACKGROUND_SINGLEBLOCK_DEFAULT)
+ .setGregTechLogo(GTUITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT);
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEAcidGenerator.java b/src/main/java/bartworks/common/tileentities/tiered/MTEAcidGenerator.java
new file mode 100644
index 0000000000..2713d3dee2
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/MTEAcidGenerator.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import bartworks.API.recipe.BartWorksRecipeMaps;
+import bartworks.util.BWTooltipReference;
+import gregtech.api.enums.GTValues;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEBasicGenerator;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.render.TextureFactory;
+
+public class MTEAcidGenerator extends MTEBasicGenerator {
+
+ public MTEAcidGenerator(int aID, String aName, String aNameRegional, int aTier, ITexture... aTextures) {
+ super(aID, aName, aNameRegional, aTier, new String[] {}, aTextures);
+ }
+
+ public MTEAcidGenerator(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ }
+
+ @Override
+ public int getPollution() {
+ return 0;
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return BartWorksRecipeMaps.acidGenFuels;
+ }
+
+ @Override
+ public int getEfficiency() {
+ return 100 - 3 * this.mTier;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEAcidGenerator(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ public ITexture[] getFront(byte aColor) {
+ return new ITexture[] { super.getFront(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL),
+ Textures.BlockIcons.OVERLAYS_ENERGY_OUT[this.mTier] };
+ }
+
+ @Override
+ public ITexture[] getBack(byte aColor) {
+ return new ITexture[] { super.getBack(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) };
+ }
+
+ @Override
+ public ITexture[] getBottom(byte aColor) {
+ return new ITexture[] { super.getBottom(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) };
+ }
+
+ @Override
+ public ITexture[] getTop(byte aColor) {
+ return new ITexture[] { super.getTop(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL),
+ TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_GLOW"))
+ .glow()
+ .build() };
+ }
+
+ @Override
+ public ITexture[] getSides(byte aColor) {
+ return new ITexture[] { super.getSides(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) };
+ }
+
+ @Override
+ public ITexture[] getFrontActive(byte aColor) {
+ return new ITexture[] { super.getFrontActive(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL),
+ Textures.BlockIcons.OVERLAYS_ENERGY_OUT[this.mTier] };
+ }
+
+ @Override
+ public ITexture[] getBackActive(byte aColor) {
+ return new ITexture[] { super.getBackActive(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) };
+ }
+
+ @Override
+ public ITexture[] getBottomActive(byte aColor) {
+ return new ITexture[] { super.getBottomActive(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) };
+ }
+
+ @Override
+ public ITexture[] getTopActive(byte aColor) {
+ return new ITexture[] { super.getTopActive(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL),
+ TextureFactory
+ .of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE_GLOW"))
+ .glow()
+ .build() };
+ }
+
+ @Override
+ public ITexture[] getSidesActive(byte aColor) {
+ return new ITexture[] { super.getSidesActive(aColor)[0],
+ TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) };
+ }
+
+ @Override
+ public boolean isOutputFacing(ForgeDirection side) {
+ return side == this.getBaseMetaTileEntity()
+ .getFrontFacing();
+ }
+
+ @Override
+ public String[] getDescription() {
+ return new String[] { StatCollector.translateToLocal("tooltip.tile.acidgen.0.name"),
+ StatCollector.translateToLocal("tooltip.tile.acidgen.1.name"),
+ StatCollector.translateToLocal("tooltip.tile.tiereddsc.0.name") + " "
+ + EnumChatFormatting.YELLOW
+ + GTValues.V[this.mTier],
+ StatCollector.translateToLocal("tooltip.rotor.2.name") + " "
+ + EnumChatFormatting.YELLOW
+ + this.getEfficiency(),
+ StatCollector.translateToLocal("tooltip.tile.tiereddsc.2.name") + " "
+ + EnumChatFormatting.YELLOW
+ + this.maxAmperesOut(),
+ BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get() };
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEBioLab.java b/src/main/java/bartworks/common/tileentities/tiered/MTEBioLab.java
new file mode 100644
index 0000000000..992c7188fa
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/MTEBioLab.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import static gregtech.api.enums.Mods.Gendustry;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+
+import bartworks.API.recipe.BartWorksRecipeMaps;
+import bartworks.common.items.ItemLabModule;
+import bartworks.common.items.ItemLabParts;
+import bartworks.common.loaders.BioCultureLoader;
+import bartworks.common.loaders.BioItemList;
+import bartworks.common.loaders.FluidLoader;
+import bartworks.util.BWTooltipReference;
+import bartworks.util.BWUtil;
+import bartworks.util.BioCulture;
+import bartworks.util.BioDNA;
+import bartworks.util.BioData;
+import bartworks.util.BioPlasmid;
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEBasicMachine;
+import gregtech.api.objects.XSTR;
+import gregtech.api.recipe.RecipeMap;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTOreDictUnificator;
+import gregtech.api.util.GTUtility;
+import gregtech.common.items.behaviors.BehaviourDataOrb;
+
+public class MTEBioLab extends MTEBasicMachine {
+
+ private static final int DNA_EXTRACTION_MODULE = 0;
+ private static final int PCR_THERMOCYCLE_MODULE = 1;
+ private static final int PLASMID_SYNTHESIS_MODULE = 2;
+ private static final int TRANSFORMATION_MODULE = 3;
+ private static final int CLONAL_CELLULAR_SYNTHESIS_MODULE = 4;
+ private static final int INCUBATION_MODULE = 5;
+
+ public MTEBioLab(int aID, String aName, String aNameRegional, int aTier) {
+ super(
+ aID,
+ aName,
+ aNameRegional,
+ aTier,
+ 1,
+ (String) null,
+ 6,
+ 2,
+ TextureFactory.of(
+ TextureFactory
+ .of(new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE_ACTIVE")),
+ TextureFactory.builder()
+ .addIcon(
+ new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE_ACTIVE_GLOW"))
+ .glow()
+ .build()),
+ TextureFactory.of(
+ TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE_GLOW"))
+ .glow()
+ .build()),
+ TextureFactory.of(
+ TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT_ACTIVE")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT_ACTIVE_GLOW"))
+ .glow()
+ .build()),
+ TextureFactory.of(
+ TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT_GLOW"))
+ .glow()
+ .build()),
+ TextureFactory.of(
+ TextureFactory
+ .of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE")),
+ TextureFactory.builder()
+ .addIcon(
+ new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE_GLOW"))
+ .glow()
+ .build() /* this is topactive */),
+ TextureFactory.of(
+ TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_GLOW"))
+ .glow()
+ .build() /* this is top */),
+ TextureFactory.of(
+ TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM_ACTIVE")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM_ACTIVE_GLOW"))
+ .glow()
+ .build()),
+ TextureFactory.of(
+ TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM")),
+ TextureFactory.builder()
+ .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM_GLOW"))
+ .glow()
+ .build()));
+ }
+
+ public MTEBioLab(String aName, int aTier, int aAmperage, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aAmperage, aDescription, aTextures, 6, 2);
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) {
+ return new MTEBioLab(this.mName, this.mTier, this.mAmperage, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return BartWorksRecipeMaps.bioLabRecipes;
+ }
+
+ @Override
+ public int getCapacity() {
+ return this.mTier * 1000;
+ }
+
+ @Override
+ public int checkRecipe(boolean skipOC) {
+
+ int rTier = 3;
+ FluidStack dnaFluid = Gendustry.isModLoaded() ? FluidRegistry.getFluidStack("liquiddna", 1000)
+ : Materials.Biomass.getFluid(1000L);
+
+ if (this.getSpecialSlot() != null && this.getSpecialSlot()
+ .getItem() instanceof ItemLabModule) {
+ int damage = this.getSpecialSlot()
+ .getItemDamage();
+ switch (damage) {
+ case DNA_EXTRACTION_MODULE:
+ if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()])
+ && this.mInventory[this.getInputSlot()].getItem() instanceof ItemLabParts
+ && this.mInventory[this.getInputSlot()].getItemDamage() == 0
+ && this.mInventory[this.getInputSlot()].getTagCompound() != null
+ && // checks if it is a Culture
+ GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1])
+ && this.mInventory[this.getInputSlot() + 1].getItem() instanceof ItemLabParts
+ && this.mInventory[this.getInputSlot() + 1].getItemDamage() == 1
+ && this.mInventory[this.getInputSlot() + 1].getTagCompound() == null
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2])
+ && this.mInventory[this.getInputSlot() + 2].getItem() instanceof ItemLabParts
+ && this.mInventory[this.getInputSlot() + 2].getItemDamage() == 3
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot() + 3], Materials.Ethanol.getCells(1))
+ && this.mFluid != null
+ && this.mFluid.isFluidEqual(FluidRegistry.getFluidStack("ic2distilledwater", 1000))
+ && this.mFluid.amount >= 1000) {
+
+ NBTTagCompound DNABioDataTag = this.mInventory[this.getInputSlot()].getTagCompound()
+ .getCompoundTag("DNA");
+ if (DNABioDataTag == null) return super.checkRecipe(skipOC);
+ BioData cultureDNABioData = BioData.getBioDataFromName(
+ this.mInventory[this.getInputSlot()].getTagCompound()
+ .getCompoundTag("DNA")
+ .getString("Name"));
+ if (cultureDNABioData == null) return super.checkRecipe(skipOC);
+
+ if (this.mTier < rTier + cultureDNABioData.getTier())
+ return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS;
+
+ for (int i = 0; i < 4; i++) {
+ if (this.mInventory[this.getInputSlot() + i] != null)
+ this.mInventory[this.getInputSlot() + i].stackSize--;
+ }
+
+ this.mFluid.amount -= 1000;
+
+ if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) {
+ this.mOutputItems[0] = BioItemList
+ .getDNASampleFlask(BioDNA.convertDataToDNA(cultureDNABioData));
+ }
+ this.mOutputItems[1] = GTOreDictUnificator.get(OrePrefixes.cell, Materials.Empty, 1L);
+ this.calculateOverclockedNess(
+ BWUtil.getMachineVoltageFromTier(rTier + cultureDNABioData.getTier()),
+ 500);
+
+ return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE;
+ }
+ break;
+ case PCR_THERMOCYCLE_MODULE: {
+ if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()])
+ && this.mInventory[this.getInputSlot()].getItem() instanceof ItemLabParts
+ && this.mInventory[this.getInputSlot()].getItemDamage() == 1
+ && this.mInventory[this.getInputSlot()].getTagCompound() != null
+ && // checks if it is a Culture
+ GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 3])
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot() + 3], ItemList.Tool_DataOrb.get(1L))
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1])
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot() + 1], FluidLoader.BioLabFluidCells[0])
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2])
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot() + 2], FluidLoader.BioLabFluidCells[3])
+ && this.mFluid != null
+ && this.mFluid.isFluidEqual(dnaFluid)
+ && this.mFluid.amount >= 1000) {
+ NBTTagCompound DNABioDataTag = this.mInventory[this.getInputSlot()].getTagCompound();
+ if (DNABioDataTag == null) return super.checkRecipe(skipOC);
+ BioData cultureDNABioData = BioData.getBioDataFromName(DNABioDataTag.getString("Name"));
+ if (cultureDNABioData == null) return super.checkRecipe(skipOC);
+
+ if (this.mTier < 1 + rTier + cultureDNABioData.getTier())
+ return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS;
+
+ for (int i = 0; i < 4; i++) {
+ if (this.mInventory[this.getInputSlot() + i] != null)
+ this.mInventory[this.getInputSlot() + i].stackSize--;
+ }
+
+ this.mFluid.amount -= 1000;
+
+ ItemStack Outp = ItemList.Tool_DataOrb.get(1L);
+ BehaviourDataOrb.setDataTitle(Outp, "DNA Sample");
+ BehaviourDataOrb.setDataName(Outp, cultureDNABioData.getName());
+
+ if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) {
+ this.mOutputItems[0] = Outp;
+ } else this.mOutputItems[0] = ItemList.Tool_DataOrb.get(1L);
+ this.mOutputItems[1] = ItemList.Cell_Empty.get(2L);
+
+ this.calculateOverclockedNess(
+ BWUtil.getMachineVoltageFromTier(1 + rTier + cultureDNABioData.getTier()),
+ 500);
+
+ return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE;
+ }
+ }
+ break;
+ case PLASMID_SYNTHESIS_MODULE: {
+ ItemStack inp2 = ItemList.Tool_DataOrb.get(1L);
+ BehaviourDataOrb.setDataTitle(inp2, "DNA Sample");
+ BehaviourDataOrb.setDataName(inp2, BioCultureLoader.BIO_DATA_BETA_LACMATASE.getName());
+ if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()])
+ && GTUtility
+ .areStacksEqual(FluidLoader.BioLabFluidCells[1], this.mInventory[this.getInputSlot()])
+ && // checks
+ // if
+ // it
+ // is
+ // a
+ // Culture
+ GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1])
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot() + 1], BioItemList.getPlasmidCell(null))
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2])
+ && GTUtility.areStacksEqual(
+ this.mInventory[this.getInputSlot() + 2],
+ ItemList.Tool_DataOrb.get(1L),
+ true)
+ && "DNA Sample".equals(BehaviourDataOrb.getDataTitle(this.mInventory[this.getInputSlot() + 2]))
+ && !BehaviourDataOrb.getDataName(this.mInventory[this.getInputSlot() + 2])
+ .isEmpty()
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 3])
+ && GTUtility.areStacksEqual(this.mInventory[this.getInputSlot() + 3], inp2)
+ && this.mFluid != null
+ && this.mFluid.isFluidEqual(dnaFluid)
+ && this.mFluid.amount >= 1000) {
+ BioData cultureDNABioData = BioData
+ .getBioDataFromName(BehaviourDataOrb.getDataName(this.mInventory[this.getInputSlot() + 2]));
+ if (cultureDNABioData == null) return super.checkRecipe(skipOC);
+ if (this.mTier < 1 + rTier + cultureDNABioData.getTier())
+ return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS;
+ for (int i = 0; i < 2; i++) {
+ if (this.mInventory[this.getInputSlot() + i] != null)
+ this.mInventory[this.getInputSlot() + i].stackSize--;
+ }
+ this.mFluid.amount -= 1000;
+ if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) {
+ this.mOutputItems[0] = BioItemList
+ .getPlasmidCell(BioPlasmid.convertDataToPlasmid(cultureDNABioData));
+ }
+ this.mOutputItems[1] = ItemList.Cell_Empty.get(1L);
+ this.calculateOverclockedNess(
+ BWUtil.getMachineVoltageFromTier(1 + rTier + cultureDNABioData.getTier()),
+ 500);
+ return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE;
+ }
+ }
+ break;
+ case TRANSFORMATION_MODULE: {
+ if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()])
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot()], BioItemList.getPetriDish(null), true)
+ && this.mInventory[this.getInputSlot()].getTagCompound() != null
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1])
+ && GTUtility.areStacksEqual(
+ this.mInventory[this.getInputSlot() + 1],
+ BioItemList.getPlasmidCell(null),
+ true)
+ && this.mInventory[this.getInputSlot() + 1].getTagCompound() != null
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2])
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot() + 2], FluidLoader.BioLabFluidCells[2])
+ && this.mFluid != null
+ && this.mFluid.isFluidEqual(FluidRegistry.getFluidStack("ic2distilledwater", 1000))
+ && this.mFluid.amount >= 1000) {
+ BioData cultureDNABioData = BioData
+ .getBioDataFromNBTTag(this.mInventory[this.getInputSlot() + 1].getTagCompound());
+ BioCulture bioCulture = BioCulture
+ .getBioCultureFromNBTTag(this.mInventory[this.getInputSlot()].getTagCompound());
+ if (cultureDNABioData == null || bioCulture == null) return super.checkRecipe(skipOC);
+ if (this.mTier < 3 + rTier + cultureDNABioData.getTier())
+ return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS;
+ for (int i = 0; i < 3; i++) {
+ if (this.mInventory[this.getInputSlot() + i] != null)
+ this.mInventory[this.getInputSlot() + i].stackSize--;
+ }
+ this.mFluid.amount -= 1000;
+ bioCulture = bioCulture.setPlasmid(BioPlasmid.convertDataToPlasmid(cultureDNABioData));
+ if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) {
+ this.mOutputItems[0] = BioItemList.getPetriDish(bioCulture);
+ }
+ this.mOutputItems[1] = ItemList.Cell_Empty.get(1L);
+ this.calculateOverclockedNess(
+ BWUtil.getMachineVoltageFromTier(3 + rTier + cultureDNABioData.getTier()),
+ 500);
+ return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE;
+ }
+ }
+ break;
+ case CLONAL_CELLULAR_SYNTHESIS_MODULE: {
+ ItemStack Outp = ItemList.Tool_DataOrb.get(1L);
+ BehaviourDataOrb.setDataTitle(Outp, "DNA Sample");
+
+ if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()])
+ && GTUtility
+ .areStacksEqual(this.mInventory[this.getInputSlot()], BioItemList.getPetriDish(null))
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1])
+ && GTUtility.areStacksEqual(this.mInventory[this.getInputSlot() + 1], BioItemList.getOther(4))
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2])
+ && GTUtility.areStacksEqual(
+ this.mInventory[this.getInputSlot() + 2],
+ ItemList.Circuit_Chip_Stemcell.get(2L))
+ && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 3])
+ && GTUtility.areStacksEqual(
+ this.mInventory[this.getInputSlot() + 3],
+ ItemList.Tool_DataOrb.get(1L),
+ true)
+ && "DNA Sample".equals(BehaviourDataOrb.getDataTitle(this.mInventory[this.getInputSlot() + 3]))
+ && this.mFluid.isFluidEqual(dnaFluid)
+ && this.mFluid.amount >= 8000) {
+
+ BioData cultureDNABioData = BioData
+ .getBioDataFromName(BehaviourDataOrb.getDataName(this.mInventory[this.getInputSlot() + 3]));
+ if (cultureDNABioData == null) return super.checkRecipe(skipOC);
+ if (this.mTier < 3 + rTier + cultureDNABioData.getTier())
+ return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS;
+ for (int i = 0; i < 3; i++) {
+ if (this.mInventory[this.getInputSlot() + i] != null)
+ this.mInventory[this.getInputSlot() + i].stackSize--;
+ }
+ this.mFluid.amount -= 8000;
+ if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) {
+ BioCulture out = BioCulture.getBioCulture(BioDNA.convertDataToDNA(cultureDNABioData));
+ if (out == null) return MTEBasicMachine.DID_NOT_FIND_RECIPE;
+ out = out.setPlasmid(BioPlasmid.convertDataToPlasmid(cultureDNABioData));
+ this.mOutputItems[0] = BioItemList.getPetriDish(out);
+ }
+ this.calculateOverclockedNess(
+ BWUtil.getMachineVoltageFromTier(3 + rTier + cultureDNABioData.getTier()),
+ 500);
+ return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE;
+ }
+ }
+ break;
+ case INCUBATION_MODULE:
+ default:
+ break;
+ }
+ }
+ return super.checkRecipe(skipOC);
+ }
+
+ @Override
+ public String[] getDescription() {
+ return new String[] { StatCollector.translateToLocal("tooltip.tile.biolab.0.name"),
+ BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get() };
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTECompressedFluidHatch.java b/src/main/java/bartworks/common/tileentities/tiered/MTECompressedFluidHatch.java
new file mode 100644
index 0000000000..89b21ae67e
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/MTECompressedFluidHatch.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget;
+
+import gregtech.api.enums.Materials;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.MetaTileEntity;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+import gregtech.api.util.GTUtility;
+
+public class MTECompressedFluidHatch extends MTEHatchInput {
+
+ public MTECompressedFluidHatch(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional, 0);
+ this.mDescriptionArray[1] = "Capacity: 100,000,000L";
+ }
+
+ public MTECompressedFluidHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ }
+
+ @Override
+ public int getCapacity() {
+ return 100_000_000;
+ }
+
+ @Override
+ public boolean isFluidInputAllowed(FluidStack aFluid) {
+ return GTUtility.areFluidsEqual(aFluid, Materials.LiquidAir.getFluid(1));
+ }
+
+ @Override
+ public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTECompressedFluidHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ protected FluidSlotWidget createFluidSlot() {
+ return super.createFluidSlot().setFilter(f -> f == Materials.LiquidAir.mFluid);
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEDiode.java b/src/main/java/bartworks/common/tileentities/tiered/MTEDiode.java
new file mode 100644
index 0000000000..ad3a39320f
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/MTEDiode.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import static gregtech.api.enums.MetaTileEntityIDs.Diode12A_MAX;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode12A_ULV;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode16A_MAX;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode16A_ULV;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode2A_MAX;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode2A_ULV;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode4A_MAX;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode4A_ULV;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode8A_MAX;
+import static gregtech.api.enums.MetaTileEntityIDs.Diode8A_ULV;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTEBasicHull;
+import gregtech.api.util.GTUtility;
+
+public class MTEDiode extends MTEBasicHull {
+
+ private long maxAmps;
+ private long aAmps;
+
+ public MTEDiode(int aID, String aName, String aNameRegional, int aTier) {
+ super(aID, aName, aNameRegional, aTier, StatCollector.translateToLocal("tooltip.tile.diode.0.name"));
+ this.maxAmps = this.getAmpsfromMeta(aID);
+ this.aAmps = this.maxAmps;
+ }
+
+ public MTEDiode(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, 0, aDescription, aTextures);
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ super.onFirstTick(aBaseMetaTileEntity);
+ if (this.maxAmps == 0 && !this.getBaseMetaTileEntity()
+ .getWorld().isRemote) {
+ this.maxAmps = this.getAmpsfromMeta(
+ this.getBaseMetaTileEntity()
+ .getMetaTileID());
+ this.aAmps = this.maxAmps;
+ }
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ super.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ);
+
+ if (this.getBaseMetaTileEntity()
+ .getWorld().isRemote) return;
+ if (!aPlayer.isSneaking()) {
+ --this.aAmps;
+ if (this.aAmps < 0) this.aAmps = this.maxAmps;
+ } else {
+ ++this.aAmps;
+ if (this.aAmps > this.maxAmps) this.aAmps = 0;
+ }
+ GTUtility.sendChatToPlayer(aPlayer, "Max Amps: " + this.aAmps);
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setLong("maxAmp", this.maxAmps);
+ aNBT.setLong("Amps", this.aAmps);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ this.maxAmps = aNBT.getLong("maxAmp");
+ this.aAmps = aNBT.getLong("Amps");
+ super.loadNBTData(aNBT);
+ }
+
+ @Override
+ public long maxAmperesOut() {
+ return this.aAmps;
+ }
+
+ @Override
+ public long maxAmperesIn() {
+ return this.aAmps;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEDiode(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ private long getAmpsfromMeta(int meta) {
+ if (meta >= Diode2A_ULV.ID && meta <= Diode2A_MAX.ID) return 2L;
+ if (meta >= Diode4A_ULV.ID && meta <= Diode4A_MAX.ID) return 4L;
+ if (meta >= Diode8A_ULV.ID && meta <= Diode8A_MAX.ID) return 8L;
+ if (meta >= Diode12A_ULV.ID && meta <= Diode12A_MAX.ID) return 12L;
+ if (meta >= Diode16A_ULV.ID && meta <= Diode16A_MAX.ID) return 16L;
+ return 0L;
+ }
+
+ @Override
+ public String[] getDescription() {
+ return ArrayUtils.addAll(this.mDescriptionArray);
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEEnergyDistributor.java b/src/main/java/bartworks/common/tileentities/tiered/MTEEnergyDistributor.java
new file mode 100644
index 0000000000..d361047699
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/MTEEnergyDistributor.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import net.minecraft.util.StatCollector;
+
+import gregtech.api.enums.GTValues;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.MTETransformer;
+
+public class MTEEnergyDistributor extends MTETransformer {
+
+ public MTEEnergyDistributor(int aID, String aName, String aNameRegional, int aTier) {
+ super(aID, aName, aNameRegional, aTier, null);
+ }
+
+ public MTEEnergyDistributor(String aName, int aTier, String aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ }
+
+ public MTEEnergyDistributor(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEEnergyDistributor(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ public long maxEUInput() {
+ return GTValues.V[this.mTier];
+ }
+
+ @Override
+ public long maxEUOutput() {
+ return GTValues.V[this.mTier];
+ }
+
+ @Override
+ public long maxAmperesOut() {
+ return 320;
+ }
+
+ @Override
+ public long maxAmperesIn() {
+ return 320;
+ }
+
+ @Override
+ public long maxEUStore() {
+ return 512L + GTValues.V[this.mTier] * 320L;
+ }
+
+ @Override
+ public String[] getDescription() {
+ return new String[] { StatCollector.translateToLocal("tooltip.tile.energydistributor.0.name") };
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEGiantOutputHatch.java b/src/main/java/bartworks/common/tileentities/tiered/MTEGiantOutputHatch.java
new file mode 100644
index 0000000000..dc4b031f74
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/MTEGiantOutputHatch.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.MetaTileEntity;
+import gregtech.api.metatileentity.implementations.MTEHatchOutput;
+
+public class MTEGiantOutputHatch extends MTEHatchOutput {
+
+ public MTEGiantOutputHatch(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional, 0);
+ this.mDescriptionArray[1] = "Capacity: 100000000L";
+ }
+
+ public MTEGiantOutputHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ }
+
+ @Override
+ public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEGiantOutputHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ public int getCapacity() {
+ return 100000000;
+ }
+}
diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEHumongousInputHatch.java b/src/main/java/bartworks/common/tileentities/tiered/MTEHumongousInputHatch.java
new file mode 100644
index 0000000000..efe3614250
--- /dev/null
+++ b/src/main/java/bartworks/common/tileentities/tiered/MTEHumongousInputHatch.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial
+ * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package bartworks.common.tileentities.tiered;
+
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.MetaTileEntity;
+import gregtech.api.metatileentity.implementations.MTEHatchInput;
+
+public class MTEHumongousInputHatch extends MTEHatchInput {
+
+ public MTEHumongousInputHatch(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional, 13);
+ this.mDescriptionArray[1] = "Capacity: 2,000,000,000L";
+ }
+
+ public MTEHumongousInputHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ }
+
+ @Override
+ public int getCapacity() {
+ return 2_000_000_000;
+ }
+
+ @Override
+ public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new MTEHumongousInputHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+}