From e69749300d936055aa0d9c6c30fadacfbf83a561 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 13 Feb 2024 23:51:21 +0000 Subject: [PATCH] Disguises now render arms in first person --- .../unicopia/client/URenderers.java | 2 +- .../unicopia/client/minelittlepony/Main.java | 6 + .../render/DisguisedArmsFeatureRenderer.java | 122 ++++++++++++++++++ .../client/render/EntityDisguiseRenderer.java | 5 +- .../entity/behaviour/EntityBehaviour.java | 3 +- .../entity/behaviour/IronGolemBehaviour.java | 18 +++ .../entity/behaviour/MobBehaviour.java | 10 ++ 7 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/render/DisguisedArmsFeatureRenderer.java create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/behaviour/IronGolemBehaviour.java diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index e7e15b4e..4f436d79 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -89,7 +89,7 @@ public interface URenderers { AccessoryFeatureRenderer.register( BraceletFeatureRenderer::new, AmuletFeatureRenderer::new, GlassesFeatureRenderer::new, WingsFeatureRenderer::new, HornFeatureRenderer::new, IcarusWingsFeatureRenderer::new, BatWingsFeatureRenderer::new, - HeldEntityFeatureRenderer::new + HeldEntityFeatureRenderer::new, DisguisedArmsFeatureRenderer::new ); EntityRendererRegistry.register(UEntities.THROWN_ITEM, FlyingItemEntityRenderer::new); diff --git a/src/main/java/com/minelittlepony/unicopia/client/minelittlepony/Main.java b/src/main/java/com/minelittlepony/unicopia/client/minelittlepony/Main.java index 1f6537c3..abb6659e 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/minelittlepony/Main.java +++ b/src/main/java/com/minelittlepony/unicopia/client/minelittlepony/Main.java @@ -11,6 +11,7 @@ import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback; import com.minelittlepony.api.model.gear.IGear; import com.minelittlepony.api.pony.IPony; import com.minelittlepony.api.pony.IPonyData; +import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.unicopia.*; import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; @@ -19,6 +20,7 @@ import com.minelittlepony.unicopia.util.AnimationUtil; import net.fabricmc.api.ClientModInitializer; import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.AllayEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; @@ -106,6 +108,10 @@ public class Main extends MineLPDelegate implements ClientModInitializer { @Override public Race getRace(Entity entity) { + if (entity instanceof AllayEntity) { + return MobRenderers.ALLAY.get() ? Race.PEGASUS : Race.HUMAN; + } + return IPony.getManager().getPony(entity).map(IPony::race).map(Main::toUnicopiaRace).orElse(Race.UNSET); } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/DisguisedArmsFeatureRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/DisguisedArmsFeatureRenderer.java new file mode 100644 index 00000000..9393262e --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/DisguisedArmsFeatureRenderer.java @@ -0,0 +1,122 @@ +package com.minelittlepony.unicopia.client.render; + +import com.google.common.base.MoreObjects; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.client.FirstPersonRendererOverrides.ArmRenderer; +import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate; +import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.model.ModelPart; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.LivingEntityRenderer; +import net.minecraft.client.render.entity.feature.FeatureRendererContext; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.ZombieEntity; +import net.minecraft.util.Arm; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RotationAxis; + +public class DisguisedArmsFeatureRenderer implements AccessoryFeatureRenderer.Feature { + + private final MinecraftClient client = MinecraftClient.getInstance(); + + public DisguisedArmsFeatureRenderer(FeatureRendererContext> context) { + + } + + @Override + public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, E entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { + } + + @Override + public boolean beforeRenderArms(ArmRenderer sender, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, E entity, int light) { + Entity appearance = getAppearance(entity); + if (appearance instanceof LivingEntity l) { + float swingProgress = entity.getHandSwingProgress(MinecraftClient.getInstance().getTickDelta()); + + Hand hand = MoreObjects.firstNonNull(entity.preferredHand, Hand.MAIN_HAND); + + //renderArmHoldingItem(l, matrices, vertexConsumers, light, 0, swingProgress, Arm.RIGHT); + + boolean bothHands = l instanceof ZombieEntity; + + if (bothHands || hand == Hand.MAIN_HAND) { + if (entity.getMainHandStack().isEmpty()) { + matrices.push(); + renderArmHoldingItem(l, matrices, vertexConsumers, light, 1 - sender.getEquipProgress(Hand.MAIN_HAND, tickDelta), hand == Hand.MAIN_HAND ? swingProgress : 0, entity.getMainArm()); + matrices.pop(); + } + } + + if (bothHands || hand == Hand.OFF_HAND) { + if (entity.getOffHandStack().isEmpty()) { + matrices.push(); + renderArmHoldingItem(l, matrices, vertexConsumers, light, 1 - sender.getEquipProgress(Hand.OFF_HAND, tickDelta), hand == Hand.OFF_HAND ? swingProgress : 0, entity.getMainArm().getOpposite()); + matrices.pop(); + } + } + } + + return false; + } + + private Entity getAppearance(E entity) { + return Caster.of(entity).flatMap(caster -> caster.getSpellSlot().get(SpellPredicate.IS_DISGUISE, false)).map(Disguise.class::cast) + .flatMap(Disguise::getAppearance) + .map(EntityAppearance::getAppearance) + .orElse(null); + } + + @SuppressWarnings("unchecked") + private void renderArmHoldingItem(LivingEntity entity, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, Arm arm) { + if (!(client.getEntityRenderDispatcher().getRenderer(entity) instanceof LivingEntityRenderer renderer)) { + return; + } + if (!(renderer.getModel() instanceof BipedEntityModel bipedModel)) { + return; + } + + boolean bl = arm != Arm.LEFT; + float f = bl ? 1.0f : -1.0f; + float g = MathHelper.sqrt(swingProgress); + float h = -0.3f * MathHelper.sin(g * (float)Math.PI); + float i = 0.4f * MathHelper.sin(g * ((float)Math.PI * 2)); + float j = -0.4f * MathHelper.sin(swingProgress * (float)Math.PI); + matrices.translate(f * (h + 0.64000005f), i + -0.6f + equipProgress * -0.6f, j + -0.71999997f); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(f * 45.0f)); + float k = MathHelper.sin(swingProgress * swingProgress * (float)Math.PI); + float l = MathHelper.sin(g * (float)Math.PI); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(f * l * 70.0f)); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(f * k * -20.0f)); + + Identifier texture = renderer.getTexture(entity); + RenderSystem.setShaderTexture(0, texture); + matrices.translate(f * -1.0f, 3.6f, 3.5f); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(f * 120.0f)); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(200.0f)); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(f * -135.0f)); + matrices.translate(f * 5.6f, 0.0f, 0.0f); + + bipedModel.animateModel(entity, 0, 0, 0); + bipedModel.setAngles(entity, 0, 0, 0, 0, 0); + ModelPart part = bl ? bipedModel.rightArm : bipedModel.leftArm; + part.pitch = 0; + + if (MineLPDelegate.getInstance().getRace(entity).isEquine()) { + matrices.translate(0, -part.pivotY / 16F, 0); + } + + part.render(matrices, vertexConsumers.getBuffer(RenderLayer.getEntityTranslucent(texture)), light, OverlayTexture.DEFAULT_UV); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java index 19fe7fcc..1e0aba0c 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java @@ -124,12 +124,11 @@ class EntityDisguiseRenderer { } @Nullable - private BipedEntityModel getBipedModel(Entity entity) { - if (delegate.client.getEntityRenderDispatcher().getRenderer(entity) instanceof LivingEntityRenderer livingRenderer + static BipedEntityModel getBipedModel(Entity entity) { + if (MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof LivingEntityRenderer livingRenderer && livingRenderer.getModel() instanceof BipedEntityModel biped) { return biped; } return null; } - } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java index b37e06df..a04113e6 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java @@ -276,7 +276,8 @@ public class EntityBehaviour { static { register(PlayerBehaviour::new, EntityType.PLAYER); register(FallingBlockBehaviour::new, EntityType.FALLING_BLOCK); - register(MobBehaviour::new, EntityType.RAVAGER, EntityType.IRON_GOLEM); + register(MobBehaviour::new, EntityType.RAVAGER); + register(IronGolemBehaviour::new, EntityType.IRON_GOLEM); register(HoppingBehaviour::new, EntityType.RABBIT, EntityType.SLIME, EntityType.MAGMA_CUBE); register(TraderBehaviour::new, EntityType.VILLAGER, EntityType.WANDERING_TRADER); register(SteedBehaviour::new, EntityType.HORSE, EntityType.DONKEY, EntityType.SKELETON_HORSE, EntityType.ZOMBIE_HORSE); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/IronGolemBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/IronGolemBehaviour.java new file mode 100644 index 00000000..f0ba9640 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/IronGolemBehaviour.java @@ -0,0 +1,18 @@ +package com.minelittlepony.unicopia.entity.behaviour; + +import com.minelittlepony.unicopia.entity.player.Pony; + +import net.minecraft.entity.passive.IronGolemEntity; +import net.minecraft.item.Items; +import net.minecraft.util.Hand; + +public class IronGolemBehaviour extends MobBehaviour { + @Override + public void update(Pony player, IronGolemEntity entity, Disguise spell) { + super.update(player, entity, spell); + boolean hasPoppy = player.asEntity().getStackInHand(Hand.MAIN_HAND).isOf(Items.POPPY); + if (hasPoppy != entity.getLookingAtVillagerTicks() > 0) { + entity.setLookingAtVillager(hasPoppy); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java index a56ae3d9..450b8a61 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java @@ -5,6 +5,9 @@ import com.minelittlepony.unicopia.util.TraceHelper; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.passive.IronGolemEntity; +import net.minecraft.item.Items; +import net.minecraft.util.Hand; public class MobBehaviour extends EntityBehaviour { @@ -23,6 +26,13 @@ public class MobBehaviour extends EntityBehaviour { entity.tryAttack(target); target.setAttacker(player.asEntity()); } + + if (entity instanceof IronGolemEntity i) { + boolean hasPoppy = player.asEntity().getStackInHand(Hand.MAIN_HAND).isOf(Items.POPPY); + if (hasPoppy != i.getLookingAtVillagerTicks() > 0) { + i.setLookingAtVillager(hasPoppy); + } + } } protected LivingEntity findTarget(Pony player, T entity) {