diff options
Diffstat (limited to 'src/texturePacks/java/moe/nea/firmament/mixins/custommodels')
-rw-r--r-- | src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java | 28 | ||||
-rw-r--r-- | src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java | 79 |
2 files changed, 106 insertions, 1 deletions
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java index 0863caa..ffa23f7 100644 --- a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java +++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java @@ -5,20 +5,46 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import moe.nea.firmament.events.CustomItemModelEvent; import net.minecraft.client.item.ItemModelManager; +import net.minecraft.client.render.item.model.ItemModel; +import net.minecraft.client.render.item.model.MissingItemModel; +import net.minecraft.client.render.model.BakedModelManager; import net.minecraft.component.ComponentType; import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; 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.function.Function; @Mixin(ItemModelManager.class) public class ReplaceItemModelPatch { + @Shadow + @Final + private Function<Identifier, ItemModel> modelGetter; + + @Inject(method = "<init>", at = @At("TAIL")) + private void saveMissingModel(BakedModelManager bakedModelManager, CallbackInfo ci) { + } + + @Unique + // TODO: Fix scissors + private boolean hasModel(Identifier identifier) { + return !(modelGetter.apply(identifier) instanceof MissingItemModel); + } + @WrapOperation( method = "update(Lnet/minecraft/client/render/item/ItemRenderState;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;get(Lnet/minecraft/component/ComponentType;)Ljava/lang/Object;")) private Object replaceItemModelByIdentifier(ItemStack instance, ComponentType componentType, Operation<Object> original) { var override = CustomItemModelEvent.getModelIdentifier(instance); - if (override != null) + if (override != null && hasModel(override)) { return override; + } return original.call(instance, componentType); } } diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java new file mode 100644 index 0000000..3f4cc44 --- /dev/null +++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java @@ -0,0 +1,79 @@ +package moe.nea.firmament.mixins.custommodels; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.client.item.ItemAsset; +import net.minecraft.client.item.ItemAssetsLoader; +import net.minecraft.client.render.item.model.BasicItemModel; +import net.minecraft.resource.Resource; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourcePack; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +@Mixin(ItemAssetsLoader.class) +public class SupplyFakeModelPatch { + + @ModifyReturnValue( + method = "load", + at = @At("RETURN") + ) + private static CompletableFuture<ItemAssetsLoader.Result> injectFakeGeneratedModels( + CompletableFuture<ItemAssetsLoader.Result> original, + @Local(argsOnly = true) ResourceManager resourceManager, + @Local(argsOnly = true) Executor executor + ) { + return original.thenCompose(oldModels -> CompletableFuture.supplyAsync(() -> supplyExtraModels(resourceManager, oldModels), executor)); + } + + private static ItemAssetsLoader.Result supplyExtraModels(ResourceManager resourceManager, ItemAssetsLoader.Result oldModels) { + Map<Identifier, ItemAsset> newModels = new HashMap<>(oldModels.contents()); + var resources = resourceManager.findResources( + "models/item", + id -> id.getNamespace().equals("firmskyblock") + && id.getPath().endsWith(".json") + && !id.getPath().substring("models/item/".length()).contains("/")); + for (Map.Entry<Identifier, Resource> model : resources.entrySet()) { + var resource = model.getValue(); + var itemModelId = model.getKey().withPath(it -> it.substring("models/item/".length(), it.length() - ".json".length())); + // TODO: parse json file here and make use of it in order to generate predicate files. + var genericModelId = itemModelId.withPrefixedPath("item/"); + if (resourceManager.getResource(itemModelId) + .map(Resource::getPack) + .map(it -> isResourcePackNewer(resourceManager, it, resource.getPack())) + .orElse(true)) { + newModels.put(itemModelId, new ItemAsset( + new BasicItemModel.Unbaked(genericModelId, List.of()), + new ItemAsset.Properties(true) + )); + } + } + return new ItemAssetsLoader.Result(newModels); + } + + private static boolean isResourcePackNewer( + ResourceManager manager, + ResourcePack null_, ResourcePack proposal) { + var pack = manager.streamResourcePacks() + .filter(it -> it == null_ || it == proposal) + .collect(findLast()); + return pack.orElse(null) == proposal; + } + + private static <T> Collector<T, ?, Optional<T>> findLast() { + return Collectors.reducing(Optional.empty(), Optional::of, + (left, right) -> right.isPresent() ? right : left); + + } + +} |