Quality Food

Quality Food

56.1k Downloads

[Code]Add some code to de.cadentem.quality_food.mixin.client

Awenlice opened this issue · 1 comments

commented

Hi we meet again.
I have written some appropriate code and hope you will accept it.
This refers to the original item display frame and the store display system of Lightman.
I don't use GitHub very often, so I can only submit the code in this way.

build.gradle
implementation fg.deobf("curse.maven:Lightman-472521:6146349")

ItemFrameRendererMixin
package de.cadentem.quality_food.mixin.client;

import com.mojang.blaze3d.vertex.PoseStack;
import de.cadentem.quality_food.util.OverlayUtils;
import de.cadentem.quality_food.util.QualityUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.ItemFrameRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
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(ItemFrameRenderer.class)
public abstract class ItemFrameRendererMixin {
@Inject(
method = "render(Lnet/minecraft/world/entity/decoration/ItemFrame;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V",
at = @at(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderStatic(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemDisplayContext;IILcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/level/Level;I)V",
shift = At.Shift.AFTER
)
)
private void renderOverlay(ItemFrame entity, float yaw, float delta, PoseStack poseStack, MultiBufferSource buffer, int light, CallbackInfo ci) {
ItemStack stack = entity.getItem();

    if (!QualityUtils.hasQuality(stack) || OverlayUtils.isOverlay(stack)) {
        return;
    }

    ItemStack overlay = OverlayUtils.getOverlay(stack);
    if (overlay.isEmpty()) {
        return;
    }

    poseStack.pushPose();
    poseStack.translate(0.45, 0.25, 0.01);
    poseStack.scale(0.5f, 0.5f, 0.5f);

    Minecraft.getInstance().getItemRenderer().renderStatic(
            overlay,
            ItemDisplayContext.GUI,
            light,
            OverlayTexture.NO_OVERLAY,
            poseStack,
            buffer,
            entity.level(),
            entity.getId()
    );

    poseStack.popPose();
}

}

ItemTraderBlockEntityRendererMixin

package de.cadentem.quality_food.mixin.client;

import com.mojang.blaze3d.vertex.PoseStack;
import de.cadentem.quality_food.util.OverlayUtils;
import de.cadentem.quality_food.util.QualityUtils;
import io.github.lightman314.lightmanscurrency.client.renderer.blockentity.ItemTraderBlockEntityRenderer;
import io.github.lightman314.lightmanscurrency.common.blockentity.trader.ItemTraderBlockEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
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(ItemTraderBlockEntityRenderer.class)
public abstract class ItemTraderBlockEntityRendererMixin {

@Inject(
        method = "renderItems",
        at = @At(
                value = "INVOKE",
                target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderStatic(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemDisplayContext;IILcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/level/Level;I)V",
                shift = At.Shift.AFTER
        )
)
private static void renderQualityOverlay(
        ItemTraderBlockEntity blockEntity,
        float partialTicks,
        PoseStack poseStack,
        MultiBufferSource buffer,
        int lightLevel,
        int id,
        CallbackInfo ci
) {
    // 直接从blockEntity获取显示物品
    ItemStack stack = getDisplayItem(blockEntity);
    if (stack == null || stack.isEmpty() || !QualityUtils.hasQuality(stack) || OverlayUtils.isOverlay(stack)) {
        return;
    }

    ItemStack overlay = OverlayUtils.getOverlay(stack);
    if (overlay.isEmpty()) {
        return;
    }

    poseStack.pushPose();
    poseStack.translate(0.45, 0.25, 0.01);
    poseStack.scale(0.45f, 0.45f, 0.45f);
    Minecraft.getInstance().getItemRenderer().renderStatic(
            overlay,
            ItemDisplayContext.GUI,
            lightLevel,
            OverlayTexture.NO_OVERLAY,
            poseStack,
            buffer,
            blockEntity.getLevel(),
            id
    );
    poseStack.popPose();
}

// 安全获取显示物品的方法
private static ItemStack getDisplayItem(ItemTraderBlockEntity blockEntity) {
    try {
        Object traderData = blockEntity.getClass()
                .getMethod("getTraderData")
                .invoke(blockEntity);

        Object trade = traderData.getClass()
                .getMethod("getTrade", int.class)
                .invoke(traderData, 0);

        return (ItemStack) trade.getClass()
                .getMethod("getItem", int.class)
                .invoke(trade, 0);

    } catch (Exception e) {
        return ItemStack.EMPTY;
    }
}

}