Skip to content

Commit

Permalink
Lots of Functional Interfaces
Browse files Browse the repository at this point in the history
maximum efficiency
  • Loading branch information
CleverNucleus committed Jan 31, 2022
1 parent d5e3dae commit 6dec74f
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -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<InvertedFunction> PROVIDERS = new ArrayList<InvertedFunction>();

/**
* This method can be used to register armor colors and textures. An example is provided below:
* <br></br>
* <code>
* 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);
* });
* </code>
*
* @param predicate
* @param provider
*/
public static void register(final ArmorModelPredicate predicate, final InvertedProvider provider) {
PROVIDERS.add(wrapper -> wrapper.apply(predicate, provider));
}

public static List<InvertedFunction> 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);
});
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.github.clevernucleus.armormodelpredicate.impl;

@FunctionalInterface
public interface InvertedFunction {
boolean invert(final WrapperFunction function);
}
Original file line number Diff line number Diff line change
@@ -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<ArmorModelProvider> invert(final ItemStack itemStack, final LivingEntity entity, final boolean legs);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.github.clevernucleus.armormodelpredicate.impl;

@FunctionalInterface
public interface WrapperFunction {
boolean apply(final ArmorModelPredicate predicate, final InvertedProvider prodiver);
}
Original file line number Diff line number Diff line change
@@ -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<T extends LivingEntity, M extends BipedEntityModel<T>, A extends BipedEntityModel<T>> extends FeatureRenderer<T, M> {
private ArmorFeatureRendererMixin(FeatureRendererContext<T, M> 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<T>)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();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/armor-model-predicate.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

],
"client": [

"ArmorFeatureRendererMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down

0 comments on commit 6dec74f

Please sign in to comment.