diff options
| author | NotAPenguin <michiel.vandeginste@gmail.com> | 2024-09-02 23:17:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-02 23:17:17 +0200 |
| commit | 1b820de08a05070909a267e17f033fcf58ac8710 (patch) | |
| tree | 02831a025986a06b20f87e5bcc69d1e0c639a342 /src/main/java/kekztech/common/tileentities | |
| parent | afd3fd92b6a6ab9ab0d0dc3214e6bc8ff7a86c9b (diff) | |
| download | GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.gz GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.bz2 GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.zip | |
The Great Renaming (#3014)
* move kekztech to a single root dir
* move detrav to a single root dir
* move gtnh-lanthanides to a single root dir
* move tectech and delete some gross reflection in gt++
* remove more reflection inside gt5u
* delete more reflection in gt++
* fix imports
* move bartworks and bwcrossmod
* fix proxies
* move galactigreg and ggfab
* move gtneioreplugin
* try to fix gt++ bee loader
* apply the rename rules to BW
* apply rename rules to bwcrossmod
* apply rename rules to detrav scanner mod
* apply rename rules to galacticgreg
* apply rename rules to ggfab
* apply rename rules to goodgenerator
* apply rename rules to gtnh-lanthanides
* apply rename rules to gt++
* apply rename rules to kekztech
* apply rename rules to kubatech
* apply rename rules to tectech
* apply rename rules to gt
apply the rename rules to gt
* fix tt import
* fix mui hopefully
* fix coremod except intergalactic
* rename assline recipe class
* fix a class name i stumbled on
* rename StructureUtility to GTStructureUtility to prevent conflict with structurelib
* temporary rename of GTTooltipDataCache to old name
* fix gt client/server proxy names
Diffstat (limited to 'src/main/java/kekztech/common/tileentities')
9 files changed, 2754 insertions, 0 deletions
diff --git a/src/main/java/kekztech/common/tileentities/MTEHatchTFFT.java b/src/main/java/kekztech/common/tileentities/MTEHatchTFFT.java new file mode 100644 index 0000000000..66e93a7cad --- /dev/null +++ b/src/main/java/kekztech/common/tileentities/MTEHatchTFFT.java @@ -0,0 +1,271 @@ +package kekztech.common.tileentities; + +import java.util.HashMap; + +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; + +import appeng.api.AEApi; +import appeng.api.config.AccessRestriction; +import appeng.api.config.Actionable; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.storage.IExternalStorageHandler; +import appeng.api.storage.IMEInventory; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.IMEMonitorHandlerReceiver; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import appeng.util.item.AEFluidStack; +import appeng.util.item.FluidList; +import cpw.mods.fml.common.Optional; +import gregtech.api.enums.Textures; +import gregtech.api.fluid.GTFluidTank; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.render.TextureFactory; + +@Optional.Interface(iface = "appeng.api.storage.IMEMonitor", modid = "appliedenergistics2", striprefs = true) +public class MTEHatchTFFT extends MTEHatch implements IMEMonitor<IAEFluidStack> { + + @Optional.Interface( + iface = "appeng.api.storage.IExternalStorageHandler", + modid = "appliedenergistics2", + striprefs = true) + private static class AE2TFFTHatchHandler implements IExternalStorageHandler { + + @Override + @Optional.Method(modid = "appliedenergistics2") + public boolean canHandle(TileEntity te, ForgeDirection d, StorageChannel channel, BaseActionSource mySrc) { + return channel == StorageChannel.FLUIDS && te instanceof BaseMetaTileEntity + && ((BaseMetaTileEntity) te).getMetaTileEntity() instanceof MTEHatchTFFT; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public IMEInventory getInventory(TileEntity te, ForgeDirection d, StorageChannel channel, + BaseActionSource src) { + if (channel == StorageChannel.FLUIDS) { + return ((MTEHatchTFFT) (((BaseMetaTileEntity) te).getMetaTileEntity())); + } + return null; + } + } + + private static final Textures.BlockIcons.CustomIcon TEXTURE_TFFT_HATCH = new Textures.BlockIcons.CustomIcon( + "iconsets/TFFT_HATCH"); + + private HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>(); + private MTETankTFFT controller; + + public MTEHatchTFFT(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional, 3, 0, "All-in-one access for the T.F.F.T"); + } + + public MTEHatchTFFT(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int colorIndex, boolean aActive, boolean aRedstone) { + return super.getTexture(aBaseMetaTileEntity, side, facing, colorIndex, aActive, aRedstone); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(Textures.BlockIcons.OVERLAY_PIPE_IN), + TextureFactory.builder() + .addIcon(TEXTURE_TFFT_HATCH) + .extFacing() + .build() }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(Textures.BlockIcons.OVERLAY_PIPE_IN), + TextureFactory.builder() + .addIcon(TEXTURE_TFFT_HATCH) + .extFacing() + .build() }; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchTFFT(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return (controller != null) ? controller.pull(resource, doFill) : 0; + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { + if (controller != null) { + final GTFluidTank sFluid = controller.getSelectedFluid(); + if (controller.getFluidSelector() == -1 || (sFluid != null && sFluid.contains(resource))) { + return controller.push(resource, doDrain); + } + } + return null; + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + if (controller != null) { + final GTFluidTank sFluid = controller.getSelectedFluid(); + if (controller.getFluidSelector() == -1) return controller.push(maxDrain, doDrain); + if (sFluid != null) return controller.push(sFluid.get(maxDrain), doDrain); + } + return null; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + return (controller != null) ? controller.getTankInfo() : null; + } + + public void bind(MTETankTFFT controller) { + this.controller = controller; + } + + public void unbind() { + this.controller = null; + } + + @Optional.Method(modid = "appliedenergistics2") + public static void registerAEIntegration() { + AEApi.instance() + .registries() + .externalStorage() + .addExternalStorageInterface(new AE2TFFTHatchHandler()); + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public IItemList<IAEFluidStack> getAvailableItems(IItemList out, int iteration) { + if (controller != null) { + for (int i = 0; i < MTETankTFFT.MAX_DISTINCT_FLUIDS; i++) { + if (!controller.STORE[i].isEmpty()) { + IAEFluidStack s = AEFluidStack.create(controller.STORE[i].get()); + s.setStackSize(controller.STORE[i].amount()); + out.add(s); + } + } + } + return out; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public IItemList<IAEFluidStack> getStorageList() { + IItemList<IAEFluidStack> fluidList = new FluidList(); + if (controller != null) { + for (int i = 0; i < MTETankTFFT.MAX_DISTINCT_FLUIDS; i++) { + if (!controller.STORE[i].isEmpty()) { + IAEFluidStack s = AEFluidStack.create(controller.STORE[i].get()); + s.setStackSize(controller.STORE[i].amount()); + fluidList.add(s); + } + } + } + return fluidList; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public void addListener(IMEMonitorHandlerReceiver<IAEFluidStack> l, Object verificationToken) { + if (listeners == null) listeners = new HashMap<>(); + listeners.put(l, verificationToken); + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public void removeListener(IMEMonitorHandlerReceiver<IAEFluidStack> l) { + if (listeners == null) listeners = new HashMap<>(); + listeners.remove(l); + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public AccessRestriction getAccess() { + return AccessRestriction.READ_WRITE; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public boolean isPrioritized(IAEFluidStack input) { + if (controller == null || input == null) return false; + return controller.contains(input.getFluidStack()) || controller.fluidCount() < MTETankTFFT.MAX_DISTINCT_FLUIDS; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public boolean canAccept(IAEFluidStack input) { + if (controller == null || input == null) return false; + return controller.contains(input.getFluidStack()) || controller.fluidCount() < MTETankTFFT.MAX_DISTINCT_FLUIDS; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public int getPriority() { + return 0; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public int getSlot() { + return 0; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public boolean validForPass(int i) { + return true; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public IAEFluidStack injectItems(IAEFluidStack input, Actionable mode, BaseActionSource src) { + final FluidStack inputStack = input.getFluidStack(); + if (inputStack == null) return null; + if (controller == null || getBaseMetaTileEntity() == null) return input; + if (mode != Actionable.SIMULATE) getBaseMetaTileEntity().markDirty(); + long amount = controller.pull(input.getFluidStack(), input.getStackSize(), mode != Actionable.SIMULATE); + if (amount == 0) return input; + if (amount == input.getStackSize()) return null; + IAEFluidStack result = AEFluidStack.create(input.getFluidStack()); + result.setStackSize(input.getStackSize() - amount); + return result; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public IAEFluidStack extractItems(IAEFluidStack request, Actionable mode, BaseActionSource src) { + if (controller == null || getBaseMetaTileEntity() == null) return null; + if (mode != Actionable.SIMULATE) getBaseMetaTileEntity().markDirty(); + long amount = controller.push(request.getFluidStack(), request.getStackSize(), mode != Actionable.SIMULATE); + if (amount == 0) return null; + if (amount == request.getStackSize()) return request.copy(); + IAEFluidStack result = AEFluidStack.create(request.getFluidStack()); + result.setStackSize(amount); + return result; + } + + @Override + @Optional.Method(modid = "appliedenergistics2") + public StorageChannel getChannel() { + return StorageChannel.FLUIDS; + } +} diff --git a/src/main/java/kekztech/common/tileentities/MTELapotronicSuperCapacitor.java b/src/main/java/kekztech/common/tileentities/MTELapotronicSuperCapacitor.java new file mode 100644 index 0000000000..2672d0e994 --- /dev/null +++ b/src/main/java/kekztech/common/tileentities/MTELapotronicSuperCapacitor.java @@ -0,0 +1,1213 @@ +package kekztech.common.tileentities; + +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.onlyIf; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.withChannel; +import static gregtech.api.enums.HatchElement.Maintenance; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; +import static gregtech.api.util.GTStructureUtility.filterByMTEClass; +import static java.lang.Math.min; +import static kekztech.util.Util.toPercentageFrom; +import static kekztech.util.Util.toStandardForm; + +import java.math.BigInteger; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.StructureUtility; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.drawable.UITexture; +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.FakeSyncWidget; + +import bartworks.API.BorosilicateGlass; +import gregtech.api.enums.Dyes; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Textures.BlockIcons; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.IHatchElement; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.metatileentity.implementations.MTEHatchDynamo; +import gregtech.api.metatileentity.implementations.MTEHatchEnergy; +import gregtech.api.metatileentity.implementations.MTEHatchMaintenance; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.IGTHatchAdder; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.common.misc.WirelessNetworkManager; +import kekztech.client.gui.KTUITextures; +import kekztech.common.Blocks; +import kekztech.common.itemBlocks.ItemBlockLapotronicEnergyUnit; +import tectech.thing.metaTileEntity.hatch.MTEHatchDynamoMulti; +import tectech.thing.metaTileEntity.hatch.MTEHatchDynamoTunnel; +import tectech.thing.metaTileEntity.hatch.MTEHatchEnergyMulti; +import tectech.thing.metaTileEntity.hatch.MTEHatchEnergyTunnel; + +public class MTELapotronicSuperCapacitor extends MTEEnhancedMultiBlockBase<MTELapotronicSuperCapacitor> + implements ISurvivalConstructable { + + private enum TopState { + MayBeTop, + Top, + NotTop + } + + private boolean canUseWireless = false; + private boolean wireless_mode = false; + private boolean not_processed_lsc = true; + private int counter = 1; + private boolean balanced = false; + + private final Queue<Long> energyInputValues = new LinkedList<>(); + private final Queue<Long> energyOutputValues = new LinkedList<>(); + + private final long max_passive_drain_eu_per_tick_per_uhv_cap = 1_000_000; + private final long max_passive_drain_eu_per_tick_per_uev_cap = 100_000_000; + private final long max_passive_drain_eu_per_tick_per_uiv_cap = (long) Math.pow(10, 10); + private final long max_passive_drain_eu_per_tick_per_umv_cap = (long) Math.pow(10, 12); + + private enum Capacitor { + + IV(2, BigInteger.valueOf(ItemBlockLapotronicEnergyUnit.IV_cap_storage)), + LuV(3, BigInteger.valueOf(ItemBlockLapotronicEnergyUnit.LuV_cap_storage)), + ZPM(4, BigInteger.valueOf(ItemBlockLapotronicEnergyUnit.ZPM_cap_storage)), + UV(5, BigInteger.valueOf(ItemBlockLapotronicEnergyUnit.UV_cap_storage)), + UHV(6, MAX_LONG), + None(0, BigInteger.ZERO), + EV(1, BigInteger.valueOf(ItemBlockLapotronicEnergyUnit.EV_cap_storage)), + UEV(7, MAX_LONG), + UIV(8, BigInteger.valueOf(ItemBlockLapotronicEnergyUnit.UIV_cap_storage)), + UMV(9, ItemBlockLapotronicEnergyUnit.UMV_cap_storage); + + private final int minimalGlassTier; + private final BigInteger providedCapacity; + static final Capacitor[] VALUES = values(); + static final Capacitor[] VALUES_BY_TIER = Arrays.stream(values()) + .sorted(Comparator.comparingInt(Capacitor::getMinimalGlassTier)) + .toArray(Capacitor[]::new); + + Capacitor(int minimalGlassTier, BigInteger providedCapacity) { + this.minimalGlassTier = minimalGlassTier; + this.providedCapacity = providedCapacity; + } + + public int getMinimalGlassTier() { + return minimalGlassTier; + } + + public BigInteger getProvidedCapacity() { + return providedCapacity; + } + + public static int getIndexFromGlassTier(int glassTier) { + for (int index = 0; index < values().length; index++) { + if (values()[index].getMinimalGlassTier() == glassTier) { + return index; + } + } + return -1; + } + } + + private static final String STRUCTURE_PIECE_BASE = "base"; + private static final String STRUCTURE_PIECE_LAYER = "slice"; + private static final String STRUCTURE_PIECE_TOP = "top"; + private static final String STRUCTURE_PIECE_MID = "mid"; + private static final int GLASS_TIER_UNSET = -2; + + private static final Block LSC_PART = Blocks.lscLapotronicEnergyUnit; + private static final Item LSC_PART_ITEM = Item.getItemFromBlock(LSC_PART); + private static final int CASING_META = 0; + private static final int CASING_TEXTURE_ID = (42 << 7) | 127; + + private static final int DURATION_AVERAGE_TICKS = 100; + + // height channel for height. + // glass channel for glass + // capacitor channel for capacitor, but it really just pick whatever capacitor it can find in survival + private static final IStructureDefinition<MTELapotronicSuperCapacitor> STRUCTURE_DEFINITION = IStructureDefinition + .<MTELapotronicSuperCapacitor>builder() + .addShape( + STRUCTURE_PIECE_BASE, + transpose( + new String[][] { { "bbbbb", "bbbbb", "bbbbb", "bbbbb", "bbbbb", }, + { "bb~bb", "bbbbb", "bbbbb", "bbbbb", "bbbbb", }, })) + .addShape( + STRUCTURE_PIECE_LAYER, + transpose(new String[][] { { "ggggg", "gcccg", "gcccg", "gcccg", "ggggg", }, })) + .addShape(STRUCTURE_PIECE_TOP, transpose(new String[][] { { "ggggg", "ggggg", "ggggg", "ggggg", "ggggg", }, })) + .addShape(STRUCTURE_PIECE_MID, transpose(new String[][] { { "ggggg", "gCCCg", "gCCCg", "gCCCg", "ggggg", }, })) + .addElement( + 'b', + buildHatchAdder( + MTELapotronicSuperCapacitor.class).atLeast(LSCHatchElement.Energy, LSCHatchElement.Dynamo, Maintenance) + .hatchItemFilterAnd( + (t, h) -> ChannelDataAccessor.getChannelData(h, "glass") < 6 + ? filterByMTEClass(ImmutableList.of(MTEHatchEnergyTunnel.class, MTEHatchDynamoTunnel.class)) + .negate() + : s -> true) + .casingIndex(CASING_TEXTURE_ID) + .dot(1) + .buildAndChain(onElementPass(te -> te.casingAmount++, ofBlock(LSC_PART, CASING_META)))) + .addElement( + 'g', + withChannel( + "glass", + BorosilicateGlass + .ofBoroGlass((byte) GLASS_TIER_UNSET, (te, t) -> te.glassTier = t, te -> te.glassTier))) + .addElement( + 'c', + ofChain( + onlyIf( + te -> te.topState != TopState.NotTop, + onElementPass( + te -> te.topState = TopState.Top, + withChannel( + "glass", + BorosilicateGlass.ofBoroGlass( + (byte) GLASS_TIER_UNSET, + (te, t) -> te.glassTier = t, + te -> te.glassTier)))), + onlyIf( + te -> te.topState != TopState.Top, + onElementPass( + te -> te.topState = TopState.NotTop, + new IStructureElement<MTELapotronicSuperCapacitor>() { + + @Override + public boolean check(MTELapotronicSuperCapacitor 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 (LSC_PART != worldBlock || meta == 0) return false; + t.capacitors[meta - 1]++; + return true; + } + + private int getHint(ItemStack stack) { + return Capacitor.VALUES_BY_TIER[Math.min( + Capacitor.VALUES_BY_TIER.length, + ChannelDataAccessor.getChannelData(stack, "capacitor")) - 1].getMinimalGlassTier() + + 1; + } + + @Override + public boolean spawnHint(MTELapotronicSuperCapacitor t, World world, int x, int y, int z, + ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, LSC_PART, getHint(trigger)); + return true; + } + + @Override + public boolean placeBlock(MTELapotronicSuperCapacitor t, World world, int x, int y, int z, + ItemStack trigger) { + world.setBlock(x, y, z, LSC_PART, getHint(trigger), 3); + return true; + } + + @Override + public PlaceResult survivalPlaceBlock(MTELapotronicSuperCapacitor t, World world, int x, + int y, int z, ItemStack trigger, IItemSource source, EntityPlayerMP actor, + Consumer<IChatComponent> chatter) { + if (check(t, world, x, y, z)) return PlaceResult.SKIP; + int glassTier = ChannelDataAccessor.getChannelData(trigger, "glass") + 2; + ItemStack targetStack = source + .takeOne( + s -> s != null && s.stackSize >= 0 + && s.getItem() == LSC_PART_ITEM + && Capacitor.VALUES[Math.min(s.getItemDamage(), Capacitor.VALUES.length) + - 1].getMinimalGlassTier() > glassTier, + true); + if (targetStack == null) return PlaceResult.REJECT; + return StructureUtility.survivalPlaceBlock( + targetStack, + NBTMode.EXACT, + targetStack.stackTagCompound, + true, + world, + x, + y, + z, + source, + actor, + chatter); + } + })))) + .addElement('C', ofBlock(LSC_PART, 1)) + .build(); + + private static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); + + private final Set<MTEHatchEnergyMulti> mEnergyHatchesTT = new HashSet<>(); + private final Set<MTEHatchDynamoMulti> mDynamoHatchesTT = new HashSet<>(); + private final Set<MTEHatchEnergyTunnel> mEnergyTunnelsTT = new HashSet<>(); + private final Set<MTEHatchDynamoTunnel> mDynamoTunnelsTT = new HashSet<>(); + /** + * Count the amount of capacitors of each tier in each slot. Index = meta - 1 + */ + private final int[] capacitors = new int[10]; + + private BigInteger capacity = BigInteger.ZERO; + private BigInteger stored = BigInteger.ZERO; + private long passiveDischargeAmount = 0; + private long inputLastTick = 0; + private long outputLastTick = 0; + private int repairStatusCache = 0; + + private byte glassTier = -1; + private int casingAmount = 0; + private TopState topState = TopState.MayBeTop; + + private long mMaxEUIn = 0; + private long mMaxEUOut = 0; + + public MTELapotronicSuperCapacitor(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTELapotronicSuperCapacitor(String aName) { + super(aName); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity var1) { + return new MTELapotronicSuperCapacitor(super.mName); + } + + @Override + public IStructureDefinition<MTELapotronicSuperCapacitor> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + private void processInputHatch(MTEHatch aHatch, int aBaseCasingIndex) { + mMaxEUIn += aHatch.maxEUInput() * aHatch.maxAmperesIn(); + aHatch.updateTexture(aBaseCasingIndex); + } + + private void processOutputHatch(MTEHatch aHatch, int aBaseCasingIndex) { + mMaxEUOut += aHatch.maxEUOutput() * aHatch.maxAmperesOut(); + aHatch.updateTexture(aBaseCasingIndex); + } + + private boolean addBottomHatches(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null || aTileEntity.isDead()) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (!(aMetaTileEntity instanceof MTEHatch)) return false; + if (aMetaTileEntity instanceof MTEHatchMaintenance) { + ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex); + return MTELapotronicSuperCapacitor.this.mMaintenanceHatches.add((MTEHatchMaintenance) aMetaTileEntity); + } else if (aMetaTileEntity instanceof MTEHatchEnergy) { + // Add GT hatches + final MTEHatchEnergy tHatch = ((MTEHatchEnergy) aMetaTileEntity); + processInputHatch(tHatch, aBaseCasingIndex); + return mEnergyHatches.add(tHatch); + } else if (aMetaTileEntity instanceof MTEHatchEnergyTunnel) { + // Add TT Laser hatches + final MTEHatchEnergyTunnel tHatch = ((MTEHatchEnergyTunnel) aMetaTileEntity); + processInputHatch(tHatch, aBaseCasingIndex); + return mEnergyTunnelsTT.add(tHatch); + } else if (aMetaTileEntity instanceof MTEHatchEnergyMulti) { + // Add TT hatches + final MTEHatchEnergyMulti tHatch = (MTEHatchEnergyMulti) aMetaTileEntity; + processInputHatch(tHatch, aBaseCasingIndex); + return mEnergyHatchesTT.add(tHatch); + } else if (aMetaTileEntity instanceof MTEHatchDynamo) { + // Add GT hatches + final MTEHatchDynamo tDynamo = (MTEHatchDynamo) aMetaTileEntity; + processOutputHatch(tDynamo, aBaseCasingIndex); + return mDynamoHatches.add(tDynamo); + } else if (aMetaTileEntity instanceof MTEHatchDynamoTunnel) { + // Add TT Laser hatches + final MTEHatchDynamoTunnel tDynamo = (MTEHatchDynamoTunnel) aMetaTileEntity; + processOutputHatch(tDynamo, aBaseCasingIndex); + return mDynamoTunnelsTT.add(tDynamo); + } else if (aMetaTileEntity instanceof MTEHatchDynamoMulti) { + // Add TT hatches + final MTEHatchDynamoMulti tDynamo = (MTEHatchDynamoMulti) aMetaTileEntity; + processOutputHatch(tDynamo, aBaseCasingIndex); + return mDynamoHatchesTT.add(tDynamo); + } + return false; + } + + private int getUHVCapacitorCount() { + return capacitors[4]; + } + + private int getUEVCapacitorCount() { + return capacitors[7]; + } + + private int getUIVCapacitorCount() { + return capacitors[8]; + } + + private int getUMVCapacitorCount() { + return capacitors[9]; + } + + private int wirelessCapableCapacitors() { + return capacitors[4] + capacitors[7] + capacitors[8] + capacitors[9]; + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Energy Storage") + .addInfo("Loses energy equal to 1% of the total capacity every 24 hours.") + .addInfo( + "Capped at " + EnumChatFormatting.RED + + GTUtility.formatNumbers(max_passive_drain_eu_per_tick_per_uhv_cap) + + EnumChatFormatting.GRAY + + " EU/t passive loss per " + + GTValues.TIER_COLORS[9] + + GTValues.VN[9] + + EnumChatFormatting.GRAY + + " capacitor.") + .addInfo( + "The passive loss increases " + EnumChatFormatting.DARK_RED + + "100" + + EnumChatFormatting.GRAY + + "-fold" + + " for every capacitor tier above.") + .addInfo("Passive loss is multiplied by the number of maintenance issues present.") + .addSeparator() + .addInfo("Glass shell has to be Tier - 3 of the highest capacitor tier.") + .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("Add more or better capacitors to increase capacity.") + .addSeparator() + .addInfo("Wireless mode can be enabled by right clicking with a screwdriver.") + .addInfo( + "This mode can only be enabled if you have a " + GTValues.TIER_COLORS[9] + + GTValues.VN[9] + + EnumChatFormatting.GRAY + + "+ capacitor in the multiblock.") + .addInfo( + "When enabled every " + EnumChatFormatting.BLUE + + GTUtility + .formatNumbers(ItemBlockLapotronicEnergyUnit.LSC_time_between_wireless_rebalance_in_ticks) + + EnumChatFormatting.GRAY + + " ticks the LSC will attempt to re-balance against your") + .addInfo("wireless EU network.") + .addInfo( + "If there is less than " + EnumChatFormatting.RED + + GTUtility.formatNumbers(ItemBlockLapotronicEnergyUnit.LSC_wireless_eu_cap) + + EnumChatFormatting.GRAY + + "(" + + GTValues.TIER_COLORS[9] + + GTValues.VN[9] + + EnumChatFormatting.GRAY + + ") EU in the LSC") + .addInfo("it will withdraw from the network and add to the LSC.") + .addInfo("If there is more it will add the EU to the network and remove it from the LSC.") + .addInfo( + "The threshold increases " + EnumChatFormatting.DARK_RED + + "100" + + EnumChatFormatting.GRAY + + "-fold" + + " for every capacitor tier above.") + .addSeparator() + .beginVariableStructureBlock(5, 5, 4, 50, 5, 5, false) + .addStructureInfo("Modular height of 4-50 blocks.") + .addController("Front center bottom") + .addOtherStructurePart("Lapotronic Super Capacitor Casing", "5x2x5 base (at least 17x)") + .addOtherStructurePart( + "Lapotronic Capacitor (" + GTValues.TIER_COLORS[4] + + GTValues.VN[4] + + EnumChatFormatting.GRAY + + "-" + + GTValues.TIER_COLORS[8] + + GTValues.VN[8] + + EnumChatFormatting.GRAY + + "), Ultimate Capacitor (" + + GTValues.TIER_COLORS[9] + + GTValues.VN[9] + + EnumChatFormatting.GRAY + + "-" + + GTValues.TIER_COLORS[12] + + GTValues.VN[12] + + EnumChatFormatting.GRAY + + ")", + "Center 3x(1-47)x3 above base (9-423 blocks)") + .addStructureInfo( + "You can also use the Empty Capacitor to save materials if you use it for less than half the blocks") + .addOtherStructurePart("Borosilicate Glass (any)", "41-777x, Encase capacitor pillar") + .addEnergyHatch("Any casing") + .addDynamoHatch("Any casing") + .addOtherStructurePart( + "Laser Target/Source |
