From c511d3ba39ede7e127db289e83dd26bb4c0b0e04 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Mon, 28 Jul 2025 13:09:28 +0000 Subject: [PATCH] Use any possible texture when layer0 doesn't exist --- .../rainbow/mapping/BedrockItemMapper.java | 34 ++++++++++++------- .../rainbow/mixin/TextureSlotsAccessor.java | 15 ++++++++ src/main/resources/rainbow.mixins.json | 3 +- 3 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 src/main/java/org/geysermc/rainbow/mixin/TextureSlotsAccessor.java diff --git a/src/main/java/org/geysermc/rainbow/mapping/BedrockItemMapper.java b/src/main/java/org/geysermc/rainbow/mapping/BedrockItemMapper.java index f590f0c..a8627cd 100644 --- a/src/main/java/org/geysermc/rainbow/mapping/BedrockItemMapper.java +++ b/src/main/java/org/geysermc/rainbow/mapping/BedrockItemMapper.java @@ -52,6 +52,7 @@ import org.geysermc.rainbow.mapping.geyser.predicate.GeyserPredicate; import org.geysermc.rainbow.mixin.ConditionalItemModelAccessor; import org.geysermc.rainbow.mixin.RangeSelectItemModelAccessor; import org.geysermc.rainbow.mixin.SelectItemModelAccessor; +import org.geysermc.rainbow.mixin.TextureSlotsAccessor; import org.geysermc.rainbow.pack.BedrockItem; import org.geysermc.rainbow.pack.BedrockTextures; @@ -108,31 +109,38 @@ public class BedrockItemMapper { ((ResolvedModelAccessor) Minecraft.getInstance().getModelManager()).rainbow$getResolvedModel(itemModelLocation) .ifPresentOrElse(itemModel -> { ResolvedModel parentModel = itemModel.parent(); - boolean handheld = false; - if (parentModel != null) { - // debugName() returns the resource location of the model as a string - handheld = HANDHELD_MODELS.contains(ResourceLocation.parse(parentModel.debugName())); - } + // debugName() returns the resource location of the model as a string + boolean handheld = parentModel != null && HANDHELD_MODELS.contains(ResourceLocation.parse(parentModel.debugName())); - ResourceLocation bedrockIdentifier = itemModelLocation; - if (bedrockIdentifier.getNamespace().equals(ResourceLocation.DEFAULT_NAMESPACE)) { + ResourceLocation bedrockIdentifier; + if (itemModelLocation.getNamespace().equals(ResourceLocation.DEFAULT_NAMESPACE)) { bedrockIdentifier = ResourceLocation.fromNamespaceAndPath("geyser_mc", itemModelLocation.getPath()); + } else { + bedrockIdentifier = itemModelLocation; } - ResourceLocation texture = itemModelLocation; Material layer0Texture = itemModel.getTopTextureSlots().getMaterial("layer0"); - Optional customGeometry = Optional.empty(); + Optional texture; + Optional customGeometry; if (layer0Texture != null) { - texture = layer0Texture.texture(); + texture = Optional.of(layer0Texture.texture()); + customGeometry = Optional.empty(); } else { + // We can't stitch multiple textures together yet, so we just grab the first one we see + // This will only work properly for models with just one texture + texture = ((TextureSlotsAccessor) itemModel.getTopTextureSlots()).getResolvedValues().values().stream() + .map(Material::texture) + .findAny(); // Unknown texture (doesn't use layer0), so we immediately assume the geometry is custom // This check should probably be done differently customGeometry = Optional.of(itemModel); } - // Not a problem, but just report to get the model printed in the report file - context.reporter.report(() -> "creating mapping for block model " + itemModelLocation); - context.create(bedrockIdentifier, texture, handheld, customGeometry); + texture.ifPresentOrElse(itemTexture -> { + // Not a problem, but just report to get the model printed in the report file + context.reporter.report(() -> "creating mapping for block model " + itemModelLocation); + context.create(bedrockIdentifier, itemTexture, handheld, customGeometry); + }, () -> context.reporter.report(() -> "not mapping block model " + itemModelLocation + " because it has no texture")); }, () -> context.reporter.report(() -> "missing block model " + itemModelLocation)); } case ConditionalItemModel conditional -> mapConditionalModel(conditional, context.child("condition model ")); diff --git a/src/main/java/org/geysermc/rainbow/mixin/TextureSlotsAccessor.java b/src/main/java/org/geysermc/rainbow/mixin/TextureSlotsAccessor.java new file mode 100644 index 0000000..c957971 --- /dev/null +++ b/src/main/java/org/geysermc/rainbow/mixin/TextureSlotsAccessor.java @@ -0,0 +1,15 @@ +package org.geysermc.rainbow.mixin; + +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.Material; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(TextureSlots.class) +public interface TextureSlotsAccessor { + + @Accessor + Map getResolvedValues(); +} diff --git a/src/main/resources/rainbow.mixins.json b/src/main/resources/rainbow.mixins.json index 61968ba..63567a4 100644 --- a/src/main/resources/rainbow.mixins.json +++ b/src/main/resources/rainbow.mixins.json @@ -17,7 +17,8 @@ "SelectItemModelAccessor", "SelectItemModelMixin", "SelectItemModelMixin$UnbakedSwitchMixin", - "SplashRendererAccessor" + "SplashRendererAccessor", + "TextureSlotsAccessor" ], "injectors": { "defaultRequire": 1