diff --git a/patches/minecraft/net/minecraft/server/packs/resources/ReloadableResourceManager.java.patch b/patches/minecraft/net/minecraft/server/packs/resources/ReloadableResourceManager.java.patch new file mode 100644 index 0000000000..33e6f234fb --- /dev/null +++ b/patches/minecraft/net/minecraft/server/packs/resources/ReloadableResourceManager.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/server/packs/resources/ReloadableResourceManager.java ++++ b/net/minecraft/server/packs/resources/ReloadableResourceManager.java +@@ -68,4 +_,10 @@ + public Stream m_7536_() { + return this.f_203815_.m_7536_(); + } ++ ++ public void registerReloadListenerIfNotPresent(PreparableReloadListener listener) { ++ if (!this.f_203816_.contains(listener)) { ++ this.m_7217_(listener); ++ } ++ } + } diff --git a/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java b/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java index b2af2b9c87..386102dac7 100644 --- a/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java @@ -5,12 +5,16 @@ package net.minecraftforge.client.event; -import net.minecraftforge.client.model.ForgeModelBakery; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.client.model.IModelLoader; +import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.fml.event.IModBusEvent; /** - * Fired when the {@link ForgeModelBakery} is ready to register model loaders + * Fired when the {@link ModelLoaderRegistry} is ready to register model loaders + * + * @see ModelLoaderRegistry#registerLoader(ResourceLocation, IModelLoader) */ public class ModelRegistryEvent extends Event implements IModBusEvent { diff --git a/src/main/java/net/minecraftforge/client/loading/ClientModLoader.java b/src/main/java/net/minecraftforge/client/loading/ClientModLoader.java index 63b0388b78..4544e018ac 100644 --- a/src/main/java/net/minecraftforge/client/loading/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/client/loading/ClientModLoader.java @@ -96,7 +96,6 @@ public class ClientModLoader DataPackConfig.DEFAULT.addModPacks(ResourcePackLoader.getPackNames()); mcResourceManager.registerReloadListener(ClientModLoader::onResourceReload); mcResourceManager.registerReloadListener(BrandingControl.resourceManagerReloadListener()); - ModelLoaderRegistry.init(); } } @@ -163,6 +162,8 @@ public class ClientModLoader if (error == null) { // We can finally start the forge eventbus up MinecraftForge.EVENT_BUS.start(); + // allow the ModelLoaderRegistry to register loaders as reload listeners + ModelLoaderRegistry.afterFirstReload(); } else { // Double check we have the langs loaded for forge LanguageHook.loadForgeAndMCLangs(); diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java b/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java index 80f4408fad..6973f48517 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java +++ b/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java @@ -22,6 +22,7 @@ import net.minecraft.util.GsonHelper; import net.minecraft.resources.ResourceLocation; import com.mojang.math.Transformation; import net.minecraftforge.client.event.ModelRegistryEvent; +import net.minecraftforge.client.event.RegisterClientReloadListenersEvent; import net.minecraftforge.client.model.geometry.IModelGeometry; import net.minecraftforge.client.model.geometry.ISimpleModelGeometry; import net.minecraftforge.client.model.obj.OBJLoader; @@ -48,6 +49,7 @@ import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; /** * Central hub for custom model loaders. @@ -63,17 +65,23 @@ public class ModelLoaderRegistry // Forge built-in loaders public static void init() { - registerLoader(new ResourceLocation("minecraft","elements"), VanillaProxy.Loader.INSTANCE); - registerLoader(new ResourceLocation("forge","obj"), OBJLoader.INSTANCE); - registerLoader(new ResourceLocation("forge","bucket"), DynamicBucketModel.Loader.INSTANCE); - registerLoader(new ResourceLocation("forge","composite"), CompositeModel.Loader.INSTANCE); - registerLoader(new ResourceLocation("forge","multi-layer"), MultiLayerModel.Loader.INSTANCE); - registerLoader(new ResourceLocation("forge","item-layers"), ItemLayerModel.Loader.INSTANCE); - registerLoader(new ResourceLocation("forge", "separate-perspective"), SeparatePerspectiveModel.Loader.INSTANCE); + var builtInLoaders = Map.of( + new ResourceLocation("minecraft", "elements"), VanillaProxy.Loader.INSTANCE, + new ResourceLocation("forge", "obj"), OBJLoader.INSTANCE, + new ResourceLocation("forge", "bucket"), DynamicBucketModel.Loader.INSTANCE, + new ResourceLocation("forge", "composite"), CompositeModel.Loader.INSTANCE, + new ResourceLocation("forge", "multi-layer"), MultiLayerModel.Loader.INSTANCE, + new ResourceLocation("forge", "item-layers"), ItemLayerModel.Loader.INSTANCE, + new ResourceLocation("forge", "separate-perspective"), SeparatePerspectiveModel.Loader.INSTANCE + ); // TODO: Implement as new model loaders //registerLoader(new ResourceLocation("forge:b3d"), new ModelLoaderAdapter(B3DLoader.INSTANCE)); //registerLoader(new ResourceLocation("forge:fluid"), new ModelLoaderAdapter(ModelFluid.FluidLoader.INSTANCE)); + + var modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); + modEventBus.addListener(event -> builtInLoaders.values().forEach(event::registerReloadListener)); + modEventBus.addListener(event -> builtInLoaders.forEach(ModelLoaderRegistry::registerLoader)); } /** @@ -90,8 +98,25 @@ public class ModelLoaderRegistry } /** - * Makes system aware of your loader. + * Internal method, only present for enabling legacy behavior of automatic registration of model loaders + * as resource reload listeners. + */ + @Deprecated + public static void afterFirstReload() + { + for (IModelLoader loader : loaders.values()) + { + ((ReloadableResourceManager) Minecraft.getInstance().getResourceManager()).registerReloadListenerIfNotPresent(loader); + } + } + + /** + * Makes system aware of your loader.
* Must be called from within {@link ModelRegistryEvent} + *

+ * Note: This method currently registers the model loader as a resource reload listener automatically, + * if it is not already registered. This behavior is deprecated and will be removed in the future. + * If the model loader needs to be a resource reload listener as well, use {@link net.minecraftforge.client.event.RegisterClientReloadListenersEvent}. */ public static void registerLoader(ResourceLocation id, IModelLoader loader) { @@ -101,7 +126,6 @@ public class ModelLoaderRegistry synchronized(loaders) { loaders.put(id, loader); - ((ReloadableResourceManager) Minecraft.getInstance().getResourceManager()).registerReloadListener(loader); } } diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index c1968191b6..8e3c9a62c7 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -17,6 +17,7 @@ import net.minecraft.sounds.SoundEvent; import net.minecraft.core.Registry; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import net.minecraftforge.common.crafting.PartialNBTIngredient; import net.minecraftforge.common.crafting.DifferenceIngredient; @@ -174,6 +175,11 @@ public class ForgeMod BiomeDictionary.init(); ForgeRegistries.ITEMS.tags().addOptionalTagDefaults(Tags.Items.ENCHANTING_FUELS, Set.of(Items.LAPIS_LAZULI.delegate)); + + if (FMLEnvironment.dist == Dist.CLIENT) + { + ModelLoaderRegistry.init(); + } } public void registerCapabilities(RegisterCapabilitiesEvent event)