From b13c445253a5c3e5d10fc293f9d9f6f5bc7a1c2b Mon Sep 17 00:00:00 2001 From: Ginger <75683114+gingershaped@users.noreply.github.com> Date: Tue, 4 Jun 2024 01:41:52 -0400 Subject: [PATCH] Make heart types an extensible enum and add an event to modify them (#999) --- .../net/minecraft/client/gui/Gui.java.patch | 41 ++++++++++++--- .../neoforged/neoforge/event/EventHooks.java | 14 ++++++ .../entity/player/PlayerHeartTypeEvent.java | 50 +++++++++++++++++++ .../resources/META-INF/accesstransformer.cfg | 1 + 4 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/event/entity/player/PlayerHeartTypeEvent.java diff --git a/patches/net/minecraft/client/gui/Gui.java.patch b/patches/net/minecraft/client/gui/Gui.java.patch index 494b70bc48..8dac7bc0eb 100644 --- a/patches/net/minecraft/client/gui/Gui.java.patch +++ b/patches/net/minecraft/client/gui/Gui.java.patch @@ -370,15 +370,42 @@ this.toolHighlightTimer = (int)(40.0 * this.minecraft.options.notificationDisplayTime().get()); } else if (this.toolHighlightTimer > 0) { this.toolHighlightTimer--; -@@ -1287,6 +_,11 @@ - p_282761_.drawString(font, SAVING_TEXT, p_282761_.guiWidth() - j - 10, p_282761_.guiHeight() - 15, k); - } +@@ -1289,8 +_,13 @@ } -+ } -+ + } + + @org.jetbrains.annotations.ApiStatus.Internal + public void initModdedOverlays() { + this.layerManager.initModdedLayers(); - } - ++ } ++ @OnlyIn(Dist.CLIENT) +- public static enum HeartType { ++ public static enum HeartType implements net.neoforged.neoforge.common.IExtensibleEnum { + CONTAINER( + new ResourceLocation("hud/heart/container"), + new ResourceLocation("hud/heart/container_blinking"), +@@ -1406,8 +_,23 @@ + } else { + gui$hearttype = NORMAL; + } ++ gui$hearttype = net.neoforged.neoforge.event.EventHooks.firePlayerHeartTypeEvent(p_168733_, gui$hearttype); + + return gui$hearttype; ++ } ++ ++ public static HeartType create( ++ String name, ++ ResourceLocation full, ++ ResourceLocation fullBlinking, ++ ResourceLocation half, ++ ResourceLocation halfBlinking, ++ ResourceLocation hardcoreFull, ++ ResourceLocation hardcoreFullBlinking, ++ ResourceLocation hardcoreHalf, ++ ResourceLocation hardcoreHalfBlinking ++ ) { ++ throw new IllegalStateException("Enum not extended"); + } + } + } diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index 84b4850fa1..7603e0e5be 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -17,6 +17,7 @@ import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementProgress; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; @@ -144,6 +145,7 @@ import net.neoforged.neoforge.event.entity.player.PlayerDestroyItemEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerFlyableFallEvent; +import net.neoforged.neoforge.event.entity.player.PlayerHeartTypeEvent; import net.neoforged.neoforge.event.entity.player.PlayerRespawnPositionEvent; import net.neoforged.neoforge.event.entity.player.PlayerSetSpawnEvent; import net.neoforged.neoforge.event.entity.player.PlayerSpawnPhantomsEvent; @@ -881,6 +883,18 @@ public static void firePlayerSmeltedEvent(Player player, ItemStack smelted) { NeoForge.EVENT_BUS.post(new PlayerEvent.ItemSmeltedEvent(player, smelted)); } + /** + * Called by {@link Gui.HeartType#forPlayer} to allow for modification of the displayed heart type in the + * health bar. + * + * @param player The local {@link Player} + * @param heartType The {@link Gui.HeartType} which would be displayed by vanilla + * @return The heart type which should be displayed + */ + public static Gui.HeartType firePlayerHeartTypeEvent(Player player, Gui.HeartType heartType) { + return NeoForge.EVENT_BUS.post(new PlayerHeartTypeEvent(player, heartType)).getType(); + } + /** * Fires {@link EntityTickEvent.Pre}. Called from the head of {@link LivingEntity#tick()}. * diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerHeartTypeEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerHeartTypeEvent.java new file mode 100644 index 0000000000..7e3cbb4411 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerHeartTypeEvent.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.entity.player; + +import net.minecraft.client.gui.Gui; +import net.minecraft.world.entity.player.Player; + +/** + * Fired by {@link Gui.HeartType#forPlayer} to allow mods to change the heart sprite which is displayed in the player's + * health bar. + * + *
+ * This event is fired only on the client. + */ +public class PlayerHeartTypeEvent extends PlayerEvent { + private final Gui.HeartType originalType; + private Gui.HeartType type; + + public PlayerHeartTypeEvent(Player player, Gui.HeartType type) { + super(player); + this.type = type; + this.originalType = type; + } + + /** + * @return The original heart type which would be displayed by vanilla. + */ + public Gui.HeartType getOriginalType() { + return originalType; + } + + /** + * @return The heart type which will be displayed on the health bar. + */ + public Gui.HeartType getType() { + return type; + } + + /** + * Set the heart sprite which will be displayed on the {@link Player}'s health bar. + * + * @param type The {@link Gui.HeartType} to display + */ + public void setType(Gui.HeartType type) { + this.type = type; + } +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index f32dfde01e..641a191a08 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -93,6 +93,7 @@ protected net.minecraft.client.gui.Gui renderPortalOverlay(Lnet/minecraft/client public net.minecraft.client.gui.Gui renderHotbar(FLnet/minecraft/client/gui/GuiGraphics;)V # renderHotbar public net.minecraft.client.gui.Gui renderEffects(Lnet/minecraft/client/gui/GuiGraphics;)V # renderEffects protected net.minecraft.client.gui.Gui drawBackdrop(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/client/gui/Font;III)V # drawBackdrop +public net.minecraft.client.gui.Gui$HeartType protected net.minecraft.client.gui.components.AbstractButton SPRITES protected net.minecraft.client.gui.components.AbstractSelectionList$Entry list # list protected net.minecraft.client.gui.components.AbstractSliderButton getSprite()Lnet/minecraft/resources/ResourceLocation; # getSprite