diff --git a/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java b/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java index dda4d077..20723ee0 100644 --- a/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java +++ b/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java @@ -23,12 +23,15 @@ import com.mojang.blaze3d.vertex.PoseStack; import dev.architectury.event.Event; import dev.architectury.event.EventFactory; import dev.architectury.event.EventResult; +import dev.architectury.impl.TooltipAdditionalContextsImpl; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -51,6 +54,18 @@ public interface ClientTooltipEvent { */ Event RENDER_MODIFY_COLOR = EventFactory.createLoop(); + static AdditionalContexts additionalContexts() { + return TooltipAdditionalContextsImpl.get(); + } + + @ApiStatus.NonExtendable + interface AdditionalContexts { + @Nullable + ItemStack getItem(); + + void setItem(@Nullable ItemStack stack); + } + @Environment(EnvType.CLIENT) interface Item { /** diff --git a/common/src/main/java/dev/architectury/impl/TooltipAdditionalContextsImpl.java b/common/src/main/java/dev/architectury/impl/TooltipAdditionalContextsImpl.java new file mode 100644 index 00000000..3392eca8 --- /dev/null +++ b/common/src/main/java/dev/architectury/impl/TooltipAdditionalContextsImpl.java @@ -0,0 +1,46 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.impl; + +import dev.architectury.event.events.client.ClientTooltipEvent; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +public class TooltipAdditionalContextsImpl implements ClientTooltipEvent.AdditionalContexts { + private static final ThreadLocal INSTANCE_LOCAL = ThreadLocal.withInitial(TooltipAdditionalContextsImpl::new); + + public static ClientTooltipEvent.AdditionalContexts get() { + return INSTANCE_LOCAL.get(); + } + + @Nullable + private ItemStack item; + + @Override + @Nullable + public ItemStack getItem() { + return item; + } + + @Override + public void setItem(@Nullable ItemStack item) { + this.item = item; + } +} diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinScreen.java b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinScreen.java index 3c3c4bc5..3e1ff1c6 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinScreen.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinScreen.java @@ -32,6 +32,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -98,6 +99,16 @@ public abstract class MixinScreen implements ScreenInputDelegate { return message; } + @Inject(method = "renderTooltip(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/world/item/ItemStack;II)V", at = @At("HEAD")) + private void preRenderTooltipItem(PoseStack poseStack, ItemStack stack, int x, int y, CallbackInfo ci) { + ClientTooltipEvent.additionalContexts().setItem(stack); + } + + @Inject(method = "renderTooltip(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/world/item/ItemStack;II)V", at = @At("RETURN")) + private void postRenderTooltipItem(PoseStack poseStack, ItemStack stack, int x, int y, CallbackInfo ci) { + ClientTooltipEvent.additionalContexts().setItem(null); + } + @Inject(method = "renderTooltipInternal", at = @At("HEAD"), cancellable = true) private void renderTooltip(PoseStack poseStack, List list, int x, int y, CallbackInfo ci) { if (!list.isEmpty()) { diff --git a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java index 57b6ecee..f45685ba 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java @@ -171,32 +171,42 @@ public class EventHandlerImplClient { @SubscribeEvent(priority = EventPriority.HIGH) public static void event(RenderTooltipEvent.Pre event) { PoseStack stack = event.getPoseStack(); + ClientTooltipEvent.additionalContexts().setItem(event.getItemStack()); - if (ClientTooltipEvent.RENDER_PRE.invoker().renderTooltip(stack, event.getComponents(), event.getX(), event.getY()).isFalse()) { - event.setCanceled(true); - return; + try { + if (ClientTooltipEvent.RENDER_PRE.invoker().renderTooltip(stack, event.getComponents(), event.getX(), event.getY()).isFalse()) { + event.setCanceled(true); + return; + } + + TooltipEventPositionContextImpl positionContext = tooltipPositionContext.get(); + positionContext.reset(event.getX(), event.getY()); + ClientTooltipEvent.RENDER_MODIFY_POSITION.invoker().renderTooltip(stack, positionContext); + event.setX(positionContext.getTooltipX()); + event.setY(positionContext.getTooltipY()); + } finally { + ClientTooltipEvent.additionalContexts().setItem(null); } - - TooltipEventPositionContextImpl positionContext = tooltipPositionContext.get(); - positionContext.reset(event.getX(), event.getY()); - ClientTooltipEvent.RENDER_MODIFY_POSITION.invoker().renderTooltip(stack, positionContext); - event.setX(positionContext.getTooltipX()); - event.setY(positionContext.getTooltipY()); } @SubscribeEvent(priority = EventPriority.HIGH) public static void event(RenderTooltipEvent.Color event) { PoseStack stack = event.getPoseStack(); + ClientTooltipEvent.additionalContexts().setItem(event.getItemStack()); - TooltipEventColorContextImpl colorContext = tooltipColorContext.get(); - colorContext.reset(); - colorContext.setBackgroundColor(event.getBackgroundStart()); - colorContext.setOutlineGradientTopColor(event.getBorderStart()); - colorContext.setOutlineGradientBottomColor(event.getBorderEnd()); - ClientTooltipEvent.RENDER_MODIFY_COLOR.invoker().renderTooltip(stack, event.getX(), event.getY(), colorContext); - event.setBackground(colorContext.getBackgroundColor()); - event.setBorderEnd(colorContext.getOutlineGradientBottomColor()); - event.setBorderStart(colorContext.getOutlineGradientTopColor()); + try { + TooltipEventColorContextImpl colorContext = tooltipColorContext.get(); + colorContext.reset(); + colorContext.setBackgroundColor(event.getBackgroundStart()); + colorContext.setOutlineGradientTopColor(event.getBorderStart()); + colorContext.setOutlineGradientBottomColor(event.getBorderEnd()); + ClientTooltipEvent.RENDER_MODIFY_COLOR.invoker().renderTooltip(stack, event.getX(), event.getY(), colorContext); + event.setBackground(colorContext.getBackgroundColor()); + event.setBorderEnd(colorContext.getOutlineGradientBottomColor()); + event.setBorderStart(colorContext.getOutlineGradientTopColor()); + } finally { + ClientTooltipEvent.additionalContexts().setItem(null); + } } @SubscribeEvent(priority = EventPriority.HIGH) diff --git a/forge/src/main/java/dev/architectury/mixin/forge/MixinChunkSerializer.java b/forge/src/main/java/dev/architectury/mixin/forge/MixinChunkSerializer.java index 5df87a83..ccdc9739 100644 --- a/forge/src/main/java/dev/architectury/mixin/forge/MixinChunkSerializer.java +++ b/forge/src/main/java/dev/architectury/mixin/forge/MixinChunkSerializer.java @@ -59,7 +59,7 @@ public class MixinChunkSerializer { ChunkDataEvent.Load load = (ChunkDataEvent.Load) event; ((EventHandlerImplCommon.WorldEventAttachment) load).architectury$attachLevel(levelRef.get()); } - level.set(null); + level.remove(); return event; } }