diff --git a/build.gradle b/build.gradle index 5c837a5..c9c2fbb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.11-SNAPSHOT" apply false + id "dev.architectury.loom" version "1.13-SNAPSHOT" apply false } architectury { minecraft = rootProject.minecraft_version diff --git a/common/src/main/java/gjum/minecraft/civ/snitchmod/common/Renderer.java b/common/src/main/java/gjum/minecraft/civ/snitchmod/common/Renderer.java index 224749d..5598293 100644 --- a/common/src/main/java/gjum/minecraft/civ/snitchmod/common/Renderer.java +++ b/common/src/main/java/gjum/minecraft/civ/snitchmod/common/Renderer.java @@ -9,9 +9,9 @@ import net.minecraft.client.gui.Font; //import net.minecraft.client.renderer.CoreShaders; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.rendertype.RenderType; +import net.minecraft.client.renderer.rendertype.RenderTypes; import net.minecraft.client.renderer.ShapeRenderer; -import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; import org.joml.Matrix4fStack; +import org.joml.Vector3f; import org.lwjgl.opengl.GL11; import java.util.ArrayList; @@ -160,7 +161,7 @@ public static void renderOverlays(PoseStack poseStack) { if (mc.options.hideGui) return; // F1 mode // if (mc.options.renderDebug) return; // F3 mode - Vec3 camPos = mc.gameRenderer.getMainCamera().getPosition(); + Vec3 camPos = mc.gameRenderer.getMainCamera().position(); Matrix4fStack modelViewStack = RenderSystem.getModelViewStack(); modelViewStack.pushMatrix(); modelViewStack.mul(eventPoseStack.last().pose()); @@ -187,8 +188,6 @@ public static void renderOverlays(PoseStack poseStack) { renderSnitchFieldPreview(getMod().snitchFieldToPreview); } - RenderSystem.lineWidth(1.0F); - modelViewStack.popMatrix(); MultiBufferSource.BufferSource buffers = Minecraft.getInstance().renderBuffers().bufferSource(); buffers.endBatch(); @@ -472,24 +471,51 @@ private static void renderPlacementHelper(Snitch snitch) { } } - private static void renderBoxOutline(AABB box, Color color, float alpha, float lineWidth) { - //mc.gui.getChat().addMessage(Component.literal("[SnitchMod] renderBoxOutline: " + box)); - try (RenderBufferGuard guard = RenderBufferGuard.open()) { - RenderSystem.lineWidth(lineWidth); - VertexConsumer vertexConsumer = guard.bufferSource.getBuffer(RenderType.debugLineStrip(lineWidth)); - ShapeRenderer.renderLineBox( - eventPoseStack, vertexConsumer, - box.minX, box.minY, box.minZ, - box.maxX, box.maxY, box.maxZ, - color.r, color.g, color.b, alpha - ); - } - } + private static void renderBoxOutline(AABB box, Color color, float alpha, float lineWidth) { + // Convert the requested line width into a world-space thickness. + // Tweak the multiplier if you want thicker/thinner outlines visually. + double t = Math.max(0.01, lineWidth * 0.02); + + double minX = box.minX; + double minY = box.minY; + double minZ = box.minZ; + double maxX = box.maxX; + double maxY = box.maxY; + double maxZ = box.maxZ; + + // Clamp thickness so it cannot exceed half the box size on any axis. + double maxThicknessX = Math.max(0.0, (maxX - minX) / 2.0); + double maxThicknessY = Math.max(0.0, (maxY - minY) / 2.0); + double maxThicknessZ = Math.max(0.0, (maxZ - minZ) / 2.0); + t = Math.min(t, Math.min(maxThicknessX, Math.min(maxThicknessY, maxThicknessZ))); + + if (t <= 0.0) { + return; + } + + // Bottom ring + renderFilledBox(new AABB(minX, minY, minZ, maxX, minY + t, minZ + t), color, alpha); // north + renderFilledBox(new AABB(minX, minY, maxZ - t, maxX, minY + t, maxZ), color, alpha); // south + renderFilledBox(new AABB(minX, minY, minZ + t, minX + t, minY + t, maxZ - t), color, alpha); // west + renderFilledBox(new AABB(maxX - t, minY, minZ + t, maxX, minY + t, maxZ - t), color, alpha); // east + + // Top ring + renderFilledBox(new AABB(minX, maxY - t, minZ, maxX, maxY, minZ + t), color, alpha); // north + renderFilledBox(new AABB(minX, maxY - t, maxZ - t, maxX, maxY, maxZ), color, alpha); // south + renderFilledBox(new AABB(minX, maxY - t, minZ + t, minX + t, maxY, maxZ - t), color, alpha); // west + renderFilledBox(new AABB(maxX - t, maxY - t, minZ + t, maxX, maxY, maxZ - t), color, alpha); // east + + // Vertical edges + renderFilledBox(new AABB(minX, minY + t, minZ, minX + t, maxY - t, minZ + t), color, alpha); // NW + renderFilledBox(new AABB(maxX - t, minY + t, minZ, maxX, maxY - t, minZ + t), color, alpha); // NE + renderFilledBox(new AABB(minX, minY + t, maxZ - t, minX + t, maxY - t, maxZ), color, alpha); // SW + renderFilledBox(new AABB(maxX - t, minY + t, maxZ - t, maxX, maxY - t, maxZ), color, alpha); // SE + } private static void renderFilledBox(AABB box, Color color, float alpha) { //mc.gui.getChat().addMessage(Component.literal("[SnitchMod] renderFilledBox: " + box)); try (RenderBufferGuard guard = RenderBufferGuard.open()) { - VertexConsumer vertexConsumer = guard.bufferSource.getBuffer(RenderType.debugQuads()); + VertexConsumer vertexConsumer = guard.bufferSource.getBuffer(RenderTypes.debugQuads()); //ShapeRenderer.renderShape(eventPoseStack, vertexConsumer, Shapes.create(box), box.minX, box.minY, box.minZ, color.hex); float minX = (float) box.minX; float minY = (float) box.minY; @@ -497,50 +523,102 @@ private static void renderFilledBox(AABB box, Color color, float alpha) { float maxX = (float) box.maxX; float maxY = (float) box.maxY; float maxZ = (float) box.maxZ; - for (Direction direction : Direction.values()) { - ShapeRenderer.renderFace( - eventPoseStack, vertexConsumer, direction, - minX, minY, minZ, - maxX, maxY, maxZ, - color.r, color.g, color.b, alpha - ); - } + int alphaInt = Math.round(alpha * 255.0f) & 0xFF; + int colorInt = (alphaInt << 24) | (color.hex & 0x00FFFFFF); + PoseStack.Pose pose = eventPoseStack.last(); + + // Bottom (-Y) + vertexConsumer.addVertex(pose, minX, minY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, minY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, minY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, minX, minY, maxZ).setColor(colorInt); + + // Top (+Y) + vertexConsumer.addVertex(pose, minX, maxY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, minX, maxY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, maxY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, maxY, minZ).setColor(colorInt); + + // North (-Z) + vertexConsumer.addVertex(pose, minX, minY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, minX, maxY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, maxY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, minY, minZ).setColor(colorInt); + + // South (+Z) + vertexConsumer.addVertex(pose, minX, minY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, minY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, maxY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, minX, maxY, maxZ).setColor(colorInt); + + // West (-X) + vertexConsumer.addVertex(pose, minX, minY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, minX, minY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, minX, maxY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, minX, maxY, minZ).setColor(colorInt); + + // East (+X) + vertexConsumer.addVertex(pose, maxX, minY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, maxY, minZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, maxY, maxZ).setColor(colorInt); + vertexConsumer.addVertex(pose, maxX, minY, maxZ).setColor(colorInt); } } - private static void renderBoxGuides(AABB box, Color color, float a, float lineWidth) { - boolean initialLineSmooth = GL11.glIsEnabled(GL11.GL_LINE_SMOOTH); - RenderSystem.lineWidth(lineWidth); - - float r = color.r; - float g = color.g; - float b = color.b; - Vec3 center = box.getCenter(); - float radius = (float) (box.maxX - center.x); - try (RenderBufferGuard guard = RenderBufferGuard.open()) { - PoseStack poseStack = new PoseStack(); - PoseStack.Pose pose = poseStack.last(); - GL11.glEnable(GL11.GL_LINE_SMOOTH); - VertexConsumer vertexConsumer = guard.bufferSource.getBuffer(RenderType.debugLineStrip(lineWidth)); - vertexConsumer.addVertex(pose, (float) center.x + 1, (float) center.y, (float) center.z).setColor(r, g, b, a).setNormal(1, 0, 0); - vertexConsumer.addVertex(pose, (float) center.x + radius, (float) center.y, (float) center.z).setColor(r, g, b, a).setNormal(1, 0, 0); - vertexConsumer.addVertex(pose, (float) center.x - 1, (float) center.y, (float) center.z).setColor(r, g, b, a).setNormal(-1, 0, 0); - vertexConsumer.addVertex(pose, (float) center.x - radius, (float) center.y, (float) center.z).setColor(r, g, b, a).setNormal(-1, 0, 0); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y + 1, (float) center.z).setColor(r, g, b, a).setNormal(0, 1, 0); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y + radius, (float) center.z).setColor(r, g, b, a).setNormal(1, 0, 0); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y - 1, (float) center.z).setColor(r, g, b, a).setNormal(0, -1, 0); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y - radius, (float) center.z).setColor(r, g, b, a).setNormal(-1, 0, 0); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y, (float) center.z + 1).setColor(r, g, b, a).setNormal(0, 0, 1); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y, (float) center.z + radius).setColor(r, g, b, a).setNormal(0, 0, 1); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y, (float) center.z - 1).setColor(r, g, b, a).setNormal(0, 0, -1); - vertexConsumer.addVertex(pose, (float) center.x, (float) center.y, (float) center.z - radius).setColor(r, g, b, a).setNormal(0, 0, -1); - } - finally { - if (!initialLineSmooth) { - GL11.glDisable(GL11.GL_LINE_SMOOTH); - } - } - } + private static void renderBoxGuides(AABB box, Color color, float alpha, float lineWidth) { + Vec3 center = box.getCenter(); + double radius = box.maxX - center.x; + + // Convert requested line width into a world-space thickness. + double t = Math.max(0.01, lineWidth * 0.02); + double halfT = t / 2.0; + + double cx = center.x; + double cy = center.y; + double cz = center.z; + + // +X guide + renderFilledBox( + new AABB(cx + 1.0, cy - halfT, cz - halfT, + cx + radius, cy + halfT, cz + halfT), + color, alpha + ); + + // -X guide + renderFilledBox( + new AABB(cx - radius, cy - halfT, cz - halfT, + cx - 1.0, cy + halfT, cz + halfT), + color, alpha + ); + + // +Y guide + renderFilledBox( + new AABB(cx - halfT, cy + 1.0, cz - halfT, + cx + halfT, cy + radius, cz + halfT), + color, alpha + ); + + // -Y guide + renderFilledBox( + new AABB(cx - halfT, cy - radius, cz - halfT, + cx + halfT, cy - 1.0, cz + halfT), + color, alpha + ); + + // +Z guide + renderFilledBox( + new AABB(cx - halfT, cy - halfT, cz + 1.0, + cx + halfT, cy + halfT, cz + radius), + color, alpha + ); + + // -Z guide + renderFilledBox( + new AABB(cx - halfT, cy - halfT, cz - radius, + cx + halfT, cy + halfT, cz - 1.0), + color, alpha + ); + } /** * middle center of text is at `pos` before moving it down the screen by `offset` @@ -548,38 +626,38 @@ private static void renderBoxGuides(AABB box, Color color, float a, float lineWi private static void renderTextFacingCamera(Component text, Vec3 pos, float offset, float scale, int colorAlphaHex) { // Create a new pose stack for proper 3D positioning PoseStack poseStack = new PoseStack(); - + // Translate to the world position poseStack.translate(pos.x, pos.y, pos.z); - + // Make text face the camera poseStack.mulPose(mc.gameRenderer.getMainCamera().rotation()); - + // Calculate scale based on distance scale *= 0.005f * (mc.player.position().distanceTo(pos) / 2.4); scale = Math.clamp(scale, 0.015f, 0.15f); - + // Apply scaling (negative Y to flip text right-side up) poseStack.scale(scale, -scale, scale); - + // Calculate text positioning float w = mc.font.width(text); float x = -w / 2f; float y = -(.5f - offset) * (mc.font.lineHeight + 2); // +2 for background padding, -1 for default line spacing boolean shadow = false; - + // Get the final transformation matrix Matrix4f matrix = poseStack.last().pose(); - + // Background settings - make it more transparent to see text better float bgOpacity = Minecraft.getInstance().options.getBackgroundOpacity(0.25f); int bgColor = (int) (bgOpacity * 255.0f) << 24; - + // Ensure text has full alpha if not already set if ((colorAlphaHex & 0xFF000000) == 0) { colorAlphaHex |= 0xFF000000; // Add full alpha if missing } - + // Use immediate mode rendering with proper depth handling try (RenderBufferGuard guard = RenderBufferGuard.open(false, true, false)) { mc.font.drawInBatch(text, x, y, colorAlphaHex, shadow, matrix, guard.bufferSource, Font.DisplayMode.NORMAL, bgColor, 15728880); diff --git a/common/src/main/java/gjum/minecraft/civ/snitchmod/common/SnitchMod.java b/common/src/main/java/gjum/minecraft/civ/snitchmod/common/SnitchMod.java index 60914a3..523df50 100644 --- a/common/src/main/java/gjum/minecraft/civ/snitchmod/common/SnitchMod.java +++ b/common/src/main/java/gjum/minecraft/civ/snitchmod/common/SnitchMod.java @@ -13,6 +13,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; @@ -28,54 +29,56 @@ public abstract class SnitchMod { private final static Minecraft mc = Minecraft.getInstance(); + public static final KeyMapping.Category SNITCHMOD_CATEGORY + = KeyMapping.Category.register(Identifier.fromNamespaceAndPath("snitchmod", "category")); protected static final KeyMapping openGuiKey = new KeyMapping( "key.snitchmod.openGui", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_L, - "category.snitchmod" + SNITCHMOD_CATEGORY ); protected static final KeyMapping toggleOverlayKey = new KeyMapping( "key.snitchmod.toggleOverlay", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_O, - "category.snitchmod" + SNITCHMOD_CATEGORY ); protected static final KeyMapping togglePlacementKey = new KeyMapping( "key.snitchmod.togglePlacement", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_P, - "category.snitchmod" + SNITCHMOD_CATEGORY ); protected static final KeyMapping previewSnitchFieldKey = new KeyMapping( "key.snitchmod.togglePreviewSnitchFieldKey", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_N, - "category.snitchmod" + SNITCHMOD_CATEGORY ); protected static final KeyMapping jalistAutoKey = new KeyMapping( "key.snitchmod.jalistAuto", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_J, - "category.snitchmod" + SNITCHMOD_CATEGORY ); protected static final KeyMapping toggleSnitchGoneStatusKey = new KeyMapping( "key.snitchmod.toggleSnitchGoneStatusKey", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_DELETE, - "category.snitchmod" + SNITCHMOD_CATEGORY ); protected static final KeyMapping toggleSnitchFieldRenderKey = new KeyMapping( "key.snitchmod.toggleSnitchFieldRenderKey", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_T, - "category.snitchmod" + SNITCHMOD_CATEGORY ); private static SnitchMod INSTANCE; @@ -107,7 +110,7 @@ public SnitchMod() { public String getCurrentWorld() { if (mc.level == null) return null; - String dimension = mc.level.dimension().location().getPath(); + String dimension = mc.level.dimension().identifier().getPath(); // civ server world names as they occur in snitches are different from dimension names return switch (dimension) { case "overworld" -> "world"; diff --git a/fabric/src/main/java/gjum/minecraft/civ/snitchmod/fabric/FabricSnitchMod.java b/fabric/src/main/java/gjum/minecraft/civ/snitchmod/fabric/FabricSnitchMod.java index e2c8a35..31ef395 100644 --- a/fabric/src/main/java/gjum/minecraft/civ/snitchmod/fabric/FabricSnitchMod.java +++ b/fabric/src/main/java/gjum/minecraft/civ/snitchmod/fabric/FabricSnitchMod.java @@ -5,7 +5,8 @@ import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderEvents; +import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderContext; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import org.lwjgl.glfw.GLFW; @@ -29,7 +30,7 @@ public void onInitializeClient() { if (mc.screen instanceof AbstractContainerScreen containerScreen) { String title = containerScreen.getTitle().getString(); if ((title.toLowerCase().contains("snitches") || title.contains("JukeAlert")) - && GLFW.glfwGetKey(mc.getWindow().getWindow(), GLFW.GLFW_KEY_J) == GLFW.GLFW_PRESS) { + && GLFW.glfwGetKey(mc.getWindow().handle(), GLFW.GLFW_KEY_J) == GLFW.GLFW_PRESS) { // Prevent spam clicking by checking if auto-paginator is not already active if (!JalistAutoPaginator.getInstance().isActive()) { @@ -42,9 +43,9 @@ public void onInitializeClient() { e.printStackTrace(); } }); - WorldRenderEvents.LAST.register(((context) -> { + WorldRenderEvents.BEFORE_TRANSLUCENT.register(((context) -> { try { - handleRenderBlockOverlay(context.matrixStack()); + handleRenderBlockOverlay(context.matrices()); } catch (Exception e) { e.printStackTrace(); } diff --git a/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/ForgeSnitchMod.java b/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/ForgeSnitchMod.java index 8ec1478..950d929 100644 --- a/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/ForgeSnitchMod.java +++ b/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/ForgeSnitchMod.java @@ -24,9 +24,7 @@ public static void onRegisterKeyMappings(RegisterKeyMappingsEvent event) { } @SubscribeEvent - public void onClientTick(TickEvent.ClientTickEvent event) { - if (event.phase == TickEvent.Phase.START) { - handleTick(); - } + public void onClientTick(TickEvent.ClientTickEvent.Pre event) { + handleTick(); } } diff --git a/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/mixins/LevelRenderMixin.java b/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/mixins/LevelRenderMixin.java index d2dfa13..3d5e59f 100644 --- a/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/mixins/LevelRenderMixin.java +++ b/forge/src/main/java/gjum/minecraft/civ/snitchmod/forge/mixins/LevelRenderMixin.java @@ -3,7 +3,6 @@ import com.mojang.blaze3d.vertex.PoseStack; import gjum.minecraft.civ.snitchmod.forge.ForgeSnitchMod; import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.RenderType; import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/gradle.properties b/gradle.properties index 7c84890..0a5e86b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,15 +3,15 @@ org.gradle.jvmargs=-Xmx2048M maven_group=gjum.minecraft.snitchmod archives_base_name=snitchmod -mod_version=1.5.0-mc1.21.8 +mod_version=1.5.0-mc1.21.11 -minecraft_version=1.21.8 +minecraft_version=1.21.11 enabled_platforms=fabric,forge,neoforge # https://fabricmc.net/versions.html -fabric_loader_version=0.17.3 -fabric_api_version=0.136.0+1.21.8 +fabric_loader_version=0.18.4 +fabric_api_version=0.141.3+1.21.11 -forge_version=58.1.0 +forge_version=61.1.4 -neoforge_version=21.8.49 +neoforge_version=21.11.38-beta