diff options
5 files changed, 147 insertions, 6 deletions
diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java b/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java index 9e39287..9085e6f 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java @@ -1,5 +1,8 @@ package shcm.shsupercm.fabric.citresewn; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.VertexConsumers; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.LivingEntity; @@ -145,4 +148,23 @@ public class ActiveCITs { return null; } + + public void setEnchantmentAppliedContextCached(ItemStack stack, World world, LivingEntity entity) { + if (stack == null) { + CITEnchantment.appliedContext = null; + return; + } + + Supplier<List<CITEnchantment>> realtime = () -> getCITEnchantment(stack, world, entity); + + //noinspection ConstantConditions + List<CITEnchantment> citEnchantments = CITResewnConfig.INSTANCE().cache_ms == 0 ? realtime.get() : ((CITEnchantment.Cached) (Object) stack).citresewn_getCachedCITEnchantment(realtime); + + if (citEnchantments == null || citEnchantments.isEmpty()) { + CITEnchantment.appliedContext = null; + return; + } + + CITEnchantment.appliedContext = citEnchantments; + } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemRendererMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemRendererMixin.java index b19e901..4594d8f 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemRendererMixin.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemRendererMixin.java @@ -1,8 +1,69 @@ package shcm.shsupercm.fabric.citresewn.mixin.citenchantment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.*; import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.render.model.json.ModelTransformation; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; 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.CallbackInfoReturnable; +import shcm.shsupercm.fabric.citresewn.CITResewn; +import shcm.shsupercm.fabric.citresewn.pack.cits.CITEnchantment; @Mixin(ItemRenderer.class) public class ItemRendererMixin { + @Inject(method = "getHeldItemModel", at = @At("TAIL")) + private void setAppliedContext(ItemStack stack, World world, LivingEntity entity, int seed, CallbackInfoReturnable<BakedModel> cir) { + if (CITResewn.INSTANCE.activeCITs != null) + CITResewn.INSTANCE.activeCITs.setEnchantmentAppliedContextCached(stack, world, entity); + } + + @Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformation$Mode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V", at = @At("TAIL")) + private void clearAppliedContext(ItemStack stack, ModelTransformation.Mode renderMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, CallbackInfo ci) { + if (CITResewn.INSTANCE.activeCITs != null) + CITResewn.INSTANCE.activeCITs.setEnchantmentAppliedContextCached(null, null, null); + } + + + @Inject(method = "getArmorGlintConsumer", cancellable = true, at = @At("RETURN")) + private static void getArmorGlintConsumer(VertexConsumerProvider provider, RenderLayer layer, boolean solid, boolean glint, CallbackInfoReturnable<VertexConsumer> cir) { + VertexConsumer vertexConsumer = solid ? CITEnchantment.GlintRenderLayer.ARMOR_GLINT.tryApply(cir.getReturnValue(), provider) : CITEnchantment.GlintRenderLayer.ARMOR_ENTITY_GLINT.tryApply(cir.getReturnValue(), provider); + if (vertexConsumer != null) + cir.setReturnValue(vertexConsumer); + } + + @Inject(method = "getCompassGlintConsumer", cancellable = true, at = @At("RETURN")) + private static void getCompassGlintConsumer(VertexConsumerProvider provider, RenderLayer layer, MatrixStack.Entry entry, CallbackInfoReturnable<VertexConsumer> cir) { + VertexConsumer vertexConsumer = CITEnchantment.GlintRenderLayer.GLINT.tryApply(null, provider); + if (vertexConsumer != null) + cir.setReturnValue(VertexConsumers.union(new OverlayVertexConsumer(vertexConsumer, entry.getModel(), entry.getNormal()), cir.getReturnValue())); + } + + @Inject(method = "getDirectCompassGlintConsumer", cancellable = true, at = @At("RETURN")) + private static void getDirectCompassGlintConsumer(VertexConsumerProvider provider, RenderLayer layer, MatrixStack.Entry entry, CallbackInfoReturnable<VertexConsumer> cir) { + VertexConsumer vertexConsumer = CITEnchantment.GlintRenderLayer.DIRECT_GLINT.tryApply(null, provider); + if (vertexConsumer != null) + cir.setReturnValue(VertexConsumers.union(new OverlayVertexConsumer(vertexConsumer, entry.getModel(), entry.getNormal()), cir.getReturnValue())); + } + + @Inject(method = "getItemGlintConsumer", cancellable = true, at = @At("RETURN")) + private static void getItemGlintConsumer(VertexConsumerProvider provider, RenderLayer layer, boolean solid, boolean glint, CallbackInfoReturnable<VertexConsumer> cir) { + VertexConsumer vertexConsumer = MinecraftClient.isFabulousGraphicsOrBetter() && layer == TexturedRenderLayers.getItemEntityTranslucentCull() ? CITEnchantment.GlintRenderLayer.GLINT_TRANSLUCENT.tryApply(cir.getReturnValue(), provider) : (solid ? CITEnchantment.GlintRenderLayer.GLINT.tryApply(cir.getReturnValue(), provider) : CITEnchantment.GlintRenderLayer.ENTITY_GLINT.tryApply(cir.getReturnValue(), provider)); + if (vertexConsumer != null) + cir.setReturnValue(vertexConsumer); + } + + @Inject(method = "getDirectItemGlintConsumer", cancellable = true, at = @At("RETURN")) + private static void getDirectItemGlintConsumer(VertexConsumerProvider provider, RenderLayer layer, boolean solid, boolean glint, CallbackInfoReturnable<VertexConsumer> cir) { + VertexConsumer vertexConsumer = solid ? CITEnchantment.GlintRenderLayer.DIRECT_GLINT.tryApply(cir.getReturnValue(), provider) : CITEnchantment.GlintRenderLayer.DIRECT_ENTITY_GLINT.tryApply(cir.getReturnValue(), provider); + if (vertexConsumer != null) + cir.setReturnValue(vertexConsumer); + } }
\ No newline at end of file diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemStackMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemStackMixin.java index 07faf22..7ac7a3a 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemStackMixin.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/citenchantment/ItemStackMixin.java @@ -2,7 +2,34 @@ package shcm.shsupercm.fabric.citresewn.mixin.citenchantment; import net.minecraft.item.ItemStack; 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.CallbackInfoReturnable; +import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig; +import shcm.shsupercm.fabric.citresewn.pack.cits.CITEnchantment; + +import java.lang.ref.WeakReference; +import java.util.List; +import java.util.function.Supplier; @Mixin(ItemStack.class) -public class ItemStackMixin { +public class ItemStackMixin implements CITEnchantment.Cached { + private WeakReference<List<CITEnchantment>> citresewn_cachedCITEnchantment = new WeakReference<>(null); + private long citresewn_cacheTimeCITEnchantment = 0; + + @Override + public List<CITEnchantment> citresewn_getCachedCITEnchantment(Supplier<List<CITEnchantment>> realtime) { + if (System.currentTimeMillis() - citresewn_cacheTimeCITEnchantment >= CITResewnConfig.INSTANCE().cache_ms) { + citresewn_cachedCITEnchantment = new WeakReference<>(realtime.get()); + citresewn_cacheTimeCITEnchantment = System.currentTimeMillis(); + } + + return citresewn_cachedCITEnchantment.get(); + } + + @Inject(method = "hasGlint", cancellable = true, at = @At("HEAD")) + private void disableDefaultGlint(CallbackInfoReturnable<Boolean> cir) { + if (CITEnchantment.appliedContext != null && !CITEnchantment.appliedContext.get(0).useGlint) + cir.setReturnValue(false); + } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java index db29fdd..7b6acde 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java @@ -252,7 +252,7 @@ public abstract class CIT { } public boolean test(ItemStack stack, Hand hand, World world, LivingEntity entity, boolean ignoreItemType) { - if (!ignoreItemType && !items.contains(stack.getItem())) + if (!ignoreItemType && !items.isEmpty() && !items.contains(stack.getItem())) return false; if (!damageAny && stack.getItem().isDamageable()) { diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITEnchantment.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITEnchantment.java index cd0b604..3c063db 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITEnchantment.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITEnchantment.java @@ -2,8 +2,13 @@ package shcm.shsupercm.fabric.citresewn.pack.cits; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.*; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; +import net.minecraft.world.World; +import shcm.shsupercm.fabric.citresewn.ActiveCITs; +import shcm.shsupercm.fabric.citresewn.CITResewn; import shcm.shsupercm.fabric.citresewn.ex.CITParseException; import shcm.shsupercm.fabric.citresewn.mixin.citenchantment.BufferBuilderStorageAccessor; import shcm.shsupercm.fabric.citresewn.mixin.citenchantment.RenderPhaseAccessor; @@ -11,11 +16,15 @@ import shcm.shsupercm.fabric.citresewn.pack.CITPack; import java.util.*; import java.util.function.Consumer; +import java.util.function.Supplier; public class CITEnchantment extends CIT { + public static List<CITEnchantment> appliedContext = null; + public final Identifier textureIdentifier; public final float speed, rotation, duration; public final int layer; + public final boolean useGlint; public final Blend blend; public final Map<GlintRenderLayer, RenderLayer> renderLayers = new EnumMap<>(GlintRenderLayer.class); @@ -27,15 +36,21 @@ public class CITEnchantment extends CIT { if (textureIdentifier == null) throw new Exception("Cannot resolve texture"); - layer = Integer.parseInt(properties.getProperty("layer", "0")); - - blend = Blend.valueOf(properties.getProperty("blend", "add").toUpperCase(Locale.ENGLISH)); - speed = Float.parseFloat(properties.getProperty("speed", "0")); rotation = Float.parseFloat(properties.getProperty("rotation", "0")); duration = Float.max(0f, Float.parseFloat(properties.getProperty("duration", "0"))); + + layer = Integer.parseInt(properties.getProperty("layer", "0")); + + useGlint = switch (properties.getProperty("useGlint", "false").toLowerCase(Locale.ENGLISH)) { + case "true" -> true; + case "false" -> false; + default -> throw new Exception("useGlint is not a boolean"); + }; + + blend = Blend.valueOf(properties.getProperty("blend", "add").toUpperCase(Locale.ENGLISH)); } catch (Exception e) { throw new CITParseException(pack.resourcePack, identifier, (e.getClass() == Exception.class ? "" : e.getClass().getSimpleName() + ": ") + e.getMessage()); } @@ -52,6 +67,7 @@ public class CITEnchantment extends CIT { @Override public void dispose() { + appliedContext = null; for (RenderLayer renderLayer : renderLayers.values()) ((BufferBuilderStorageAccessor) MinecraftClient.getInstance().getBufferBuilders()).entityBuilders().remove(renderLayer); } @@ -144,5 +160,20 @@ public class CITEnchantment extends CIT { 256, layer.build(false)); } + + public VertexConsumer tryApply(VertexConsumer base, VertexConsumerProvider provider) { + if (appliedContext == null) + return null; + + VertexConsumer applied = VertexConsumers.union(appliedContext.stream() + .map(cit -> provider.getBuffer(cit.renderLayers.get(GlintRenderLayer.this))) + .toArray(VertexConsumer[]::new)); + + return base == null ? applied : VertexConsumers.union(applied, base); + } + } + + public interface Cached { + List<CITEnchantment> citresewn_getCachedCITEnchantment(Supplier<List<CITEnchantment>> realtime); } }
\ No newline at end of file |