package net.minecraft.client.renderer.entity; import com.google.common.collect.Maps; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; import java.util.Map; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.Util; import net.minecraft.client.model.PandaModel; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.layers.PandaHoldsItemLayer; import net.minecraft.client.renderer.entity.state.PandaRenderState; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.entity.animal.Panda; @Environment(EnvType.CLIENT) public class PandaRenderer extends AgeableMobRenderer { private static final Map TEXTURES = Util.make(Maps.newEnumMap(Panda.Gene.class), enumMap -> { enumMap.put(Panda.Gene.NORMAL, ResourceLocation.withDefaultNamespace("textures/entity/panda/panda.png")); enumMap.put(Panda.Gene.LAZY, ResourceLocation.withDefaultNamespace("textures/entity/panda/lazy_panda.png")); enumMap.put(Panda.Gene.WORRIED, ResourceLocation.withDefaultNamespace("textures/entity/panda/worried_panda.png")); enumMap.put(Panda.Gene.PLAYFUL, ResourceLocation.withDefaultNamespace("textures/entity/panda/playful_panda.png")); enumMap.put(Panda.Gene.BROWN, ResourceLocation.withDefaultNamespace("textures/entity/panda/brown_panda.png")); enumMap.put(Panda.Gene.WEAK, ResourceLocation.withDefaultNamespace("textures/entity/panda/weak_panda.png")); enumMap.put(Panda.Gene.AGGRESSIVE, ResourceLocation.withDefaultNamespace("textures/entity/panda/aggressive_panda.png")); }); public PandaRenderer(EntityRendererProvider.Context context) { super(context, new PandaModel(context.bakeLayer(ModelLayers.PANDA)), new PandaModel(context.bakeLayer(ModelLayers.PANDA_BABY)), 0.9F); this.addLayer(new PandaHoldsItemLayer(this, context.getItemRenderer())); } public ResourceLocation getTextureLocation(PandaRenderState renderState) { return (ResourceLocation)TEXTURES.getOrDefault(renderState.variant, (ResourceLocation)TEXTURES.get(Panda.Gene.NORMAL)); } public PandaRenderState createRenderState() { return new PandaRenderState(); } public void extractRenderState(Panda entity, PandaRenderState reusedState, float partialTick) { super.extractRenderState(entity, reusedState, partialTick); reusedState.variant = entity.getVariant(); reusedState.isUnhappy = entity.getUnhappyCounter() > 0; reusedState.isSneezing = entity.isSneezing(); reusedState.sneezeTime = entity.getSneezeCounter(); reusedState.isEating = entity.isEating(); reusedState.isScared = entity.isScared(); reusedState.isSitting = entity.isSitting(); reusedState.sitAmount = entity.getSitAmount(partialTick); reusedState.lieOnBackAmount = entity.getLieOnBackAmount(partialTick); reusedState.rollAmount = entity.isBaby() ? 0.0F : entity.getRollAmount(partialTick); reusedState.rollTime = entity.rollCounter > 0 ? entity.rollCounter + partialTick : 0.0F; } protected void setupRotations(PandaRenderState renderState, PoseStack poseStack, float bodyRot, float scale) { super.setupRotations(renderState, poseStack, bodyRot, scale); if (renderState.rollTime > 0.0F) { float f = Mth.frac(renderState.rollTime); int i = Mth.floor(renderState.rollTime); int j = i + 1; float g = 7.0F; float h = renderState.isBaby ? 0.3F : 0.8F; if (i < 8.0F) { float k = 90.0F * i / 7.0F; float l = 90.0F * j / 7.0F; float m = this.getAngle(k, l, j, f, 8.0F); poseStack.translate(0.0F, (h + 0.2F) * (m / 90.0F), 0.0F); poseStack.mulPose(Axis.XP.rotationDegrees(-m)); } else if (i < 16.0F) { float k = (i - 8.0F) / 7.0F; float l = 90.0F + 90.0F * k; float n = 90.0F + 90.0F * (j - 8.0F) / 7.0F; float m = this.getAngle(l, n, j, f, 16.0F); poseStack.translate(0.0F, h + 0.2F + (h - 0.2F) * (m - 90.0F) / 90.0F, 0.0F); poseStack.mulPose(Axis.XP.rotationDegrees(-m)); } else if (i < 24.0F) { float k = (i - 16.0F) / 7.0F; float l = 180.0F + 90.0F * k; float n = 180.0F + 90.0F * (j - 16.0F) / 7.0F; float m = this.getAngle(l, n, j, f, 24.0F); poseStack.translate(0.0F, h + h * (270.0F - m) / 90.0F, 0.0F); poseStack.mulPose(Axis.XP.rotationDegrees(-m)); } else if (i < 32) { float k = (i - 24.0F) / 7.0F; float l = 270.0F + 90.0F * k; float n = 270.0F + 90.0F * (j - 24.0F) / 7.0F; float m = this.getAngle(l, n, j, f, 32.0F); poseStack.translate(0.0F, h * ((360.0F - m) / 90.0F), 0.0F); poseStack.mulPose(Axis.XP.rotationDegrees(-m)); } } float f = renderState.sitAmount; if (f > 0.0F) { poseStack.translate(0.0F, 0.8F * f, 0.0F); poseStack.mulPose(Axis.XP.rotationDegrees(Mth.lerp(f, renderState.xRot, renderState.xRot + 90.0F))); poseStack.translate(0.0F, -1.0F * f, 0.0F); if (renderState.isScared) { float o = (float)(Math.cos(renderState.ageInTicks * 1.25F) * Math.PI * 0.05F); poseStack.mulPose(Axis.YP.rotationDegrees(o)); if (renderState.isBaby) { poseStack.translate(0.0F, 0.8F, 0.55F); } } } float o = renderState.lieOnBackAmount; if (o > 0.0F) { float p = renderState.isBaby ? 0.5F : 1.3F; poseStack.translate(0.0F, p * o, 0.0F); poseStack.mulPose(Axis.XP.rotationDegrees(Mth.lerp(o, renderState.xRot, renderState.xRot + 180.0F))); } } private float getAngle(float currentAngle, float nextAngle, int nextRollCounter, float partialTick, float rollEndCount) { return nextRollCounter < rollEndCount ? Mth.lerp(partialTick, currentAngle, nextAngle) : currentAngle; } }