Hey, I've managed to fix most issues. The approach I took was to copy most of the PlayerRenderer code and adjust it to my needs in the RenderPlayerEvent.Pre. Now, the issue I have is that I can't get the armor to render. I see that in the PlayerRenderer constructor the armor layers are set up from something called EntityRendererProvider.Context, but I can't seem to find where to get this context from.
I did try to extend the PlayerRenderer class into my own with my needed modifications, but I can't seem to register it as a replacement to the vanilla PlayerRenderer. Altough I'm thinking this might not be the best approach because it might make other mods incompatible.
This is the relevant code of the RenderEvent if needed:
@SubscribeEvent
public static void onPlayerRender(RenderPlayerEvent.Pre event) {
// Note: conditions are not yet setup, I'll do it once I get the render right
event.setCanceled(true);
final PoseStack poseStack = event.getPoseStack();
final MultiBufferSource buffer = event.getMultiBufferSource();
final PlayerRenderer renderer = event.getRenderer();
final PlayerModel<AbstractClientPlayer> playerModel = renderer.getModel();
final Entity entity = event.getEntity();
final float ticks = event.getPartialTick();
final LivingEntity livingEntity = event.getEntityLiving();
final AbstractClientPlayer abstractPlayer = (AbstractClientPlayer) event.getPlayer();
event.getPoseStack().pushPose();
// Set the model attack time
playerModel.attackTime = event.getEntityLiving().attackAnim;
boolean shouldSit = entity.isPassenger() && (entity.getVehicle() != null && entity.getVehicle().shouldRiderSit());
playerModel.riding = shouldSit;
playerModel.young = false;
float f = Mth.rotLerp(ticks, livingEntity.yBodyRotO, livingEntity.yBodyRot);
float f1 = Mth.rotLerp(ticks, livingEntity.yHeadRotO, livingEntity.yHeadRot);
float f2 = f1 - f;
if (shouldSit && entity.getVehicle() instanceof LivingEntity) {
LivingEntity livingentity = (LivingEntity)entity.getVehicle();
f = Mth.rotLerp(ticks, livingentity.yBodyRotO, livingentity.yBodyRot);
f2 = f1 - f;
float f3 = Mth.wrapDegrees(f2);
if (f3 < -85.0F) {
f3 = -85.0F;
}
if (f3 >= 85.0F) {
f3 = 85.0F;
}
f = f1 - f3;
if (f3 * f3 > 2500.0F) {
f += f3 * 0.2F;
}
f2 = f1 - f;
}
float f6 = Mth.lerp(ticks, livingEntity.xRotO, livingEntity.getXRot());
if (LivingEntityRenderer.isEntityUpsideDown(livingEntity)) {
f6 *= -1.0F;
f2 *= -1.0F;
}
if (livingEntity.getPose() == Pose.SLEEPING) {
Direction direction = livingEntity.getBedOrientation();
if (direction != null) {
float f4 = livingEntity.getEyeHeight(Pose.STANDING) - 0.1F;
poseStack.translate((double)((float)(-direction.getStepX()) * f4), 0.0D, (double)((float)(-direction.getStepZ()) * f4));
}
}
float f7 = livingEntity.tickCount + ticks;
setupRotations(livingEntity, poseStack, f7, f, ticks);
poseStack.scale(-1.0F, -1.0F, 1.0F);
poseStack.translate(0.0D, (double)-1.501F, 0.0D);
float f8 = 0.0F;
float f5 = 0.0F;
if (!shouldSit && livingEntity.isAlive()) {
f8 = Mth.lerp(ticks, livingEntity.animationSpeedOld, livingEntity.animationSpeed);
f5 = livingEntity.animationPosition - livingEntity.animationSpeed * (1.0F - ticks);
if (livingEntity.isBaby()) {
f5 *= 3.0F;
}
if (f8 > 1.0F) {
f8 = 1.0F;
}
}
playerModel.prepareMobModel((AbstractClientPlayer) livingEntity, f5, f8, ticks);
playerModel.setupAnim((AbstractClientPlayer) livingEntity, f5, f8, f7, f2, f6);
// This is the part responsible for making the player translucent, specifically the RenderType#itemEntityTranslucentCull
event.getRenderer().getModel().renderToBuffer(
event.getPoseStack(),
event.getMultiBufferSource()
.getBuffer(
RenderType.itemEntityTranslucentCull(
event.getRenderer().getTextureLocation((AbstractClientPlayer) event.getPlayer()))), event.getPackedLight(), 0, 1.0f, 1.0f, 1.0f, 0.8f);
event.getPoseStack().popPose();
}
// Direct copy of PlayerRenderer#setupRotations
private static void setupRotations(LivingEntity entityLiving, PoseStack pMatrixStack, float pAgeInTicks, float pRotationYaw, float pPartialTicks) {
if (entityLiving.isFullyFrozen()) {
pRotationYaw += (float)(Math.cos((double)entityLiving.tickCount * 3.25D) * Math.PI * (double)0.4F);
}
Pose pose = entityLiving.getPose();
if (pose != Pose.SLEEPING) {
pMatrixStack.mulPose(Vector3f.YP.rotationDegrees(180.0F - pRotationYaw));
}
if (entityLiving.deathTime > 0) {
float f = ((float)entityLiving.deathTime + pPartialTicks - 1.0F) / 20.0F * 1.6F;
f = Mth.sqrt(f);
if (f > 1.0F) {
f = 1.0F;
}
pMatrixStack.mulPose(Vector3f.ZP.rotationDegrees(f * 90.0F));
} else if (entityLiving.isAutoSpinAttack()) {
pMatrixStack.mulPose(Vector3f.XP.rotationDegrees(-90.0F - entityLiving.getXRot()));
pMatrixStack.mulPose(Vector3f.YP.rotationDegrees(((float)entityLiving.tickCount + pPartialTicks) * -75.0F));
} else if (pose == Pose.SLEEPING) {
Direction direction = entityLiving.getBedOrientation();
float f1 = direction != null ? sleepDirectionToRotation(direction) : pRotationYaw;
pMatrixStack.mulPose(Vector3f.YP.rotationDegrees(f1));
pMatrixStack.mulPose(Vector3f.ZP.rotationDegrees(90.0F));
pMatrixStack.mulPose(Vector3f.YP.rotationDegrees(270.0F));
} else if (LivingEntityRenderer.isEntityUpsideDown(entityLiving)) {
pMatrixStack.translate(0.0D, (double)(entityLiving.getBbHeight() + 0.1F), 0.0D);
pMatrixStack.mulPose(Vector3f.ZP.rotationDegrees(180.0F));
}
}
// Direct copy of PlayerRenderer#sleepDirectionToRotation
private static float sleepDirectionToRotation(Direction pFacing) {
switch(pFacing) {
case SOUTH:
return 90.0F;
case WEST:
return 0.0F;
case NORTH:
return 270.0F;
case EAST:
return 180.0F;
default:
return 0.0F;
}
}
}