package net.minecraft.client.renderer.entity; import com.mojang.blaze3d.vertex.PoseStack; import java.util.Objects; import java.util.function.UnaryOperator; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.model.ShulkerModel; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.entity.EntityRendererProvider.Context; import net.minecraft.client.renderer.entity.state.ShulkerRenderState; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.monster.Shulker; import net.minecraft.world.item.DyeColor; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) public class ShulkerRenderer extends MobRenderer { private static final ResourceLocation DEFAULT_TEXTURE_LOCATION = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION .texture() .withPath((UnaryOperator)(string -> "textures/" + string + ".png")); private static final ResourceLocation[] TEXTURE_LOCATION = (ResourceLocation[])Sheets.SHULKER_TEXTURE_LOCATION .stream() .map(material -> material.texture().withPath((UnaryOperator)(string -> "textures/" + string + ".png"))) .toArray(ResourceLocation[]::new); public ShulkerRenderer(Context context) { super(context, new ShulkerModel(context.bakeLayer(ModelLayers.SHULKER)), 0.0F); } public Vec3 getRenderOffset(ShulkerRenderState shulkerRenderState) { return shulkerRenderState.renderOffset; } public boolean shouldRender(Shulker livingEntity, Frustum camera, double camX, double camY, double camZ) { if (super.shouldRender(livingEntity, camera, camX, camY, camZ)) { return true; } else { Vec3 vec3 = livingEntity.getRenderPosition(0.0F); if (vec3 == null) { return false; } else { EntityType entityType = livingEntity.getType(); float f = entityType.getHeight() / 2.0F; float g = entityType.getWidth() / 2.0F; Vec3 vec32 = Vec3.atBottomCenterOf(livingEntity.blockPosition()); return camera.isVisible(new AABB(vec3.x, vec3.y + f, vec3.z, vec32.x, vec32.y + f, vec32.z).inflate(g, f, g)); } } } public ResourceLocation getTextureLocation(ShulkerRenderState shulkerRenderState) { return getTextureLocation(shulkerRenderState.color); } public ShulkerRenderState createRenderState() { return new ShulkerRenderState(); } public void extractRenderState(Shulker shulker, ShulkerRenderState shulkerRenderState, float f) { super.extractRenderState(shulker, shulkerRenderState, f); shulkerRenderState.renderOffset = (Vec3)Objects.requireNonNullElse(shulker.getRenderPosition(f), Vec3.ZERO); shulkerRenderState.color = shulker.getColor(); shulkerRenderState.peekAmount = shulker.getClientPeekAmount(f); shulkerRenderState.yHeadRot = shulker.yHeadRot; shulkerRenderState.yBodyRot = shulker.yBodyRot; shulkerRenderState.attachFace = shulker.getAttachFace(); } public static ResourceLocation getTextureLocation(@Nullable DyeColor color) { return color == null ? DEFAULT_TEXTURE_LOCATION : TEXTURE_LOCATION[color.getId()]; } protected void setupRotations(ShulkerRenderState shulkerRenderState, PoseStack poseStack, float f, float g) { super.setupRotations(shulkerRenderState, poseStack, f + 180.0F, g); poseStack.rotateAround(shulkerRenderState.attachFace.getOpposite().getRotation(), 0.0F, 0.5F, 0.0F); } }