From 4549ce27df01d49971dab3d9366f4e3725fd863e Mon Sep 17 00:00:00 2001 From: SHsuperCM Date: Fri, 30 Sep 2022 14:37:26 +0300 Subject: Added item redirect api for armor and elytra types To allow resolving #17 and #98 (and similar issues) more easily. --- .../defaults/CITResewnDefaultsCompatAPI.java | 46 ++++++++++++++++++++++ .../citresewn/defaults/cit/types/TypeArmor.java | 16 ++++++++ .../citresewn/defaults/cit/types/TypeElytra.java | 17 ++++++++ .../types/armor/ArmorFeatureRendererMixin.java | 2 +- .../types/elytra/ElytraFeatureRendererMixin.java | 3 +- 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/CITResewnDefaultsCompatAPI.java diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/CITResewnDefaultsCompatAPI.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/CITResewnDefaultsCompatAPI.java new file mode 100644 index 0000000..8ff101a --- /dev/null +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/CITResewnDefaultsCompatAPI.java @@ -0,0 +1,46 @@ +package shcm.shsupercm.fabric.citresewn.defaults; + +import io.shcm.shsupercm.fabric.fletchingtable.api.Entrypoint; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.entrypoint.EntrypointContainer; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import shcm.shsupercm.fabric.citresewn.defaults.cit.types.TypeArmor; +import shcm.shsupercm.fabric.citresewn.defaults.cit.types.TypeElytra; + +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Holder for utility compatibility methods for use in other mods. + */ +public abstract class CITResewnDefaultsCompatAPI implements ClientModInitializer { + /** + * Entrypoint for client initialization that's only called with CIT Resewn: Defaults present. + */ + public static final String ENTRYPOINT = "citresewn:defaults_compat"; + + @Entrypoint(Entrypoint.CLIENT) + public static void initAll() { + for (EntrypointContainer compat : FabricLoader.getInstance().getEntrypointContainers(CITResewnDefaultsCompatAPI.ENTRYPOINT, CITResewnDefaultsCompatAPI.class)) + compat.getEntrypoint().onInitializeClient(); + } + + /** + * Registers a slot redirect for type=armor + * @param redirect returns the currently visible armor item in the given equipment slot or null to not redirect. + */ + protected final void typeArmorRedirectSlotGetter(BiFunction redirect) { + TypeArmor.CONTAINER.getItemInSlotCompatRedirects.add(redirect); + } + + /** + * Registers a slot redirect for type=elytra + * @param redirect returns the currently visible elytra item or null to not redirect. + */ + protected final void typeElytraRedirectSlotGetter(Function redirect) { + TypeElytra.CONTAINER.getItemInSlotCompatRedirects.add(redirect); + } +} diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java index d97bf67..4c745a9 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java @@ -1,8 +1,11 @@ package shcm.shsupercm.fabric.citresewn.defaults.cit.types; import io.shcm.shsupercm.fabric.fletchingtable.api.Entrypoint; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; import net.minecraft.item.ArmorItem; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; @@ -15,6 +18,7 @@ import shcm.shsupercm.fabric.citresewn.pack.format.PropertyKey; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyValue; import java.util.*; +import java.util.function.BiFunction; public class TypeArmor extends CITType { @Entrypoint(CITTypeContainer.ENTRYPOINT) @@ -67,6 +71,8 @@ public class TypeArmor extends CITType { super(TypeArmor.class, TypeArmor::new, "armor"); } + public final List> getItemInSlotCompatRedirects = new ArrayList<>(); + public Set> loaded = new HashSet<>(); public Map>> loadedTyped = new IdentityHashMap<>(); @@ -103,6 +109,16 @@ public class TypeArmor extends CITType { return null; } + + public ItemStack getVisualItemInSlot(LivingEntity entity, EquipmentSlot slot) { + for (BiFunction redirect : getItemInSlotCompatRedirects) { + ItemStack stack = redirect.apply(entity, slot); + if (stack != null) + return stack; + } + + return entity.getEquippedStack(slot); + } } public interface CITCacheArmor { diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeElytra.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeElytra.java index 40e6fbe..c417db5 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeElytra.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeElytra.java @@ -1,8 +1,11 @@ package shcm.shsupercm.fabric.citresewn.defaults.cit.types; import io.shcm.shsupercm.fabric.fletchingtable.api.Entrypoint; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; import net.minecraft.item.ElytraItem; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; import shcm.shsupercm.fabric.citresewn.api.CITTypeContainer; @@ -12,9 +15,11 @@ import shcm.shsupercm.fabric.citresewn.ex.CITParsingException; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyGroup; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyKey; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Function; public class TypeElytra extends CITType { @Entrypoint(CITTypeContainer.ENTRYPOINT) @@ -45,6 +50,8 @@ public class TypeElytra extends CITType { super(TypeElytra.class, TypeElytra::new, "elytra"); } + public final List> getItemInSlotCompatRedirects = new ArrayList<>(); + public Set> loaded = new HashSet<>(); @Override @@ -68,6 +75,16 @@ public class TypeElytra extends CITType { return null; } + + public ItemStack getVisualElytraItem(LivingEntity entity) { + for (Function redirect : getItemInSlotCompatRedirects) { + ItemStack stack = redirect.apply(entity); + if (stack != null) + return stack; + } + + return entity.getEquippedStack(EquipmentSlot.CHEST); + } } public interface CITCacheElytra { diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ArmorFeatureRendererMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ArmorFeatureRendererMixin.java index d61af4c..313293c 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ArmorFeatureRendererMixin.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ArmorFeatureRendererMixin.java @@ -32,7 +32,7 @@ public class ArmorFeatureRendererMixin cit = CONTAINER.getCIT(new CITContext(equippedStack, entity.getWorld(), entity)); if (cit != null) diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/elytra/ElytraFeatureRendererMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/elytra/ElytraFeatureRendererMixin.java index efde76f..45e4316 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/elytra/ElytraFeatureRendererMixin.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/elytra/ElytraFeatureRendererMixin.java @@ -3,7 +3,6 @@ package shcm.shsupercm.fabric.citresewn.defaults.mixin.types.elytra; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.ElytraFeatureRenderer; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -30,7 +29,7 @@ public class ElytraFeatureRendererMixin { if (!CONTAINER.active()) return; - ItemStack equippedStack = livingEntity.getEquippedStack(EquipmentSlot.CHEST); + ItemStack equippedStack = CONTAINER.getVisualElytraItem(livingEntity); if (!equippedStack.isOf(Items.ELYTRA)) return; -- cgit