diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index 944745374ff..e0436526968 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -103,4 +103,10 @@ public class GregtechDataCodes { public static final int UPDATE_ENERGY_PER = 5; public static final int UPDATE_MACHINE = 6; + // Phantom Tanks + public static final int REMOVE_PHANTOM_FLUID_TYPE = 10; + public static final int CHANGE_PHANTOM_FLUID = 11; + public static final int VOID_PHANTOM_FLUID = 12; + public static final int LOAD_PHANTOM_FLUID_STACK_FROM_NBT = 13; + } diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index ce68f9baecb..cffe28cc7a9 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -38,6 +38,9 @@ public class GuiTextures { public static final TextureArea BUTTON_FILTER_NBT = TextureArea.fullImage("textures/gui/widget/button_filter_nbt.png"); public static final TextureArea BUTTON_FLUID_OUTPUT = TextureArea.fullImage("textures/gui/widget/button_fluid_output.png"); public static final TextureArea BUTTON_ITEM_OUTPUT = TextureArea.fullImage("textures/gui/widget/button_item_output.png"); + public static final TextureArea BUTTON_LOCK = TextureArea.fullImage("textures/gui/widget/button_lock.png"); + public static final TextureArea BUTTON_VOID = TextureArea.fullImage("textures/gui/widget/button_void.png"); + public static final TextureArea BUTTON_VOID_PARTIAL = TextureArea.fullImage("textures/gui/widget/button_void_partial.png"); public static final TextureArea BUTTON_LEFT = TextureArea.fullImage("textures/gui/widget/left.png"); public static final TextureArea BUTTON_OVERCLOCK = TextureArea.fullImage("textures/gui/widget/button_overclock.png"); public static final TextureArea BUTTON_PUBLIC_PRIVATE = TextureArea.fullImage("textures/gui/widget/button_public_private.png"); diff --git a/src/main/java/gregtech/api/gui/widgets/PhantomTankWidget.java b/src/main/java/gregtech/api/gui/widgets/PhantomTankWidget.java new file mode 100644 index 00000000000..e11a2ce587f --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/PhantomTankWidget.java @@ -0,0 +1,239 @@ +package gregtech.api.gui.widgets; + +import com.google.common.collect.Lists; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.ingredient.IGhostIngredientTarget; +import gregtech.api.util.GTUtility; +import gregtech.api.util.Position; +import gregtech.api.util.RenderUtil; +import gregtech.api.util.Size; +import mezz.jei.api.gui.IGhostIngredientHandler.Target; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandlerItem; + +import javax.annotation.Nonnull; +import java.awt.*; +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import static gregtech.api.capability.GregtechDataCodes.*; +import static gregtech.api.gui.impl.ModularUIGui.*; + +/** + * Class Designed for the Quantum Tank. Could be used elsewhere, but is very specialized. + */ +public class PhantomTankWidget extends TankWidget implements IGhostIngredientTarget { + + private final FluidTank phantomTank; + + protected FluidStack lastPhantomStack; + + public PhantomTankWidget(IFluidTank fluidTank, int x, int y, int width, int height, FluidTank phantomTank) { + super(fluidTank, x, y, width, height); + this.phantomTank = phantomTank; + } + + @Override + public PhantomTankWidget setClient() { + super.setClient(); + this.lastPhantomStack = phantomTank != null ? phantomTank.getFluid() != null ? phantomTank.getFluid().copy() : null : null; + return this; + } + + @Override + public List> getPhantomTargets(Object ingredient) { + if (lastFluidInTank != null || (!(ingredient instanceof FluidStack) && drainFrom(ingredient) == null)) { + return Collections.emptyList(); + } + + Rectangle rectangle = toRectangleBox(); + return Lists.newArrayList(new Target() { + + @Nonnull + @Override + public Rectangle getArea() { + return rectangle; + } + + @Override + public void accept(@Nonnull Object ingredient) { + FluidStack stack; + if (ingredient instanceof FluidStack) { + stack = (FluidStack) ingredient; + } else { + stack = drainFrom(ingredient); + } + + if (stack != null) { + NBTTagCompound compound = stack.writeToNBT(new NBTTagCompound()); + writeClientAction(LOAD_PHANTOM_FLUID_STACK_FROM_NBT, buf -> buf.writeCompoundTag(compound)); + } + + if (isClient) { + phantomTank.setFluid(stack); + } + } + }); + } + + @Override + public void handleClientAction(int id, PacketBuffer buf) { + super.handleClientAction(id, buf); + if (id == VOID_PHANTOM_FLUID) { + ItemStack stack = gui.entityPlayer.inventory.getItemStack().copy(); + if (!stack.isEmpty()) { + stack.setCount(1); + IFluidHandlerItem fluidHandler = stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + if (fluidHandler != null) { + FluidStack resultStack = fluidHandler.drain(Integer.MAX_VALUE, false); + phantomTank.setFluid(resultStack); + } + } else { + phantomTank.setFluid(null); + } + } else if (id == LOAD_PHANTOM_FLUID_STACK_FROM_NBT) { + FluidStack stack; + try { + stack = FluidStack.loadFluidStackFromNBT(buf.readCompoundTag()); + } catch (IOException e) { + throw new RuntimeException(e); + } + phantomTank.setFluid(stack); + } + } + + @Override + public Object getIngredientOverMouse(int mouseX, int mouseY) { + if (isMouseOverElement(mouseX, mouseY)) { + return lastFluidInTank == null ? lastPhantomStack : lastFluidInTank; + } + return null; + } + + @Override + public boolean mouseClicked(int mouseX, int mouseY, int button) { + if (isMouseOverElement(mouseX, mouseY)) { + writeClientAction(VOID_PHANTOM_FLUID, buf -> {}); + if (isClient) { + phantomTank.setFluid(null); + } + return true; + } + return false; + } + + private FluidStack drainFrom(Object ingredient) { + if (ingredient instanceof ItemStack) { + ItemStack itemStack = (ItemStack) ingredient; + IFluidHandlerItem fluidHandler = itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + if (fluidHandler != null) + return fluidHandler.drain(Integer.MAX_VALUE, false); + } + return null; + } + + @Override + public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { + if (this.lastFluidInTank != null) { + super.drawInBackground(mouseX, mouseY, partialTicks, context); + return; + } + Position pos = getPosition(); + Size size = getSize(); + if (lastPhantomStack != null && !gui.isJEIHandled) { + GlStateManager.disableBlend(); + FluidStack stackToDraw = lastPhantomStack; + if (stackToDraw.amount == 0) { + stackToDraw = GTUtility.copyAmount(1, stackToDraw); + } + RenderUtil.drawFluidForGui(stackToDraw, 1, + pos.x + fluidRenderOffset, pos.y + fluidRenderOffset, + size.width - fluidRenderOffset, size.height - fluidRenderOffset); + GlStateManager.enableBlend(); + GlStateManager.color(rColorForOverlay, gColorForOverlay, bColorForOverlay, 1.0F); + } + } + + @Override + public void drawInForeground(int mouseX, int mouseY) { + if (this.lastFluidInTank == null) return; + super.drawInForeground(mouseX, mouseY); + } + + @Override + public void updateScreen() { + super.updateScreen(); + if (isClient) { + FluidStack stack = phantomTank.getFluid(); + if (stack == null && lastPhantomStack != null) { + lastPhantomStack = null; + } else if (stack != null) { + if (!stack.isFluidEqual(lastPhantomStack)) { + lastPhantomStack = stack.copy(); + } else if (stack.amount != 0) { + lastPhantomStack.amount = 0; + } + } + } + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + FluidStack stack = phantomTank.getFluid(); + if (stack == null && lastPhantomStack != null) { + lastPhantomStack = null; + writeUpdateInfo(REMOVE_PHANTOM_FLUID_TYPE, buf -> {}); + } else if (stack != null) { + if (!stack.isFluidEqual(lastPhantomStack)) { + lastPhantomStack = stack.copy(); + NBTTagCompound stackTag = stack.writeToNBT(new NBTTagCompound()); + writeUpdateInfo(CHANGE_PHANTOM_FLUID, buf -> buf.writeCompoundTag(stackTag)); + } else if (stack.amount != 0) { + lastPhantomStack.amount = 0; + writeUpdateInfo(VOID_PHANTOM_FLUID, buf -> {}); + } + } + } + + @Override + public void readUpdateInfo(int id, PacketBuffer buf) { + super.readUpdateInfo(id, buf); + if (id == REMOVE_PHANTOM_FLUID_TYPE) { + lastPhantomStack = null; + } else if (id == CHANGE_PHANTOM_FLUID) { + NBTTagCompound stackTag; + try { + stackTag = buf.readCompoundTag(); + } catch (IOException ignored) { + return; + } + lastPhantomStack = FluidStack.loadFluidStackFromNBT(stackTag); + } else if (id == VOID_PHANTOM_FLUID) { + lastPhantomStack.amount = 0; + } + } + + public String getFormattedFluidAmount() { + if (lastFluidInTank == null) { + return "0"; + } + return super.getFormattedFluidAmount(); + } + + public String getFluidLocalizedName() { + if (lastFluidInTank == null) { + return lastPhantomStack == null ? "" : lastPhantomStack.getLocalizedName(); + } + return super.getFluidLocalizedName(); + } +} diff --git a/src/main/java/gregtech/api/gui/widgets/TankWidget.java b/src/main/java/gregtech/api/gui/widgets/TankWidget.java index 5385420934d..cc44ccad218 100644 --- a/src/main/java/gregtech/api/gui/widgets/TankWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/TankWidget.java @@ -36,6 +36,7 @@ public class TankWidget extends Widget implements IIngredientSlot { public int fluidRenderOffset = 1; private boolean hideTooltip; private boolean alwaysShowFull; + private boolean drawHoveringText; private boolean allowClickFilling; private boolean allowClickEmptying; @@ -43,13 +44,14 @@ public class TankWidget extends Widget implements IIngredientSlot { private IGuiTexture[] backgroundTexture; private IGuiTexture overlayTexture; - private FluidStack lastFluidInTank; + protected FluidStack lastFluidInTank; private int lastTankCapacity; - private boolean isClient; + protected boolean isClient; public TankWidget(IFluidTank fluidTank, int x, int y, int width, int height) { super(new Position(x, y), new Size(width, height)); this.fluidTank = fluidTank; + this.drawHoveringText = true; } public TankWidget setClient() { @@ -64,6 +66,11 @@ public TankWidget setHideTooltip(boolean hideTooltip) { return this; } + public TankWidget setDrawHoveringText(boolean drawHoveringText) { + this.drawHoveringText = drawHoveringText; + return this; + } + public TankWidget setAlwaysShowFull(boolean alwaysShowFull) { this.alwaysShowFull = alwaysShowFull; return this; @@ -109,7 +116,7 @@ public String getFluidLocalizedName() { } @Override - public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { Position pos = getPosition(); Size size = getSize(); if (backgroundTexture != null) { @@ -118,13 +125,20 @@ public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { } } //do not draw fluids if they are handled by JEI - it draws them itself - if (lastFluidInTank != null && lastFluidInTank.amount > 0 && !gui.isJEIHandled) { + if (lastFluidInTank != null && !gui.isJEIHandled) { GlStateManager.disableBlend(); - RenderUtil.drawFluidForGui(lastFluidInTank, alwaysShowFull ? lastFluidInTank.amount : lastTankCapacity, + FluidStack stackToDraw = lastFluidInTank; + int drawAmount = alwaysShowFull ? lastFluidInTank.amount : lastTankCapacity; + if (alwaysShowFull && lastFluidInTank.amount == 0) { + stackToDraw = lastFluidInTank.copy(); + stackToDraw.amount = 1; + drawAmount = 1; + } + RenderUtil.drawFluidForGui(stackToDraw, drawAmount, pos.x + fluidRenderOffset, pos.y + fluidRenderOffset, size.width - fluidRenderOffset, size.height - fluidRenderOffset); - if (alwaysShowFull && !hideTooltip) { + if (alwaysShowFull && !hideTooltip && drawHoveringText) { GlStateManager.pushMatrix(); GlStateManager.scale(0.5, 0.5, 1); diff --git a/src/main/java/gregtech/api/gui/widgets/ToggleButtonWidget.java b/src/main/java/gregtech/api/gui/widgets/ToggleButtonWidget.java index 12e758756ee..5b01a97d479 100644 --- a/src/main/java/gregtech/api/gui/widgets/ToggleButtonWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/ToggleButtonWidget.java @@ -25,6 +25,7 @@ public class ToggleButtonWidget extends Widget { private final BooleanSupplier isPressedCondition; private final BooleanConsumer setPressedExecutor; private String tooltipText; + private Object[] tooltipArgs; protected boolean isPressed; public ToggleButtonWidget(int xPosition, int yPosition, int width, int height, BooleanSupplier isPressedCondition, BooleanConsumer setPressedExecutor) { @@ -46,9 +47,10 @@ public ToggleButtonWidget setButtonTexture(TextureArea texture) { return this; } - public ToggleButtonWidget setTooltipText(String tooltipText) { + public ToggleButtonWidget setTooltipText(String tooltipText, Object... args) { Preconditions.checkNotNull(tooltipText, "tooltipText"); this.tooltipText = tooltipText; + this.tooltipArgs = args; return this; } @@ -69,7 +71,7 @@ public void drawInForeground(int mouseX, int mouseY) { if (isMouseOverElement(mouseX, mouseY) && tooltipText != null) { String postfix = isPressed ? ".enabled" : ".disabled"; String tooltipHoverString = tooltipText + postfix; - List hoverList = Arrays.asList(I18n.format(tooltipHoverString).split("/n")); + List hoverList = Arrays.asList(I18n.format(tooltipHoverString, tooltipArgs).split("/n")); drawHoveringText(ItemStack.EMPTY, hoverList, 300, mouseX, mouseY); } } diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index c1c5212118c..3e1d5aa317f 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -668,6 +668,7 @@ public static ItemStack copyAmount(int amount, ItemStack... stacks) { } public static FluidStack copyAmount(int amount, FluidStack fluidStack) { + if (fluidStack == null) return null; FluidStack stack = fluidStack.copy(); stack.amount = amount; return stack; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java index 48a439ac3de..62be794ee10 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java @@ -6,13 +6,13 @@ import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import gregtech.api.capability.impl.ThermalFluidHandlerItemStack; import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.recipes.ModHandler; import gregtech.api.render.Textures; import gregtech.api.unification.material.Material; -import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.GTUtility; import gregtech.api.util.WatchedFluidTank; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -26,7 +26,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.Constants; @@ -125,38 +124,8 @@ public void writeItemStackData(NBTTagCompound itemStack) { @Override public ICapabilityProvider initItemStackCapabilities(ItemStack itemStack) { - return new FluidHandlerItemStack(itemStack, tankSize) { - @Override - public FluidStack drain(FluidStack resource, boolean doDrain) { - FluidStack drained = super.drain(resource, doDrain); - this.removeTagWhenEmptied(doDrain); - return drained; - } - - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - FluidStack drained = super.drain(maxDrain, doDrain); - this.removeTagWhenEmptied(doDrain); - return drained; - } - - private void removeTagWhenEmptied(boolean doDrain) { - if (doDrain && this.getFluid() == null) { - this.container.setTagCompound(null); - } - } - - @Override - public boolean canFillFluidType(FluidStack fluid) { - return MetaTileEntityDrum.this.canFillFluidType(fluid); - } - }; - } - - protected boolean canFillFluidType(FluidStack fluid) { - return !ModHandler.isMaterialWood(material) && - !material.hasFlag(FLAMMABLE) || - fluid.getFluid().getTemperature(fluid) <= 325; + int maxTemperature = (ModHandler.isMaterialWood(material) || material.hasFlag(FLAMMABLE)) ? 325 : Integer.MAX_VALUE; + return new ThermalFluidHandlerItemStack(itemStack, tankSize, Integer.MIN_VALUE, maxTemperature); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java index 6d68c39f918..71738ae0435 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java @@ -7,18 +7,20 @@ import codechicken.lib.vec.Matrix4; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IActiveOutputSide; +import gregtech.api.capability.impl.FilteredFluidHandler; import gregtech.api.capability.impl.FluidHandlerProxy; import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ThermalFluidHandlerItemStack; import gregtech.api.cover.ICoverable; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; import gregtech.api.gui.widgets.*; import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.render.Textures; import gregtech.api.util.GTUtility; +import gregtech.api.gui.widgets.PhantomTankWidget; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; @@ -33,7 +35,8 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.Constants; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; @@ -45,15 +48,18 @@ import javax.annotation.Nullable; import java.util.List; -import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_OUTPUT_FLUIDS; -import static gregtech.api.capability.GregtechDataCodes.UPDATE_OUTPUT_FACING; +import static gregtech.api.capability.GregtechDataCodes.*; +import static net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack.FLUID_NBT_KEY; -//todo allow super tanks to fill from machine fluid slots in the gui public class MetaTileEntityQuantumTank extends MetaTileEntity implements ITieredMetaTileEntity, IActiveOutputSide { + // This field (ranging from 1 to 99) is the percentage filled + // at which the Partial Void feature will start voiding Fluids. + private final int VOID_PERCENT = 95; private final int tier; private final int maxFluidCapacity; + private final int maxPartialFluidCapacity; private FluidTank fluidTank; private final ItemStackHandler containerInventory; private boolean autoOutputFluids; @@ -61,10 +67,16 @@ public class MetaTileEntityQuantumTank extends MetaTileEntity implements ITiered private boolean allowInputFromOutputSide = false; protected IFluidHandler outputFluidInventory; + private boolean isLocked; + private boolean isVoiding; + private boolean isPartialVoiding; + private FluidTank lockedFluid; + public MetaTileEntityQuantumTank(ResourceLocation metaTileEntityId, int tier, int maxFluidCapacity) { super(metaTileEntityId); this.tier = tier; this.maxFluidCapacity = maxFluidCapacity; + this.maxPartialFluidCapacity = (int) Math.round(maxFluidCapacity * (VOID_PERCENT / 100.0)); this.containerInventory = new ItemStackHandler(2); initializeInventory(); } @@ -77,7 +89,8 @@ public int getTier() { @Override protected void initializeInventory() { super.initializeInventory(); - this.fluidTank = new FluidTank(maxFluidCapacity); + this.lockedFluid = new FluidTank(1); + this.fluidTank = new FilteredFluidHandler(maxFluidCapacity).setFillPredicate(fs -> lockedFluid.getFluid() == null || fs.isFluidEqual(lockedFluid.getFluid())); this.fluidInventory = fluidTank; this.importFluids = new FluidTankList(false, fluidTank); this.exportFluids = new FluidTankList(false, fluidTank); @@ -98,6 +111,19 @@ public void update() { super.update(); EnumFacing currentOutputFacing = getOutputFacing(); if (!getWorld().isRemote) { + if (isVoiding) { + fluidTank.setFluid(null); + } else if (isPartialVoiding && fluidTank.getFluid() != null) { + if (fluidTank.getFluidAmount() > maxPartialFluidCapacity) { + fluidTank.setFluid(GTUtility.copyAmount(maxPartialFluidCapacity, fluidTank.getFluid())); + } + } + if (isLocked && lockedFluid.getFluid() == null && fluidTank.getFluid() != null) { + this.lockedFluid.setFluid(GTUtility.copyAmount(0, fluidTank.getFluid())); + } + if (lockedFluid.getFluid() != null && !isLocked) { + setLocked(true); + } fillContainerFromInternalTank(containerInventory, containerInventory, 0, 1); fillInternalTankFromFluidContainer(containerInventory, containerInventory, 0, 1); if (isAutoOutputFluids()) { @@ -113,6 +139,10 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setTag("FluidInventory", fluidTank.writeToNBT(new NBTTagCompound())); data.setBoolean("AutoOutputFluids", autoOutputFluids); data.setInteger("OutputFacing", getOutputFacing().getIndex()); + data.setBoolean("IsVoiding", isVoiding); + data.setBoolean("IsPartialVoiding", isPartialVoiding); + data.setBoolean("IsLocked", isLocked); + data.setTag("LockedFluid", lockedFluid.writeToNBT(new NBTTagCompound())); return data; } @@ -123,18 +153,27 @@ public void readFromNBT(NBTTagCompound data) { this.fluidTank.readFromNBT(data.getCompoundTag("FluidInventory")); this.autoOutputFluids = data.getBoolean("AutoOutputFluids"); this.outputFacing = EnumFacing.VALUES[data.getInteger("OutputFacing")]; + this.isVoiding = data.getBoolean("IsVoiding"); + this.isPartialVoiding = data.getBoolean("IsPartialVoiding"); + this.isLocked = data.getBoolean("IsLocked"); + this.lockedFluid.readFromNBT(data.getCompoundTag("LockedFluid")); } @Override public void initFromItemStackData(NBTTagCompound itemStack) { super.initFromItemStackData(itemStack); - fluidTank.readFromNBT(itemStack); + if (itemStack.hasKey(FLUID_NBT_KEY, Constants.NBT.TAG_COMPOUND)) { + fluidTank.setFluid(FluidStack.loadFluidStackFromNBT(itemStack.getCompoundTag(FLUID_NBT_KEY))); + } } @Override public void writeItemStackData(NBTTagCompound itemStack) { super.writeItemStackData(itemStack); - fluidTank.writeToNBT(itemStack); + FluidStack stack = fluidTank.getFluid(); + if (stack != null && stack.amount > 0) { + itemStack.setTag(FLUID_NBT_KEY, stack.writeToNBT(new NBTTagCompound())); + } } @Override @@ -187,43 +226,47 @@ public void addInformation(ItemStack stack, @Nullable World player, List tooltip.add(I18n.format("gregtech.machine.quantum_tank.tooltip")); tooltip.add(I18n.format("gregtech.machine.quantum_tank.capacity", maxFluidCapacity)); NBTTagCompound compound = stack.getTagCompound(); - if (compound != null && compound.hasKey("FluidName")) { - FluidStack fluidStack = new FluidStack(FluidRegistry.getFluid(compound.getString("FluidName")), 1000); - tooltip.add(I18n.format("gregtech.machine.quantum_tank.tooltip.name", fluidStack.getLocalizedName())); - tooltip.add(I18n.format("gregtech.machine.quantum_tank.tooltip.count", compound.getInteger("Amount"))); + if (compound != null && compound.hasKey(FLUID_NBT_KEY, Constants.NBT.TAG_COMPOUND)) { + FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(compound.getCompoundTag(FLUID_NBT_KEY)); + if (fluidStack != null) { + tooltip.add(I18n.format("gregtech.machine.quantum_tank.tooltip.name", fluidStack.getLocalizedName())); + tooltip.add(I18n.format("gregtech.machine.quantum_tank.tooltip.count", fluidStack.amount)); + } } } @Override protected ModularUI createUI(EntityPlayer entityPlayer) { - Builder builder = ModularUI.defaultBuilder(); - int leftButtonStartX = 7; - builder.image(7, 16, 81, 55, GuiTextures.DISPLAY); - TankWidget tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setHideTooltip(true).setAlwaysShowFull(true); - builder.widget(tankWidget); - builder.label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF); - builder.dynamicLabel(11, 30, tankWidget::getFormattedFluidAmount, 0xFFFFFF); - builder.dynamicLabel(11, 40, tankWidget::getFluidLocalizedName, 0xFFFFFF); - return builder.label(6, 6, getMetaFullName()) + TankWidget tankWidget = new PhantomTankWidget(fluidTank, 69, 43, 18, 18, lockedFluid) + .setAlwaysShowFull(true).setDrawHoveringText(false); + + return ModularUI.defaultBuilder() + .widget(new ImageWidget(7, 16, 81, 46, GuiTextures.DISPLAY)) + .widget(new LabelWidget(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF)) + .widget(tankWidget) + .dynamicLabel(11, 30, tankWidget::getFormattedFluidAmount, 0xFFFFFF) + .dynamicLabel(11, 40, tankWidget::getFluidLocalizedName, 0xFFFFFF) + .label(6, 6, getMetaFullName()) .widget(new FluidContainerSlotWidget(containerInventory, 0, 90, 17, false) .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.IN_SLOT_OVERLAY)) - .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) - .widget(new SlotWidget(containerInventory, 1, 90, 54, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)).widget(new ToggleButtonWidget(leftButtonStartX, 53, 18, 18, + .widget(new SlotWidget(containerInventory, 1, 90, 44, true, false) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)) + .widget(new ToggleButtonWidget(7, 64, 18, 18, GuiTextures.BUTTON_FLUID_OUTPUT, this::isAutoOutputFluids, this::setAutoOutputFluids) .setTooltipText("gregtech.gui.fluid_auto_output.tooltip")) + .widget(new ToggleButtonWidget(25, 64, 18, 18, + GuiTextures.BUTTON_LOCK, this::isLocked, this::setLocked) + .setTooltipText("gregtech.gui.fluid_lock.tooltip")) + .widget(new ToggleButtonWidget(43, 64, 18, 18, + GuiTextures.BUTTON_VOID_PARTIAL, this::isPartialVoid, this::setPartialVoid) + .setTooltipText("gregtech.gui.fluid_voiding_partial.tooltip", VOID_PERCENT)) + .widget(new ToggleButtonWidget(61, 64, 18, 18, + GuiTextures.BUTTON_VOID, this::isVoiding, this::setVoiding) + .setTooltipText("gregtech.gui.fluid_voiding_all.tooltip")) .bindPlayerInventory(entityPlayer.inventory) .build(getHolder(), entityPlayer); } - @Override - public void writeInitialSyncData(PacketBuffer buf) { - super.writeInitialSyncData(buf); - buf.writeByte(getOutputFacing().getIndex()); - buf.writeBoolean(autoOutputFluids); - } - public EnumFacing getOutputFacing() { return outputFacing == null ? frontFacing.getOpposite() : outputFacing; } @@ -273,11 +316,20 @@ public boolean isValidFrontFacing(EnumFacing facing) { return super.isValidFrontFacing(facing) && facing != outputFacing; } + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeByte(getOutputFacing().getIndex()); + buf.writeBoolean(autoOutputFluids); + buf.writeBoolean(isLocked); + } + @Override public void receiveInitialSyncData(PacketBuffer buf) { super.receiveInitialSyncData(buf); this.outputFacing = EnumFacing.VALUES[buf.readByte()]; this.autoOutputFluids = buf.readBoolean(); + this.isLocked = buf.readBoolean(); } public void setOutputFacing(EnumFacing outputFacing) { @@ -306,7 +358,11 @@ else if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { return null; } return super.getCapability(capability, side); + } + @Override + public ICapabilityProvider initItemStackCapabilities(ItemStack itemStack) { + return new ThermalFluidHandlerItemStack(itemStack, maxFluidCapacity, Integer.MIN_VALUE, Integer.MAX_VALUE); } @Override @@ -347,6 +403,7 @@ public void setAllowInputFromOutputSide(boolean allowInputFromOutputSide) { markDirty(); } } + public void setAutoOutputFluids(boolean autoOutputFluids) { this.autoOutputFluids = autoOutputFluids; if (!getWorld().isRemote) { @@ -354,4 +411,49 @@ public void setAutoOutputFluids(boolean autoOutputFluids) { markDirty(); } } + + private boolean isLocked() { + return isLocked; + } + + private void setLocked(boolean locked) { + this.isLocked = locked; + if (locked && fluidTank.getFluid() != null) { + this.lockedFluid.setFluid(GTUtility.copyAmount(1, fluidTank.getFluid())); + } + if (!locked && lockedFluid.getFluid() != null) { + this.lockedFluid.setFluid(null); + } + if (!getWorld().isRemote) { + markDirty(); + } + } + + private boolean isVoiding() { + return isVoiding; + } + + private void setVoiding(boolean isVoiding) { + this.isVoiding = isVoiding; + if (isVoiding && isPartialVoiding) { + this.isPartialVoiding = false; + } + if (!getWorld().isRemote) { + markDirty(); + } + } + + private boolean isPartialVoid() { + return isPartialVoiding; + } + + private void setPartialVoid(boolean isPartialVoid) { + this.isPartialVoiding = isPartialVoid; + if (isPartialVoid && isVoiding) { + this.isVoiding = false; + } + if (!getWorld().isRemote) { + markDirty(); + } + } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 65be29c7ae6..e446ac2ae3f 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -3962,6 +3962,12 @@ gregtech.gui.fluid_auto_output.tooltip.enabled=Fluid Auto-Output Enabled gregtech.gui.fluid_auto_output.tooltip.disabled=Fluid Auto-Output Disabled gregtech.gui.item_auto_output.tooltip.enabled=Item Auto-Output Enabled gregtech.gui.item_auto_output.tooltip.disabled=Item Auto-Output Disabled +gregtech.gui.fluid_lock.tooltip.enabled=Fluid Locking Enabled +gregtech.gui.fluid_lock.tooltip.disabled=Fluid Locking Disabled +gregtech.gui.fluid_voiding_partial.tooltip.enabled=Fluid Voiding (Above %d%%) Enabled +gregtech.gui.fluid_voiding_partial.tooltip.disabled=Fluid Voiding (Above %d%%) Disabled +gregtech.gui.fluid_voiding_all.tooltip.enabled=Fluid Voiding (All) Enabled +gregtech.gui.fluid_voiding_all.tooltip.disabled=Fluid Voiding (All) Disabled gregtech.gui.silktouch.enabled=Silk Touch Enabled: Click to Disable./n§7Switching requires an idle machine. gregtech.gui.silktouch.disabled=Silk Touch Disabled: Click to Enable./n§7Switching requires an idle machine. gregtech.gui.chunkmode.enabled=Chunk Mode Enabled: Click to Disable./n§7Switching requires an idle machine. diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_lock.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_lock.png new file mode 100644 index 00000000000..e539a38b2d8 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_lock.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_void.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_void.png new file mode 100644 index 00000000000..b532667a1bd Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_void.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_void_partial.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_void_partial.png new file mode 100644 index 00000000000..912b36f6dac Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_void_partial.png differ