ConstructionWand/src/main/java/thetadev/constructionwand/client/RenderBlockPreview.java
2023-06-01 17:54:48 +02:00

81 lines
3.3 KiB
Java

package thetadev.constructionwand.client;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraftforge.client.event.DrawHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import thetadev.constructionwand.basics.WandUtil;
import thetadev.constructionwand.items.wand.ItemWand;
import thetadev.constructionwand.wand.WandJob;
import java.util.Set;
public class RenderBlockPreview
{
private WandJob wandJob;
public Set<BlockPos> undoBlocks;
@SubscribeEvent
public void renderBlockHighlight(DrawHighlightEvent event) {
if(event.getTarget().getType() != RayTraceResult.Type.BLOCK) return;
BlockRayTraceResult rtr = (BlockRayTraceResult) event.getTarget();
Entity entity = event.getInfo().getRenderViewEntity();
if(!(entity instanceof PlayerEntity)) return;
PlayerEntity player = (PlayerEntity) entity;
Set<BlockPos> blocks;
float colorR = 0, colorG = 0, colorB = 0;
ItemStack wand = WandUtil.holdingWand(player);
if(wand == null) return;
if(!(player.isCrouching() && ClientEvents.isOptKeyDown())) {
// Use cached wandJob for previews of the same target pos/dir
// Exception: always update if blockCount < 2 to prevent 1-block previews when block updates
// from the last placement are lagging
if(wandJob == null || !compareRTR(wandJob.rayTraceResult, rtr) || !(wandJob.wand.equals(wand))
|| wandJob.blockCount() < 2) {
wandJob = ItemWand.getWandJob(player, player.getEntityWorld(), rtr, wand);
}
blocks = wandJob.getBlockPositions();
}
else {
blocks = undoBlocks;
colorG = 1;
}
if(blocks == null || blocks.isEmpty()) return;
MatrixStack ms = event.getMatrix();
IRenderTypeBuffer buffer = event.getBuffers();
IVertexBuilder lineBuilder = buffer.getBuffer(RenderTypes.TRANSLUCENT_LINES);
double partialTicks = event.getPartialTicks();
double d0 = player.lastTickPosX + (player.getPosX() - player.lastTickPosX) * partialTicks;
double d1 = player.lastTickPosY + player.getEyeHeight() + (player.getPosY() - player.lastTickPosY) * partialTicks;
double d2 = player.lastTickPosZ + (player.getPosZ() - player.lastTickPosZ) * partialTicks;
ms.push();
for(BlockPos block : blocks) {
AxisAlignedBB aabb = new AxisAlignedBB(block).offset(-d0, -d1, -d2);
WorldRenderer.drawBoundingBox(ms, lineBuilder, aabb, colorR, colorG, colorB, 0.4F);
}
ms.pop();
event.setCanceled(true);
}
private static boolean compareRTR(BlockRayTraceResult rtr1, BlockRayTraceResult rtr2) {
return rtr1.getPos().equals(rtr2.getPos()) && rtr1.getFace().equals(rtr2.getFace());
}
}