Skip to content

Commit a963ff9

Browse files
committed
wip
1 parent b619a36 commit a963ff9

4 files changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package de.rettichlp;
2+
3+
import net.minecraft.client.MinecraftClient;
4+
import net.minecraft.entity.player.PlayerEntity;
5+
import net.minecraft.util.math.BlockPos;
6+
import net.minecraft.world.World;
7+
8+
import java.util.Optional;
9+
10+
import static java.util.Optional.ofNullable;
11+
12+
public class AddonPlayer {
13+
14+
private final MinecraftClient minecraftClient;
15+
16+
public AddonPlayer(MinecraftClient minecraftClient) {
17+
this.minecraftClient = minecraftClient;
18+
}
19+
20+
public PlayerEntity getPlayer() {
21+
return this.minecraftClient.player;
22+
}
23+
24+
public Optional<World> getWorld() {
25+
return getPlayer().getWorld();
26+
}
27+
28+
public BlockPos getBlockPos() {
29+
return getPlayer().getBlockPos();
30+
}
31+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
package de.rettichlp;
22

3+
import de.rettichlp.listener.ChatListener;
4+
import de.rettichlp.render.WorldBlockHighlighter;
35
import net.fabricmc.api.ClientModInitializer;
6+
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
7+
import net.fabricmc.fabric.api.message.v1.ServerMessageEvents;
8+
import net.minecraft.client.MinecraftClient;
9+
10+
import static java.util.Optional.ofNullable;
411

512
public class PKUtilsClient implements ClientModInitializer {
613

14+
public static AddonPlayer addonPlayer;
15+
716
@Override
817
public void onInitializeClient() {
918
// This entrypoint is suitable for setting up client-specific logic, such as rendering.
19+
20+
WorldRenderEvents.AFTER_ENTITIES.register(context -> ofNullable(MinecraftClient.getInstance().world).ifPresent(world -> {
21+
new WorldBlockHighlighter(context).highlightBomb(world);
22+
new WorldBlockHighlighter(context).highlightPlant(world);
23+
}));
24+
25+
ServerMessageEvents.CHAT_MESSAGE.register((message, sender, params) -> new ChatListener(message, sender));
1026
}
1127
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package de.rettichlp.listener;
2+
3+
import net.minecraft.network.message.SignedMessage;
4+
import net.minecraft.server.network.ServerPlayerEntity;
5+
6+
public class ChatListener {
7+
8+
private final SignedMessage signedMessage;
9+
private final ServerPlayerEntity sender;
10+
private final String rawMessage;
11+
12+
public ChatListener(SignedMessage signedMessage, ServerPlayerEntity sender) {
13+
this.signedMessage = signedMessage;
14+
this.rawMessage = signedMessage.getSignedContent();
15+
this.sender = sender;
16+
17+
process();
18+
}
19+
20+
private void process() {
21+
22+
}
23+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package de.rettichlp.render;
2+
3+
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
4+
import net.minecraft.client.MinecraftClient;
5+
import net.minecraft.client.network.ClientPlayerEntity;
6+
import net.minecraft.client.render.BufferBuilderStorage;
7+
import net.minecraft.client.render.OutlineVertexConsumerProvider;
8+
import net.minecraft.client.util.math.MatrixStack;
9+
import net.minecraft.client.world.ClientWorld;
10+
import net.minecraft.util.math.BlockPos;
11+
import net.minecraft.util.math.Vec3d;
12+
import net.minecraft.world.World;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
import java.util.HashSet;
16+
import java.util.Set;
17+
import java.util.function.Predicate;
18+
19+
import static de.rettichlp.PKUtilsClient.addonPlayer;
20+
import static net.minecraft.block.Blocks.FERN;
21+
import static net.minecraft.block.Blocks.PODZOL;
22+
import static net.minecraft.block.Blocks.TNT;
23+
import static net.minecraft.util.math.BlockPos.iterate;
24+
25+
public class WorldBlockHighlighter {
26+
27+
private static final int RENDER_DISTANCE = 32; // Render distance for bomb spots
28+
29+
private final WorldRenderContext context;
30+
31+
public WorldBlockHighlighter(WorldRenderContext context) {
32+
this.context = context;
33+
}
34+
35+
public void highlightBomb(@NotNull World world) {
36+
MatrixStack matrices = this.context.matrixStack();
37+
38+
if (matrices == null) {
39+
return;
40+
}
41+
42+
Set<BlockPos> filteredBlocks = filterBlocks(blockPos -> world.getBlockState(blockPos).isOf(TNT));
43+
44+
for (BlockPos filteredBlock : filteredBlocks) {
45+
drawOutline(255, 0, 0, 1, matrices, filteredBlock);
46+
}
47+
}
48+
49+
public void highlightPlant(@NotNull World world) {
50+
MatrixStack matrices = this.context.matrixStack();
51+
52+
if (matrices == null) {
53+
return;
54+
}
55+
56+
Set<BlockPos> filteredBlocks = filterBlocks(blockPos -> world.getBlockState(blockPos).isOf(FERN) && world.getBlockState(blockPos.down()).isOf(PODZOL));
57+
58+
for (BlockPos filteredBlock : filteredBlocks) {
59+
drawOutline(0, 255, 0, 1, matrices, filteredBlock);
60+
drawOutline(0, 255, 255, 1, matrices, filteredBlock.down());
61+
}
62+
}
63+
64+
private @NotNull Set<BlockPos> filterBlocks(Predicate<BlockPos> predicate) {
65+
ClientPlayerEntity clientPlayerEntity = MinecraftClient.getInstance().player;
66+
67+
if (clientPlayerEntity == null) {
68+
return Set.of();
69+
}
70+
71+
BlockPos playerPos = addonPlayer.getBlockPos();
72+
BlockPos renderStartPos = playerPos.add(-RENDER_DISTANCE, -RENDER_DISTANCE, -RENDER_DISTANCE);
73+
BlockPos renderEndPos = playerPos.add(RENDER_DISTANCE, RENDER_DISTANCE, RENDER_DISTANCE);
74+
75+
Set<BlockPos> positions = new HashSet<>();
76+
77+
for (BlockPos pos : iterate(renderStartPos, renderEndPos)) {
78+
if (predicate.test(pos)) {
79+
positions.add(pos);
80+
}
81+
}
82+
83+
return positions;
84+
}
85+
86+
private void drawOutline(int red, int green, int blue, int alpha, MatrixStack matrices, BlockPos pos) {
87+
MinecraftClient client = MinecraftClient.getInstance();
88+
ClientWorld world = client.world;
89+
90+
if (world == null) {
91+
return;
92+
}
93+
94+
BufferBuilderStorage bufferBuilders = client.getBufferBuilders();
95+
96+
// Get the outline provider (special buffer that renders outlines visible through walls)
97+
OutlineVertexConsumerProvider outlineProvider = bufferBuilders.getOutlineVertexConsumers();
98+
99+
// Set the outline color (RGBA)
100+
bufferBuilders.getOutlineVertexConsumers().setColor(red, green, blue, alpha);
101+
102+
matrices.push();
103+
104+
// Translate the rendering position relative to the camera,
105+
// so the block outline is drawn at the correct world coordinates
106+
Vec3d cameraPos = client.gameRenderer.getCamera().getPos();
107+
matrices.translate(pos.getX() - cameraPos.x, pos.getY() - cameraPos.y, pos.getZ() - cameraPos.z);
108+
109+
// Render the block state into the outline buffer
110+
client.getBlockRenderManager().renderBlockAsEntity(
111+
world.getBlockState(pos), // fetch the real block state at this position
112+
matrices,
113+
outlineProvider,
114+
15728880, // full light value
115+
0 // overlay
116+
);
117+
118+
matrices.pop();
119+
120+
// Flush the outline buffer so it actually gets drawn
121+
outlineProvider.draw();
122+
}
123+
}

0 commit comments

Comments
 (0)