Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/main/java/gregtech/api/util/JEIUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package gregtech.api.util;

import net.minecraft.enchantment.EnchantmentData;

import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot;
import com.cleanroommc.modularui.integration.jei.ModularUIJeiPlugin;
import mezz.jei.Internal;

public class JEIUtil {

/**
* Check if the player is currently hovering over a valid ingredient for this slot. <br/>
* Will always return false is JEI is not installed.
*/
public static boolean hoveringOverIngredient(JeiGhostIngredientSlot<?> jeiGhostIngredientSlot) {
if (!Mods.JustEnoughItems.isModLoaded()) return false;
return ModularUIJeiPlugin.hoveringOverIngredient(jeiGhostIngredientSlot);
}

public static Object getBookStackIfEnchantment(Object ingredient) {
if (ingredient instanceof EnchantmentData enchantmentData) {
return Internal.getIngredientRegistry()
.getIngredientHelper(enchantmentData)
.getCheatItemStack(enchantmentData);
}

return ingredient;
}
}
49 changes: 39 additions & 10 deletions src/main/java/gregtech/client/utils/RenderUtil.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package gregtech.client.utils;

import gregtech.api.gui.resources.TextureArea;
import gregtech.api.util.Mods;
import gregtech.api.util.JEIUtil;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
Expand Down Expand Up @@ -29,8 +29,11 @@
import codechicken.lib.vec.Matrix4;
import com.cleanroommc.modularui.api.MCHelper;
import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.drawable.GuiDraw;
import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot;
import com.cleanroommc.modularui.integration.jei.ModularUIJeiPlugin;
import com.cleanroommc.modularui.theme.WidgetSlotTheme;
import com.cleanroommc.modularui.theme.WidgetTheme;
import com.cleanroommc.modularui.utils.Color;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.opengl.GL11;
Expand All @@ -43,6 +46,7 @@
public class RenderUtil {

private static final Deque<int[]> scissorFrameStack = new ArrayDeque<>();
public static final int defaultSlotHoverColor = Color.withAlpha(Color.WHITE.main, 0x60);

public static void useScissor(int x, int y, int width, int height, Runnable codeBlock) {
pushScissorFrame(x, y, width, height);
Expand Down Expand Up @@ -716,14 +720,39 @@ public void put(int element, float @NotNull... data) {
return getTextureMap().getMissingSprite();
}

public static void handleJeiGhostHighlight(IWidget slot) {
if (!Mods.JustEnoughItems.isModLoaded()) return;
if (!(slot instanceof JeiGhostIngredientSlot<?>ingredientSlot)) return;
if (ModularUIJeiPlugin.hasDraggingGhostIngredient() ||
ModularUIJeiPlugin.hoveringOverIngredient(ingredientSlot)) {
GlStateManager.colorMask(true, true, true, false);
ingredientSlot.drawHighlight(slot.getArea(), slot.isHovering());
GlStateManager.colorMask(true, true, true, true);
public static void drawSlotOverlay(@NotNull IWidget slot, int overlayColor) {
GlStateManager.colorMask(true, true, true, false);
GuiDraw.drawRect(1, 1, slot.getArea().w() - 2, slot.getArea().h() - 2, overlayColor);
GlStateManager.colorMask(true, true, true, true);
}

public static void drawSlotOverlay(@NotNull IWidget slot, WidgetTheme widgetTheme) {
drawSlotOverlay(slot, widgetTheme instanceof WidgetSlotTheme slotTheme ? slotTheme.getSlotHoverColor() :
defaultSlotHoverColor);
}

public static void handleSlotOverlay(@NotNull IWidget slot, @NotNull WidgetTheme widgetTheme) {
if (slot.isHovering()) {
drawSlotOverlay(slot, widgetTheme);
}
}

public static <
T extends IWidget & JeiGhostIngredientSlot<?>> void drawJEIGhostSlotOverlay(@NotNull T jeiGhostIngredientSlot) {
GlStateManager.colorMask(true, true, true, false);
jeiGhostIngredientSlot.drawHighlight(jeiGhostIngredientSlot.getArea(), jeiGhostIngredientSlot.isHovering());
GlStateManager.colorMask(true, true, true, true);
}

public static <
T extends IWidget & JeiGhostIngredientSlot<?>> boolean handleJEIGhostSlotOverlay(@NotNull T jeiGhostIngredientSlot,
@NotNull WidgetTheme widgetTheme) {
if (JEIUtil.hoveringOverIngredient(jeiGhostIngredientSlot)) {
drawJEIGhostSlotOverlay(jeiGhostIngredientSlot);
return true;
}

handleSlotOverlay(jeiGhostIngredientSlot, widgetTheme);
return false;
}
}
9 changes: 1 addition & 8 deletions src/main/java/gregtech/common/mui/widget/GTFluidSlot.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import gregtech.api.util.GTUtility;
import gregtech.client.utils.RenderUtil;

import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
Expand Down Expand Up @@ -116,13 +115,7 @@ public void draw(ModularGuiContext context, WidgetSlotTheme widgetTheme) {
this.textRenderer.draw(amount);
}

if (isHovering()) {
GlStateManager.colorMask(true, true, true, false);
GuiDraw.drawRect(1, 1, getArea().w() - 2, getArea().h() - 2, widgetTheme.getSlotHoverColor());
GlStateManager.colorMask(true, true, true, true);
}

RenderUtil.handleJeiGhostHighlight(this);
RenderUtil.handleJEIGhostSlotOverlay(this, widgetTheme);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gregtech.common.mui.widget.workbench;

import gregtech.api.util.GTUtility;
import gregtech.api.util.JEIUtil;
import gregtech.client.utils.RenderUtil;
import gregtech.common.metatileentities.storage.CraftingRecipeLogic;

Expand Down Expand Up @@ -102,15 +103,21 @@ public void onMouseDrag(int mouseButton, long timeSinceClick) {
@Override
public void draw(ModularGuiContext context, WidgetTheme widgetTheme) {
ItemStack itemstack = this.syncHandler.getStack();
boolean jeiIngredientBeingHovered = JEIUtil.hoveringOverIngredient(this);

if (!itemstack.isEmpty()) {
if (!this.hasIngredients) {
if (!jeiIngredientBeingHovered && !this.hasIngredients) {
RenderUtil.renderRect(0, 0, 18, 18, 200, 0x80FF0000);
}

RenderUtil.renderItem(itemstack, 1, 1, 16, 16);
}

RenderUtil.handleJeiGhostHighlight(this);
if (jeiIngredientBeingHovered) {
RenderUtil.drawJEIGhostSlotOverlay(this);
} else {
RenderUtil.handleSlotOverlay(this, widgetTheme);
}
}

@Override
Expand All @@ -128,6 +135,7 @@ public void setGhostIngredient(@NotNull ItemStack ingredient) {

@Override
public @Nullable ItemStack castGhostIngredientIfValid(@NotNull Object ingredient) {
ingredient = JEIUtil.getBookStackIfEnchantment(ingredient);
return areAncestorsEnabled() && ingredient instanceof ItemStack ? (ItemStack) ingredient : null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,8 @@ public boolean isValidSyncHandler(SyncHandler syncHandler) {
@Override
public void draw(ModularGuiContext context, WidgetTheme widgetTheme) {
ItemStack itemstack = this.syncHandler.getOutputStack();
if (itemstack.isEmpty()) return;

RenderUtil.renderItem(itemstack, 1, 1, 16, 16);
RenderUtil.handleSlotOverlay(this, widgetTheme);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,23 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) {

@Override
public void draw(ModularGuiContext context, WidgetTheme widgetTheme) {
ItemStack itemstack = this.memory.getRecipeOutputAtIndex(this.index);
if (itemstack.isEmpty()) return;

int cachedCount = itemstack.getCount();
itemstack.setCount(1); // required to not render the amount overlay
RenderUtil.renderItem(itemstack, 1, 1, 16, 16);
itemstack.setCount(cachedCount);

// noinspection DataFlowIssue
if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) {
GlStateManager.disableDepth();
GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme);
GlStateManager.enableDepth();
ItemStack itemStack = this.memory.getRecipeOutputAtIndex(this.index);

if (!itemStack.isEmpty()) {
int cachedCount = itemStack.getCount();
itemStack.setCount(1); // required to not render the amount overlay
RenderUtil.renderItem(itemStack, 1, 1, 16, 16);
itemStack.setCount(cachedCount);

// noinspection DataFlowIssue
if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) {
GlStateManager.disableDepth();
GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme);
GlStateManager.enableDepth();
}
}

RenderUtil.handleSlotOverlay(this, widgetTheme);
}

@Override
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/gregtech/mixins/mui2/ItemSlotMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package gregtech.mixins.mui2;

import gregtech.api.util.JEIUtil;

import net.minecraft.item.ItemStack;

import com.cleanroommc.modularui.integration.jei.ModularUIJeiPlugin;
import com.cleanroommc.modularui.widgets.ItemSlot;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import mezz.jei.gui.ghost.GhostIngredientDrag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

// TODO: remove once MUI PR 146 merges into a release we use
@Mixin(value = ItemSlot.class, remap = false)
public abstract class ItemSlotMixin {

@Shadow
public abstract @Nullable ItemStack castGhostIngredientIfValid(@NotNull Object ingredient);

@Redirect(method = "draw",
at = @At(value = "INVOKE",
target = "Lcom/cleanroommc/modularui/integration/jei/ModularUIJeiPlugin;hasDraggingGhostIngredient()Z"))
private boolean onlyHighlightOnValidDrag() {
GhostIngredientDrag<?> ingredientDrag = ModularUIJeiPlugin.getGhostDrag();
if (ingredientDrag == null) return false;
Object ingredient = ingredientDrag.getIngredient();
if (ingredient == null) return false;
return castGhostIngredientIfValid(ingredient) != null;
}

@WrapMethod(method = "castGhostIngredientIfValid(Ljava/lang/Object;)Lnet/minecraft/item/ItemStack;")
public @Nullable ItemStack addSupportForEnchantedBooks(Object ingredient, Operation<ItemStack> original) {
return original.call(JEIUtil.getBookStackIfEnchantment(ingredient));
}
}
22 changes: 22 additions & 0 deletions src/main/java/gregtech/mixins/mui2/ModularUIJeiPluginMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package gregtech.mixins.mui2;

import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot;
import com.cleanroommc.modularui.integration.jei.ModularUIJeiPlugin;
import mezz.jei.config.Config;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(value = ModularUIJeiPlugin.class)
public class ModularUIJeiPluginMixin {

// TODO: remove this mixin when the fix from Brachy makes it into a release we use
@Inject(method = "hoveringOverIngredient", at = @At(value = "HEAD"), remap = false, cancellable = true)
private static void cancelIfCheatsOn(JeiGhostIngredientSlot<?> ingredientSlot,
CallbackInfoReturnable<Boolean> cir) {
if (Config.isCheatItemsEnabled()) {
cir.setReturnValue(false);
}
}
}
4 changes: 3 additions & 1 deletion src/main/resources/mixins.gregtech.mui2.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"RichTextCompilerMixin"
],
"client": [
"LangKeyMixin"
"LangKeyMixin",
"ModularUIJeiPluginMixin",
"ItemSlotMixin"
],
"server": []
}
Loading