Skip to content

Commit

Permalink
allow quantum tanks to lock their fluids (#278)
Browse files Browse the repository at this point in the history
* allow quantum tanks to lock their fluids

* allow Quantum Tanks to be used in machine fluid slots

Refactor `MetaTileEntityDrum` slightly

* Finish Quantum Tank work

* Add Data Codes to PhantomTankWidget

Co-authored-by: DStrand1 <[email protected]>
Co-authored-by: bruberu <[email protected]>
  • Loading branch information
3 people authored Dec 12, 2021
1 parent 3bc3f34 commit 7d5a1bd
Show file tree
Hide file tree
Showing 12 changed files with 416 additions and 74 deletions.
6 changes: 6 additions & 0 deletions src/main/java/gregtech/api/capability/GregtechDataCodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

}
3 changes: 3 additions & 0 deletions src/main/java/gregtech/api/gui/GuiTextures.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
239 changes: 239 additions & 0 deletions src/main/java/gregtech/api/gui/widgets/PhantomTankWidget.java
Original file line number Diff line number Diff line change
@@ -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<Target<?>> getPhantomTargets(Object ingredient) {
if (lastFluidInTank != null || (!(ingredient instanceof FluidStack) && drainFrom(ingredient) == null)) {
return Collections.emptyList();
}

Rectangle rectangle = toRectangleBox();
return Lists.newArrayList(new Target<Object>() {

@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();
}
}
26 changes: 20 additions & 6 deletions src/main/java/gregtech/api/gui/widgets/TankWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,22 @@ 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;

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() {
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}

Expand All @@ -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<String> hoverList = Arrays.asList(I18n.format(tooltipHoverString).split("/n"));
List<String> hoverList = Arrays.asList(I18n.format(tooltipHoverString, tooltipArgs).split("/n"));
drawHoveringText(ItemStack.EMPTY, hoverList, 300, mouseX, mouseY);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/gregtech/api/util/GTUtility.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 7d5a1bd

Please sign in to comment.