package com.thebrokenrail.energonrelics.client.block.entity.render; import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.api.block.entity.core.EnergyReceiverBlockEntity; import com.thebrokenrail.energonrelics.mixin.RenderPhaseAccessor; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderPhase; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexFormats; import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.Vector3f; import net.minecraft.item.ItemStack; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Matrix4f; import java.util.Objects; @Environment(EnvType.CLIENT) public class HighlightBlockEntityRenderer extends BlockEntityRenderer { public HighlightBlockEntityRenderer(BlockEntityRenderDispatcher dispatcher) { super(dispatcher); } private static RenderLayer getLayer(Identifier texture) { return RenderLayer.of(EnergonRelics.NAMESPACE + ":highlight", VertexFormats.POSITION_COLOR, 7, 256, false, true, RenderLayer.MultiPhaseParameters.builder().writeMaskState(RenderPhaseAccessor.getCOLOR_MASK()).transparency(RenderPhaseAccessor.getTRANSLUCENT_TRANSPARENCY()).layering(RenderPhaseAccessor.getVIEW_OFFSET_Z_LAYERING()).texture(new RenderPhase.Texture(texture, false, false)).fog(RenderPhaseAccessor.getNO_FOG()).cull(RenderPhaseAccessor.getENABLE_CULLING()).build(false)); } private static final RenderLayer SELECTED_LAYER = getLayer(new Identifier(EnergonRelics.NAMESPACE, "textures/entity/selected_energy_block.png")); private static final RenderLayer UNSELECTED_LAYER = getLayer(new Identifier(EnergonRelics.NAMESPACE, "textures/entity/unselected_energy_block.png")); @Override public void render(BlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) { matrices.push(); if (entity instanceof EnergyReceiverBlockEntity) { MinecraftClient client = MinecraftClient.getInstance(); assert client.player != null; ItemStack stack = client.player.getStackInHand(Hand.MAIN_HAND); if (stack.getItem() == EnergonRelics.Items.NETWORK_CHIP_ITEM) { boolean contains = ((EnergyReceiverBlockEntity) entity).contains(EnergonRelics.Items.NETWORK_CHIP_ITEM.getID(stack)); if (!contains) { renderCuboid(entity, matrices, vertexConsumers.getBuffer(UNSELECTED_LAYER)); } else { renderCuboid(entity, matrices, vertexConsumers.getBuffer(SELECTED_LAYER)); } } } matrices.pop(); } private static boolean shouldDrawSide(BlockEntity entity, Direction side) { BlockState state = entity.getCachedState(); return Block.shouldDrawSide(state, Objects.requireNonNull(entity.getWorld()), entity.getPos(), side); } protected static void renderCuboid(BlockEntity entity, MatrixStack matrices, VertexConsumer consumer) { float sizeX = 1f; float sizeY = 1f; float sizeZ = 1f; matrices.translate(0.5d, 0.5d, 0.5d); for (Direction side : Direction.values()) { if (shouldDrawSide(entity, side)) { matrices.push(); multiply(matrices, side); Matrix4f model = matrices.peek().getModel(); vertex(consumer, model, -0.5f, -0.5f, -0.5f); vertex(consumer, model, -0.5f, -0.5f + sizeY, -0.5f); vertex(consumer, model, -0.5f + sizeX, -0.5f + sizeY, -0.5f); vertex(consumer, model, -0.5f + sizeX, -0.5f, -0.5f); matrices.pop(); } } } private static void vertex(VertexConsumer consumer, Matrix4f model, float x, float y, float z) { consumer.vertex(model, x, y, z).color(1f, 1f, 1f, 1f).next(); } private static void multiply(MatrixStack matrices, Direction side) { switch (side) { case NORTH: { break; } case SOUTH: { matrices.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(180)); break; } case EAST: { matrices.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(-90)); break; } case WEST: { matrices.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90)); break; } case UP: { matrices.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90)); break; } case DOWN: { matrices.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(-90)); break; } } } }