mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Disguises now render arms in first person
This commit is contained in:
parent
e7e88c4805
commit
e69749300d
7 changed files with 161 additions and 5 deletions
|
@ -89,7 +89,7 @@ public interface URenderers {
|
||||||
AccessoryFeatureRenderer.register(
|
AccessoryFeatureRenderer.register(
|
||||||
BraceletFeatureRenderer::new, AmuletFeatureRenderer::new, GlassesFeatureRenderer::new,
|
BraceletFeatureRenderer::new, AmuletFeatureRenderer::new, GlassesFeatureRenderer::new,
|
||||||
WingsFeatureRenderer::new, HornFeatureRenderer::new, IcarusWingsFeatureRenderer::new, BatWingsFeatureRenderer::new,
|
WingsFeatureRenderer::new, HornFeatureRenderer::new, IcarusWingsFeatureRenderer::new, BatWingsFeatureRenderer::new,
|
||||||
HeldEntityFeatureRenderer::new
|
HeldEntityFeatureRenderer::new, DisguisedArmsFeatureRenderer::new
|
||||||
);
|
);
|
||||||
|
|
||||||
EntityRendererRegistry.register(UEntities.THROWN_ITEM, FlyingItemEntityRenderer::new);
|
EntityRendererRegistry.register(UEntities.THROWN_ITEM, FlyingItemEntityRenderer::new);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback;
|
||||||
import com.minelittlepony.api.model.gear.IGear;
|
import com.minelittlepony.api.model.gear.IGear;
|
||||||
import com.minelittlepony.api.pony.IPony;
|
import com.minelittlepony.api.pony.IPony;
|
||||||
import com.minelittlepony.api.pony.IPonyData;
|
import com.minelittlepony.api.pony.IPonyData;
|
||||||
|
import com.minelittlepony.client.render.MobRenderers;
|
||||||
import com.minelittlepony.unicopia.*;
|
import com.minelittlepony.unicopia.*;
|
||||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||||
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
||||||
|
@ -19,6 +20,7 @@ import com.minelittlepony.unicopia.util.AnimationUtil;
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.passive.AllayEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
@ -106,6 +108,10 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Race getRace(Entity entity) {
|
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);
|
return IPony.getManager().getPony(entity).map(IPony::race).map(Main::toUnicopiaRace).orElse(Race.UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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<E extends LivingEntity> implements AccessoryFeatureRenderer.Feature<E> {
|
||||||
|
|
||||||
|
private final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
|
public DisguisedArmsFeatureRenderer(FeatureRendererContext<E, ? extends BipedEntityModel<E>> 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -124,12 +124,11 @@ class EntityDisguiseRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private BipedEntityModel<?> getBipedModel(Entity entity) {
|
static BipedEntityModel<?> getBipedModel(Entity entity) {
|
||||||
if (delegate.client.getEntityRenderDispatcher().getRenderer(entity) instanceof LivingEntityRenderer livingRenderer
|
if (MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof LivingEntityRenderer livingRenderer
|
||||||
&& livingRenderer.getModel() instanceof BipedEntityModel<?> biped) {
|
&& livingRenderer.getModel() instanceof BipedEntityModel<?> biped) {
|
||||||
return biped;
|
return biped;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,7 +276,8 @@ public class EntityBehaviour<T extends Entity> {
|
||||||
static {
|
static {
|
||||||
register(PlayerBehaviour::new, EntityType.PLAYER);
|
register(PlayerBehaviour::new, EntityType.PLAYER);
|
||||||
register(FallingBlockBehaviour::new, EntityType.FALLING_BLOCK);
|
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(HoppingBehaviour::new, EntityType.RABBIT, EntityType.SLIME, EntityType.MAGMA_CUBE);
|
||||||
register(TraderBehaviour::new, EntityType.VILLAGER, EntityType.WANDERING_TRADER);
|
register(TraderBehaviour::new, EntityType.VILLAGER, EntityType.WANDERING_TRADER);
|
||||||
register(SteedBehaviour::new, EntityType.HORSE, EntityType.DONKEY, EntityType.SKELETON_HORSE, EntityType.ZOMBIE_HORSE);
|
register(SteedBehaviour::new, EntityType.HORSE, EntityType.DONKEY, EntityType.SKELETON_HORSE, EntityType.ZOMBIE_HORSE);
|
||||||
|
|
|
@ -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<IronGolemEntity> {
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,9 @@ import com.minelittlepony.unicopia.util.TraceHelper;
|
||||||
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.mob.MobEntity;
|
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<T extends MobEntity> extends EntityBehaviour<T> {
|
public class MobBehaviour<T extends MobEntity> extends EntityBehaviour<T> {
|
||||||
|
|
||||||
|
@ -23,6 +26,13 @@ public class MobBehaviour<T extends MobEntity> extends EntityBehaviour<T> {
|
||||||
entity.tryAttack(target);
|
entity.tryAttack(target);
|
||||||
target.setAttacker(player.asEntity());
|
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) {
|
protected LivingEntity findTarget(Pony player, T entity) {
|
||||||
|
|
Loading…
Reference in a new issue