diff options
| author | Raven Szewczyk <git@eigenraven.me> | 2024-05-25 14:13:58 +0100 |
|---|---|---|
| committer | Raven Szewczyk <git@eigenraven.me> | 2024-05-25 14:13:58 +0100 |
| commit | 91b1909427bb0cab0f72505c325b07f8fb39c62e (patch) | |
| tree | d6570897b7150afd4f3cb1470202af11e3e9ece3 /src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity | |
| parent | 40efa0d238677418071b658b11b0a1a7c9e0d864 (diff) | |
| download | GT5-Unofficial-91b1909427bb0cab0f72505c325b07f8fb39c62e.tar.gz GT5-Unofficial-91b1909427bb0cab0f72505c325b07f8fb39c62e.tar.bz2 GT5-Unofficial-91b1909427bb0cab0f72505c325b07f8fb39c62e.zip | |
Move GoodGen sources
Diffstat (limited to 'src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity')
4 files changed, 1009 insertions, 0 deletions
diff --git a/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/DieselGenerator.java b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/DieselGenerator.java new file mode 100644 index 0000000000..4d54be44d1 --- /dev/null +++ b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/DieselGenerator.java @@ -0,0 +1,214 @@ +package goodgenerator.blocks.tileEntity.GTMetaTileEntity; + +import static gregtech.api.enums.Textures.BlockIcons.*; +import static gregtech.api.enums.Textures.BlockIcons.DIESEL_GENERATOR_SIDE_ACTIVE_GLOW; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; + +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.GT_Mod; +import gregtech.api.enums.ItemList; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicGenerator; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GT_Log; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Utility; + +public class DieselGenerator extends GT_MetaTileEntity_BasicGenerator { + + public int mEfficiency; + + public DieselGenerator(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + new String[] { "Requires liquid Fuel", + "Causes " + (int) (GT_Mod.gregtechproxy.mPollutionBaseDieselGeneratorPerSecond * (1.1 - aTier * 0.1)) + + " Pollution per second" }); + mEfficiency = 100 - aTier * 10; + } + + public DieselGenerator(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + mEfficiency = 100 - aTier * 10; + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new DieselGenerator(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + @Override + public RecipeMap<?> getRecipeMap() { + return RecipeMaps.dieselFuels; + } + + @Override + public int getCapacity() { + return 16000; + } + + @Override + public int getEfficiency() { + return this.mEfficiency; + } + + @Override + public int getFuelValue(ItemStack aStack) { + if (GT_Utility.isStackInvalid(aStack) || getRecipeMap() == null) return 0; + long rValue = Math.max(GT_ModHandler.getFuelCanValue(aStack) * 6 / 5, super.getFuelValue(aStack)); + if (ItemList.Fuel_Can_Plastic_Filled.isStackEqual(aStack, false, true)) { + rValue = Math.max(rValue, GameRegistry.getFuelValue(aStack) * 3L); + } + if (rValue > Integer.MAX_VALUE) { + throw new ArithmeticException("Integer LOOPBACK!"); + } + return (int) rValue; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aTick % 100 == 0 && mFluid != null && mFluid.amount > this.getCapacity()) { + GT_Log.err.println( + "Dupe Abuse: " + aBaseMetaTileEntity.getOwnerName() + + " Coords: " + + aBaseMetaTileEntity.getXCoord() + + " " + + aBaseMetaTileEntity.getYCoord() + + " " + + aBaseMetaTileEntity.getZCoord()); + aBaseMetaTileEntity.setToFire(); + } + super.onPostTick(aBaseMetaTileEntity, aTick); + } + + @Override + public ITexture[] getFront(byte aColor) { + return new ITexture[] { super.getFront(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_FRONT), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_FRONT_GLOW) + .glow() + .build()), + OVERLAYS_ENERGY_OUT[this.mTier] }; + } + + @Override + public ITexture[] getBack(byte aColor) { + return new ITexture[] { super.getBack(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_BACK), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_BACK_GLOW) + .glow() + .build()) }; + } + + @Override + public ITexture[] getBottom(byte aColor) { + return new ITexture[] { super.getBottom(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_BOTTOM), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_BOTTOM_GLOW) + .glow() + .build()) }; + } + + @Override + public ITexture[] getTop(byte aColor) { + return new ITexture[] { super.getTop(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_TOP), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_TOP_GLOW) + .glow() + .build()) }; + } + + @Override + public ITexture[] getSides(byte aColor) { + return new ITexture[] { super.getSides(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_SIDE), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_SIDE_GLOW) + .glow() + .build()) }; + } + + @Override + public ITexture[] getFrontActive(byte aColor) { + return new ITexture[] { super.getFrontActive(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_FRONT_ACTIVE), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_FRONT_ACTIVE_GLOW) + .glow() + .build()), + OVERLAYS_ENERGY_OUT[this.mTier] }; + } + + @Override + public ITexture[] getBackActive(byte aColor) { + return new ITexture[] { super.getBackActive(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_BACK_ACTIVE), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_BACK_ACTIVE_GLOW) + .glow() + .build()) }; + } + + @Override + public ITexture[] getBottomActive(byte aColor) { + return new ITexture[] { super.getBottomActive(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_BOTTOM_ACTIVE), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_BOTTOM_ACTIVE_GLOW) + .glow() + .build()) }; + } + + @Override + public ITexture[] getTopActive(byte aColor) { + return new ITexture[] { super.getTopActive(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_TOP_ACTIVE), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_TOP_ACTIVE_GLOW) + .glow() + .build()) }; + } + + @Override + public ITexture[] getSidesActive(byte aColor) { + return new ITexture[] { super.getSidesActive(aColor)[0], + TextureFactory.of( + TextureFactory.of(DIESEL_GENERATOR_SIDE_ACTIVE), + TextureFactory.builder() + .addIcon(DIESEL_GENERATOR_SIDE_ACTIVE_GLOW) + .glow() + .build()) }; + } + + @Override + public int getPollution() { + return (int) (GT_Mod.gregtechproxy.mPollutionBaseDieselGeneratorPerSecond * (1.1 - mTier * 0.1)); + } +} diff --git a/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/NeutronAccelerator.java b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/NeutronAccelerator.java new file mode 100644 index 0000000000..730374db66 --- /dev/null +++ b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/NeutronAccelerator.java @@ -0,0 +1,48 @@ +package goodgenerator.blocks.tileEntity.GTMetaTileEntity; + +import static gregtech.api.enums.GT_Values.V; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy; + +public class NeutronAccelerator extends GT_MetaTileEntity_Hatch_Energy { + + public NeutronAccelerator(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier); + } + + public NeutronAccelerator(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + public int getMaxEUConsume() { + return (int) (V[mTier] * 8 / 10); + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new NeutronAccelerator(mName, mTier, this.getDescription(), mTextures); + } + + @Override + public String[] getDescription() { + return new String[] { "Input EU to Accelerate the Neutron!", "Max EU input: " + this.maxEUInput(), + "Max EU consumption: " + this.getMaxEUConsume(), + "Every EU can be transformed into 10~20 eV Neutron Kinetic Energy." }; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + if (aBaseMetaTileEntity.getStoredEU() >= getMaxEUConsume() && aBaseMetaTileEntity.isAllowedToWork()) { + setEUVar(aBaseMetaTileEntity.getStoredEU() - getMaxEUConsume()); + aBaseMetaTileEntity.setActive(true); + } else { + aBaseMetaTileEntity.setActive(false); + } + } + super.onPostTick(aBaseMetaTileEntity, aTick); + } +} diff --git a/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/NeutronSensor.java b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/NeutronSensor.java new file mode 100644 index 0000000000..86bcbeece9 --- /dev/null +++ b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/NeutronSensor.java @@ -0,0 +1,277 @@ +package goodgenerator.blocks.tileEntity.GTMetaTileEntity; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.api.math.Color; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.TextWidget; +import com.gtnewhorizons.modularui.common.widget.textfield.NumericWidget; + +import crazypants.enderio.Log; +import gregtech.api.enums.Textures; +import gregtech.api.gui.modularui.GT_UIInfos; +import gregtech.api.gui.modularui.GT_UITextures; +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_Hatch; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GT_Utility; +import gregtech.common.gui.modularui.widget.CoverCycleButtonWidget; + +public class NeutronSensor extends GT_MetaTileEntity_Hatch { + + private static final IIconContainer textureFont = new Textures.BlockIcons.CustomIcon("icons/NeutronSensorFont"); + private static final IIconContainer textureFont_Glow = new Textures.BlockIcons.CustomIcon( + "icons/NeutronSensorFont_GLOW"); + + protected int threshold = 0; + protected boolean inverted = false; + boolean isOn = false; + + public NeutronSensor(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, 0, "Detect Neutron Kinetic Energy."); + } + + public NeutronSensor(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + @Override + public String[] getDescription() { + return new String[] { "Can be installed in Neutron Activator.", + "Output Redstone Signal according to the Neutron Kinetic Energy.", + "Right click to open the GUI and setting." }; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + if (aNBT.hasKey("mBoxContext")) { + // Convert legacy settings + setThresholdFromString(aNBT.getString("mBoxContext")); + } else { + threshold = aNBT.getInteger("mThreshold"); + inverted = aNBT.getBoolean("mInverted"); + } + super.loadNBTData(aNBT); + } + + /** + * Used to convert legacy setting where the sensor would use a string like ">200keV" to set its threshold. This + * method updates the {@link #threshold} and {@link #inverted} fields based on the input string. The string is + * assumed to be in format "(operator)(value)[suffix](ev)", where: + * <ul> + * <li>(operator) is one of "<", ">", "<=", ">=", "==", or "!="</li> + * <li>(value) is a numeric value (sequence of decimal digits)</li> + * <li>(suffix) is "k", "K", "m", or "M" (optional)</li> + * <li>(ev) is the string "ev", case-insensitive.</li> + * </ul> + * Note that operators "==" and "!=" can not be converted exactly, as the new threshold supports only a binary + * comparison (less than, or greater than or equal). Thus "==" is interpreted in the same way as "<=", and "!=" as + * ">". This shouldn't be a big problem for real setups, because one should probably not be testing for strict + * equality here anyway. The possible reasonable conditions "==0eV" and "!=0eV" will continue working as before. + * + * @param text String to convert. + */ + private void setThresholdFromString(String text) { + Matcher matcher = Pattern.compile("^(<|>|<=|>=|==|!=)([0-9]*)(|k|m)(ev)$", Pattern.CASE_INSENSITIVE) + .matcher(text); + + if (!matcher.matches()) { + Log.error("Failed to parse Neutron Sensor setting: \"" + text + "\"!"); + return; + } + + String operator = matcher.group(1); + String value = matcher.group(2); + String suffix = matcher.group(3); + + int newThreshold = Integer.parseInt(value); + + switch (suffix) { + case "k": + case "K": + newThreshold *= 1000; + break; + case "m": + case "M": + newThreshold *= 1_000_000; + break; + } + + switch (operator) { + case "<": + threshold = newThreshold; + inverted = true; + break; + case ">": + threshold = newThreshold + 1; + inverted = false; + break; + case "<=": + threshold = newThreshold + 1; + inverted = true; + break; + case ">=": + threshold = newThreshold; + inverted = false; + break; + case "==": // Interpret as <= to keep "==0eV" working as before. + threshold = newThreshold + 1; + inverted = true; + break; + case "!=": // Interpret as > to keep "!=0eV" working as before. + threshold = newThreshold + 1; + inverted = false; + break; + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setInteger("mThreshold", threshold); + aNBT.setBoolean("mInverted", inverted); + super.saveNBTData(aNBT); + } + + @Override + public void initDefaultModes(NBTTagCompound aNBT) { + getBaseMetaTileEntity().setActive(true); + } + + @Override + public boolean isValidSlot(int aIndex) { + return false; + } + + @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 onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side, + float aX, float aY, float aZ) { + GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + /** + * Updates redstone output strength based on the eV of the multiblock. + * + * @param eV Amount of eV to compare. + */ + public void updateRedstoneOutput(int eV) { + isOn = (eV >= threshold) ^ inverted; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(textureFont), TextureFactory.builder() + .addIcon(textureFont_Glow) + .glow() + .build() }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(textureFont) }; + } + + @Override + public boolean allowGeneralRedstoneOutput() { + return true; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (isOn) { + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) 15); + } + } else { + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) 0); + } + } + super.onPostTick(aBaseMetaTileEntity, aTick); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new NeutronSensor(mName, mTier, mDescriptionArray, mTextures); + } + + @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 false; + } + + @Override + public boolean useModularUI() { + return true; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + final String INVERTED = GT_Utility.trans("INVERTED", "Inverted"); + final String NORMAL = GT_Utility.trans("NORMAL", "Normal"); + + builder.widget( + new CoverCycleButtonWidget().setToggle(() -> inverted, (val) -> inverted = val) + .setTextureGetter( + (state) -> state == 1 ? GT_UITextures.OVERLAY_BUTTON_REDSTONE_ON + : GT_UITextures.OVERLAY_BUTTON_REDSTONE_OFF) + .addTooltip(0, NORMAL) + .addTooltip(1, INVERTED) + .setPos(10, 8)) + .widget( + new TextWidget().setStringSupplier(() -> inverted ? INVERTED : NORMAL) + .setDefaultColor(COLOR_TEXT_GRAY.get()) + .setTextAlignment(Alignment.CenterLeft) + .setPos(28, 12)) + .widget( + new NumericWidget().setBounds(0, 1200000000) + .setGetter(() -> threshold) + .setSetter((value) -> threshold = (int) value) + .setScrollValues(1000, 1, 1_000_000) + .setTextColor(Color.WHITE.dark(1)) + .setTextAlignment(Alignment.CenterLeft) + .setFocusOnGuiOpen(true) + .setBackground(GT_UITextures.BACKGROUND_TEXT_FIELD.withOffset(-1, -1, 2, 2)) + .setPos(10, 28) + .setSize(77, 12)) + .widget( + new TextWidget(StatCollector.translateToLocal("gui.NeutronSensor.4")) + .setDefaultColor(COLOR_TEXT_GRAY.get()) + .setTextAlignment(Alignment.CenterLeft) + .setPos(90, 30)); + } +} diff --git a/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/YOTTAHatch.java b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/YOTTAHatch.java new file mode 100644 index 0000000000..f905e82f8c --- /dev/null +++ b/src/main/java/goodgenerator/blocks/tileEntity/GTMetaTileEntity/YOTTAHatch.java @@ -0,0 +1,470 @@ +package goodgenerator.blocks.tileEntity.GTMetaTileEntity; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; + +import appeng.api.config.AccessRestriction; +import appeng.api.config.Actionable; +import appeng.api.networking.GridFlags; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import appeng.api.networking.events.MENetworkCellArrayUpdate; +import appeng.api.networking.events.MENetworkStorageEvent; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.security.IActionHost; +import appeng.api.networking.storage.IStorageGrid; +import appeng.api.storage.ICellContainer; +import appeng.api.storage.IMEInventory; +import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import appeng.api.util.AECableType; +import appeng.api.util.DimensionalCoord; +import appeng.me.helpers.AENetworkProxy; +import appeng.me.helpers.IGridProxyable; +import goodgenerator.blocks.tileEntity.YottaFluidTank; +import goodgenerator.loader.Loaders; +import goodgenerator.util.StackUtils; +import gregtech.api.enums.Textures; +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_Hatch; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GT_Utility; + +public class YOTTAHatch extends GT_MetaTileEntity_Hatch implements IGridProxyable, IActionHost, ICellContainer, + IMEInventory<IAEFluidStack>, IMEInventoryHandler<IAEFluidStack> { + + private static final IIconContainer textureFont = new Textures.BlockIcons.CustomIcon("icons/YOTTAHatch"); + + private YottaFluidTank host; + private AENetworkProxy gridProxy = null; + private int priority; + private byte tickRate = 20; + private FluidStack lastFluid = null; + private BigInteger lastAmt = BigInteger.ZERO; + private AccessRestriction readMode = AccessRestriction.READ_WRITE; + private final AccessRestriction[] AEModes = new AccessRestriction[] { AccessRestriction.NO_ACCESS, + AccessRestriction.READ, AccessRestriction.WRITE, AccessRestriction.READ_WRITE }; + + private static final BigInteger MAX_LONG_BIGINT = BigInteger.valueOf(Long.MAX_VALUE); + + public YOTTAHatch(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + 0, + new String[] { "Special I/O port for AE2FC.", "Directly connected YOTTank with AE fluid storage system.", + "Use screwdriver to set storage priority", "Use soldering iron to set read/write mode" }); + } + + public YOTTAHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + public void setTank(YottaFluidTank te) { + this.host = te; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setInteger("mAEPriority", this.priority); + aNBT.setInteger("mAEMode", this.readMode.ordinal()); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + this.priority = aNBT.getInteger("mAEPriority"); + this.readMode = AEModes[aNBT.getInteger("mAEMode")]; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public final void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ, + ItemStack toolStack) { + if (aPlayer.isSneaking()) this.priority -= 10; + else this.priority += 10; + GT_Utility + .sendChatToPlayer(aPlayer, String.format(StatCollector.translateToLocal("yothatch.chat.0"), this.priority)); + } + + @Override + public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ, ItemStack toolStack) { + this.readMode = AEModes[(readMode.ordinal() + 1) % 4]; + GT_Utility + .sendChatToPlayer(aPlayer, String.format(StatCollector.translateToLocal("yothatch.chat.1"), this.readMode)); + return true; + } + + @Override + public IGridNode getGridNode(ForgeDirection forgeDirection) { + AENetworkProxy gp = getProxy(); + return gp != null ? gp.getNode() : null; + } + + @Override + public AECableType getCableConnectionType(ForgeDirection forgeDirection) { + return AECableType.SMART; + } + + @Override + public void securityBreak() {} + + @Override + public AENetworkProxy getProxy() { + if (gridProxy == null) { + gridProxy = new AENetworkProxy(this, "proxy", Loaders.YFH, true); + gridProxy.onReady(); + gridProxy.setFlags(GridFlags.REQUIRE_CHANNEL); + } + return this.gridProxy; + } + + @Override + public DimensionalCoord getLocation() { + IGregTechTileEntity gtm = this.getBaseMetaTileEntity(); + return new DimensionalCoord(gtm.getWorld(), gtm.getXCoord(), gtm.getYCoord(), gtm.getZCoord()); + } + + @Override + public IItemList<IAEFluidStack> getAvailableItems(IItemList<IAEFluidStack> out) { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return out; + if (host.mFluid == null || host.mStorageCurrent.signum() <= 0) return out; + long ready; + if (host.mStorageCurrent.compareTo(MAX_LONG_BIGINT) >= 0) { + ready = Long.MAX_VALUE; + } else ready = host.mStorageCurrent.longValue(); + out.add(StackUtils.createAEFluidStack(host.mFluid.getFluid(), ready)); + return out; + } + + @Override + public IAEFluidStack injectItems(IAEFluidStack input, Actionable type, BaseActionSource src) { + long amt = fill(null, input, false); + if (amt == input.getStackSize()) { + if (type.equals(Actionable.MODULATE)) fill(null, input, true); + return null; + } + return input; + } + + @Override + public IAEFluidStack extractItems(IAEFluidStack request, Actionable mode, BaseActionSource src) { + IAEFluidStack ready = drain(null, request, false); + if (ready != null) { + if (mode.equals(Actionable.MODULATE)) drain(null, ready, true); + return ready; + } else return null; + } + + @Override + public StorageChannel getChannel() { + return StorageChannel.FLUIDS; + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + super.onFirstTick(aBaseMetaTileEntity); + getProxy(); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (shouldTick(aTick)) { + if (isChanged()) { + IGridNode node = getGridNode(null); + if (node != null) { + IGrid grid = node.getGrid(); + if (grid != null) { + grid.postEvent(new MENetworkCellArrayUpdate()); + IStorageGrid storageGrid = grid.getCache(IStorageGrid.class); + if (storageGrid == null) { + node.getGrid() + .postEvent(new MENetworkStorageEvent(null, StorageChannel.FLUIDS)); + } else { + node.getGrid() + .postEvent( + new MENetworkStorageEvent(storageGrid.getFluidInventory(), StorageChannel.FLUIDS)); + } + node.getGrid() + .postEvent(new MENetworkCellArrayUpdate()); + } + } + faster(); + update(); + } else { + slower(); + } + } + super.onPostTick(aBaseMetaTileEntity, aTick); + } + + @Override + public int getCapacity() { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return 0; + if (host.mStorage.compareTo(YottaFluidTank.MAX_INT_BIGINT) >= 0) { + return Integer.MAX_VALUE; + } else return host.mStorage.intValue(); + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return 0; + if (host.mLockedFluid != null && !host.mLockedFluid.isFluidEqual(resource)) return 0; + if (host.mFluid == null || host.mFluid.isFluidEqual(resource)) { + if (host.mFluid == null) { + host.mFluid = resource.copy(); + host.mFluid.amount = 1; + } + + if (host.addFluid(resource.amount, doFill)) { + return resource.amount; + } else { + final int returned; + if (host.getIsVoidExcessEnabled()) { + returned = resource.amount; + } else { + final BigInteger delta = host.mStorage.subtract(host.mStorageCurrent); + returned = delta.intValueExact(); + } + host.mStorageCurrent = host.mStorage; + return returned; + } + } + return 0; + } + + public long fill(@SuppressWarnings("unused") ForgeDirection from, IAEFluidStack resource, boolean doFill) { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return 0; + if (host.mLockedFluid != null && host.mLockedFluid.getFluid() != resource.getFluid()) return 0; + if (host.mFluid == null || host.mFluid.getFluid() == resource.getFluid()) { + if (host.mFluid == null) { + host.mFluid = resource.getFluidStack(); // makes a copy internally + host.mFluid.amount = 1; + } + + if (host.addFluid(resource.getStackSize(), doFill)) { + return resource.getStackSize(); + } else { + final long returned; + if (host.getIsVoidExcessEnabled()) { + returned = resource.getStackSize(); + } else { + final BigInteger delta = host.mStorage.subtract(host.mStorageCurrent); + returned = delta.longValueExact(); + } + host.mStorageCurrent = host.mStorage; + return returned; + } + } + return 0; + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return null; + if (host.mFluid == null || host.mFluid.getFluid() != resource.getFluid()) return null; + int ready; + if (host.mStorageCurrent.compareTo(YottaFluidTank.MAX_INT_BIGINT) >= 0) { + ready = Integer.MAX_VALUE; + } else ready = host.mStorageCurrent.intValue(); + ready = Math.min(ready, resource.amount); + if (doDrain) { + host.reduceFluid(ready); + } + return new FluidStack(resource.getFluid(), ready); + } + + public IAEFluidStack drain(@SuppressWarnings("unused") ForgeDirection from, IAEFluidStack resource, + boolean doDrain) { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return null; + if (host.mFluid == null || host.mFluid.getFluid() != resource.getFluid()) return null; + long ready; + if (host.mStorageCurrent.compareTo(MAX_LONG_BIGINT) > 0) { + ready = Long.MAX_VALUE; + } else ready = host.mStorageCurrent.longValue(); + ready = Math.min(ready, resource.getStackSize()); + if (doDrain) { + host.reduceFluid(ready); + } + IAEFluidStack copy = resource.copy(); + copy.setStackSize(ready); + return copy; + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return null; + if (host.mFluid == null) return null; + final FluidStack drainStack = host.mFluid.copy(); + drainStack.amount = maxDrain; + return this.drain(from, drainStack, doDrain); + } + + private static final FluidTankInfo[] EMPTY_TANK_INFO = new FluidTankInfo[] { new FluidTankInfo(null, 0) }; + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + if (host == null || host.getBaseMetaTileEntity() == null + || !host.getBaseMetaTileEntity() + .isActive()) + return EMPTY_TANK_INFO; + + return host.getTankInfo(from); + } + + @Override + public boolean canTankBeFilled() { + return true; + } + + @Override + public boolean canTankBeEmptied() { + return true; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(textureFont), }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(textureFont), }; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new YOTTAHatch(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public IGridNode getActionableNode() { + AENetworkProxy gp = getProxy(); + return gp != null ? gp.getNode() : null; + } + + @Override + public AccessRestriction getAccess() { + return this.readMode; + } + + @Override + public boolean isPrioritized(IAEFluidStack input) { + return true; + } + + @Override + public boolean canAccept(IAEFluidStack input) { + FluidStack rInput = input.getFluidStack(); + return fill(null, rInput, false) > 0; + } + + @Override + @SuppressWarnings("rawtypes") + public List<IMEInventoryHandler> getCellArray(StorageChannel channel) { + List<IMEInventoryHandler> list = new ArrayList<>(); + if (channel == StorageChannel.FLUIDS) { + list.add(this); + } + return list; + } + + @Override + public int getPriority() { + return this.priority; + } + + @Override + public int getSlot() { + return 0; + } + + @Override + public boolean validForPass(int i) { + return true; + } + + @Override + public void blinkCell(int slot) {} + + @Override + public void saveChanges(IMEInventory cellInventory) { + // This is handled by host itself. + } + + private boolean isChanged() { + if (this.host == null) return false; + return !this.lastAmt.equals(this.host.mStorageCurrent) || this.lastFluid != this.host.mFluid; + } + + private void update() { + if (this.host == null) return; + this.lastAmt = this.host.mStorageCurrent; + this.lastFluid = this.host.mFluid; + } + + private void faster() { + if (this.tickRate > 15) { + this.tickRate -= 5; + } + } + + private void slower() { + if (this.tickRate < 100) { + this.tickRate += 5; + } + } + + private boolean shouldTick(long tick) { + if (this.host == null) return false; + return tick % this.tickRate == 0; + } +} |
