From b42e397365b296c03a2f56d4ed6f7a145bf437ac Mon Sep 17 00:00:00 2001 From: Julian Lechner Date: Tue, 14 Jul 2026 15:27:23 +0200 Subject: [PATCH] feat: pass cosmetic data through avatar render state --- .../citrusDev/mixin/AvatarRendererMixin.java | 38 +++++++++++++++++++ .../mixin/LivingEntityRendererMixin.java | 32 ++++++++++++++++ src/main/resources/citrus-dev.mixins.json | 2 + 3 files changed, 72 insertions(+) create mode 100644 src/main/java/de/fullrisk/citrusDev/mixin/AvatarRendererMixin.java create mode 100644 src/main/java/de/fullrisk/citrusDev/mixin/LivingEntityRendererMixin.java diff --git a/src/main/java/de/fullrisk/citrusDev/mixin/AvatarRendererMixin.java b/src/main/java/de/fullrisk/citrusDev/mixin/AvatarRendererMixin.java new file mode 100644 index 0000000..4ca7dc4 --- /dev/null +++ b/src/main/java/de/fullrisk/citrusDev/mixin/AvatarRendererMixin.java @@ -0,0 +1,38 @@ +package de.fullrisk.citrusDev.mixin; + +import de.fullrisk.citrusDev.client.cosmetic.CosmeticData; +import de.fullrisk.citrusDev.client.cosmetic.CosmeticRenderData; +import de.fullrisk.citrusDev.client.cosmetic.CosmeticRenderStateKeys; +import de.fullrisk.citrusDev.client.cosmetic.PlayerCosmeticManager; +import net.minecraft.client.renderer.entity.player.AvatarRenderer; +import net.minecraft.client.renderer.entity.state.AvatarRenderState; +import net.minecraft.world.entity.Avatar; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.UUID; + +@Mixin(AvatarRenderer.class) +abstract class AvatarRendererMixin { + @Inject( + method = "extractRenderState(Lnet/minecraft/world/entity/Avatar;Lnet/minecraft/client/renderer/entity/state/AvatarRenderState;F)V", + at = @At("TAIL") + ) + private void citrus$extractCosmetic( + Avatar avatar, + AvatarRenderState state, + float partialTick, + CallbackInfo callbackInfo + ) { + UUID playerId = avatar.getUUID(); + CosmeticData cosmetic = PlayerCosmeticManager.getCosmetic(playerId) + .filter(CosmeticData::visible) + .orElse(null); + state.setData( + CosmeticRenderStateKeys.COSMETIC, + cosmetic == null ? null : new CosmeticRenderData(playerId, cosmetic, partialTick) + ); + } +} diff --git a/src/main/java/de/fullrisk/citrusDev/mixin/LivingEntityRendererMixin.java b/src/main/java/de/fullrisk/citrusDev/mixin/LivingEntityRendererMixin.java new file mode 100644 index 0000000..f492e06 --- /dev/null +++ b/src/main/java/de/fullrisk/citrusDev/mixin/LivingEntityRendererMixin.java @@ -0,0 +1,32 @@ +package de.fullrisk.citrusDev.mixin; + +import com.mojang.blaze3d.vertex.PoseStack; +import de.fullrisk.citrusDev.client.cosmetic.CosmeticRenderStateKeys; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.state.AvatarRenderState; +import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; +import net.minecraft.client.renderer.state.level.CameraRenderState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LivingEntityRenderer.class) +abstract class LivingEntityRendererMixin { + @Inject( + method = "submit(Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/CameraRenderState;)V", + at = @At("HEAD") + ) + private void citrus$captureAvatarCamera( + LivingEntityRenderState state, + PoseStack poseStack, + SubmitNodeCollector nodeCollector, + CameraRenderState cameraRenderState, + CallbackInfo callbackInfo + ) { + if (state instanceof AvatarRenderState avatarState) { + avatarState.setData(CosmeticRenderStateKeys.CAMERA, cameraRenderState); + } + } +} diff --git a/src/main/resources/citrus-dev.mixins.json b/src/main/resources/citrus-dev.mixins.json index 4f48afb..13c2871 100644 --- a/src/main/resources/citrus-dev.mixins.json +++ b/src/main/resources/citrus-dev.mixins.json @@ -6,8 +6,10 @@ "mixins": [ ], "client": [ + "AvatarRendererMixin", "HitboxColorMixin", "LightmapRenderStateExtractorMixin", + "LivingEntityRendererMixin", "MouseHandlerMixin", "OwnNametagMixin", "PlayerNametagMixin",