package net.minecraft.client.renderer.blockentity; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Axis; import java.util.Calendar; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.model.ChestModel; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context; import net.minecraft.client.resources.model.Material; import net.minecraft.core.Direction; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.AbstractChestBlock; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.ChestBlock; import net.minecraft.world.level.block.DoubleBlockCombiner.Combiner; import net.minecraft.world.level.block.DoubleBlockCombiner.NeighborCombineResult; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.ChestBlockEntity; import net.minecraft.world.level.block.entity.LidBlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.ChestType; import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.phys.Vec3; @Environment(EnvType.CLIENT) public class ChestRenderer implements BlockEntityRenderer { private final ChestModel singleModel; private final ChestModel doubleLeftModel; private final ChestModel doubleRightModel; private final boolean xmasTextures = xmasTextures(); public ChestRenderer(Context context) { this.singleModel = new ChestModel(context.bakeLayer(ModelLayers.CHEST)); this.doubleLeftModel = new ChestModel(context.bakeLayer(ModelLayers.DOUBLE_CHEST_LEFT)); this.doubleRightModel = new ChestModel(context.bakeLayer(ModelLayers.DOUBLE_CHEST_RIGHT)); } public static boolean xmasTextures() { Calendar calendar = Calendar.getInstance(); return calendar.get(2) + 1 == 12 && calendar.get(5) >= 24 && calendar.get(5) <= 26; } @Override public void render(T blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, Vec3 cameraPos) { Level level = blockEntity.getLevel(); boolean bl = level != null; BlockState blockState = bl ? blockEntity.getBlockState() : Blocks.CHEST.defaultBlockState().setValue((Property)ChestBlock.FACING, Direction.SOUTH); ChestType chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE; if (blockState.getBlock() instanceof AbstractChestBlock abstractChestBlock) { boolean bl2 = chestType != ChestType.SINGLE; poseStack.pushPose(); float f = ((Direction)blockState.getValue((Property)ChestBlock.FACING)).toYRot(); poseStack.translate(0.5F, 0.5F, 0.5F); poseStack.mulPose(Axis.YP.rotationDegrees(-f)); poseStack.translate(-0.5F, -0.5F, -0.5F); NeighborCombineResult neighborCombineResult; if (bl) { neighborCombineResult = abstractChestBlock.combine(blockState, level, blockEntity.getBlockPos(), true); } else { neighborCombineResult = Combiner::acceptNone; } float g = neighborCombineResult.apply(ChestBlock.opennessCombiner(blockEntity)).get(partialTick); g = 1.0F - g; g = 1.0F - g * g * g; int i = neighborCombineResult.apply(new BrightnessCombiner<>()).applyAsInt(packedLight); Material material = Sheets.chooseMaterial(blockEntity, chestType, this.xmasTextures); VertexConsumer vertexConsumer = material.buffer(bufferSource, RenderType::entityCutout); if (bl2) { if (chestType == ChestType.LEFT) { this.render(poseStack, vertexConsumer, this.doubleLeftModel, g, i, packedOverlay); } else { this.render(poseStack, vertexConsumer, this.doubleRightModel, g, i, packedOverlay); } } else { this.render(poseStack, vertexConsumer, this.singleModel, g, i, packedOverlay); } poseStack.popPose(); } } private void render(PoseStack poseStack, VertexConsumer buffer, ChestModel model, float openness, int packedLight, int packedOverlay) { model.setupAnim(openness); model.renderToBuffer(poseStack, buffer, packedLight, packedOverlay); } }