From 95f63bb1d6ba39a01a7124626c051130640d39c4 Mon Sep 17 00:00:00 2001 From: Anthony Hilyard Date: Sat, 30 Oct 2021 10:25:30 -0700 Subject: Added rendertick event, added color results for color event. --- .../iceberg/events/RenderTickEvents.java | 23 +++++ .../iceberg/events/RenderTooltipEvents.java | 8 +- .../iceberg/mixin/LivingEntityMixin.java | 1 - .../iceberg/mixin/MinecraftMixin.java | 31 +++++++ .../anthonyhilyard/iceberg/mixin/ScreenMixin.java | 100 ++++++++++++++++++++- .../com/anthonyhilyard/iceberg/util/Tooltips.java | 8 +- src/main/resources/iceberg.mixins.json | 4 +- 7 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/anthonyhilyard/iceberg/events/RenderTickEvents.java create mode 100644 src/main/java/com/anthonyhilyard/iceberg/mixin/MinecraftMixin.java (limited to 'src/main') diff --git a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTickEvents.java b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTickEvents.java new file mode 100644 index 0000000..dc3a91a --- /dev/null +++ b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTickEvents.java @@ -0,0 +1,23 @@ +package com.anthonyhilyard.iceberg.events; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +public class RenderTickEvents +{ + public RenderTickEvents() { } + + public static final Event START = EventFactory.createArrayBacked(RenderTickEvents.Start.class, + callbacks -> (timer) -> { + for (RenderTickEvents.Start callback : callbacks) + { + callback.onStart(timer); + } + }); + + @FunctionalInterface + public interface Start + { + void onStart(float timer); + } +} diff --git a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java index 1ef654d..7dd58b7 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java +++ b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java @@ -31,10 +31,12 @@ public final class RenderTooltipEvents public static final Event COLOR = EventFactory.createArrayBacked(RenderTooltipEvents.Color.class, callbacks -> (stack, components, poseStack, x, y, font, background, borderStart, borderEnd, comparison) -> { + ColorResult result = new ColorResult(background, borderStart, borderEnd); for (RenderTooltipEvents.Color callback : callbacks) { - callback.onColor(stack, components, poseStack, x, y, font, background, borderStart, borderEnd, comparison); + result = callback.onColor(stack, components, poseStack, x, y, font, result.background, result.borderStart, result.borderEnd, comparison); } + return result; }); public static final Event POST = EventFactory.createArrayBacked(RenderTooltipEvents.Post.class, @@ -54,7 +56,7 @@ public final class RenderTooltipEvents @FunctionalInterface public interface Color { - void onColor(ItemStack stack, List components, PoseStack poseStack, int x, int y, Font font, int background, int borderStart, int borderEnd, boolean comparison); + ColorResult onColor(ItemStack stack, List components, PoseStack poseStack, int x, int y, Font font, int background, int borderStart, int borderEnd, boolean comparison); } @FunctionalInterface @@ -62,4 +64,6 @@ public final class RenderTooltipEvents { void onPost(ItemStack stack, List components, PoseStack poseStack, int x, int y, Font font, int width, int height, boolean comparison); } + + public record ColorResult(int background, int borderStart, int borderEnd) {} } diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/LivingEntityMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/LivingEntityMixin.java index d01df84..09db766 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/mixin/LivingEntityMixin.java +++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/LivingEntityMixin.java @@ -7,7 +7,6 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; -import com.anthonyhilyard.iceberg.Loader; import com.anthonyhilyard.iceberg.events.NewItemPickupCallback; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/MinecraftMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/MinecraftMixin.java new file mode 100644 index 0000000..34d514b --- /dev/null +++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/MinecraftMixin.java @@ -0,0 +1,31 @@ +package com.anthonyhilyard.iceberg.mixin; + +import com.anthonyhilyard.iceberg.events.RenderTickEvents; + +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.Timer; + +@Mixin(Minecraft.class) +public class MinecraftMixin +{ + @Shadow + private boolean pause; + + @Shadow + private float pausePartialTick; + + @Shadow + private Timer timer; + + @Inject(method = "runTick", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = { "ldc=gameRenderer" })) + public void runTick(boolean tickWorld, CallbackInfo callbackInfo) + { + RenderTickEvents.START.invoker().onStart(pause ? pausePartialTick : timer.partialTick); + } +} diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java index fd2abc0..4f6625b 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java +++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java @@ -3,13 +3,20 @@ package com.anthonyhilyard.iceberg.mixin; import java.util.List; import com.anthonyhilyard.iceberg.events.RenderTooltipEvents; +import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorResult; import com.google.common.collect.Lists; +import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.math.Matrix4f; +import org.spongepowered.asm.mixin.Final; 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.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -19,6 +26,7 @@ import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.world.InteractionResult; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; @@ -29,9 +37,99 @@ public class ScreenMixin extends AbstractContainerEventHandler @Shadow protected Font font = null; + @Final @Shadow private final List children = Lists.newArrayList(); + @SuppressWarnings("unchecked") + @Inject(method = "renderTooltipInternal", at = @At(value = "HEAD"), cancellable = true) + private void preRenderTooltipInternal(PoseStack poseStack, List components, int x, int y, CallbackInfo info) + { + Screen self = (Screen)(Object)this; + if (self instanceof AbstractContainerScreen) + { + if (!components.isEmpty()) + { + Slot hoveredSlot = ((AbstractContainerScreen)self).hoveredSlot; + if (hoveredSlot != null) + { + ItemStack tooltipStack = hoveredSlot.getItem(); + if (RenderTooltipEvents.PRE.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, -1, font, false) != InteractionResult.PASS) + { + info.cancel(); + } + } + } + } + } + + @SuppressWarnings("unchecked") + @Redirect(method = "renderTooltipInternal", at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/screens/Screen;fillGradient(Lcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIIIII)V")) + private void fillGradientProxy(Matrix4f matrix4f, BufferBuilder bufferBuilder, int left, int top, int right, int bottom, int zIndex, int colorStart, int colorEnd) + { + Screen self = (Screen)(Object)this; + ItemStack tooltipStack = ItemStack.EMPTY; + if (self instanceof AbstractContainerScreen) + { + Slot hoveredSlot = ((AbstractContainerScreen)self).hoveredSlot; + + if (hoveredSlot != null) + { + tooltipStack = hoveredSlot.getItem(); + } + } + if (tooltipStack == ItemStack.EMPTY) + { + // Do standard functionality if this isn't a container screen. + Screen.fillGradient(matrix4f, bufferBuilder, left, top, right, bottom, zIndex, colorStart, colorEnd); + } + else + { + // Otherwise do nothing to disable the default calls. + } + } + + @SuppressWarnings("unchecked") + @Inject(method = "renderTooltipInternal", at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/screens/Screen;fillGradient(Lcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIIIII)V", shift = Shift.BEFORE), + locals = LocalCapture.CAPTURE_FAILEXCEPTION) + private void preFillGradient(PoseStack poseStack, List components, int x, int y, CallbackInfo info, + int __, int ___, int left, int top, int width, int height, int background, int borderStart, int borderEnd, + int zIndex, float blitOffset, Tesselator tesselator, BufferBuilder bufferBuilder, Matrix4f matrix4f) + { + Screen self = (Screen)(Object)this; + ItemStack tooltipStack = ItemStack.EMPTY; + if (self instanceof AbstractContainerScreen) + { + Slot hoveredSlot = ((AbstractContainerScreen)self).hoveredSlot; + + if (hoveredSlot != null) + { + tooltipStack = hoveredSlot.getItem(); + } + } + + if (tooltipStack != ItemStack.EMPTY) + { + // Do colors now, sure why not. + ColorResult result = RenderTooltipEvents.COLOR.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, borderStart, borderEnd, false); + background = result.background(); + borderStart = result.borderStart(); + borderEnd = result.borderEnd(); + + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 4, left + width + 3, top - 3, zIndex, background, background); + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 3, left + width + 3, top + height + 4, zIndex, background, background); + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top + height + 3, zIndex, background, background); + Screen.fillGradient(matrix4f, bufferBuilder, left - 4, top - 3, left - 3, top + height + 3, zIndex, background, background); + Screen.fillGradient(matrix4f, bufferBuilder, left + width + 3, top - 3, left + width + 4, top + height + 3, zIndex, background, background); + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3 + 1, left - 3 + 1, top + height + 3 - 1, zIndex, borderStart, borderEnd); + Screen.fillGradient(matrix4f, bufferBuilder, left + width + 2, top - 3 + 1, left + width + 3, top + height + 3 - 1, zIndex, borderStart, borderEnd); + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top - 3 + 1, zIndex, borderStart, borderStart); + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 2, left + width + 3, top + height + 3, zIndex, borderEnd, borderEnd); + } + } + @SuppressWarnings("unchecked") @Inject(method = "renderTooltipInternal", at = @At(value = "TAIL"), locals = LocalCapture.CAPTURE_FAILEXCEPTION) private void renderTooltipInternal(PoseStack poseStack, List components, int x, int y, CallbackInfo info, int tooltipWidth, int tooltipHeight, int postX, int postY) @@ -44,7 +142,7 @@ public class ScreenMixin extends AbstractContainerEventHandler if (hoveredSlot != null) { ItemStack tooltipStack = hoveredSlot.getItem(); - RenderTooltipEvents.POST.invoker().onPost(tooltipStack, components, poseStack, x, y, font, tooltipWidth, tooltipHeight, false); + RenderTooltipEvents.POST.invoker().onPost(tooltipStack, components, poseStack, x + 12, y - 12, font, tooltipWidth, tooltipHeight, false); } } } diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java index 6492dfa..c55c5c7 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java +++ b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.List; import com.anthonyhilyard.iceberg.events.RenderTooltipEvents; +import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorResult; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.BufferUploader; import com.mojang.blaze3d.vertex.DefaultVertexFormat; @@ -135,7 +136,6 @@ public class Tooltips renderItemTooltip(stack, mStack, info, rect, screenWidth, screenHeight, backgroundColor, borderColorStart, borderColorEnd, false); } - //private void renderTooltipInternal(PoseStack poseStack, List list, int x, int y) public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info, Rect2i rect, int screenWidth, int screenHeight, int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison) @@ -221,7 +221,11 @@ public class Tooltips int borderStart = 0x505000FF; int borderEnd = 0x5028007F; - RenderTooltipEvents.COLOR.invoker().onColor(stack, info.lines, poseStack, tooltipX, tooltipY, info.getFont(), bgColor, borderStart, borderEnd, comparison); + ColorResult colors = RenderTooltipEvents.COLOR.invoker().onColor(stack, info.lines, poseStack, tooltipX, tooltipY, info.getFont(), bgColor, borderStart, borderEnd, comparison); + + bgColor = colors.background(); + borderStart = colors.borderStart(); + borderEnd = colors.borderEnd(); float f = itemRenderer.blitOffset; itemRenderer.blitOffset = 400.0F; diff --git a/src/main/resources/iceberg.mixins.json b/src/main/resources/iceberg.mixins.json index b5d3ac3..0a3f8d5 100644 --- a/src/main/resources/iceberg.mixins.json +++ b/src/main/resources/iceberg.mixins.json @@ -2,9 +2,11 @@ "required": true, "package": "com.anthonyhilyard.iceberg.mixin", "compatibilityLevel": "JAVA_8", + "verbose": true, "mixins": [ "EntityMixin", - "PlayerAdvancementsMixin" + "PlayerAdvancementsMixin", + "MinecraftMixin" ], "client": [ "ScreenMixin", -- cgit