From f9bb00a7e7a0f320fd81881adc3b645ca5d582e8 Mon Sep 17 00:00:00 2001 From: Dane Strandboge Date: Sat, 10 Dec 2022 18:17:26 -0600 Subject: [PATCH] fix patterns not respecting item models and colors... (#193) when shift key is held and the "output" item in the pattern is rendered instead of the base pattern texture Consequences: - The "output" item of the pattern will now be rendered always when shift is held, not just when the TransformType is GUI. - This means that you will see the "output" item now for in-world patterns, as well as the rendered model in the player's hand or offhand - However, I honestly think this is an improvement from before --- src/main/java/appeng/client/ClientHelper.java | 5 + .../ItemEncodedPatternBakedModel.java | 105 +++--------------- 2 files changed, 20 insertions(+), 90 deletions(-) diff --git a/src/main/java/appeng/client/ClientHelper.java b/src/main/java/appeng/client/ClientHelper.java index 912425100..91af9bd96 100644 --- a/src/main/java/appeng/client/ClientHelper.java +++ b/src/main/java/appeng/client/ClientHelper.java @@ -23,6 +23,7 @@ import appeng.api.parts.CableRenderMode; import appeng.api.util.AEColor; import appeng.block.AEBaseBlock; import appeng.client.gui.AEBaseGui; +import appeng.client.render.crafting.ItemEncodedPatternBakedModel; import appeng.client.render.effects.*; import appeng.client.render.model.UVLModelLoader; import appeng.client.render.tesr.InscriberTESR; @@ -30,6 +31,7 @@ import appeng.client.render.textures.ParticleTextures; import appeng.container.interfaces.IJEIGhostIngredients; import appeng.core.AEConfig; import appeng.core.AELog; +import appeng.core.Api; import appeng.core.AppEng; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketAssemblerAnimation; @@ -96,6 +98,9 @@ public class ClientHelper extends ServerHelper { ClientRegistry.registerKeyBinding(binding); this.bindings.put(key, binding); } + + Api.INSTANCE.definitions().items().encodedPattern().maybeItem().ifPresent(pattern -> + Minecraft.getMinecraft().getItemColors().registerItemColorHandler(ItemEncodedPatternBakedModel.PATTERN_ITEM_COLOR_HANDLER, pattern)); } @SubscribeEvent diff --git a/src/main/java/appeng/client/render/crafting/ItemEncodedPatternBakedModel.java b/src/main/java/appeng/client/render/crafting/ItemEncodedPatternBakedModel.java index 5c914faab..8b8a676bd 100644 --- a/src/main/java/appeng/client/render/crafting/ItemEncodedPatternBakedModel.java +++ b/src/main/java/appeng/client/render/crafting/ItemEncodedPatternBakedModel.java @@ -5,11 +5,11 @@ import appeng.items.misc.ItemEncodedPattern; import com.google.common.collect.ImmutableMap; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.color.IItemColor; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; @@ -32,13 +32,22 @@ import java.util.List; * the pattern is being * rendered in the GUI, and not anywhere else. */ -class ItemEncodedPatternBakedModel implements IBakedModel { +public class ItemEncodedPatternBakedModel implements IBakedModel { private final IBakedModel baseModel; private final ImmutableMap transforms; private final CustomOverrideList overrides; + public static final IItemColor PATTERN_ITEM_COLOR_HANDLER = (stack, tintIndex) -> { + ItemEncodedPattern iep = (ItemEncodedPattern) stack.getItem(); + ItemStack output = iep.getOutput(stack); + if (!output.isEmpty() && isShiftKeyDown()) { + return Minecraft.getMinecraft().getItemColors().colorMultiplier(output, tintIndex); + } + return 0xFFFFFF; + }; + ItemEncodedPatternBakedModel(IBakedModel baseModel, ImmutableMap transforms) { this.baseModel = baseModel; this.transforms = transforms; @@ -90,88 +99,8 @@ class ItemEncodedPatternBakedModel implements IBakedModel { return PerspectiveMapWrapper.handlePerspective(this, this.transforms, cameraTransformType); } - /** - * Since the ItemOverrideList handling comes before handling the perspective awareness (which is the first place - * where we - * know how we are being rendered) we need to remember the model of the crafting output, and make the decision on - * which to render later on. - * Sadly, Forge is pretty inconsistent when it will call the handlePerspective method, so some methods are called - * even on this interim-model. - * Usually those methods only matter for rendering on the ground and other cases, where we wouldn't render the - * crafting output model anyway, - * so in those cases we delegate to the model of the encoded pattern. - */ - private class ShiftHoldingModelWrapper implements IBakedModel { - - private final IBakedModel outputModel; - - private ShiftHoldingModelWrapper(IBakedModel outputModel) { - this.outputModel = outputModel; - } - - @Override - public Pair handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) { - final IBakedModel selectedModel; - - // No need to re-check for shift being held since this model is only handed out in that case - if (cameraTransformType == ItemCameraTransforms.TransformType.GUI) { - selectedModel = this.outputModel; - } else { - selectedModel = ItemEncodedPatternBakedModel.this.baseModel; - } - - // Now retroactively handle the isGui3d call, for which we always return false below - if (selectedModel.isGui3d() != ItemEncodedPatternBakedModel.this.baseModel.isGui3d()) { - GlStateManager.enableLighting(); - } - - if (selectedModel instanceof IBakedModel) { - return selectedModel.handlePerspective(cameraTransformType); - } - - return PerspectiveMapWrapper.handlePerspective(this, ItemEncodedPatternBakedModel.this.transforms, cameraTransformType); - } - - @Override - public List getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) { - // This may be called for items on the ground, in which case we will always fall back to the pattern - return ItemEncodedPatternBakedModel.this.baseModel.getQuads(state, side, rand); - } - - @Override - public boolean isAmbientOcclusion() { - return ItemEncodedPatternBakedModel.this.baseModel.isAmbientOcclusion(); - } - - @Override - public boolean isGui3d() { - // NOTE: Sadly, Forge will let Minecraft call this method before handling the perspective awareness - return ItemEncodedPatternBakedModel.this.baseModel.isGui3d(); - } - - @Override - public boolean isBuiltInRenderer() { - // This may be called for items on the ground, in which case we will always fall back to the pattern - return ItemEncodedPatternBakedModel.this.baseModel.isBuiltInRenderer(); - } - - @Override - public TextureAtlasSprite getParticleTexture() { - // This may be called for items on the ground, in which case we will always fall back to the pattern - return ItemEncodedPatternBakedModel.this.baseModel.getParticleTexture(); - } - - @Override - public ItemCameraTransforms getItemCameraTransforms() { - // This may be called for items on the ground, in which case we will always fall back to the pattern - return ItemEncodedPatternBakedModel.this.baseModel.getItemCameraTransforms(); - } - - @Override - public ItemOverrideList getOverrides() { - // This may be called for items on the ground, in which case we will always fall back to the pattern - return ItemEncodedPatternBakedModel.this.baseModel.getOverrides(); - } + private static boolean isShiftKeyDown() { + return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); } /** @@ -188,15 +117,11 @@ class ItemEncodedPatternBakedModel implements IBakedModel { @Override public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { - boolean shiftHeld = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); - if (shiftHeld) { + if (isShiftKeyDown()) { ItemEncodedPattern iep = (ItemEncodedPattern) stack.getItem(); ItemStack output = iep.getOutput(stack); if (!output.isEmpty()) { - IBakedModel realModel = Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getItemModel(output); - // Give the item model a chance to handle the overrides as well - realModel = realModel.getOverrides().handleItemState(realModel, output, world, entity); - return new ShiftHoldingModelWrapper(realModel); + return Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides(output, world, entity); } }