From 6a36ab8fe1f8650f9fb7817c8d4c4bcdf6cb0f19 Mon Sep 17 00:00:00 2001 From: DianeXD Date: Sat, 22 Oct 2022 21:02:11 +0800 Subject: TFFT totally rework --- src/main/java/common/Blocks.java | 4 + src/main/java/common/CommonProxy.java | 4 + src/main/java/common/Recipes.java | 50 +- src/main/java/common/TileEntities.java | 16 +- .../java/common/blocks/Block_TFFTStorageField.java | 88 +++ .../common/itemBlocks/IB_TFFTStorageField.java | 47 ++ .../tileentities/GTMTE_FluidMultiStorage.java | 562 ---------------- src/main/java/common/tileentities/GTMTE_TFFT.java | 713 +++++++++++++++++++++ .../java/common/tileentities/GTMTE_TFFTHatch.java | 268 ++++++++ .../common/tileentities/GTMTE_TFFTMultiHatch.java | 217 ------- 10 files changed, 1141 insertions(+), 828 deletions(-) create mode 100644 src/main/java/common/blocks/Block_TFFTStorageField.java create mode 100644 src/main/java/common/itemBlocks/IB_TFFTStorageField.java delete mode 100644 src/main/java/common/tileentities/GTMTE_FluidMultiStorage.java create mode 100644 src/main/java/common/tileentities/GTMTE_TFFT.java create mode 100644 src/main/java/common/tileentities/GTMTE_TFFTHatch.java delete mode 100644 src/main/java/common/tileentities/GTMTE_TFFTMultiHatch.java (limited to 'src/main/java') diff --git a/src/main/java/common/Blocks.java b/src/main/java/common/Blocks.java index 2a4bf328f7..fb5b152f26 100644 --- a/src/main/java/common/Blocks.java +++ b/src/main/java/common/Blocks.java @@ -17,6 +17,8 @@ public class Blocks { public static Block tfftStorageField5; public static Block tfftMultiHatch; + public static Block tfftStorageField; + public static Block reactorChamberOFF; public static Block reactorChamberON; public static Block reactorControlRod; @@ -69,6 +71,8 @@ public class Blocks { tfftStorageField4 = Block_TFFTStorageFieldBlockT4.registerBlock(); tfftStorageField5 = Block_TFFTStorageFieldBlockT5.registerBlock(); tfftMultiHatch = Block_TFFTMultiHatch.registerBlock(); + + tfftStorageField = Block_TFFTStorageField.registerBlock(); } /*private static void registerBlocks_Nuclear() { diff --git a/src/main/java/common/CommonProxy.java b/src/main/java/common/CommonProxy.java index bf92f6c697..464f8eab49 100644 --- a/src/main/java/common/CommonProxy.java +++ b/src/main/java/common/CommonProxy.java @@ -3,10 +3,12 @@ package common; import common.items.ErrorItem; import common.items.MetaItem_CraftingComponent; import common.items.MetaItem_ReactorComponent; +import common.tileentities.GTMTE_TFFTHatch; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.network.NetworkRegistry; +import gregtech.api.GregTech_API; import kekztech.GuiHandler; import kekztech.Items; import kekztech.KekzCore; @@ -39,5 +41,7 @@ public class CommonProxy { Recipes.postInit(); // Research Researches.postInit(); + + if (GregTech_API.mAE2) GTMTE_TFFTHatch.registerAEIntegration(); } } diff --git a/src/main/java/common/Recipes.java b/src/main/java/common/Recipes.java index 558f0b83db..64b4036d88 100644 --- a/src/main/java/common/Recipes.java +++ b/src/main/java/common/Recipes.java @@ -70,7 +70,7 @@ public class Recipes { 'C', OrePrefixes.circuit.get(Materials.Data) }; - GT_ModHandler.addCraftingRecipe(TileEntities.fms.getStackForm(1), tfft_recipe); + GT_ModHandler.addCraftingRecipe(TileEntities.tfft.getStackForm(1), tfft_recipe); // Blocks final ItemStack[] tfftcasing = { @@ -82,7 +82,7 @@ public class Recipes { GT_Values.RA.addAssemblerRecipe( tfftcasing, FluidRegistry.getFluidStack("molten.polytetrafluoroethylene", 144), - new ItemStack(Blocks.tfftCasing, 1), + new ItemStack(Blocks.tfftStorageField, 1), 200, 256); final ItemStack[] tfftstoragefield1 = { @@ -95,7 +95,7 @@ public class Recipes { GT_Values.RA.addAssemblerRecipe( tfftstoragefield1, FluidRegistry.getFluidStack("molten.glass", 144), - new ItemStack(Blocks.tfftStorageField1, 1), + new ItemStack(Blocks.tfftStorageField, 1, 1), 200, 256); final ItemStack[] tfftstoragefield2 = { @@ -108,7 +108,7 @@ public class Recipes { GT_Values.RA.addAssemblerRecipe( tfftstoragefield2, FluidRegistry.getFluidStack("molten.plastic", 576), - new ItemStack(Blocks.tfftStorageField2, 1), + new ItemStack(Blocks.tfftStorageField, 1, 2), 200, 480); final ItemStack[] tfftstoragefield3 = { @@ -122,7 +122,7 @@ public class Recipes { GT_Values.RA.addAssemblerRecipe( tfftstoragefield3, FluidRegistry.getFluidStack("molten.epoxid", 576), - new ItemStack(Blocks.tfftStorageField3, 1), + new ItemStack(Blocks.tfftStorageField, 1, 3), 300, 1920); final ItemStack[] tfftstoragefield4 = { @@ -136,7 +136,7 @@ public class Recipes { GT_Values.RA.addAssemblerRecipe( tfftstoragefield4, FluidRegistry.getFluidStack("molten.epoxid", 1152), - new ItemStack(Blocks.tfftStorageField4, 1), + new ItemStack(Blocks.tfftStorageField, 1, 4), 400, 4098); final ItemStack[] tfftstoragefield5 = { @@ -150,11 +150,11 @@ public class Recipes { GT_Values.RA.addAssemblerRecipe( tfftstoragefield5, FluidRegistry.getFluidStack("molten.epoxid", 1152), - new ItemStack(Blocks.tfftStorageField5, 1), + new ItemStack(Blocks.tfftStorageField, 1, 5), 400, 6147); // Multi Hatch - final Object[] multi_hatch_HV = { + final Object[] multihatch = { "PRP", "UFU", "PRP", @@ -167,39 +167,7 @@ public class Recipes { 'F', ItemList.Field_Generator_LV.get(1L) }; - GT_ModHandler.addCraftingRecipe(new ItemStack(Blocks.tfftMultiHatch), multi_hatch_HV); - final Object[] multi_hatch_IV = { - "PRP", - "UFU", - "PRP", - 'P', - GT_OreDictUnificator.get(OrePrefixes.pipeTiny, Materials.TungstenSteel, 1), - 'R', - GT_OreDictUnificator.get(OrePrefixes.rotor, Materials.TungstenSteel, 1), - 'U', - ItemList.Electric_Pump_IV.get(1L), - 'F', - ItemList.Field_Generator_HV.get(1L) - }; - GT_ModHandler.addCraftingRecipe(new ItemStack(Blocks.tfftMultiHatch), multi_hatch_IV); - final Object[] multi_hatch_ZPM = { - "PRP", - "UFU", - "PRP", - 'P', - GT_OreDictUnificator.get(OrePrefixes.pipeTiny, Materials.NaquadahAlloy, 1), - 'R', - GT_OreDictUnificator.get(OrePrefixes.rotor, Materials.NaquadahAlloy, 1), - 'U', - ItemList.Electric_Pump_ZPM.get(1L), - 'F', - ItemList.Field_Generator_IV.get(1L) - }; - GT_ModHandler.addCraftingRecipe(new ItemStack(Blocks.tfftMultiHatch), multi_hatch_ZPM); - - // Conversion recipe from deprecated hatch to new one (old hatch is equal to new IV hatch) - GT_ModHandler.addShapelessCraftingRecipe( - TileEntities.mhIV.getStackForm(1), new ItemStack[] {new ItemStack(Blocks.tfftMultiHatch, 1)}); + GT_ModHandler.addCraftingRecipe(TileEntities.tfftHatch.getStackForm(1), multihatch); } private static void registerRecipes_SOFC() { diff --git a/src/main/java/common/TileEntities.java b/src/main/java/common/TileEntities.java index 6253629ddb..78f27db269 100644 --- a/src/main/java/common/TileEntities.java +++ b/src/main/java/common/TileEntities.java @@ -1,6 +1,8 @@ package common; import common.tileentities.*; +import common.tileentities.GTMTE_TFFT; +import common.tileentities.GTMTE_TFFTHatch; import cpw.mods.fml.common.registry.GameRegistry; public class TileEntities { @@ -9,13 +11,12 @@ public class TileEntities { public static GTMTE_SOFuelCellMK1 sofc1; public static GTMTE_SOFuelCellMK2 sofc2; // public static GTMTE_ModularNuclearReactor mdr; - public static GTMTE_FluidMultiStorage fms; + public static GTMTE_TFFT tfft; public static GTMTE_LapotronicSuperCapacitor lsc; public static GTMTE_SpaceElevator se; + // Singleblocks - public static GTMTE_TFFTMultiHatch mhHV; - public static GTMTE_TFFTMultiHatch mhIV; - public static GTMTE_TFFTMultiHatch mhZPM; + public static GTMTE_TFFTHatch tfftHatch; public static void preInit() { GameRegistry.registerTileEntity(TE_TFFTMultiHatch.class, "kekztech_tfftmultihatch_tile"); @@ -35,12 +36,11 @@ public class TileEntities { sofc1 = new GTMTE_SOFuelCellMK1(13101, "multimachine.fuelcellmk1", "Solid-Oxide Fuel Cell Mk I"); sofc2 = new GTMTE_SOFuelCellMK2(13102, "multimachine.fuelcellmk2", "Solid-Oxide Fuel Cell Mk II"); // mdr = new GTMTE_ModularNuclearReactor(13103, "multimachine.nuclearreactor", "Nuclear Reactor"); - fms = new GTMTE_FluidMultiStorage(13104, "multimachine.tf_fluidtank", "T.F.F.T"); + tfft = new GTMTE_TFFT(13104, "multimachine.tfft", "T.F.F.T"); lsc = new GTMTE_LapotronicSuperCapacitor(13106, "multimachine.supercapacitor", "Lapotronic Supercapacitor"); // se = new GTMTE_SpaceElevator(13107, "multimachine.spaceelevator", "Space Elevator"); + // Singleblocks - mhHV = new GTMTE_TFFTMultiHatch(13108, "machine.multihatch.0", "T.F.F.T Multi I/O Hatch [HV]", 3); - mhIV = new GTMTE_TFFTMultiHatch(13109, "machine.multihatch.1", "T.F.F.T Multi I/O Hatch [IV]", 5); - mhZPM = new GTMTE_TFFTMultiHatch(13110, "machine.multihatch.2", "T.F.F.T Multi I/O Hatch [ZPM]", 7); + tfftHatch = new GTMTE_TFFTHatch(13109, "machine.tffthatch", "T.F.F.T Multi I/O Hatch"); } } diff --git a/src/main/java/common/blocks/Block_TFFTStorageField.java b/src/main/java/common/blocks/Block_TFFTStorageField.java new file mode 100644 index 0000000000..36439548af --- /dev/null +++ b/src/main/java/common/blocks/Block_TFFTStorageField.java @@ -0,0 +1,88 @@ +package common.blocks; + +import common.itemBlocks.IB_TFFTStorageField; +import common.tileentities.GTMTE_TFFT; +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GT_Utility; +import java.util.List; +import kekztech.KekzCore; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +public class Block_TFFTStorageField extends BaseGTUpdateableBlock { + + private static final Block_TFFTStorageField INSTANCE = new Block_TFFTStorageField(); + private static final int SUB_BLOCK_COUNT = GTMTE_TFFT.Field.VALUES.length + 1; + private static final IIcon[] textures = new IIcon[SUB_BLOCK_COUNT]; + + public enum TFFTCasingIcon implements IIconContainer { + INSTANCE; + + @Override + public IIcon getIcon() { + return textures[0]; + } + + @Override + public IIcon getOverlayIcon() { + return null; + } + + @Override + public ResourceLocation getTextureFile() { + return TextureMap.locationBlocksTexture; + } + } + + // I guess glodblock won't mind + static { + GT_Utility.addTexturePage((byte) 12); + Textures.BlockIcons.setCasingTexture( + (byte) 12, (byte) 127, TextureFactory.of(Block_TFFTStorageField.TFFTCasingIcon.INSTANCE)); + } + + private Block_TFFTStorageField() { + super(Material.iron); + } + + public static Block registerBlock() { + final String blockName = "kekztech_tfftstoragefield_block"; + INSTANCE.setBlockName(blockName); + INSTANCE.setCreativeTab(CreativeTabs.tabMisc); + INSTANCE.setHardness(5.0f); + INSTANCE.setResistance(6.0f); + GameRegistry.registerBlock(INSTANCE, IB_TFFTStorageField.class, blockName); + + return INSTANCE; + } + + @Override + public void registerBlockIcons(IIconRegister ir) { + textures[0] = ir.registerIcon(KekzCore.MODID + ":" + "TFFTCasing"); + for (int i = 1; i < SUB_BLOCK_COUNT; i++) { + textures[i] = ir.registerIcon(KekzCore.MODID + ":" + "TFFTStorageFieldBlock" + i); + } + } + + @Override + public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) { + for (int i = 0; i < SUB_BLOCK_COUNT; i++) { + par3List.add(new ItemStack(par1, 1, i)); + } + } + + @Override + public IIcon getIcon(int side, int meta) { + return textures[meta]; + } +} diff --git a/src/main/java/common/itemBlocks/IB_TFFTStorageField.java b/src/main/java/common/itemBlocks/IB_TFFTStorageField.java new file mode 100644 index 0000000000..8e75a881f2 --- /dev/null +++ b/src/main/java/common/itemBlocks/IB_TFFTStorageField.java @@ -0,0 +1,47 @@ +package common.itemBlocks; + +import common.tileentities.GTMTE_TFFT; +import java.text.NumberFormat; +import java.util.List; +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; + +public class IB_TFFTStorageField extends ItemBlock { + + public IB_TFFTStorageField(Block block) { + super(block); + } + + @Override + public int getMetadata(int meta) { + return meta; + } + + @Override + public boolean getHasSubtypes() { + return true; + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + return super.getUnlocalizedName() + "." + stack.getItemDamage(); + } + + @SuppressWarnings("unchecked") + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List lines, boolean advancedTooltips) { + int meta = stack.getItemDamage(); + if (meta > 0) { + lines.add(StatCollector.translateToLocal("tile.kekztech_tfftstoragefield_block.desc")); + lines.add("Capacity: " + EnumChatFormatting.BLUE + + NumberFormat.getNumberInstance().format(GTMTE_TFFT.Field.VALUES[meta - 1].getCapacity()) + + EnumChatFormatting.GRAY + " L"); + lines.add("Power Draw: " + EnumChatFormatting.BLUE + GTMTE_TFFT.Field.VALUES[meta - 1].getCost() + + EnumChatFormatting.GRAY + " EU/t"); + } + } +} diff --git a/src/main/java/common/tileentities/GTMTE_FluidMultiStorage.java b/src/main/java/common/tileentities/GTMTE_FluidMultiStorage.java deleted file mode 100644 index df60be8362..0000000000 --- a/src/main/java/common/tileentities/GTMTE_FluidMultiStorage.java +++ /dev/null @@ -1,562 +0,0 @@ -package common.tileentities; - -import common.Blocks; -import common.blocks.*; -import gregtech.api.enums.Textures.BlockIcons; -import gregtech.api.gui.GT_GUIContainer_MultiMachine; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.implementations.*; -import gregtech.api.objects.GT_RenderedTexture; -import gregtech.api.util.GT_Multiblock_Tooltip_Builder; -import gregtech.api.util.GT_Utility; -import java.util.ArrayList; -import java.util.HashSet; -import kekztech.MultiFluidHandler; -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumChatFormatting; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import util.Vector3i; -import util.Vector3ic; - -public class GTMTE_FluidMultiStorage extends GT_MetaTileEntity_TooltipMultiBlockBase { - - private static final String glassNameIC2Reinforced = "blockAlloyGlass"; - private static final Block CASING = Blocks.tfftCasing; - private static final Block_TFFTStorageFieldBlockT1 STORAGE_FIELD1 = - (Block_TFFTStorageFieldBlockT1) Blocks.tfftStorageField1; - private static final Block_TFFTStorageFieldBlockT2 STORAGE_FIELD2 = - (Block_TFFTStorageFieldBlockT2) Blocks.tfftStorageField2; - private static final Block_TFFTStorageFieldBlockT3 STORAGE_FIELD3 = - (Block_TFFTStorageFieldBlockT3) Blocks.tfftStorageField3; - private static final Block_TFFTStorageFieldBlockT4 STORAGE_FIELD4 = - (Block_TFFTStorageFieldBlockT4) Blocks.tfftStorageField4; - private static final Block_TFFTStorageFieldBlockT5 STORAGE_FIELD5 = - (Block_TFFTStorageFieldBlockT5) Blocks.tfftStorageField5; - private static final int CASING_TEXTURE_ID = 176; - - private MultiFluidHandler mfh; - private final HashSet sMultiHatches = new HashSet<>(); - - private int runningCost = 0; - private boolean doVoidExcess = false; - private byte fluidSelector = 0; - - public GTMTE_FluidMultiStorage(int aID, String aName, String aNameRegional) { - super(aID, aName, aNameRegional); - } - - public GTMTE_FluidMultiStorage(String aName) { - super(aName); - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity var1) { - return new GTMTE_FluidMultiStorage(super.mName); - } - - @Override - protected GT_Multiblock_Tooltip_Builder createTooltip() { - final GT_Multiblock_Tooltip_Builder tt = new GT_Multiblock_Tooltip_Builder(); - tt.addMachineType("Fluid Tank") - .addInfo("High-Tech fluid tank that can hold up to 25 different fluids!") - .addInfo("Has 1/25th of the total capacity as capacity for each fluid.") - .addInfo("Right clicking the controller with a screwdriver will turn on excess voiding.") - .addInfo("Fluid storage amount and running cost depends on the storage field blocks used.") - .addSeparator() - .addInfo("Note on hatch locking:") - .addInfo("Use an Integrated Circuit in the GUI slot to limit which fluid is output.") - .addInfo("The index of a stored fluid can be obtained through the Tricorder.") - .addSeparator() - .beginStructureBlock(5, 9, 5, false) - .addController("Top Center") - .addCasingInfo("T.F.F.T. Casing", 20) - .addOtherStructurePart("Storage Field Blocks (Tier I-V)", "Inner 3x7x3 solid pillar") - .addOtherStructurePart("IC2 Reinforced Glass", "Outer 5x7x5 glass shell") - .addMaintenanceHatch("Any top or bottom casing") - .addEnergyHatch("Any top or bottom casing") - .addInputHatch("Instead of any casing or glass, has to touch storage field block") - .addOutputHatch("Instead of any casing or glass, has to touch storage field block") - .addStructureInfo("You can have a bunch of hatches") - .addOtherStructurePart( - "Multi I/O Hatches", "Instead of any casing or glass, has to touch storage field block") - .addStructureInfo( - "Use MIOH with conduits or fluid storage busses to see all fluids at once. If it's fixed.") - .addStructureInfo("Ask someone else why there's 4 versions, with 2 uncraftable ones") - .toolTipFinisher("KekzTech"); - return tt; - } - - @Override - public ITexture[] getTexture( - IGregTechTileEntity aBaseMetaTileEntity, - byte aSide, - byte aFacing, - byte aColorIndex, - boolean aActive, - boolean aRedstone) { - return aSide == aFacing - ? new ITexture[] { - BlockIcons.casingTexturePages[1][48], - new GT_RenderedTexture( - aActive - ? BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE - : BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR) - } - : new ITexture[] {BlockIcons.casingTexturePages[1][48]}; - } - - public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { - return new GT_GUIContainer_MultiMachine( - aPlayerInventory, aBaseMetaTileEntity, this.getLocalName(), "MultiblockDisplay.png"); - } - - @Override - public boolean isCorrectMachinePart(ItemStack var1) { - return true; - } - - @Override - public boolean checkRecipe(ItemStack guiSlotItem) { - - super.mEfficiency = 10000 - (super.getIdealStatus() - super.getRepairStatus()) * 1000; - super.mEfficiencyIncrease = 10000; - super.mEUt = runningCost; - super.mMaxProgresstime = 10; - - if (guiSlotItem != null && guiSlotItem.getUnlocalizedName().equals("gt.integrated_circuit")) { - this.fluidSelector = (byte) guiSlotItem.getItemDamage(); - } - - // If there are no basic I/O hatches, let multi hatches handle it and skip a lot of code! - if (sMultiHatches.size() > 0 && super.mInputHatches.size() == 0 && super.mOutputHatches.size() == 0) { - return true; - } - - // Suck in fluids - final ArrayList inputHatchFluids = super.getStoredFluids(); - if (inputHatchFluids.size() > 0) { - - for (FluidStack fluidStack : inputHatchFluids) { - - final int pushed = mfh.pushFluid(fluidStack, true); - final FluidStack toDeplete = fluidStack.copy(); - toDeplete.amount = pushed; - super.depleteInput(toDeplete); - } - } - - // Push out fluids - if (guiSlotItem != null && guiSlotItem.getUnlocalizedName().equals("gt.integrated_circuit")) { - final FluidStack storedFluid = mfh.getFluidCopy(fluidSelector); - // Sum available output capacity - int possibleOutput = 0; - for (GT_MetaTileEntity_Hatch_Output outputHatch : super.mOutputHatches) { - if (outputHatch.isFluidLocked() - && outputHatch.getLockedFluidName().equals(storedFluid.getUnlocalizedName())) { - possibleOutput += outputHatch.getCapacity() - outputHatch.getFluidAmount(); - } else if (outputHatch.getFluid() != null - && outputHatch.getFluid().getUnlocalizedName().equals(storedFluid.getUnlocalizedName())) { - possibleOutput += outputHatch.getCapacity() - outputHatch.getFluidAmount(); - } else if (outputHatch.getFluid() == null) { - possibleOutput += outputHatch.getCapacity() - outputHatch.getFluidAmount(); - } - } - // Output as much as possible - final FluidStack tempStack = storedFluid.copy(); - tempStack.amount = possibleOutput; - tempStack.amount = mfh.pullFluid(tempStack, fluidSelector, true); - super.addOutput(tempStack); - - } else { - int tDistinct = mfh.getDistinctFluids(); - int tDistinctCount = 0; - int tMaxDistinct = mfh.getMaxDistinctFluids(); - for (int i = 0; i < tMaxDistinct && tDistinctCount < tDistinct; i++) { - final FluidStack storedFluidCopy = mfh.getFluidCopy(i); - if (storedFluidCopy == null) continue; - tDistinctCount++; - storedFluidCopy.amount = 0; - // Calculate how much capacity all available Output Hatches offer - for (GT_MetaTileEntity_Hatch_Output outputHatch : super.mOutputHatches) { - if (outputHatch.isFluidLocked() - && outputHatch.getLockedFluidName().equals(storedFluidCopy.getUnlocalizedName())) { - storedFluidCopy.amount += outputHatch.getCapacity() - outputHatch.getFluidAmount(); - addFluidToHatch(storedFluidCopy, outputHatch); - } else if (outputHatch.getFluid() != null - && outputHatch.getFluid().isFluidEqual(storedFluidCopy)) { - storedFluidCopy.amount += outputHatch.getCapacity() - outputHatch.getFluidAmount(); - addFluidToHatch(storedFluidCopy, outputHatch); - } else if (!outputHatch.isFluidLocked() && outputHatch.getFluid() == null) { - storedFluidCopy.amount += outputHatch.getCapacity() - outputHatch.getFluidAmount(); - addFluidToHatch(storedFluidCopy, outputHatch); - } - } - } - } - - return true; - } - - public void addFluidToHatch(FluidStack aFluid, GT_MetaTileEntity_Hatch_Output aHatch) { - aFluid.amount = mfh.pullFluid(aFluid, true); - aHatch.fill(aFluid, true); - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - - if (mfh != null) { - mfh.setLock(!super.getBaseMetaTileEntity().isActive()); - mfh.setFluidSelector(fluidSelector); - mfh.setDoVoidExcess(doVoidExcess); - } - } - - public Vector3ic rotateOffsetVector(Vector3ic forgeDirection, int x, int y, int z) { - final Vector3i offset = new Vector3i(); - - // either direction on z-axis - if (forgeDirection.x() == 0 && forgeDirection.z() == -1) { - offset.x = x; - offset.y = y; - offset.z = z; - } - if (forgeDirection.x() == 0 && forgeDirection.z() == 1) { - offset.x = -x; - offset.y = y; - offset.z = -z; - } - // either direction on x-axis - if (forgeDirection.x() == -1 && forgeDirection.z() == 0) { - offset.x = z; - offset.y = y; - offset.z = -x; - } - if (forgeDirection.x() == 1 && forgeDirection.z() == 0) { - offset.x = -z; - offset.y = y; - offset.z = x; - } - // either direction on y-axis - if (forgeDirection.y() == -1) { - offset.x = x; - offset.y = z; - offset.z = y; - } - - return offset; - } - - @Override - public boolean checkMachine(IGregTechTileEntity thisController, ItemStack guiSlotItem) { - // Figure out the vector for the direction the back face of the controller is facing - final Vector3ic forgeDirection = new Vector3i( - ForgeDirection.getOrientation(thisController.getBackFacing()).offsetX, - ForgeDirection.getOrientation(thisController.getBackFacing()).offsetY, - ForgeDirection.getOrientation(thisController.getBackFacing()).offsetZ); - int minCasingAmount = 20; - boolean formationChecklist = true; // If this is still true at the end, machine is good to go :) - float runningCostAcc = 0; - double fluidCapacityAcc = 0; - - sMultiHatches.clear(); - - // Front segment - for (int X = -2; X <= 2; X++) { - for (int Y = -2; Y <= 2; Y++) { - if (X == 0 && Y == 0) { - continue; // Skip controller - } - - // Get next TE - final Vector3ic offset = rotateOffsetVector(forgeDirection, X, Y, 0); - final IGregTechTileEntity currentTE = - thisController.getIGregTechTileEntityOffset(offset.x(), offset.y(), offset.z()); - - // Fluid hatches should touch the storage field. - // Maintenance/Energy hatch can go anywhere - if (X > -2 && X < 2 && Y > -2 && Y < 2) { - if (!super.addMaintenanceToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addInputToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addOutputToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addEnergyInputToMachineList(currentTE, CASING_TEXTURE_ID) - && !addMultiHatchToMachineList(currentTE, CASING_TEXTURE_ID)) { - - // If it's not a hatch, is it the right casing for this machine? Check block and block meta. - // Also check for multi hatch - if (thisController.getBlockOffset(offset.x(), offset.y(), offset.z()) == CASING) { - // Seems to be valid casing. Decrement counter. - minCasingAmount--; - } else { - formationChecklist = false; - } - } - } else { - if (!super.addMaintenanceToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addEnergyInputToMachineList(currentTE, CASING_TEXTURE_ID)) { - - // If it's not a hatch, is it the right casing for this machine? Check block and block meta. - if (thisController.getBlockOffset(offset.x(), offset.y(), offset.z()) == CASING) { - // Seems to be valid casing. Decrement counter. - minCasingAmount--; - } else { - formationChecklist = false; - } - } - } - } - } - - // Middle seven long segment - for (int X = -2; X <= 2; X++) { - for (int Y = -2; Y <= 2; Y++) { - for (int Z = -1; Z >= -7; Z--) { - final Vector3ic offset = rotateOffsetVector(forgeDirection, X, Y, Z); - if (X > -2 && X < 2 && Y > -2 && Y < 2) { - if (thisController - .getBlockOffset(offset.x(), offset.y(), offset.z()) - .getUnlocalizedName() - .equals(STORAGE_FIELD1.getUnlocalizedName())) { - runningCostAcc += 0.5f; - fluidCapacityAcc += (float) Block_TFFTStorageFieldBlockT1.getCapacity(); - } else if (thisController - .getBlockOffset(offset.x(), offset.y(), offset.z()) - .getUnlocalizedName() - .equals(STORAGE_FIELD2.getUnlocalizedName())) { - runningCostAcc += 1.0f; - fluidCapacityAcc += (float) Block_TFFTStorageFieldBlockT2.getCapacity(); - } else if (thisController - .getBlockOffset(offset.x(), offset.y(), offset.z()) - .getUnlocalizedName() - .equals(STORAGE_FIELD3.getUnlocalizedName())) { - runningCostAcc += 2.0f; - fluidCapacityAcc += (float) Block_TFFTStorageFieldBlockT3.getCapacity(); - } else if (thisController - .getBlockOffset(offset.x(), offset.y(), offset.z()) - .getUnlocalizedName() - .equals(STORAGE_FIELD4.getUnlocalizedName())) { - runningCostAcc += 4.0f; - fluidCapacityAcc += (float) Block_TFFTStorageFieldBlockT4.getCapacity(); - } else if (thisController - .getBlockOffset(offset.x(), offset.y(), offset.z()) - .getUnlocalizedName() - .equals(STORAGE_FIELD5.getUnlocalizedName())) { - runningCostAcc += 8.0f; - fluidCapacityAcc += (float) Block_TFFTStorageFieldBlockT5.getCapacity(); - } else { - formationChecklist = false; - } - continue; - } - - // Get next TE - final IGregTechTileEntity currentTE = - thisController.getIGregTechTileEntityOffset(offset.x(), offset.y(), offset.z()); - - // Corner allows only glass - if (X == -2 && Y == -2 || X == 2 && Y == 2 || X == -2 && Y == 2 || X == 2 && Y == -2) { - if (!(thisController - .getBlockOffset(offset.x(), offset.y(), offset.z()) - .getUnlocalizedName() - .equals(glassNameIC2Reinforced))) { - formationChecklist = false; - } - } else { - // Tries to add TE as either of those kinds of hatches. - // The number is the texture index number for the texture that needs to be painted over the - // hatch texture (TAE for GT++) - if (!super.addInputToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addOutputToMachineList(currentTE, CASING_TEXTURE_ID) - && !addMultiHatchToMachineList(currentTE, CASING_TEXTURE_ID)) { - - // If it's not a hatch, is it the right casing for this machine? Check block and block meta. - // Also check for multi hatch - if (thisController.getBlockOffset(offset.x(), offset.y(), offset.z()) == CASING) { - // Seems to be valid casing. Decrement counter. - minCasingAmount--; - } else if (!thisController - .getBlockOffset(offset.x(), offset.y(), offset.z()) - .getUnlocalizedName() - .equals(glassNameIC2Reinforced)) { - formationChecklist = false; - } - } - } - } - } - } - - // Back segment - for (int X = -2; X <= 2; X++) { - for (int Y = -2; Y <= 2; Y++) { - // Get next TE - final Vector3ic offset = rotateOffsetVector(forgeDirection, X, Y, -8); - final IGregTechTileEntity currentTE = - thisController.getIGregTechTileEntityOffset(offset.x(), offset.y(), offset.z()); - - // Fluid hatches should touch the storage field. - // Maintenance/Energy hatch can go anywhere - if (X > -2 && X < 2 && Y > -2 && Y < 2) { - if (!super.addMaintenanceToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addInputToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addOutputToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addEnergyInputToMachineList(currentTE, CASING_TEXTURE_ID) - && !addMultiHatchToMachineList(currentTE, CASING_TEXTURE_ID)) { - - // If it's not a hatch, is it the right casing for this machine? Check block and block meta. - if (thisController.getBlockOffset(offset.x(), offset.y(), offset.z()) == CASING) { - // Seems to be valid casing. Decrement counter. - minCasingAmount--; - } else { - formationChecklist = false; - } - } - } else { - if (!super.addMaintenanceToMachineList(currentTE, CASING_TEXTURE_ID) - && !super.addEnergyInputToMachineList(currentTE, CASING_TEXTURE_ID)) { - - // If it's not a hatch, is it the right casing for this machine? Check block and block meta. - if (thisController.getBlockOffset(offset.x(), offset.y(), offset.z()) == CASING) { - // Seems to be valid casing. Decrement counter. - minCasingAmount--; - } else { - formationChecklist = false; - } - } - } - } - } - - if (this.mEnergyHatches.size() < 1) { - formationChecklist = false; - } - - if (this.mMaintenanceHatches.size() != 1) { - formationChecklist = false; - } - - if (minCasingAmount > 0) { - formationChecklist = false; - } - - if (formationChecklist) { - runningCost = Math.round(-runningCostAcc); - // Update MultiFluidHandler in case storage cells have been changed - final int capacityPerFluid = (int) Math.round(fluidCapacityAcc / 25.0f); - if (mfh == null) { - mfh = MultiFluidHandler.newInstance(25, capacityPerFluid); - } else { - if (mfh.getCapacity() != capacityPerFluid) { - mfh = MultiFluidHandler.newAdjustedInstance(mfh, capacityPerFluid); - } - } - for (GTMTE_TFFTMultiHatch mh : sMultiHatches) { - mh.setMultiFluidHandler(mfh); - } - } - - return formationChecklist; - } - - public boolean addMultiHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) { - return false; - } else { - final IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) { - return false; - } else if (aMetaTileEntity instanceof GTMTE_TFFTMultiHatch) { - ((GTMTE_TFFTMultiHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex); - return this.sMultiHatches.add((GTMTE_TFFTMultiHatch) aMetaTileEntity); - } else { - return false; - } - } - } - - @Override - public void onScrewdriverRightClick(byte aSide, EntityPlayer aPlayer, float aX, float aY, float aZ) { - doVoidExcess = !doVoidExcess; - GT_Utility.sendChatToPlayer(aPlayer, doVoidExcess ? "Auto-voiding enabled" : "Auto-voiding disabled"); - } - - @Override - public String[] getInfoData() { - final ArrayList ll = mfh.getInfoData(); - - ll.add(EnumChatFormatting.YELLOW + "Operational Data:" + EnumChatFormatting.RESET); - ll.add("Auto-voiding: " + doVoidExcess); - ll.add("Per-Fluid Capacity: " + mfh.getCapacity() + "L"); - ll.add("Running Cost: " - // mEUt does not naturally reflect efficiency status. Do that here. - + ((-super.mEUt) * 10000 / Math.max(1000, super.mEfficiency)) + "EU/t"); - ll.add("Maintenance Status: " - + ((super.getRepairStatus() == super.getIdealStatus()) - ? EnumChatFormatting.GREEN + "Working perfectly" + EnumChatFormatting.RESET - : EnumChatFormatting.RED + "Has Problems" + EnumChatFormatting.RESET)); - ll.add("---------------------------------------------"); - - final String[] a = new String[ll.size()]; - return ll.toArray(a); - } - - @Override - public void saveNBTData(NBTTagCompound nbt) { - nbt = (nbt == null) ? new NBTTagCompound() : nbt; - - nbt.setInteger("runningCost", runningCost); - nbt.setBoolean("doVoidExcess", doVoidExcess); - - nbt.setInteger("capacityPerFluid", mfh.getCapacity()); - nbt.setTag("fluids", mfh.saveNBTData(new NBTTagCompound())); - - super.saveNBTData(nbt); - } - - @Override - public void loadNBTData(NBTTagCompound nbt) { - nbt = (nbt == null) ? new NBTTagCompound() : nbt; - - runningCost = nbt.getInteger("runningCost"); - doVoidExcess = nbt.getBoolean("doVoidExcess"); - - mfh = MultiFluidHandler.loadNBTData(nbt); - for (GTMTE_TFFTMultiHatch mh : sMultiHatches) { - mh.setMultiFluidHandler(mfh); - } - super.loadNBTData(nbt); - } - - @Override - public boolean isGivingInformation() { - return true; - } - - @Override - public int getMaxEfficiency(ItemStack var1) { - return 10000; - } - - @Override - public int getPollutionPerTick(ItemStack var1) { - return 0; - } - - @Override - public int getDamageToComponent(ItemStack var1) { - return 0; - } - - @Override - public boolean explodesOnComponentBreak(ItemStack var1) { - return false; - } -} diff --git a/src/main/java/common/tileentities/GTMTE_TFFT.java b/src/main/java/common/tileentities/GTMTE_TFFT.java new file mode 100644 index 0000000000..c107d76896 --- /dev/null +++ b/src/main/java/common/tileentities/GTMTE_TFFT.java @@ -0,0 +1,713 @@ +package common.tileentities; + +import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; +import static gregtech.api.enums.GT_HatchElement.*; +import static gregtech.api.util.GT_StructureUtility.buildHatchAdder; +import static java.lang.Math.min; + +import com.github.bartimaeusnek.bartworks.API.BorosilicateGlass; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import common.Blocks; +import gregtech.api.enums.Textures; +import gregtech.api.fluid.FluidTankGT; +import gregtech.api.interfaces.IHatchElement; +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.GT_MetaTileEntity_EnhancedMultiBlockBase; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Output; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GT_Multiblock_Tooltip_Builder; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.IGT_HatchAdder; +import gregtech.common.items.GT_IntegratedCircuit_Item; +import java.math.BigInteger; +import java.text.MessageFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; + +public class GTMTE_TFFT extends GT_MetaTileEntity_EnhancedMultiBlockBase { + + public enum Field { + T1(1_000_000L, 2), // LV + T2(4_000_000L, 3), // MV + T3(16_000_000L, 5), // HV + T4(64_000_000L, 13), // EV + T5(256_000_000L, 89), // IV + + T6(2_048_000_000L, 233), // LuV + T7(131_072_000_000L, 1597), // UV + T8(8_388_608_000_000L, 28657), // UEV + T9(536_870_912_000_000L, 514229), // UIV + + T10(1_099_511_627_776_000_000L, 0); // UXV + + public static final GTMTE_TFFT.Field[] VALUES = values(); + private final long capacity; + private final int cost; + + Field(long capacity, int cost) { + this.capacity = capacity; + this.cost = cost; + } + + public long getCapacity() { + return capacity; + } + + public int getCost() { + return cost; + } + } + + private enum TFFTMultiHatch implements IHatchElement { + INSTANCE; + + @Override + public List> mteClasses() { + return Collections.singletonList(GTMTE_TFFT.class); + } + + @Override + public IGT_HatchAdder adder() { + return GTMTE_TFFT::addMultiHatchToMachineList; + } + + @Override + public long count(GTMTE_TFFT t) { + return t.tfftHatch == null ? 0 : 1; + } + } + + private static final IIconContainer TEXTURE_TFFT = new Textures.BlockIcons.CustomIcon("iconsets/TFFT"); + private static final IIconContainer TEXTURE_TFFT_ACTIVE = + new Textures.BlockIcons.CustomIcon("iconsets/TFFT_ACTIVE"); + private static final IIconContainer TEXTURE_TFFT_ACTIVE_GLOW = + new Textures.BlockIcons.CustomIcon("iconsets/TFFT_ACTIVE_GLOW"); + private static final int CASING_TEXTURE_ID_1 = (12 << 7) | 127; + private static final int CASING_TEXTURE_ID_2 = 176; + + private static final Block TFFT_FIELD = Blocks.tfftStorageField; + private static final Item TFFT_FIELD_ITEM = Item.getItemFromBlock(TFFT_FIELD); + public static final int MAX_DISTINCT_FLUIDS = 25; + private static final BigInteger MAX_CAPACITY = + BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(25)); + private static final int CASING_META = 0; + private static final int MIN_CASING_AMOUNT = 20; + private static final int MAX_LAYER_AMOUNT = 13; + private static final int DEFAULT_LAYER_AMOUNT = 3; + + private static final String STRUCTURE_PIECE_TOP = "top"; + private static final String STRUCTURE_PIECE_MID = "mid"; + private static final String STRUCTURE_PIECE_BOTTOM = "bottom"; + private static final IStructureDefinition STRUCTURE_DEFINITION = + IStructureDefinition.builder() + .addShape( + STRUCTURE_PIECE_TOP, + transpose(new String[][] {{"ccccc"}, {"cCCCc"}, {"cC~Cc"}, {"cCCCc"}, {"ccccc"}})) + .addShape( + STRUCTURE_PIECE_MID, + transpose(new String[][] {{"gGGGg"}, {"GfffG"}, {"GfffG"}, {"GfffG"}, {"gGGGg"}})) + .addShape( + STRUCTURE_PIECE_BOTTOM, + transpose(new String[][] {{"ccccc"}, {"cCCCc"}, {"cCCCc"}, {"cCCCc"}, {"ccccc"}})) + .addElement( + 'c', + buildHatchAdder(GTMTE_TFFT.class) + .atLeast(Energy, Maintenance) + .casingIndex(CASING_TEXTURE_ID_1) + .dot(1) + .buildAndChain( + onElementPass(te -> te.casingAmount++, ofBlock(TFFT_FIELD, CASING_META)))) + .addElement( + 'C', + buildHatchAdder(GTMTE_TFFT.class) + .casingIndex(CASING_TEXTURE_ID_1) + .atLeast( + Energy, + Maintenance, + InputHatch.or(TFFTMultiHatch.INSTANCE), + OutputHatch.or(TFFTMultiHatch.INSTANCE)) + .dot(2) + .buildAndChain( + onElementPass(te -> te.casingAmount++, ofBlock(TFFT_FIELD, CASING_META)))) + .addElement( + 'G', + buildHatchAdder(GTMTE_TFFT.class) + .atLeast( + InputHatch.or(TFFTMultiHatch.INSTANCE), + OutputHatch.or(TFFTMultiHatch.INSTANCE)) + .casingIndex(CASING_TEXTURE_ID_2) + .dot(3) + .buildAndChain( + ofBlockUnlocalizedName("IC2", "blockAlloyGlass", 0, true), + ofBlockUnlocalizedName("Thaumcraft", "blockCosmeticOpaque", 2, false), + BorosilicateGlass.ofBoroGlassAnyTier())) + .addElement( + 'g', + ofChain( + ofBlockUnlocalizedName("IC2", "blockAlloyGlass", 0, true), + ofBlockUnlocalizedName("Thaumcraft", "blockCosmeticOpaque", 2, false), + BorosilicateGlass.ofBoroGlassAnyTier())) + .addElement('f', ofChain(new IStructureElement() { + @Override + public boolean check(GTMTE_TFFT t, World world, int x, int y, int z) { + Block worldBlock = world.getBlock(x, y, z); + int meta = worldBlock.getDamageValue(world, x, y, z); + if (TFFT_FIELD != worldBlock || meta == 0) return false; + t.FIELDS[meta - 1]++; + return true; + } + + private int getHint(ItemStack stack) { + return Math.min(Field.VALUES.length, ChannelDataAccessor.getChannelData(stack, "field")); + } + + @Override + public boolean spawnHint(GTMTE_TFFT t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, TFFT_FIELD, getHint(trigger)); + return true; + } + + @Override + public boolean placeBlock(GTMTE_TFFT t, World world, int x, int y, int z, ItemStack trigger) { + world.setBlock(x, y, z, TFFT_FIELD, getHint(trigger), 3); + return true; + } + })) + .build(); + + public final FluidTankGT[] STORE = new FluidTankGT[MAX_DISTINCT_FLUIDS]; + + { + for (int i = 0; i < MAX_DISTINCT_FLUIDS; i++) { + STORE[i] = new FluidTankGT(0); + } + } + + private final int[] FIELDS = new int[Field.VALUES.length]; + + private BigInteger capacity = BigInteger.ZERO; + private long capacityPerFluid = 0L; + private int casingAmount = 0; + private int runningCost = 0; + + private boolean locked = true; + private boolean doVoidExcess = false; + private byte fluidSelector = -1; + + private GTMTE_TFFTHatch tfftHatch = null; + + public GTMTE_TFFT(String aName) { + super(aName); + } + + public GTMTE_TFFT(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + @Override + public IStructureDefinition getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new GTMTE_TFFT(super.mName); + } + + @Override + public ITexture[] getTexture( + IGregTechTileEntity aBaseMetaTileEntity, + byte aSide, + byte aFacing, + byte aColorIndex, + boolean aActive, + boolean aRedstone) { + if (aSide == aFacing) { + if (aActive) + return new ITexture[] { + Textures.BlockIcons.getCasingTextureForId(CASING_TEXTURE_ID_1), + TextureFactory.builder() + .addIcon(TEXTURE_TFFT_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(TEXTURE_TFFT_ACTIVE_GLOW) + .extFacing() + .glow() + .build() + }; + return new ITexture[] { + Textures.BlockIcons.getCasingTextureForId(CASING_TEXTURE_ID_1), + TextureFactory.builder().addIcon(TEXTURE_TFFT).extFacing().build() + }; + } + return new ITexture[] {Textures.BlockIcons.getCasingTextureForId(CASING_TEXTURE_ID_1)}; + } + + @Override + protected GT_Multiblock_Tooltip_Builder createTooltip() { + final GT_Multiblock_Tooltip_Builder tt = new GT_Multiblock_Tooltip_Builder(); + tt.addMachineType("Fluid Tank") + .addInfo("High-Tech fluid tank that can hold up to 25 different fluids!") + .addInfo("Has 1/25th of the total capacity as capacity for each fluid.") + .addInfo("Right clicking the controller with a screwdriver will turn on excess voiding.") + .addInfo("Fluid storage amount and running cost depends on the storage field blocks used.") + .addSeparator() + .addInfo("Note on hatch locking:") + .addInfo("Use an Integrated Circuit in the GUI slot to limit which fluid is output.") + .addInfo("The index of a stored fluid can be obtained through the Tricorder.") + .addSeparator() + .beginVariableStructureBlock(5, 5, 5, 15, 5, 5, false) + .addController("Top Center") + .addCasingInfo("T.F.F.T Casing", MIN_CASING_AMOUNT) + .addOtherStructurePart("Storage Field Blocks (Tier I-X)", "Inner 3xhx3 solid pillar") + .addStructureInfo("Energy hatch is not required when running cost is 0") + .addOtherStructurePart( + "Borosilicate Glass(any)/Warded Glass/Reinforced Glass", "Outer 5xhx5 glass shell") + .addMaintenanceHatch("Any top or bottom casing") + .addEnergyHatch("Any top or bottom casing") + .addInputHatch("Instead of any casing or glass, has to touch storage field block") + .addOutputHatch("Instead of any casing or glass, has to touch storage field block") + .addStructureInfo("You can have a bunch of hatches") + .addOtherStructurePart( + "Multi I/O Hatches", "Instead of any casing or glass, has to touch storage field block") + .addStructureInfo("Use MIOH with conduits or fluid storage busses to see all fluids at once.") + .toolTipFinisher("KekzTech"); + return tt; + } + + @Override + public void construct(ItemStack stackSize, boolean hintsOnly) { + int layer = min(stackSize.stackSize + DEFAULT_LAYER_AMOUNT, MAX_LAYER_AMOUNT + 1); + buildPiece(STRUCTURE_PIECE_TOP, stackSize, hintsOnly, 2, 2, 0); + for (int i = -1; i >= 1 - layer; i--) buildPiece(STRUCTURE_PIECE_MID, stackSize, hintsOnly, 2, 2, i); + buildPiece(STRUCTURE_PIECE_BOTTOM, stackSize, hintsOnly, 2, 2, -layer); + } + + // @Override + // public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { + // if (mMachine) return -1; + // int build = survivialBuildPiece(STRUCTURE_PIECE_TOP, stackSize, 2, 2, 0, elementBudget, env, false, true); + // if (build >= 0) return build; + // int layer = min(stackSize.stackSize + DEFAULT_LAYER_AMOUNT, MAX_LAYER_AMOUNT + 1); + // for (int i = -1; i >= 1 - layer; i--) { + // survivialBuildPiece(STRUCTURE_PIECE_MID, stackSize, 2, 2, i, elementBudget, env, false, true); + // if (build >= 0) return build; + // } + // return survivialBuildPiece(STRUCTURE_PIECE_BOTTOM, stackSize, 2, 2, -layer, elementBudget, env, false, + // true); + // } + + @Override + public boolean isCorrectMachinePart(ItemStack aStack) { + return true; + } + + @Override + public void clearHatches() { + super.clearHatches(); + if (tfftHatch != null) { + tfftHatch.unbind(); + tfftHatch = null; + } + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + Arrays.fill(FIELDS, 0); + + this.capacity = BigInteger.ZERO; + this.capacityPerFluid = 0L; + this.casingAmount = 0; + this.runningCost = 0; + + if (!checkPiece(STRUCTURE_PIECE_TOP, 2, 2, 0)) return false; + + int layer = 1; + while (checkPiece(STRUCTURE_PIECE_MID, 2, 2, -layer)) layer++; + if (layer - 1 > MAX_LAYER_AMOUNT || layer - 1 < DEFAULT_LAYER_AMOUNT) return false; + if (!checkPiece(STRUCTURE_PIECE_BOTTOM, 2, 2, -layer)) return false; + if (casingAmount >= MIN_CASING_AMOUNT + && (tfftHatch != null || (!mInputHatches.isEmpty() && !mOutputHatches.isEmpty())) + && mInputHatches.size() + mOutputHatches.size() <= MAX_DISTINCT_FLUIDS * 2 + && mMaintenanceHatches.size() == 1) { + BigInteger tempCap = BigInteger.ZERO; + for (int i = 0; i < this.FIELDS.length; i++) { + tempCap = tempCap.add( + BigInteger.valueOf(Field.VALUES[i].getCapacity()).multiply(BigInteger.valueOf(this.FIELDS[i]))); + this.runningCost += Field.VALUES[i].getCost() * this.FIELDS[i]; + } + this.setCapacity(tempCap); + + if (tfftHatch != null) tfftHatch.bind(this); + + return !mEnergyHatches.isEmpty() ^ this.runningCost == 0; + } + return false; + } + + @Override + public boolean checkRecipe(ItemStack itemStack) { + mEfficiency = getCurrentEfficiency(null); + mEfficiencyIncrease = 10000; + mEUt = this.runningCost; + mMaxProgresstime = 20; + + this.fluidSelector = (itemStack != null && itemStack.getItem() instanceof GT_IntegratedCircuit_Item) + ? (byte) itemStack.getItemDamage() + : -1; + + // Suck in fluids + final ArrayList inputFluids = getStoredFluids(); + + if (!inputFluids.isEmpty()) { + for (FluidStack aFluid : inputFluids) { + final FluidStack toDeplete = aFluid.copy(); + toDeplete.amount = this.pull(aFluid, true); + depleteInput(toDeplete); + } + } + + // Push out fluids + if (!this.mOutputHatches.isEmpty()) { + final FluidTankGT sFluid = this.getSelectedFluid(); + boolean isFluidSelected = this.fluidSelector != -1; + + if (!isFluidSelected || !sFluid.isEmpty()) { + for (GT_MetaTileEntity_Hatch_Output tHatch : this.mOutputHatches) { + int hatchCapacity = tHatch.getCapacity(); + int hatchAmount = tHatch.getFluidAmount(); + int remaining = hatchCapacity - hatchAmount; + + if (remaining <= 0) continue; + + final FluidStack tFluid = tHatch.getFluid(); + + String lockedFluidName = tHatch.getLockedFluidName() == null ? "" : tHatch.getLockedFluidName(); + String tFluidName = tFluid == null ? "" : tFluid.getFluid().getName(); + + boolean isFluidLocked = tHatch.isFluidLocked(); + boolean isFluidEmpty = tFluid == null || tHatch.getFluidAmount() == 0; + + if (isFluidLocked && !this.contains(lockedFluidName)) continue; + if (!isFluidEmpty && !this.contains(tFluid)) continue; + if ((isFluidLocked && !isFluidEmpty) && !lockedFluidName.equals(tFluidName)) continue; + + if (isFluidSelected) { + if (isFluidLocked && !lockedFluidName.equals(sFluid.name())) continue; + if (!isFluidEmpty && !sFluid.contains(tFluid)) continue; + + tHatch.fill(this.push(sFluid.get(remaining), true), true); + } else if (isFluidLocked) { + if (!isFluidEmpty + && !lockedFluidName.equals(tFluid.getFluid().getName())) continue; + + FluidStack aFluid = FluidRegistry.getFluidStack(lockedFluidName, remaining); + tHatch.fill(this.push(aFluid, true), true); + } else if (isFluidEmpty) { + if (this.firstNotNull() != null) tHatch.fill(this.push(hatchCapacity, true), true); + } else { + tHatch.fill(this.push(new FluidStack(tFluid, remaining), true), true); + } + } + } + } + + if (this.mEUt > 0) this.mEUt = -this.mEUt; + + return true; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide()) this.locked = !aBaseMetaTileEntity.isActive(); + } + + @Override + public String[] getInfoData() { + ArrayList ll = new ArrayList<>(); + NumberFormat nf = NumberFormat.getNumberInstance(); + + ll.add(EnumChatFormatting.YELLOW + "Stored Fluids:" + EnumChatFormatting.RESET); + for (int i = 0; i < MAX_DISTINCT_FLUIDS; i++) { + FluidTankGT tank = STORE[i]; + if (tank.isEmpty()) { + ll.add(MessageFormat.format("{0} - {1}: {2}L ({3}%)", i, "NULL", 0, 0)); + } else { + String localizedName = STORE[i].get().getLocalizedName(); + String amount = nf.format(STORE[i].amount()); + String percentage = + capacityPerFluid > 0 ? String.valueOf(STORE[i].amount() * 100 / capacityPerFluid) : ""; + + ll.add(MessageFormat.format("{0} - {1}: {2}L ({3}%)", i, localizedName, amount, percentage)); + } + } + ll.add(EnumChatFormatting.YELLOW + "Operational Data:" + EnumChatFormatting.RESET); + ll.add("Used Capacity: " + nf.format(getStoredAmount()) + "L"); + ll.add("Total Capacity: " + nf.format(capacity) + "L"); + ll.add("Per-Fluid Capacity: " + nf.format(capacityPerFluid) + "L"); + ll.add("Running Cost: " + getActualEnergyUsage() + "EU/t"); + ll.add("Auto-voiding: " + doVoidExcess); + ll.add("Maintenance Status: " + + ((getRepairStatus() == getIdealStatus()) + ? EnumChatFormatting.GREEN + "Working perfectly" + EnumChatFormatting.RESET + : EnumChatFormatting.RED + "Has Problems" + EnumChatFormatting.RESET)); + ll.add("---------------------------------------------"); + + return ll.toArray(new String[0]); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setByteArray("capacity", capacity.toByteArray()); + aNBT.setBoolean("doVoidExcess", doVoidExcess); + aNBT.setInteger("runningCost", runningCost); + aNBT.setBoolean