Skip to content

Commit

Permalink
Fix another crash with new tooltip events (MinecraftForge#8155)
Browse files Browse the repository at this point in the history
* Fix another crash with new tooltip events
* Add ItemStack context to ghost recipe tooltip events
* Expand Tooltip Event test mod to add a screen to test all tooltip render methods
  • Loading branch information
diesieben07 authored Oct 17, 2021
1 parent 827ca83 commit f4a827a
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(stack, tooltips, mouseX, f_96543_, f_96544_, this.tooltipFont, this.f_96547_);
+ this.m_169383_(poseStack, components, mouseX, mouseY);
+ this.tooltipFont = null;
+ this.tooltipStack = null;
+ this.tooltipStack = ItemStack.f_41583_;
}

public void m_96617_(PoseStack p_96618_, List<? extends FormattedCharSequence> p_96619_, int p_96620_, int p_96621_) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
this.f_100279_.add(new RecipeBookTabButton(recipebookcategories));
}

@@ -319,7 +_,7 @@
}

if (itemstack != null && this.f_100272_.f_91080_ != null) {
- this.f_100272_.f_91080_.m_96597_(p_100375_, this.f_100272_.f_91080_.m_96555_(itemstack), p_100378_, p_100379_);
+ this.f_100272_.f_91080_.renderComponentTooltip(p_100375_, this.f_100272_.f_91080_.m_96555_(itemstack), p_100378_, p_100379_, itemstack);
}

}
@@ -462,7 +_,7 @@

languagemanager.m_118974_(languageinfo);
Expand Down
205 changes: 203 additions & 2 deletions src/test/java/net/minecraftforge/debug/client/CustomTooltipTest.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,56 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library 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 version 2.1
* of the License.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.minecraftforge.debug.client;

import com.google.common.collect.ImmutableMap;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.datafixers.util.Either;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.font.FontManager;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.packs.resources.ReloadableResourceManager;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.client.event.RenderTooltipEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
Expand All @@ -29,7 +60,9 @@
import net.minecraftforge.registries.ForgeRegistries;

import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Mod(CustomTooltipTest.ID)
Expand All @@ -40,7 +73,10 @@ public class CustomTooltipTest
static final String ID = "custom_tooltip_test";

private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, ID);
static final RegistryObject<Item> CUSTOM_ITEM = ITEMS.register("test_item", () -> new CustomItemWithTooltip(new Item.Properties()));
static final RegistryObject<Item> CUSTOM_ITEM = ITEMS.register(
"test_item",
() -> new CustomItemWithTooltip(new Item.Properties().tab(CreativeModeTab.TAB_MISC))
);

public CustomTooltipTest()
{
Expand Down Expand Up @@ -94,6 +130,16 @@ public void appendHoverText(ItemStack stack, @Nullable Level level, List<Compone
components.add(new TextComponent("This is a very very very very very very long hover text that should really really be split across multiple lines.").withStyle(ChatFormatting.YELLOW));
}

@Override
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand)
{
if (level.isClientSide)
{
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> TooltipTestScreen::show);
}
return InteractionResultHolder.success(player.getItemInHand(hand));
}

@Override
public Optional<TooltipComponent> getTooltipImage(ItemStack stack)
{
Expand All @@ -105,10 +151,19 @@ public Optional<TooltipComponent> getTooltipImage(ItemStack stack)
private static class ClientModBusEventHandler
{

static FontManager customFontManager;
static Font customFont;

@SubscribeEvent
public static void clientSetup(FMLClientSetupEvent event)
{
MinecraftForgeClient.registerTooltipComponentFactory(CustomTooltip.class, CustomClientTooltip::new);
event.enqueueWork(() -> {
customFontManager = new FontManager(Minecraft.getInstance().textureManager);
customFont = customFontManager.createFont();
((ReloadableResourceManager) Minecraft.getInstance().getResourceManager()).registerReloadListener(customFontManager.getReloadListener());
customFontManager.setRenames(ImmutableMap.of(Minecraft.DEFAULT_FONT, Minecraft.UNIFORM_FONT));
});
}

}
Expand Down Expand Up @@ -143,5 +198,151 @@ public static void preTooltip(RenderTooltipEvent.Color event)

}

