diff --git a/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/SimpleItemOverrideProvider.java b/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/SimpleItemOverrideProvider.java index 1ec4918f..d917afc8 100644 --- a/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/SimpleItemOverrideProvider.java +++ b/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/SimpleItemOverrideProvider.java @@ -1,9 +1,11 @@ package dev.dhyces.trimmed.api.client.override.provider; +import dev.dhyces.trimmed.modhelper.services.Services; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; @@ -13,8 +15,22 @@ public abstract class SimpleItemOverrideProvider implements ItemOverrideProvider { @Override public Optional getModel(ItemStack itemStack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { - return getModelLocation(itemStack, world, entity, seed).map(Minecraft.getInstance().getModelManager()::getModel); + ModelPair pair = getModelLocation(itemStack, world, entity, seed); + return pair.getTopLevelModelId().map(Minecraft.getInstance().getModelManager()::getModel) + .filter(model -> model != Minecraft.getInstance().getModelManager().getMissingModel()) + .or(() -> pair.getResourceId().map(Services.CLIENT_HELPER::getModel)); } - public abstract Optional getModelLocation(ItemStack itemStack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed); + public abstract ModelPair getModelLocation(ItemStack itemStack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed); + + public record ModelPair(@Nullable ResourceLocation resourceId, @Nullable ModelResourceLocation topLevelModelId) { + public static final ModelPair EMPTY = new ModelPair(null, null); + + public Optional getResourceId() { + return Optional.ofNullable(resourceId); + } + public Optional getTopLevelModelId() { + return Optional.ofNullable(topLevelModelId); + } + } } diff --git a/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/AnyTrimItemOverrideProvider.java b/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/AnyTrimItemOverrideProvider.java index 358a5e38..255bd411 100644 --- a/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/AnyTrimItemOverrideProvider.java +++ b/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/AnyTrimItemOverrideProvider.java @@ -40,9 +40,9 @@ public Optional getModel(ItemStack itemStack, @Nullable ClientLevel } @Override - public Optional getModelLocation(ItemStack itemStack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { + public ModelPair getModelLocation(ItemStack itemStack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { if (!(itemStack.getItem() instanceof ArmorItem armorItem)) { - return Optional.empty(); + return ModelPair.EMPTY; } Optional materialIdOptional = Optional.ofNullable(itemStack.get(DataComponents.TRIM)) @@ -55,10 +55,11 @@ public Optional getModelLocation(ItemStack itemStack, @Nu } else { return null; } - })).withPath(s -> s.substring(s.indexOf("/")+1)); - return Optional.of(new ModelResourceLocation(id, "inventory")); + })); + // TODO: Fabric is silly and forces custom models to be saved in top level as namespace:resource_id#fabric_resource + return new ModelPair(id, new ModelResourceLocation(id.withPath(s -> s.substring(s.indexOf("/")+1)), "inventory")); } - return Optional.empty(); + return ModelPair.EMPTY; } @Override diff --git a/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/ComponentItemOverrideProvider.java b/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/ComponentItemOverrideProvider.java index ff3ba2ee..cefbade4 100644 --- a/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/ComponentItemOverrideProvider.java +++ b/common/src/main/java/dev/dhyces/trimmed/api/client/override/provider/providers/ComponentItemOverrideProvider.java @@ -34,25 +34,25 @@ public ComponentItemOverrideProvider(DataComponentPatch componentPatch, ModelRes } @Override - public Optional getModelLocation(ItemStack itemStack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { + public ModelPair getModelLocation(ItemStack itemStack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { if (!itemStack.getComponentsPatch().isEmpty()) { DataComponentPatch stackPatch = itemStack.getComponentsPatch(); for (Map.Entry, Optional> entry : componentPatch.entrySet()) { Optional stackData = stackPatch.get(entry.getKey()); Optional testData = componentPatch.get(entry.getKey()); if ((stackData == null) != (testData == null)) { - return Optional.empty(); + return ModelPair.EMPTY; } if (stackData.isEmpty() != testData.isEmpty()) { - return Optional.empty(); + return ModelPair.EMPTY; } if (stackData.isPresent() && testData.isPresent() && !stackData.get().equals(testData.get())) { - return Optional.empty(); + return ModelPair.EMPTY; } } - return Optional.of(model); + return new ModelPair(null, model); } - return Optional.empty(); + return ModelPair.EMPTY; } @Override diff --git a/common/src/main/java/dev/dhyces/trimmed/impl/client/models/source/NamedModel.java b/common/src/main/java/dev/dhyces/trimmed/impl/client/models/source/NamedModel.java index 1385a932..5dc6dc85 100644 --- a/common/src/main/java/dev/dhyces/trimmed/impl/client/models/source/NamedModel.java +++ b/common/src/main/java/dev/dhyces/trimmed/impl/client/models/source/NamedModel.java @@ -1,18 +1,12 @@ package dev.dhyces.trimmed.impl.client.models.source; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.Nullable; import java.util.function.Supplier; -public record NamedModel(ResourceLocation id, Supplier model, @Nullable ModelResourceLocation modelId) { +public record NamedModel(ResourceLocation id, Supplier model) { public static NamedModel item(ResourceLocation fileId, Supplier model) { - return new NamedModel(fileId, model, convertToItemModelId(fileId)); - } - - public static ModelResourceLocation convertToItemModelId(ResourceLocation modelFileId) { - return new ModelResourceLocation(modelFileId.withPath(s -> s.substring(s.indexOf("/")+1)), "inventory"); + return new NamedModel(fileId, model); } } diff --git a/common/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/ClientHelper.java b/common/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/ClientHelper.java index 9bf4a6cc..a30a81b9 100644 --- a/common/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/ClientHelper.java +++ b/common/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/ClientHelper.java @@ -2,9 +2,12 @@ import dev.dhyces.trimmed.api.client.TrimmedClientApiEntrypoint; import dev.dhyces.trimmed.impl.ModApiConsumer; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.resources.ResourceLocation; import java.util.List; public interface ClientHelper { List> getClientApiConsumers(); + BakedModel getModel(ResourceLocation resourceId); } diff --git a/fabric/src/main/java/dev/dhyces/trimmed/FabricTrimmedClient.java b/fabric/src/main/java/dev/dhyces/trimmed/FabricTrimmedClient.java index a787b132..72f5d7ab 100644 --- a/fabric/src/main/java/dev/dhyces/trimmed/FabricTrimmedClient.java +++ b/fabric/src/main/java/dev/dhyces/trimmed/FabricTrimmedClient.java @@ -39,9 +39,7 @@ public void onInitializeClient() { (data, pluginContext) -> { Map modelMapByFileId = new Object2ObjectOpenHashMap<>(); for (NamedModel namedModel : data) { - // Need to add as ModelResourceLocations pluginContext.addModels(namedModel.id()); - // But the context ids are in regular ResourceLocations modelMapByFileId.put(namedModel.id(), namedModel); } pluginContext.resolveModel().register(context -> { diff --git a/fabric/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/FabricClientHelper.java b/fabric/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/FabricClientHelper.java index bc027409..a3e42d7e 100644 --- a/fabric/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/FabricClientHelper.java +++ b/fabric/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/FabricClientHelper.java @@ -3,6 +3,9 @@ import dev.dhyces.trimmed.api.client.TrimmedClientApiEntrypoint; import dev.dhyces.trimmed.impl.ModApiConsumer; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.resources.ResourceLocation; import java.util.List; @@ -12,4 +15,9 @@ public List> getClientApiConsumers() return FabricLoader.getInstance().getEntrypointContainers("trimmed:client_api_entrypoint", TrimmedClientApiEntrypoint.class) .stream().map(container -> new ModApiConsumer<>(container.getProvider().getMetadata().getId(), container.getEntrypoint())).toList(); } + + @Override + public BakedModel getModel(ResourceLocation resourceId) { + return Minecraft.getInstance().getModelManager().getModel(resourceId); + } } diff --git a/neo/src/main/java/dev/dhyces/trimmed/NeoTrimmedClient.java b/neo/src/main/java/dev/dhyces/trimmed/NeoTrimmedClient.java index a9356e18..cec2fb17 100644 --- a/neo/src/main/java/dev/dhyces/trimmed/NeoTrimmedClient.java +++ b/neo/src/main/java/dev/dhyces/trimmed/NeoTrimmedClient.java @@ -19,7 +19,7 @@ @SuppressWarnings("unused") @Mod(value = Trimmed.MODID, dist = Dist.CLIENT) public class NeoTrimmedClient { - private static Set additionalGeneratedModels; + private static Set additionalGeneratedModels; public NeoTrimmedClient(IEventBus modBus, ModContainer container) { TrimmedClient.init(); @@ -44,7 +44,7 @@ private void registerClientReloadListener(final RegisterClientReloadListenersEve } private void addModels(final ModelEvent.RegisterAdditional event) { - additionalGeneratedModels.forEach(event::register); + additionalGeneratedModels.forEach(resourceId -> event.register(ModelResourceLocation.standalone(resourceId))); } private void tagsSynced(final TagsUpdatedEvent event) { @@ -59,7 +59,7 @@ private void onLogout(final ClientPlayerNetworkEvent.LoggingOut event) { TrimmedClient.resetSyncedStatus(); } - public static void setModels(Set models) { + public static void setModels(Set models) { additionalGeneratedModels = models; } } diff --git a/neo/src/main/java/dev/dhyces/trimmed/impl/mixin/client/BakedModelManagerMixin.java b/neo/src/main/java/dev/dhyces/trimmed/impl/mixin/client/BakedModelManagerMixin.java index ee2f5c6c..1362d4b7 100644 --- a/neo/src/main/java/dev/dhyces/trimmed/impl/mixin/client/BakedModelManagerMixin.java +++ b/neo/src/main/java/dev/dhyces/trimmed/impl/mixin/client/BakedModelManagerMixin.java @@ -29,12 +29,12 @@ private static CompletableFuture> injectGenera return original.thenCombineAsync(TrimmedClient.startGeneratingModels(resourceManager, executor), (originalMap, generatedModels) -> { Object2ObjectMap newMap = new Object2ObjectOpenHashMap<>(); - Set generatedModelIds = new ObjectOpenHashSet<>(); + Set generatedModelIds = new ObjectOpenHashSet<>(); generatedModels.forEach(namedModel -> { ResourceLocation path = namedModel.id().withPrefix("models/").withSuffix(".json"); if (!originalMap.containsKey(path)) { newMap.put(path, namedModel.model().get()); - generatedModelIds.add(namedModel.modelId()); + generatedModelIds.add(namedModel.id()); } }); NeoTrimmedClient.setModels(generatedModelIds); diff --git a/neo/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/NeoClientHelper.java b/neo/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/NeoClientHelper.java index ceba107d..718b5c14 100644 --- a/neo/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/NeoClientHelper.java +++ b/neo/src/main/java/dev/dhyces/trimmed/modhelper/services/helpers/NeoClientHelper.java @@ -3,6 +3,10 @@ import dev.dhyces.trimmed.api.TrimmedClientApiConsumer; import dev.dhyces.trimmed.api.client.TrimmedClientApiEntrypoint; import dev.dhyces.trimmed.impl.ModApiConsumer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.resources.ResourceLocation; import net.neoforged.fml.ModList; import java.lang.annotation.ElementType; @@ -34,4 +38,9 @@ public List> getClientApiConsumers() return new ModApiConsumer<>(modid, apiEntrypoint); }).toList(); } + + @Override + public BakedModel getModel(ResourceLocation resourceId) { + return Minecraft.getInstance().getModelManager().getModel(ModelResourceLocation.standalone(resourceId)); + } }