diff options
Diffstat (limited to 'src/main/java/gregtech/common/covers/CoverEUMeter.java')
-rw-r--r-- | src/main/java/gregtech/common/covers/CoverEUMeter.java | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/src/main/java/gregtech/common/covers/CoverEUMeter.java b/src/main/java/gregtech/common/covers/CoverEUMeter.java new file mode 100644 index 0000000000..07f54012d5 --- /dev/null +++ b/src/main/java/gregtech/common/covers/CoverEUMeter.java @@ -0,0 +1,408 @@ +package gregtech.common.covers; + +import java.util.function.Function; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; + +import com.google.common.io.ByteArrayDataInput; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import gregtech.api.gui.modularui.CoverUIBuildContext; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEBasicBatteryBuffer; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTUtility; +import gregtech.api.util.ISerializableObject; +import gregtech.common.gui.modularui.widget.CoverDataControllerWidget; +import gregtech.common.gui.modularui.widget.CoverDataFollowerCycleButtonWidget; +import gregtech.common.gui.modularui.widget.CoverDataFollowerNumericWidget; +import gregtech.common.gui.modularui.widget.CoverDataFollowerToggleButtonWidget; +import io.netty.buffer.ByteBuf; + +public class CoverEUMeter extends CoverBehaviorBase<CoverEUMeter.EUMeterData> { + + public CoverEUMeter(ITexture coverTexture) { + super(EUMeterData.class, coverTexture); + } + + @Override + public EUMeterData createDataObject(int aLegacyData) { + return new EUMeterData(aLegacyData, 0); + } + + @Override + public EUMeterData createDataObject() { + return new EUMeterData(); + } + + @Override + protected EUMeterData doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, + EUMeterData aCoverVariable, ICoverable aTileEntity, long aTimer) { + final long stored = aCoverVariable.type.getTileEntityStoredEnergy(aTileEntity); + final long capacity = aCoverVariable.type.getTileEntityEnergyCapacity(aTileEntity); + + byte redstoneSignal; + + if (stored == 0L) { + // nothing + redstoneSignal = 0; + } else if (stored >= capacity) { + // full + redstoneSignal = 15; + } else { + // 1-14 range + redstoneSignal = (byte) (1 + (14 * stored) / capacity); + } + + if (aCoverVariable.inverted) { + redstoneSignal = (byte) (15 - redstoneSignal); + } + + if (aCoverVariable.threshold > 0) { + if (aCoverVariable.inverted && stored >= aCoverVariable.threshold) { + redstoneSignal = 0; + } else if (!aCoverVariable.inverted && stored < aCoverVariable.threshold) { + redstoneSignal = 0; + } + } + + aTileEntity.setOutputRedstoneSignal(side, redstoneSignal); + return aCoverVariable; + } + + @Override + protected EUMeterData onCoverScrewdriverClickImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, + ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) { + int num = (aCoverVariable.getNum() + (aPlayer.isSneaking() ? -1 : 1) + EnergyType.values().length * 2) + % (EnergyType.values().length * 2); + switch (num) { + case 0 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("031", "Normal Universal Storage")); + case 1 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("032", "Inverted Universal Storage")); + case 2 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("033", "Normal Electricity Storage")); + case 3 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("034", "Inverted Electricity Storage")); + case 4 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("035", "Normal Steam Storage")); + case 5 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("036", "Inverted Steam Storage")); + case 6 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("037", "Normal Average Electric Input")); + case 7 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("038", "Inverted Average Electric Input")); + case 8 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("039", "Normal Average Electric Output")); + case 9 -> GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("040", "Inverted Average Electric Output")); + case 10 -> GTUtility + .sendChatToPlayer(aPlayer, GTUtility.trans("041", "Normal Electricity Storage(Including Batteries)")); + case 11 -> GTUtility + .sendChatToPlayer(aPlayer, GTUtility.trans("042", "Inverted Electricity Storage(Including Batteries)")); + } + aCoverVariable.setNum(num); + return aCoverVariable; + } + + // region Static Result Methods + @Override + protected boolean isRedstoneSensitiveImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, + ICoverable aTileEntity, long aTimer) { + return false; + } + + @Override + protected boolean letsEnergyInImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, + ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsEnergyOutImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, + ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsFluidInImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsFluidOutImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsItemsInImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsItemsOutImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean manipulatesSidedRedstoneOutputImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, + ICoverable aTileEntity) { + return true; + } + + @Override + protected int getTickRateImpl(ForgeDirection side, int aCoverID, EUMeterData aCoverVariable, + ICoverable aTileEntity) { + return 20; + } + // endregion + + // region GUI Stuff + @Override + public boolean hasCoverGUI() { + return true; + } + + @Override + public ModularWindow createWindow(CoverUIBuildContext buildContext) { + return new EUMeterUIFactory(buildContext).createWindow(); + } + + private class EUMeterUIFactory extends UIFactory { + + private static final int startX = 10; + private static final int startY = 25; + private static final int spaceX = 18; + private static final int spaceY = 18; + + public EUMeterUIFactory(CoverUIBuildContext buildContext) { + super(buildContext); + } + + @SuppressWarnings("PointlessArithmeticExpression") + @Override + protected void addUIWidgets(ModularWindow.Builder builder) { + final String INVERTED = GTUtility.trans("INVERTED", "Inverted"); + final String NORMAL = GTUtility.trans("NORMAL", "Normal"); + + final CoverDataFollowerNumericWidget<EUMeterData> numericWidget = new CoverDataFollowerNumericWidget<>(); + + builder.widget( + new CoverDataControllerWidget<>(this::getCoverData, this::setCoverData, CoverEUMeter.this).addFollower( + new CoverDataFollowerCycleButtonWidget<>(), + coverData -> coverData.type.ordinal(), + (coverData, state) -> { + coverData.type = EnergyType.getEnergyType(state); + return coverData; + }, + widget -> widget.setLength(EnergyType.values().length) + .addTooltip( + state -> EnergyType.getEnergyType(state) + .getTooltip()) + .setStaticTexture(GTUITextures.OVERLAY_BUTTON_CYCLIC) + .setPos(spaceX * 0, spaceY * 0)) + .addFollower( + CoverDataFollowerToggleButtonWidget.ofRedstone(), + coverData -> coverData.inverted, + (coverData, state) -> { + coverData.inverted = state; + return coverData; + }, + widget -> widget.addTooltip(0, NORMAL) + .addTooltip(1, INVERTED) + .setPos(spaceX * 0, spaceY * 1)) + .addFollower(numericWidget, coverData -> (double) coverData.threshold, (coverData, state) -> { + coverData.threshold = state.longValue(); + return coverData; + }, + widget -> widget.setScrollValues(1000, 100, 100000) + .setFocusOnGuiOpen(true) + .setPos(spaceX * 0, spaceY * 2 + 2) + .setSize(spaceX * 8, 12)) + .setPos(startX, startY)) + .widget( + new TextWidget() + .setStringSupplier(() -> getCoverData() != null ? getCoverData().type.getTitle() : "") + .setDefaultColor(COLOR_TEXT_GRAY.get()) + .setPos(startX + spaceX, 4 + startY)) + .widget( + new TextWidget() + .setStringSupplier( + () -> getCoverData() != null ? getCoverData().inverted ? INVERTED : NORMAL : "") + .setDefaultColor(COLOR_TEXT_GRAY.get()) + .setPos(startX + spaceX, 4 + startY + spaceY)) + .widget( + new TextWidget(GTUtility.trans("222.1", "Energy threshold")).setDefaultColor(COLOR_TEXT_GRAY.get()) + .setPos(startX, startY + spaceY * 3 + 4)) + + .widget( + new FakeSyncWidget.LongSyncer( + () -> getCoverData() != null + ? getCoverData().type.getTileEntityEnergyCapacity(getUIBuildContext().getTile()) + : Long.MAX_VALUE, + value -> numericWidget.setMaxValue(value))); + } + } + + // endregion + + public static class EUMeterData implements ISerializableObject { + + private EnergyType type; + private boolean inverted; + /** + * The special value {@code 0} means threshold check is disabled. + */ + private long threshold; + + public EUMeterData() { + type = EnergyType.UNIVERSAL_STORAGE; + inverted = false; + threshold = 0; + } + + public EUMeterData(EnergyType type, boolean inverted, long threshold) { + this.type = type; + this.inverted = inverted; + this.threshold = threshold; + } + + public EUMeterData(int num, long threshold) { + this(); + this.setNum(num); + this.threshold = threshold; + } + + public int getNum() { + return type.ordinal() * 2 + (inverted ? 1 : 0); + } + + public void setNum(int num) { + type = EnergyType.getEnergyType(num / 2); + inverted = num % 2 == 1; + } + + @Nonnull + @Override + public ISerializableObject copy() { + return new EUMeterData(type, inverted, threshold); + } + + @Nonnull + @Override + public NBTBase saveDataToNBT() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setInteger("typeOrdinal", type.ordinal()); + tag.setBoolean("inverted", inverted); + tag.setLong("threshold", threshold); + return tag; + } + + @Override + public void writeToByteBuf(ByteBuf aBuf) { + aBuf.writeInt(type.ordinal()); + aBuf.writeBoolean(inverted); + aBuf.writeLong(threshold); + } + + @Override + public void loadDataFromNBT(NBTBase aNBT) { + NBTTagCompound tag = (NBTTagCompound) aNBT; + int typeOrdinal = tag.getInteger("typeOrdinal"); + type = EnergyType.getEnergyType(typeOrdinal); + inverted = tag.getBoolean("inverted"); + threshold = tag.getLong("threshold"); + } + + @Nonnull + @Override + public ISerializableObject readFromPacket(ByteArrayDataInput aBuf, @Nullable EntityPlayerMP aPlayer) { + int typeOrdinal = aBuf.readInt(); + type = EnergyType.getEnergyType(typeOrdinal); + inverted = aBuf.readBoolean(); + threshold = aBuf.readLong(); + return this; + } + } + + private enum EnergyType { + + UNIVERSAL_STORAGE(GTUtility.trans("301", "Universal"), GTUtility.trans("256", "Universal Storage"), + ICoverable::getUniversalEnergyStored, ICoverable::getUniversalEnergyCapacity), + ELECTRICITY_STORAGE(GTUtility.trans("302", "Int. EU"), GTUtility.trans("257", "Electricity Storage"), + ICoverable::getStoredEU, ICoverable::getEUCapacity), + STEAM_STORAGE(GTUtility.trans("303", "Steam"), GTUtility.trans("258", "Steam Storage"), + ICoverable::getStoredSteam, ICoverable::getSteamCapacity), + AVERAGE_ELECTRIC_INPUT(GTUtility.trans("304", "Avg. Input"), GTUtility.trans("259", "Average Electric Input"), + ICoverable::getAverageElectricInput, (te) -> te.getInputVoltage() * te.getInputAmperage()), + AVERAGE_ELECTRIC_OUTPUT(GTUtility.trans("305", "Avg. Output"), + GTUtility.trans("260", "Average Electric Output"), ICoverable::getAverageElectricOutput, + (te) -> te.getOutputVoltage() * te.getOutputAmperage()), + ELECTRICITY_STORAGE_INCLUDING_BATTERIES(GTUtility.trans("306", "EU stored"), + GTUtility.trans("261", "Electricity Storage(Including Batteries)"), (te) -> { + if (te instanceof IGregTechTileEntity) { + IMetaTileEntity mte = ((IGregTechTileEntity) te).getMetaTileEntity(); + if (mte instanceof MTEBasicBatteryBuffer buffer) { + return buffer.getStoredEnergy()[0]; + } + } + return te.getStoredEU(); + }, (te) -> { + if (te instanceof IGregTechTileEntity) { + IMetaTileEntity mte = ((IGregTechTileEntity) te).getMetaTileEntity(); + if (mte instanceof MTEBasicBatteryBuffer buffer) { + return buffer.getStoredEnergy()[1]; + } + } + return te.getEUCapacity(); + }); + + private final String title; + private final String tooltip; + private final Function<ICoverable, Long> getTileEntityStoredEnergyFunc; + private final Function<ICoverable, Long> getTileEntityEnergyCapacityFunc; + + EnergyType(String title, String tooltip, Function<ICoverable, Long> getTileEntityStoredEnergyFunc, + Function<ICoverable, Long> getTileEntityEnergyCapacityFunc) { + this.title = title; + this.tooltip = tooltip; + this.getTileEntityStoredEnergyFunc = getTileEntityStoredEnergyFunc; + this.getTileEntityEnergyCapacityFunc = getTileEntityEnergyCapacityFunc; + } + + public String getTitle() { + return title; + } + + public String getTooltip() { + return tooltip; + } + + public long getTileEntityStoredEnergy(ICoverable aTileEntity) { + return getTileEntityStoredEnergyFunc.apply(aTileEntity); + } + + public long getTileEntityEnergyCapacity(ICoverable aTileEntity) { + return getTileEntityEnergyCapacityFunc.apply(aTileEntity); + } + + public EnergyType getNext() { + return values()[(ordinal() + 1) % values().length]; + } + + public static EnergyType getEnergyType(int ordinal) { + if (ordinal < 0 || values().length <= ordinal) { + ordinal = 0; + } + return values()[ordinal]; + } + } +} |