static class TooltipTestScreen extends Screen
{

private ItemStack testStack = ItemStack.EMPTY;
private Font testFont = null;

protected TooltipTestScreen()
{
super(new TextComponent("TooltipMethodTest"));
}

static void show()
{
Minecraft.getInstance().setScreen(new TooltipTestScreen());
}

@Override
public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks)
{
super.render(poseStack, mouseX, mouseY, partialTicks);
this.font.draw(poseStack, "* must have Stack, # must have custom font", 0, 0, 0xFFFFFF);
}

@Override
protected void init()
{
addRenderableWidget(new Button(10, 10, 200, 20, new TextComponent("Toggle Stack: EMPTY"), button -> {
this.testStack = this.testStack.isEmpty() ? new ItemStack(Items.APPLE) : ItemStack.EMPTY;
button.setMessage(new TextComponent("Toggle Stack: " + (testStack.isEmpty() ? "EMPTY" : "Apple")));
}));

addRenderableWidget(new Button(220, 10, 200, 20, new TextComponent("Toggle Font: null"), button -> {
this.testFont = this.testFont == null ? ClientModBusEventHandler.customFont : null;
button.setMessage(new TextComponent("Toggle Font: " + (testFont == null ? "null" : "customFont")));
}));

// * must have stack context
// # must have custom font
List<Map.Entry<String, Button.OnTooltip>> tooltipTests = Arrays.asList(
Map.entry(" 1 * ", this::test1),
Map.entry(" 2 * ", this::test2),
Map.entry(" 3 #", this::test3),
Map.entry(" 4 *#", this::test4),
Map.entry(" 5 ", this::test5),
Map.entry(" 6 ", this::test6),
Map.entry(" 7 * ", this::test7),
Map.entry(" 8 #", this::test8),
Map.entry(" 9 *#", this::test9),
Map.entry("10 ", this::test10),
Map.entry("11 ", this::test11),
Map.entry("12 #", this::test12),
Map.entry("13 #", this::test13),
Map.entry("14 #", this::test14)
);
int x = 50;
int y = 50;
for (var test : tooltipTests)
{
addRenderableWidget(new Button(x, y, 100, 20, new TextComponent(test.getKey()), button -> {}, test.getValue()));
y+= 22;
if (y >= height - 50)
{
y = 50;
x += 110;
}
}
}

private void test1(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, this.testStack, mouseX, mouseY);
}

// renderTooltip with List<Component> and all combinations of ItemStack/Font
private void test2(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, List.of(new TextComponent("test")), Optional.empty(), mouseX, mouseY, this.testStack);
}

private void test3(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, List.of(new TextComponent("test")), Optional.empty(), mouseX, mouseY, this.testFont);
}

private void test4(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, List.of(new TextComponent("test")), Optional.empty(), mouseX, mouseY, this.testFont, this.testStack);
}

private void test5(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, List.of(new TextComponent("test")), Optional.empty(), mouseX, mouseY);
}

// renderTooltip with just Component
private void test6(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, new TextComponent("test"), mouseX, mouseY);
}

// renderComponentTooltip with all combinations of ItemStack/Font
private void test7(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderComponentTooltip(poseStack, List.of(new TextComponent("test")), mouseX, mouseY, this.testStack);
}

private void test8(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderComponentTooltip(poseStack, List.of(new TextComponent("test")), mouseX, mouseY, this.testFont);
}

private void test9(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderComponentTooltip(poseStack, List.of(new TextComponent("test")), mouseX, mouseY, this.testFont, this.testStack);
}

private void test10(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderComponentTooltip(poseStack, List.of(new TextComponent("test")), mouseX, mouseY);
}

// renderTooltip with list of FormattedCharSequence
private void test11(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, List.of(new TextComponent("test").getVisualOrderText()), mouseX, mouseY);
}

// renderTooltip with list of FormattedCharSequence and Font
private void test12(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderTooltip(poseStack, List.of(new TextComponent("test").getVisualOrderText()), mouseX, mouseY, this.testFont);
}

// legacy ToolTip methods
@SuppressWarnings("removal")
private void test13(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderToolTip(poseStack, List.of(new TextComponent("test").getVisualOrderText()), mouseX, mouseY, this.testFont);
}

@SuppressWarnings("removal")
private void test14(Button button, PoseStack poseStack, int mouseX, int mouseY)
{
renderComponentToolTip(poseStack, List.of(new TextComponent("test")), mouseX, mouseY, this.testFont);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"XX"
],
"key": {
"X": {
"item": "minecraft:apple"
}
},
"result": {
"item": "custom_tooltip_test:test_item"
}
}

0 comments on commit f4a827a

Please sign in to comment.