diff --git a/src/main/java/com/atsuishio/superbwarfare/block/ContainerBlock.java b/src/main/java/com/atsuishio/superbwarfare/block/ContainerBlock.java index 339e94fbb..bc9d3a2a5 100644 --- a/src/main/java/com/atsuishio/superbwarfare/block/ContainerBlock.java +++ b/src/main/java/com/atsuishio/superbwarfare/block/ContainerBlock.java @@ -85,7 +85,7 @@ public class ContainerBlock extends BaseEntityBlock { return containerBlockEntity.entity != null || containerBlockEntity.entityType != null; } - public boolean canOpen(Level pLevel, BlockPos pPos, EntityType entityType, Entity entity) { + public static boolean canOpen(Level pLevel, BlockPos pPos, EntityType entityType, Entity entity) { boolean flag = true; int w = 0; @@ -131,30 +131,28 @@ public class ContainerBlock extends BaseEntityBlock { public void appendHoverText(ItemStack pStack, @Nullable BlockGetter pLevel, List pTooltip, TooltipFlag pFlag) { super.appendHoverText(pStack, pLevel, pTooltip, pFlag); CompoundTag tag = BlockItem.getBlockEntityData(pStack); - if (tag != null) { - if (tag.contains("EntityType")) { - String s = getTranslationKey(tag.getString("EntityType")); - pTooltip.add(Component.translatable(s == null ? "des.superbwarfare.container.empty" : s).withStyle(ChatFormatting.GRAY)); + if (tag != null && tag.contains("EntityType")) { + String s = getTranslationKey(tag.getString("EntityType")); + pTooltip.add(Component.translatable(s == null ? "des.superbwarfare.container.empty" : s).withStyle(ChatFormatting.GRAY)); - var entityType = EntityType.byString(tag.getString("EntityType")).orElse(null); - if (entityType != null) { - int w = 0, h = 0; - if (pLevel instanceof Level level && tag.contains("Entity")) { - var entity = entityType.create(level); - if (entity != null) { - entity.load(tag.getCompound("Entity")); - w = (int) (entity.getType().getDimensions().width + 1); - if (w % 2 == 0) w++; - h = (int) (entity.getType().getDimensions().height + 1); - } - } else { - w = (int) (entityType.getDimensions().width + 1); + var entityType = EntityType.byString(tag.getString("EntityType")).orElse(null); + if (entityType != null) { + int w = 0, h = 0; + if (pLevel instanceof Level level && tag.contains("Entity")) { + var entity = entityType.create(level); + if (entity != null) { + entity.load(tag.getCompound("Entity")); + w = (int) (entity.getType().getDimensions().width + 1); if (w % 2 == 0) w++; - h = (int) (entityType.getDimensions().height + 1); - } - if (w != 0 && h != 0) { - pTooltip.add(Component.literal(w + " x " + w + " x " + h).withStyle(ChatFormatting.YELLOW)); + h = (int) (entity.getType().getDimensions().height + 1); } + } else { + w = (int) (entityType.getDimensions().width + 1); + if (w % 2 == 0) w++; + h = (int) (entityType.getDimensions().height + 1); + } + if (w != 0 && h != 0) { + pTooltip.add(Component.literal(w + " x " + w + " x " + h).withStyle(ChatFormatting.YELLOW)); } } } diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/special/ContainerBlockPreview.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/special/ContainerBlockPreview.java new file mode 100644 index 000000000..82fec8fc7 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/special/ContainerBlockPreview.java @@ -0,0 +1,129 @@ +package com.atsuishio.superbwarfare.client.renderer.special; + +import com.atsuishio.superbwarfare.block.ContainerBlock; +import com.atsuishio.superbwarfare.block.entity.ContainerBlockEntity; +import com.atsuishio.superbwarfare.client.renderer.CustomRenderType; +import com.atsuishio.superbwarfare.item.Crowbar; +import net.minecraft.client.Minecraft; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.RenderLevelStageEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT) +public class ContainerBlockPreview { + @SubscribeEvent + public static void render(RenderLevelStageEvent event) { + if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) { + return; + } + + var player = Minecraft.getInstance().player; + assert player != null; + + // 仅在手持撬棍时检测 + var item = player.getMainHandItem(); + if (!(item.getItem() instanceof Crowbar)) return; + + var level = player.level(); + var look = player.getLookAngle(); + + // 查找玩家看向方块 + int distance = 32; + var start = player.position().add(0, player.getEyeHeight(), 0); + var end = player.position().add(look.x * distance, look.y * distance + player.getEyeHeight(), look.z * distance); + var context = new ClipContext(start, end, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player); + var result = player.level().clip(context); + + if (result.getType().equals(BlockHitResult.Type.MISS)) return; + + // 获取集装箱 + var blockEntity = level.getBlockEntity(result.getBlockPos()); + if (!(blockEntity instanceof ContainerBlockEntity container)) return; + + // 获取实体信息 + var entityType = container.entityType; + var entity = container.entity; + + int w = 0, h = 0; + if (entityType != null) { + w = (int) (entityType.getDimensions().width / 2 + 1); + h = (int) (entityType.getDimensions().height + 1); + } + if (entity != null) { + w = (int) (entity.getType().getDimensions().width / 2 + 1); + h = (int) (entity.getType().getDimensions().height + 1); + } + if (w == 0 || h == 0) return; + + var poseStack = event.getPoseStack(); + poseStack.pushPose(); + var pos = container.getBlockPos(); + var view = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); + poseStack.translate(pos.getX() - view.x, pos.getY() - view.y + 1, pos.getZ() - view.z); + + // 什么b位置 + var aabb = new AABB(pos) + .inflate(w, 0, w) + .expandTowards(0, h - 1, 0) + .move(0, -1, 0); + + float startX = (float) aabb.minX - 0.001f - pos.getX(); + float startY = (float) aabb.minY - 0.001f - pos.getY(); + float startZ = (float) aabb.minZ - 0.001f - pos.getZ(); + float endX = (float) aabb.maxX + 0.001f - pos.getX(); + float endY = (float) aabb.maxY + 0.001f - pos.getY(); + float endZ = (float) aabb.maxZ + 0.001f - pos.getZ(); + + var hasEnoughSpace = ContainerBlock.canOpen(level, pos, entityType, entity); + + var red = hasEnoughSpace ? 0 : 1; + var green = 1 - red; + var blue = 0.0f; + var alpha = 0.2f; + + var builder = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(CustomRenderType.BLOCK_OVERLAY); + var m4f = poseStack.last().pose(); + + // east + builder.vertex(m4f, startX, startY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, startX, endY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, endY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, startY, startZ).color(red, green, blue, alpha).endVertex(); + + // west + builder.vertex(m4f, startX, startY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, startY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, endY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, startX, endY, endZ).color(red, green, blue, alpha).endVertex(); + + // south + builder.vertex(m4f, endX, startY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, endY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, endY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, startY, endZ).color(red, green, blue, alpha).endVertex(); + + // north + builder.vertex(m4f, startX, startY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, startX, startY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, startX, endY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, startX, endY, startZ).color(red, green, blue, alpha).endVertex(); + + // top + builder.vertex(m4f, startX, endY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, endY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, endY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, startX, endY, endZ).color(red, green, blue, alpha).endVertex(); + + // bottom + builder.vertex(m4f, startX, startY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, startY, startZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, endX, startY, endZ).color(red, green, blue, alpha).endVertex(); + builder.vertex(m4f, startX, startY, endZ).color(red, green, blue, alpha).endVertex(); + + poseStack.popPose(); + } +}