diff --git a/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java new file mode 100644 index 00000000..5697f927 --- /dev/null +++ b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java @@ -0,0 +1,83 @@ +package org.embeddedt.modernfix.neoforge.mixin.perf.dynamic_resources; + +import net.minecraft.client.renderer.ItemModelShaper; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.neoforged.neoforge.client.model.RegistryAwareItemModelShaper; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.dynamicresources.ModelLocationCache; +import org.embeddedt.modernfix.util.ItemMesherMap; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.HashMap; +import java.util.Map; + +@Mixin(RegistryAwareItemModelShaper.class) +@ClientOnlyMixin +public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { + @Shadow(remap = false) @Final @Mutable private Map, ModelResourceLocation> locations; + + private Map, ModelResourceLocation> overrideLocations; + + public ItemModelMesherForgeMixin(ModelManager arg) { + super(arg); + } + + private static final ModelResourceLocation SENTINEL = new ModelResourceLocation(new ResourceLocation("modernfix", "sentinel"), "sentinel"); + + @Inject(method = "", at = @At("RETURN")) + private void replaceLocationMap(CallbackInfo ci) { + overrideLocations = new HashMap<>(); + // need to replace this map because mods query locations through it + locations = new ItemMesherMap<>(this::mfix$getLocationForge); + } + + @Unique + private ModelResourceLocation mfix$getLocationForge(Holder.Reference item) { + ModelResourceLocation map = overrideLocations.getOrDefault(item, SENTINEL); + if(map == SENTINEL) { + /* generate the appropriate location from our cache */ + map = ModelLocationCache.get(item.value()); + } + return map; + } + + /** + * @author embeddedt + * @reason Get the stored location for that item and meta, and get the model + * from that location from the model manager. + **/ + @Overwrite + @Override + public BakedModel getItemModel(Item item) { + ModelResourceLocation map = mfix$getLocationForge(item.builtInRegistryHolder()); + return map == null ? null : getModelManager().getModel(map); + } + + /** + * @author embeddedt + * @reason Don't get all models during init (with dynamic loading, that would + * generate them all). Just store location instead. + **/ + @Overwrite + @Override + public void register(Item item, ModelResourceLocation location) { + overrideLocations.put(item.builtInRegistryHolder(), location); + } + + /** + * @author embeddedt + * @reason Disable cache rebuilding (with dynamic loading, that would generate + * all models). + **/ + @Overwrite + @Override + public void rebuildCache() {} +}