From 6dec74fa7928843882ed88b2f1cb6e7933c438a7 Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Mon, 31 Jan 2022 16:27:02 +0000 Subject: [PATCH] Lots of Functional Interfaces maximum efficiency --- .../ArmorModelPredicateProviderRegistry.java | 59 ++++++++++++++++ .../impl/ArmorModelPredicate.java | 9 +++ .../impl/ArmorModelProvider.java | 8 +++ .../impl/InvertedFunction.java | 6 ++ .../impl/InvertedProvider.java | 11 +++ .../impl/WrapperFunction.java | 6 ++ .../mixin/ArmorFeatureRendererMixin.java | 67 +++++++++++++++++++ .../armor-model-predicate.mixins.json | 2 +- 8 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/github/clevernucleus/armormodelpredicate/api/ArmorModelPredicateProviderRegistry.java create mode 100644 src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelPredicate.java create mode 100644 src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelProvider.java create mode 100644 src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedFunction.java create mode 100644 src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedProvider.java create mode 100644 src/main/java/com/github/clevernucleus/armormodelpredicate/impl/WrapperFunction.java create mode 100644 src/main/java/com/github/clevernucleus/armormodelpredicate/mixin/ArmorFeatureRendererMixin.java diff --git a/src/main/java/com/github/clevernucleus/armormodelpredicate/api/ArmorModelPredicateProviderRegistry.java b/src/main/java/com/github/clevernucleus/armormodelpredicate/api/ArmorModelPredicateProviderRegistry.java new file mode 100644 index 0000000..14b1be5 --- /dev/null +++ b/src/main/java/com/github/clevernucleus/armormodelpredicate/api/ArmorModelPredicateProviderRegistry.java @@ -0,0 +1,59 @@ +package com.github.clevernucleus.armormodelpredicate.api; + +import java.util.ArrayList; +import java.util.List; + +import com.github.clevernucleus.armormodelpredicate.impl.ArmorModelPredicate; +import com.github.clevernucleus.armormodelpredicate.impl.InvertedFunction; +import com.github.clevernucleus.armormodelpredicate.impl.InvertedProvider; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.item.DyeableArmorItem; +import net.minecraft.util.Identifier; + +/** + * Register custom armor texture/colors with this class. + * + * @author CleverNucleus + * + */ +@Environment(EnvType.CLIENT) +public final class ArmorModelPredicateProviderRegistry { + private static final List PROVIDERS = new ArrayList(); + + /** + * This method can be used to register armor colors and textures. An example is provided below: + *

+ * + * ArmorModelPredicateProviderRegistry.register((itemStack, entity) -> { + * return itemStack.getItem() == Items.IRON_CHESTPLATE; + * }, (itemStack, entity, legs) -> { + * Identifier texture = new Identifier("example_mod:textures/models/armor/custom_iron_layer_" + (legs ? 2 : 1) + ".png"); + * return provider -> provider.provide(texture, 0xFF0000); + * }); + * + * + * @param predicate + * @param provider + */ + public static void register(final ArmorModelPredicate predicate, final InvertedProvider provider) { + PROVIDERS.add(wrapper -> wrapper.apply(predicate, provider)); + } + + public static List providers() { + return PROVIDERS; + } + + static { + register((itemStack, entity) -> itemStack.getItem() instanceof DyeableArmorItem, (itemStack, entity, legs) -> { + Identifier texture = new Identifier("minecraft:textures/models/armor/leather_layer_" + (legs ? 2 : 1) + ".png"); + int color = ((DyeableArmorItem)itemStack.getItem()).getColor(itemStack); + return provider -> provider.provide(texture, color); + }); + register((itemStack, entity) -> itemStack.getItem() instanceof DyeableArmorItem, (itemStack, entity, legs) -> { + Identifier texture = new Identifier("minecraft:textures/models/armor/leather_layer_" + (legs ? 2 : 1) + "_overlay.png"); + return provider -> provider.provide(texture, 16777215); + }); + } +} diff --git a/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelPredicate.java b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelPredicate.java new file mode 100644 index 0000000..6e82167 --- /dev/null +++ b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelPredicate.java @@ -0,0 +1,9 @@ +package com.github.clevernucleus.armormodelpredicate.impl; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; + +@FunctionalInterface +public interface ArmorModelPredicate { + boolean test(final ItemStack itemStack, final LivingEntity entity); +} diff --git a/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelProvider.java b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelProvider.java new file mode 100644 index 0000000..332074e --- /dev/null +++ b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/ArmorModelProvider.java @@ -0,0 +1,8 @@ +package com.github.clevernucleus.armormodelpredicate.impl; + +import net.minecraft.util.Identifier; + +@FunctionalInterface +public interface ArmorModelProvider { + void provide(final Identifier texture, final int color); +} diff --git a/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedFunction.java b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedFunction.java new file mode 100644 index 0000000..b1ee37c --- /dev/null +++ b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedFunction.java @@ -0,0 +1,6 @@ +package com.github.clevernucleus.armormodelpredicate.impl; + +@FunctionalInterface +public interface InvertedFunction { + boolean invert(final WrapperFunction function); +} diff --git a/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedProvider.java b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedProvider.java new file mode 100644 index 0000000..f0c76a6 --- /dev/null +++ b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/InvertedProvider.java @@ -0,0 +1,11 @@ +package com.github.clevernucleus.armormodelpredicate.impl; + +import java.util.function.Consumer; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; + +@FunctionalInterface +public interface InvertedProvider { + Consumer invert(final ItemStack itemStack, final LivingEntity entity, final boolean legs); +} diff --git a/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/WrapperFunction.java b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/WrapperFunction.java new file mode 100644 index 0000000..b751c05 --- /dev/null +++ b/src/main/java/com/github/clevernucleus/armormodelpredicate/impl/WrapperFunction.java @@ -0,0 +1,6 @@ +package com.github.clevernucleus.armormodelpredicate.impl; + +@FunctionalInterface +public interface WrapperFunction { + boolean apply(final ArmorModelPredicate predicate, final InvertedProvider prodiver); +} diff --git a/src/main/java/com/github/clevernucleus/armormodelpredicate/mixin/ArmorFeatureRendererMixin.java b/src/main/java/com/github/clevernucleus/armormodelpredicate/mixin/ArmorFeatureRendererMixin.java new file mode 100644 index 0000000..87c0df3 --- /dev/null +++ b/src/main/java/com/github/clevernucleus/armormodelpredicate/mixin/ArmorFeatureRendererMixin.java @@ -0,0 +1,67 @@ +package com.github.clevernucleus.armormodelpredicate.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import com.github.clevernucleus.armormodelpredicate.api.ArmorModelPredicateProviderRegistry; + +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer; +import net.minecraft.client.render.entity.feature.FeatureRenderer; +import net.minecraft.client.render.entity.feature.FeatureRendererContext; +import net.minecraft.client.render.entity.model.AnimalModel; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; + +@Mixin(ArmorFeatureRenderer.class) +abstract class ArmorFeatureRendererMixin, A extends BipedEntityModel> extends FeatureRenderer { + private ArmorFeatureRendererMixin(FeatureRendererContext context, A leggingsModel, A bodyModel) { super(context); } + + private void amp_renderArmorParts(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, Identifier texture, boolean usesSecondLayer, A model, float red, float green, float blue) { + VertexConsumer vertexConsumer = ItemRenderer.getArmorGlintConsumer(vertexConsumers, RenderLayer.getArmorCutoutNoCull(texture), false, usesSecondLayer); + ((AnimalModel)model).render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, red, green, blue, 1.0F); + } + + @Inject(method = "renderArmor", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;hasGlint()Z", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) + private void onRenderArmor(MatrixStack matrices, VertexConsumerProvider vertexConsumers, T entity, EquipmentSlot armorSlot, int light, A model, CallbackInfo info, ItemStack itemStack, ArmorItem armorItem, boolean bl) { + boolean bl2 = itemStack.hasGlint(); + boolean check = true; + + for(var function : ArmorModelPredicateProviderRegistry.providers()) { + if(function.invert((predicate, provider) -> { + if(predicate.test(itemStack, entity)) { + provider.invert(itemStack, entity, bl).accept((texture, color) -> { + float r = (float)(color >> 16 & 0xFF) / 255.0F; + float g = (float)(color >> 8 & 0xFF) / 255.0F; + float b = (float)(color & 0xFF) / 255.0F; + this.amp_renderArmorParts(matrices, vertexConsumers, light, texture, bl2, model, r, g, b); + }); + + return true; + } else { + return false; + } + })) { + check = false; + } + } + + if(check) { + this.amp_renderArmorParts(matrices, vertexConsumers, light, new Identifier("minecraft:textures/models/armor/" + armorItem.getMaterial().getName() + "_layer_" + (bl ? 2 : 1) + ".png"), bl2, model, 1.0F, 1.0F, 1.0F); + } + + info.cancel(); + } +} diff --git a/src/main/resources/armor-model-predicate.mixins.json b/src/main/resources/armor-model-predicate.mixins.json index 77fef7c..0c77989 100644 --- a/src/main/resources/armor-model-predicate.mixins.json +++ b/src/main/resources/armor-model-predicate.mixins.json @@ -7,7 +7,7 @@ ], "client": [ - + "ArmorFeatureRendererMixin" ], "injectors": { "defaultRequire": 1