Skip to content

Commit

Permalink
[1.21.4] Fix IClientItemExtensions#renderHelmetOverlay never being ca…
Browse files Browse the repository at this point in the history
…lled (#1837)
  • Loading branch information
IThundxr authored Jan 14, 2025
1 parent 9d2c3aa commit 6bbd94a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
15 changes: 15 additions & 0 deletions patches/net/minecraft/client/gui/Gui.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,21 @@
}

private void renderCameraOverlays(GuiGraphics p_316735_, DeltaTracker p_348538_) {
@@ -236,8 +_,12 @@
for (EquipmentSlot equipmentslot : EquipmentSlot.values()) {
ItemStack itemstack = this.minecraft.player.getItemBySlot(equipmentslot);
Equippable equippable = itemstack.get(DataComponents.EQUIPPABLE);
- if (equippable != null && equippable.slot() == equipmentslot && equippable.cameraOverlay().isPresent()) {
- this.renderTextureOverlay(p_316735_, equippable.cameraOverlay().get().withPath(p_380782_ -> "textures/" + p_380782_ + ".png"), 1.0F);
+ if (equippable != null && equippable.slot() == equipmentslot) {
+ if (equippable.cameraOverlay().isPresent()) {
+ this.renderTextureOverlay(p_316735_, equippable.cameraOverlay().get().withPath(p_380782_ -> "textures/" + p_380782_ + ".png"), 1.0F);
+ }
+
+ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack).renderFirstPersonOverlay(itemstack, equipmentslot, this.minecraft.player, p_316735_, p_348538_);
}
}
}
@@ -289,8 +_,12 @@
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
package net.neoforged.neoforge.client.extensions.common;

import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.Model;
import net.minecraft.client.player.LocalPlayer;
Expand All @@ -23,6 +25,7 @@
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.DyedItemColor;
import net.minecraft.world.item.equipment.Equippable;
import net.neoforged.fml.LogicalSide;
import net.neoforged.neoforge.client.ClientHooks;
import net.neoforged.neoforge.client.IArmPoseTransformer;
Expand Down Expand Up @@ -142,17 +145,22 @@ default Model getGenericArmorModel(ItemStack itemStack, EquipmentClientInfo.Laye
default void setupModelAnimations(LivingEntity livingEntity, ItemStack itemStack, EquipmentSlot equipmentSlot, Model model, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) {}

/**
* Called when the client starts rendering the HUD, and is wearing this item in the helmet slot.
* Called to render an overlay on the first-person camera.
* <p>
* This is where pumpkins would render their overlay.
* This method will always be called to render an overlay, regardless of whether the client camera overlay provided
* by the {@link DataComponents#EQUIPPABLE Equippable data component} is present. If the equippable overlay is present
* (e.g. the pumpkin overlay), this method will be called after it has been rendered.
* <p>
* This method should be used if the overlay is dynamic or has dynamic components.
* For a static overlay, prefer using {@link Equippable#cameraOverlay()}.
*
* @param stack The item stack
* @param player The player entity
* @param width The viewport width
* @param height Viewport height
* @param partialTick Partial tick time, useful for interpolation
* @param stack The item stack that the player is wearing
* @param equipmentSlot The slot in which the player is wearing or holding the above item stack
* @param player The player entity
* @param guiGraphics The gui graphics
* @param deltaTracker The delta tracker
*/
default void renderHelmetOverlay(ItemStack stack, Player player, int width, int height, float partialTick) {}
default void renderFirstPersonOverlay(ItemStack stack, EquipmentSlot equipmentSlot, Player player, GuiGraphics guiGraphics, DeltaTracker deltaTracker) {}

/**
* {@return Whether the item should bob when rendered in the world as an entity}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
import java.nio.ByteBuffer;
import java.util.concurrent.CompletableFuture;
import javax.sound.sampled.AudioFormat;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.resources.sounds.AbstractSoundInstance;
Expand All @@ -21,15 +24,21 @@
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.neoforge.client.event.ClientChatEvent;
import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import net.neoforged.neoforge.client.event.TextureAtlasStitchedEvent;
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent;
import net.neoforged.neoforge.common.data.LanguageProvider;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.testframework.DynamicTest;
import net.neoforged.testframework.annotation.ForEachTest;
import net.neoforged.testframework.annotation.TestHolder;
Expand Down Expand Up @@ -107,6 +116,33 @@ static void namespacedDirectoryListerTest(final DynamicTest test) {
});
}

@TestHolder(description = "Tests that helmets with custom rendering work", enabledByDefault = true)
static void customHelmetRendering(final DynamicTest test) {
var item = test.registrationHelper().items().registerItem("neo_helmet", properties -> new Item(properties.equippable(EquipmentSlot.HEAD)));
test.framework().modEventBus().addListener((final RegisterClientExtensionsEvent event) -> {
event.registerItem(new IClientItemExtensions() {
@Override
public void renderFirstPersonOverlay(ItemStack stack, EquipmentSlot equipmentSlot, Player player, GuiGraphics guiGraphics, DeltaTracker deltaTracker) {
guiGraphics.blit(
RenderType::guiTexturedOverlay,
ResourceLocation.withDefaultNamespace("textures/block/stone.png"),
0,
0,
0,
0,
guiGraphics.guiWidth(),
guiGraphics.guiHeight(),
guiGraphics.guiWidth(),
guiGraphics.guiHeight(),
-1);
}
}, item);
});
test.eventListeners().forge().addListener((final PlayerEvent.PlayerLoggedInEvent event) -> {
test.requestConfirmation(event.getEntity(), Component.literal("Does stone cover the screen when wearing the *_custom_helmet_rendering:neo_helmet?"));
});
}

private static final class SineSound extends AbstractSoundInstance {
SineSound(Vec3 position) {
super(ResourceLocation.fromNamespaceAndPath("neotests_audio_stream_test", "sine_wave"), SoundSource.BLOCKS, SoundInstance.createUnseededRandom());
Expand Down

0 comments on commit 6bbd94a

Please sign in to comment.