From c2be7f5c1e4425e48e532bb6ed6b1f1661ee33c9 Mon Sep 17 00:00:00 2001 From: lowercasebtw Date: Tue, 16 Sep 2025 10:58:16 -0400 Subject: [PATCH 1/2] Tons of fixes & Updated OneConfig --- build.gradle.kts | 27 +-- gradle.properties | 1 + root.gradle.kts | 26 ++- settings.gradle.kts | 18 +- .../polyhitbox/mixin/MixinRenderManager.java | 122 +++++++++++ .../polyhitbox/mixin/RenderManagerMixin.java | 158 -------------- .../org/polyfrost/polyhitbox/HitboxInfo.kt | 117 ++++++++--- .../polyfrost/polyhitbox/HitboxRenderer.kt | 194 ++++++++++++++++++ .../org/polyfrost/polyhitbox/PolyHitbox.kt | 113 ++++++---- .../polyhitbox/PolyHitboxConstants.kt | 7 + src/main/resources/fabric.mod.json | 23 +++ src/main/resources/mcmod.info | 32 +-- src/main/resources/mixins.polyhitbox.json | 16 +- src/main/resources/polyhitbox.svg | 11 +- versions/mainProject | 2 +- 15 files changed, 593 insertions(+), 274 deletions(-) create mode 100644 src/main/java/org/polyfrost/polyhitbox/mixin/MixinRenderManager.java delete mode 100644 src/main/java/org/polyfrost/polyhitbox/mixin/RenderManagerMixin.java create mode 100644 src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt create mode 100644 src/main/kotlin/org/polyfrost/polyhitbox/PolyHitboxConstants.kt create mode 100644 src/main/resources/fabric.mod.json diff --git a/build.gradle.kts b/build.gradle.kts index b8de8bf..b64d32b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,20 +16,18 @@ plugins { toolkitLoomHelper { useOneConfig { - version = "1.0.0-alpha.70" - loaderVersion = "1.1.0-alpha.44" - + version = "1.0.0-alpha.163" + loaderVersion = "1.1.0-alpha.49" usePolyMixin = true - polyMixinVersion = "0.8.4+build.2" - + polyMixinVersion = "0.8.4+build.6" applyLoaderTweaker = true - for (module in arrayOf("commands", "config", "config-impl", "events", "internal", "ui", "utils")) { +module } } + useDevAuth("1.2.1") - useMixinExtras("0.4.1") + useMixinExtras("0.5.0") // Turns off the server-side run configs, as we're building a client-sided mod. disableRunConfigs(GameSide.SERVER) @@ -43,17 +41,4 @@ toolkitLoomHelper { // Configures the Mixin tweaker if we are building for Forge. useForgeMixin(modData.id) } -} - -dependencies { - // Add (Legacy) Fabric API as dependencies (these are both optional but are particularly useful). - if (mcData.isFabric) { - if (mcData.isLegacyFabric) { - // 1.8.9 - 1.13 - modImplementation("net.legacyfabric.legacy-fabric-api:legacy-fabric-api:${mcData.dependencies.legacyFabric.legacyFabricApiVersion}") - } else { - // 1.16.5+ - modImplementation("net.fabricmc.fabric-api:fabric-api:${mcData.dependencies.fabric.fabricApiVersion}") - } - } -} +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 64f65b6..e3a4864 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,6 +4,7 @@ org.gradle.parallel=true org.gradle.configureoncommand=true org.gradle.parallel.threads=4 org.gradle.jvmargs=-Xmx2G +loom.ignoreDependencyLoomVersionValidation=true mod.group=org.polyfrost mod.id=polyhitbox diff --git a/root.gradle.kts b/root.gradle.kts index a013e9f..952b9c9 100644 --- a/root.gradle.kts +++ b/root.gradle.kts @@ -3,5 +3,29 @@ plugins { } preprocess { - "1.8.9-forge"(10809, "srg") + "1.21.8-fabric"(1_21_08, "yarn") { + "1.21.5-fabric"(1_21_05, "yarn") { + "1.21.4-fabric"(1_21_04, "yarn") { + "1.21.1-fabric"(1_21_01, "yarn") { + "1.20.4-fabric"(1_20_04, "yarn") { + "1.20.1-fabric"(1_20_01, "yarn") { + "1.16.5-fabric"(1_16_05, "yarn") { + "1.16.5-forge"(1_16_05, "srg") { + "1.12.2-forge"(1_12_02, "srg") { + "1.12.2-fabric"(1_12_02, "yarn") { + "1.8.9-fabric"(1_08_09, "yarn") { + "1.8.9-forge"(1_08_09, "srg") + } + } + } + } + } + } + } + } + } + } + } + + strictExtraMappings.set(true) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 1719c31..ea74e6d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,19 +21,31 @@ pluginManagement { } plugins { - kotlin("jvm") version("2.0.0") - id("dev.deftu.gradle.multiversion-root") version("2.35.0") + kotlin("jvm") version ("2.2.10") + id("dev.deftu.gradle.multiversion-root") version ("2.51.0") } } val projectName: String = extra["mod.name"]?.toString() ?: throw MissingPropertyException("mod.name has not been set.") rootProject.name = projectName + rootProject.buildFileName = "root.gradle.kts" // Adds all of our build target versions to the classpath if we need to add version-specific code. listOf( - "1.8.9-forge" + "1.8.9-forge", + "1.8.9-fabric", + "1.12.2-forge", + "1.12.2-fabric", + "1.16.5-forge", + "1.16.5-fabric", + "1.20.1-fabric", + "1.20.4-fabric", + "1.21.1-fabric", + "1.21.4-fabric", + "1.21.5-fabric", + "1.21.8-fabric" ).forEach { version -> include(":$version") project(":$version").apply { diff --git a/src/main/java/org/polyfrost/polyhitbox/mixin/MixinRenderManager.java b/src/main/java/org/polyfrost/polyhitbox/mixin/MixinRenderManager.java new file mode 100644 index 0000000..392d346 --- /dev/null +++ b/src/main/java/org/polyfrost/polyhitbox/mixin/MixinRenderManager.java @@ -0,0 +1,122 @@ +package org.polyfrost.polyhitbox.mixin; + +import dev.deftu.omnicore.api.client.OmniClient; +import dev.deftu.omnicore.api.client.render.stack.OmniMatrixStack; +import dev.deftu.omnicore.api.client.render.stack.OmniMatrixStacks; +import dev.deftu.omnicore.api.data.vec.OmniVec3d; +import dev.deftu.omnicore.api.entity.OmniEntities; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import org.polyfrost.polyhitbox.HitboxRendererKt; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +//#if MC >=1.21.5 +import net.minecraft.client.render.entity.state.EntityHitbox; +//#endif + +//#if MC >=1.16.5 +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import org.spongepowered.asm.mixin.Unique; +//#endif + +@Mixin(EntityRenderDispatcher.class) +public abstract class MixinRenderManager { + //#if MC >=1.21.5 + @Unique + private static ThreadLocal polyhitbox$entity = ThreadLocal.withInitial(() -> null); + //#endif + + @Inject( + //#if MC >=1.16.5 + method = "renderHitbox", + //#else + //$$ method = "renderDebugBoundingBox", + //#endif + at = @At("HEAD"), + cancellable = true + ) + //#if MC >=1.16.5 + private + //#if MC >=1.20.1 + static + //#endif + void polyhitbox$customRendering( + MatrixStack matrixStack, + VertexConsumer vertexConsumer, + //#if MC >=1.21.5 + EntityHitbox entityHitbox, + //#else + //$$ Entity entity, + //$$ float tickDelta, + //#if MC >=1.21.1 + //$$ float offsetX, float offsetY, float offsetZ, + //#endif + //#endif + CallbackInfo ci + ) { + //#else + //$$ private void polyhitbox$customRendering(Entity entity, double offsetX, double offsetY, double offsetZ, float yaw, float tickDelta, CallbackInfo ci) { + //#endif + ci.cancel(); + OmniMatrixStack stack = OmniMatrixStacks.vanilla( + //#if MC >=1.16.5 + matrixStack + //#endif + ); + + //#if MC >=1.21.5 + Entity entity = polyhitbox$entity.get(); + OmniVec3d offset = new OmniVec3d(entityHitbox.comp_3855(), entityHitbox.comp_3856(), entityHitbox.comp_3857()); + //#else + //$$ OmniVec3d offset = OmniVec3d.ZERO; + //#endif + + HitboxRendererKt.renderHitbox( + stack, + offset, + OmniEntities.getCurrentPos(entity), + new OmniVec3d(entity.getRotationVector()), + entity.getStandingEyeHeight(), + entity instanceof LivingEntity, + entity == OmniClient.get().targetedEntity, + //#if MC >=1.16.5 + entity.getWidth(), + //#else + //$$ entity.width, + //#endif + entity.getTargetingMargin(), + OmniEntities.getRenderBoundingBox(entity) + ); + } + + //#if MC >=1.21.5 + @com.llamalad7.mixinextras.injector.v2.WrapWithCondition(method = "renderHitboxes(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/entity/state/EntityHitboxAndView;Lnet/minecraft/client/render/VertexConsumer;F)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/VertexRendering;drawVector(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;Lorg/joml/Vector3f;Lnet/minecraft/util/math/Vec3d;I)V")) + private static boolean polyhitbox$removeViewRay( + net.minecraft.client.util.math.MatrixStack matrixStack, + net.minecraft.client.render.VertexConsumer vertexConsumer, + org.joml.Vector3f vector3f, + net.minecraft.util.math.Vec3d vec3d, + int i + ) { + return false; + } + + @Inject(method = "render(Lnet/minecraft/entity/Entity;DDDFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD")) + private static void polyhitbox$storeEntity( + Entity entity, + double x, double y, double z, float tickDelta, + MatrixStack matrixStack, + VertexConsumerProvider vertexConsumerProvider, + int i, + CallbackInfo ci + ) { + polyhitbox$entity.set(entity); + } + //#endif +} diff --git a/src/main/java/org/polyfrost/polyhitbox/mixin/RenderManagerMixin.java b/src/main/java/org/polyfrost/polyhitbox/mixin/RenderManagerMixin.java deleted file mode 100644 index 0f02f69..0000000 --- a/src/main/java/org/polyfrost/polyhitbox/mixin/RenderManagerMixin.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.polyfrost.polyhitbox.mixin; - -import com.llamalad7.mixinextras.sugar.Share; -import com.llamalad7.mixinextras.sugar.ref.LocalRef; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.RenderGlobal; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.WorldRenderer; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.entity.Entity; -import net.minecraft.util.AxisAlignedBB; -import org.polyfrost.polyhitbox.HitboxInfo; -import org.polyfrost.polyhitbox.PolyHitbox; -import org.polyfrost.polyui.color.PolyColor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import static org.lwjgl.opengl.GL11.*; - -@Mixin(RenderManager.class) -public abstract class RenderManagerMixin { - - @Inject(method = "renderDebugBoundingBox", at = @At("HEAD"), cancellable = true) - public void checkAndSetup(Entity entity, double x, double y, double z, float yaw, float partialTicks, CallbackInfo ci, @Share("info") LocalRef infoRef) { - HitboxInfo info = PolyHitbox.INSTANCE.getHitboxInfo(entity); - switch (info.getShowMode()) { - case 2: // NEVER - ci.cancel(); - return; - case 1: // ONLY TARGETED - if (entity != Minecraft.getMinecraft().pointedEntity) { - ci.cancel(); - return; - } else info.setTargeted(true); - break; - case 0: // ALWAYS - info.setTargeted(entity == Minecraft.getMinecraft().pointedEntity); - break; - } - if (info.getUseDistanceBasedWidth()) info.setSqrDistance((float) (x * x + y * y + z * z)); - glLineStipple(info.getDashFactor(), (short) 0b1010101010101010); - infoRef.set(info); - } - - @Inject(method = "renderDebugBoundingBox", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/Tessellator;getInstance()Lnet/minecraft/client/renderer/Tessellator;"), cancellable = true) - private void renderViewRayCheck(Entity entity, double x, double y, double z, float yaw, float partialTicks, CallbackInfo ci, @Share("info") LocalRef infoRef) { - if (!infoRef.get().getViewRay().isShown()) { - GlStateManager.enableTexture2D(); - GlStateManager.enableLighting(); - GlStateManager.enableCull(); - GlStateManager.disableBlend(); - GlStateManager.depthMask(true); - restoreState(entity, x, y, z, yaw, partialTicks, ci); - ci.cancel(); - } - } - - @Redirect(method = "renderDebugBoundingBox", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;drawOutlinedBoundingBox(Lnet/minecraft/util/AxisAlignedBB;IIII)V", ordinal = 0)) - private void renderHitboxModifyColorAndSides(AxisAlignedBB bb, int r, int g, int b, int a, Entity entity, @Share("info") LocalRef infoRef) { - HitboxInfo info = infoRef.get(); - if (info.isAccurate()) { - double offset = entity.getCollisionBorderSize(); - bb = bb.expand(offset, offset, offset); - } - HitboxInfo.ElementInfo outline = info.getOutline(); - if (outline.isShown()) { - PolyColor color = outline.getColor(); - if (outline.isDashed()) glEnable(GL_LINE_STIPPLE); - glLineWidth(outline.getWidth()); - RenderGlobal.drawOutlinedBoundingBox(bb, color.red(), color.green(), color.blue(), color.alpha()); - glDisable(GL_LINE_STIPPLE); - } - HitboxInfo.ElementInfo sides = info.getSides(); - if (sides.isShown()) { - PolyColor color = sides.getColor(); - Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer wr = tessellator.getWorldRenderer(); - GlStateManager.color(color.red() / 255f, color.green() / 255f, color.blue() / 255f, color.getAlpha()); - GlStateManager.enableBlend(); - wr.begin(GL_QUADS, DefaultVertexFormats.POSITION); - // back - wr.pos(bb.minX, bb.minY, bb.maxZ).endVertex(); - wr.pos(bb.maxX, bb.minY, bb.maxZ).endVertex(); - wr.pos(bb.maxX, bb.maxY, bb.maxZ).endVertex(); - wr.pos(bb.minX, bb.maxY, bb.maxZ).endVertex(); - // front - wr.pos(bb.maxX, bb.minY, bb.minZ).endVertex(); - wr.pos(bb.minX, bb.minY, bb.minZ).endVertex(); - wr.pos(bb.minX, bb.maxY, bb.minZ).endVertex(); - wr.pos(bb.maxX, bb.maxY, bb.minZ).endVertex(); - // left - wr.pos(bb.minX, bb.minY, bb.minZ).endVertex(); - wr.pos(bb.minX, bb.minY, bb.maxZ).endVertex(); - wr.pos(bb.minX, bb.maxY, bb.maxZ).endVertex(); - wr.pos(bb.minX, bb.maxY, bb.minZ).endVertex(); - // right - wr.pos(bb.maxX, bb.minY, bb.maxZ).endVertex(); - wr.pos(bb.maxX, bb.minY, bb.minZ).endVertex(); - wr.pos(bb.maxX, bb.maxY, bb.minZ).endVertex(); - wr.pos(bb.maxX, bb.maxY, bb.maxZ).endVertex(); - // top - wr.pos(bb.minX, bb.maxY, bb.maxZ).endVertex(); - wr.pos(bb.maxX, bb.maxY, bb.maxZ).endVertex(); - wr.pos(bb.maxX, bb.maxY, bb.minZ).endVertex(); - wr.pos(bb.minX, bb.maxY, bb.minZ).endVertex(); - // bottom (+0.01 to prevent z-fighting) - wr.pos(bb.minX, bb.minY + 0.01, bb.minZ).endVertex(); - wr.pos(bb.maxX, bb.minY + 0.01, bb.minZ).endVertex(); - wr.pos(bb.maxX, bb.minY + 0.01, bb.maxZ).endVertex(); - wr.pos(bb.minX, bb.minY + 0.01, bb.maxZ).endVertex(); - tessellator.draw(); - GlStateManager.color(1f, 1f, 1f, 1f); - GlStateManager.disableBlend(); - } - } - - @Redirect(method = "renderDebugBoundingBox", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;drawOutlinedBoundingBox(Lnet/minecraft/util/AxisAlignedBB;IIII)V", ordinal = 1)) - private void renderEyelineModifyColor(AxisAlignedBB boundingBox, int red, int green, int blue, int alpha, Entity entity, @Share("info") LocalRef infoRef) { - HitboxInfo info = infoRef.get(); - HitboxInfo.ElementInfo eyeline = info.getEyeline(); - if (!eyeline.isShown()) return; - if (info.isAccurate()) { - double offset = entity.getCollisionBorderSize(); - boundingBox = boundingBox.expand(offset, 0.0, offset); - } - PolyColor color = eyeline.getColor(); - if (eyeline.isDashed()) glEnable(GL_LINE_STIPPLE); - glLineWidth(eyeline.getWidth()); - RenderGlobal.drawOutlinedBoundingBox(boundingBox, color.red(), color.green(), color.blue(), color.alpha()); - glDisable(GL_LINE_STIPPLE); - } - - @Inject(method = "renderDebugBoundingBox", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/WorldRenderer;begin(ILnet/minecraft/client/renderer/vertex/VertexFormat;)V")) - private void renderViewRayModifyWidth(Entity entity, double x, double y, double z, float yaw, float partialTicks, CallbackInfo ci, @Share("info") LocalRef infoRef) { - HitboxInfo.ElementInfo viewRay = infoRef.get().getViewRay(); - if (viewRay.isDashed()) glEnable(GL_LINE_STIPPLE); - glLineWidth(viewRay.getWidth()); - } - - @Redirect(method = "renderDebugBoundingBox", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/WorldRenderer;color(IIII)Lnet/minecraft/client/renderer/WorldRenderer;")) - private WorldRenderer renderViewRayModifyColor(WorldRenderer worldRenderer, int red, int green, int blue, int alpha, Entity entity, @Share("info") LocalRef infoRef) { - PolyColor color = infoRef.get().getViewRay().getColor(); - worldRenderer.color(color.red(), color.green(), color.blue(), color.alpha()); - return worldRenderer; - } - - @Inject(method = "renderDebugBoundingBox", at = @At(value = "RETURN")) - private void restoreState(Entity entity, double x, double y, double z, float yaw, float partialTicks, CallbackInfo ci) { - glLineWidth(1f); - glDisable(GL_LINE_STIPPLE); - } - -} diff --git a/src/main/kotlin/org/polyfrost/polyhitbox/HitboxInfo.kt b/src/main/kotlin/org/polyfrost/polyhitbox/HitboxInfo.kt index 4acf675..c3ef3a0 100644 --- a/src/main/kotlin/org/polyfrost/polyhitbox/HitboxInfo.kt +++ b/src/main/kotlin/org/polyfrost/polyhitbox/HitboxInfo.kt @@ -1,33 +1,33 @@ package org.polyfrost.polyhitbox +import dev.deftu.omnicore.api.color.OmniColor import org.polyfrost.oneconfig.api.config.v1.Properties.ktProperty import org.polyfrost.oneconfig.api.config.v1.Tree import org.polyfrost.oneconfig.api.config.v1.Visualizer import org.polyfrost.polyui.color.PolyColor import org.polyfrost.polyui.color.argb -import org.polyfrost.polyui.color.mutable -import org.polyfrost.polyui.color.rgba +import org.polyfrost.polyui.color.asMutable class HitboxInfo(private val id: String) { var showMode = 0 private set - val eyeline = ElementInfo(true, rgba(255, 0, 0, 1f), "Eyeline") - val viewRay = ElementInfo(true, rgba(0, 0, 255, 1f), "View Ray") - val outline = ElementInfo(true, rgba(255, 255, 255, 1f), "Outline") - val sides = ElementInfo(false, rgba(255, 255, 255, 0.2f), "Sides") + val eyeline = ElementInfo(true, argb(0xFFFF0000.toInt()), true, "Eyeline") + val viewRay = ElementInfo(true, argb(0xFF0000FF.toInt()), true, "View Ray") + val outline = ElementInfo(true, argb(0xFFFFFFFF.toInt()), true, "Outline") + val sides = ElementInfo(false, argb(0x14FFFFFF), false, "Sides") var isAccurate = false private set - var useDistanceBasedWidth = true + var useDistanceBasedWidth = false private set - private var distanceFactor = 4f + private var distanceFactor = 4.0F var dashFactor = 10 private set private var differentColorOnHover = true var isTargeted = false - var sqrDistance = 1f + var sqrDistance = 1.0F private var _tree: Tree? = null @@ -38,11 +38,36 @@ class HitboxInfo(private val id: String) { addMetadata("visualizer", Visualizer.RadioVisualizer::class.java) addMetadata("options", arrayOf("Always", "When Targeted", "Never")) }) - put(ktProperty(::isAccurate, "Accurate").apply { addMetadata("visualizer", Visualizer.SwitchVisualizer::class.java) }) - put(ktProperty(::useDistanceBasedWidth, "Distance Based Width").apply { addMetadata("visualizer", Visualizer.SwitchVisualizer::class.java) }) - put(ktProperty(::distanceFactor, "Distance Factor").apply { addMetadata("visualizer", Visualizer.SliderVisualizer::class.java) }) - put(ktProperty(::dashFactor, "Dash Factor").apply { addMetadata("visualizer", Visualizer.NumberVisualizer::class.java) }) - put(ktProperty(::differentColorOnHover, "Different Color on Hover").apply { addMetadata("visualizer", Visualizer.SwitchVisualizer::class.java) }) + put(ktProperty(::isAccurate, "Accurate").apply { + addMetadata( + "visualizer", + Visualizer.SwitchVisualizer::class.java + ) + }) + put(ktProperty(::useDistanceBasedWidth, "Distance Based Width").apply { + addMetadata( + "visualizer", + Visualizer.SwitchVisualizer::class.java + ) + }) + put(ktProperty(::distanceFactor, "Distance Factor").apply { + addMetadata( + "visualizer", + Visualizer.SliderVisualizer::class.java + ) + }) + put(ktProperty(::dashFactor, "Dash Factor").apply { + addMetadata( + "visualizer", + Visualizer.NumberVisualizer::class.java + ) + }) + put(ktProperty(::differentColorOnHover, "Different Color on Hover").apply { + addMetadata( + "visualizer", + Visualizer.SwitchVisualizer::class.java + ) + }) put(eyeline.tree) put(viewRay.tree) put(outline.tree) @@ -52,32 +77,72 @@ class HitboxInfo(private val id: String) { _tree = value } - - - inner class ElementInfo(isShown: Boolean, initialColor: PolyColor, private val id: String) { + inner class ElementInfo( + isShown: Boolean, + initialColor: PolyColor, + val isLines: Boolean, + private val id: String, + ) { var isShown = isShown private set var isDashed = false private set - var width = 1f - get() = if (useDistanceBasedWidth) field * (distanceFactor / sqrDistance) else field + var width = 1.0F + get() = if (isLines) + if (useDistanceBasedWidth) + field * (distanceFactor / sqrDistance) + else + field + else + 0.0F private set var colorNormal = initialColor private set - var colorHovered: PolyColor = argb(initialColor.argb).mutable().apply { alpha -= 0.2f } + var colorHovered: PolyColor = argb(initialColor.argb).asMutable().apply { alpha -= 0.2F } private set - fun getColor() = if (isTargeted && differentColorOnHover) colorHovered else colorNormal + + fun getColor() = if (isTargeted && differentColorOnHover) + OmniColor(colorHovered.rgba) + else + OmniColor(colorNormal.rgba) private var _tree: Tree? = null val tree: Tree get() = _tree ?: Tree(id, id, null, null).apply { _tree = this - put(ktProperty(::isShown, "Enabled").apply { addMetadata("visualizer", Visualizer.SwitchVisualizer::class.java) }) - put(ktProperty(::isDashed, "Dashed").apply { addMetadata("visualizer", Visualizer.SwitchVisualizer::class.java) }) - put(ktProperty(::width, "Width").apply { addMetadata("visualizer", Visualizer.SliderVisualizer::class.java) }) - put(ktProperty(::colorNormal, "Color").apply { addMetadata("visualizer", Visualizer.ColorVisualizer::class.java) }) - put(ktProperty(::colorHovered, "Hovered Color").apply { addMetadata("visualizer", Visualizer.ColorVisualizer::class.java) }) + put(ktProperty(::isShown, "Enabled").apply { + addMetadata( + "visualizer", + Visualizer.SwitchVisualizer::class.java + ) + }) + if (isLines) { + put(ktProperty(::isDashed, "Dashed").apply { + addMetadata( + "visualizer", + Visualizer.SwitchVisualizer::class.java + ) + }) + put(ktProperty(::width, "Width").apply { + addMetadata( + "visualizer", + Visualizer.SliderVisualizer::class.java + ) + }) + } + put(ktProperty(::colorNormal, "Color").apply { + addMetadata( + "visualizer", + Visualizer.ColorVisualizer::class.java + ) + }) + put(ktProperty(::colorHovered, "Hovered Color").apply { + addMetadata( + "visualizer", + Visualizer.ColorVisualizer::class.java + ) + }) } } } \ No newline at end of file diff --git a/src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt b/src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt new file mode 100644 index 0000000..4e519e4 --- /dev/null +++ b/src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt @@ -0,0 +1,194 @@ +package org.polyfrost.polyhitbox + +import dev.deftu.omnicore.api.client.render.DefaultVertexFormats +import dev.deftu.omnicore.api.client.render.DrawMode +import dev.deftu.omnicore.api.client.render.OmniShapeRenderer +import dev.deftu.omnicore.api.client.render.OmniTextureUnit +import dev.deftu.omnicore.api.client.render.pipeline.OmniRenderPipeline +import dev.deftu.omnicore.api.client.render.pipeline.OmniRenderPipelineSnippets +import dev.deftu.omnicore.api.client.render.pipeline.OmniRenderPipelines +import dev.deftu.omnicore.api.client.render.pipeline.RenderPassEncoder +import dev.deftu.omnicore.api.client.render.stack.OmniMatrixStack +import dev.deftu.omnicore.api.client.render.state.OmniBlendState +import dev.deftu.omnicore.api.color.OmniColor +import dev.deftu.omnicore.api.data.aabb.OmniAABB +import dev.deftu.omnicore.api.data.shape.OmniVoxelShapes +import dev.deftu.omnicore.api.data.vec.OmniVec3d +import dev.deftu.omnicore.api.identifierOrThrow +import dev.deftu.omnicore.api.math.OmniVector3f +import net.minecraft.entity.Entity +import kotlin.math.abs + +const val STIPPLE_PATTERN: Short = 0xAAAA.toShort() + +val HITBOX_SNIPPET: OmniRenderPipeline.Snippet = OmniRenderPipelineSnippets.builder().run { + setDepthTest(OmniRenderPipeline.DepthTest.LESS_OR_EQUAL) + setBlendState(OmniBlendState.NORMAL) + setCulling(false) + configureLegacyEffects { + lighting = false + OmniTextureUnit.TEXTURE0 equals false + } + build() +} + +val BOX_PIPELINE: OmniRenderPipeline = OmniRenderPipelines.builderWithDefaultShader( + identifierOrThrow(PolyHitboxConstants.ID, "pipeline/box"), + DefaultVertexFormats.POSITION_COLOR, + DrawMode.QUADS +).applySnippet(HITBOX_SNIPPET).build() + +val OUTLINE_BOX_PIPELINE: OmniRenderPipeline = OmniRenderPipelines.builderWithDefaultShader( + identifierOrThrow(PolyHitboxConstants.ID, "pipeline/outline_box"), + DefaultVertexFormats.POSITION_COLOR_NORMAL, + DrawMode.LINES +).applySnippet(HITBOX_SNIPPET).build() + +val OUTLINE_STIPPLE_BOX_PIPELINE: OmniRenderPipeline = OUTLINE_BOX_PIPELINE.newBuilder().configureLegacyEffects { + lineStipple = true +}.build() + +val VIEW_RAY_PIPELINE: OmniRenderPipeline = OmniRenderPipelines.builderWithDefaultShader( + identifierOrThrow(PolyHitboxConstants.ID, "pipeline/view_ray"), + DefaultVertexFormats.POSITION_COLOR_NORMAL, + DrawMode.LINES +).applySnippet(HITBOX_SNIPPET).build() + +val VIEW_RAY_STIPPLE_PIPELINE: OmniRenderPipeline = VIEW_RAY_PIPELINE.newBuilder().configureLegacyEffects { + lineStipple = true +}.build() + +fun renderHitbox( + stack: OmniMatrixStack, + offset: OmniVec3d, + entityPos: OmniVec3d, + lookVec: OmniVec3d, + eyeHeight: Float, + isLiving: Boolean, + isTargeted: Boolean, + width: Double, + collisionSize: Double, + boundingBox: OmniAABB, +) { + val info = PolyHitbox.getHitboxInfo() + when (info.showMode) { + 0 -> info.isTargeted = isTargeted + 1 -> if (!isTargeted) return else info.isTargeted = true + 2 -> return + } + + if (info.useDistanceBasedWidth) { + info.sqrDistance = (offset.x * offset.x + offset.y * offset.y + offset.z * offset.z).toFloat() + } + + var entityBoundingBox = + boundingBox.offset(-entityPos.x + offset.x, -entityPos.y + offset.y, -entityPos.z + offset.z) + if (info.isAccurate) { + entityBoundingBox = entityBoundingBox.offset(collisionSize) + } + + // Outline + val outline = info.outline + if (outline.isShown) { + val pipeline = if (outline.isDashed) OUTLINE_STIPPLE_BOX_PIPELINE else OUTLINE_BOX_PIPELINE + renderOutlineBox(pipeline, stack, entityBoundingBox, outline.getColor()) { + setLineWidth(outline.width) + if (outline.isDashed) { + setLineStipple(info.dashFactor, STIPPLE_PATTERN) + } + } + } + + // Sides + val sides = info.sides + if (sides.isShown) { + OmniShapeRenderer.FILLED_BOX.render(BOX_PIPELINE, stack, entityBoundingBox, sides.getColor()) + } + + // Eye Line + if (isLiving) { + val halfWidth = width / 2.0F + var boundingBox = OmniAABB( + offset.x - halfWidth, + offset.y + eyeHeight - 0.01, + offset.z - halfWidth, + offset.x + halfWidth, + offset.y + eyeHeight + 0.01, + offset.z + halfWidth + ) + + val eyeline = info.eyeline + if (eyeline.isShown) { + if (info.isAccurate) { + boundingBox = boundingBox.offset(collisionSize, 0.0, collisionSize) + } + + val pipeline = if (eyeline.isDashed) OUTLINE_STIPPLE_BOX_PIPELINE else OUTLINE_BOX_PIPELINE + renderOutlineBox(pipeline, stack, boundingBox, eyeline.getColor()) { + setLineWidth(eyeline.width) + if (eyeline.isDashed) { + setLineStipple(info.dashFactor, STIPPLE_PATTERN) + } + } + } + } + + // View Ray + val viewRay = info.viewRay + if (viewRay.isShown) { + val pipeline = if (viewRay.isDashed) VIEW_RAY_STIPPLE_PIPELINE else VIEW_RAY_PIPELINE + renderViewRay(pipeline, stack, offset, lookVec, eyeHeight, viewRay.getColor()) { + setLineWidth(viewRay.width) + if (viewRay.isDashed) { + setLineStipple(info.dashFactor, STIPPLE_PATTERN) + } + } + } +} + +private fun renderViewRay( + pipeline: OmniRenderPipeline, + stack: OmniMatrixStack, + offset: OmniVec3d, + lookVec: OmniVec3d, + eyeHeight: Float, + color: OmniColor, + builder: RenderPassEncoder.() -> Unit = {}, +) { + val dir = OmniVector3f(lookVec.x.toFloat(), lookVec.y.toFloat(), lookVec.z.toFloat()).normalized() + val up = if (abs(dir.y) > 0.99) OmniVector3f.UNIT_X else OmniVector3f.UNIT_Y + val normal = dir.cross(up).normalized() + pipeline.createBufferBuilder().run { + vertex(stack, offset.x, offset.y + eyeHeight, offset.z) + .color(color) + .normal(stack, normal.x, normal.y, normal.z) + .next() + vertex(stack, offset.x + lookVec.x * 2.0, offset.y + eyeHeight + lookVec.y * 2.0, offset.z + lookVec.z * 2.0) + .color(color) + .normal(stack, normal.x, normal.y, normal.z) + .next() + buildOrNull()?.drawAndClose(pipeline, builder) + } +} + +private fun renderOutlineBox( + pipeline: OmniRenderPipeline, + stack: OmniMatrixStack, + boundingBox: OmniAABB, + color: OmniColor, + builder: RenderPassEncoder.() -> Unit = {}, +) { + val buffer = pipeline.createBufferBuilder() + OmniShapeRenderer.SHAPE_OUTLINE.render(buffer, stack, OmniVoxelShapes.cuboid(boundingBox).simplify(), color) + buffer.buildOrNull()?.drawAndClose(pipeline, builder) +} + +private fun getEntityId(entity: Entity): String? { + //#if MC >= 1.16.5 + val entityType = entity.type.toString() + val type = entityType.substring(entityType.lastIndexOf("."), entityType.length).replace(".", "") + //#else + //$$ val type = EntityList.getEntityString(entity) ?: return null + //#endif + return type +} \ No newline at end of file diff --git a/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt b/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt index c56ab34..cf9e148 100644 --- a/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt +++ b/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt @@ -1,56 +1,97 @@ package org.polyfrost.polyhitbox -import net.minecraft.client.Minecraft -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityList -import net.minecraftforge.fml.common.Mod -import net.minecraftforge.fml.common.event.FMLInitializationEvent +//#if FABRIC +import net.fabricmc.api.ClientModInitializer +//#elseif FORGE +//#if MC >= 1.16.5 +//$$ import net.minecraftforge.eventbus.api.IEventBus +//$$ import net.minecraftforge.fml.common.Mod +//$$ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent +//$$ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext +//#else +//$$ import net.minecraftforge.fml.common.Mod +//$$ import net.minecraftforge.fml.common.event.FMLInitializationEvent +//#endif +//#endif + +import dev.deftu.omnicore.api.client.client import org.apache.logging.log4j.LogManager import org.polyfrost.oneconfig.api.config.v1.ConfigManager -@Mod( - modid = PolyHitbox.MODID, - name = PolyHitbox.NAME, - version = PolyHitbox.VERSION, - modLanguageAdapter = "org.polyfrost.oneconfig.utils.v1.forge.KotlinLanguageAdapter" -) -object PolyHitbox { - const val MODID = "@MOD_ID@" - const val NAME = "@MOD_NAME@" - const val VERSION = "@MOD_VERSION@" +//#if FORGE-LIKE +//#if MC >= 1.16.5 +//$$ @Mod(PolyHitboxConstants.ID) +//#else +//$$ @Mod(modid = PolyHitboxConstants.ID, version = PolyHitboxConstants.VERSION) +//#endif +//#endif +object PolyHitbox +//#if FABRIC + : ClientModInitializer +//#endif +{ private val LOGGER = LogManager.getLogger("PolyHitbox") private val hitboxInfo = HitboxInfo("hitbox.yaml") - private val hitboxMap = HashMap, HitboxInfo>() private var hitboxesEnabled: Boolean - get() = Minecraft.getMinecraft().renderManager.isDebugBoundingBox + get() { + //#if MC < 1.14 + //$$ return client.renderManager.isDebugBoundingBox + //#else + return client.entityRenderDispatcher.shouldRenderHitboxes() + //#endif + } set(value) { - Minecraft.getMinecraft().renderManager.isDebugBoundingBox = value + //#if MC < 1.14 + //$$ client.renderManager.isDebugBoundingBox = value + //#else + client.entityRenderDispatcher.setRenderHitboxes(value) + //#endif } - @Mod.EventHandler - fun onFMLInit(event: FMLInitializationEvent) { + //#if FABRIC + override + //#elseif FORGE && MC <= 1.12.2 + //$$ @Mod.EventHandler + //#endif + fun onInitializeClient( + //#if FORGE-LIKE + //#if MC >= 1.16.5 + //$$ event: FMLClientSetupEvent + //#else + //$$ event: FMLInitializationEvent + //#endif + //#endif + ) { hitboxInfo.tree.title = "PolyHitbox" hitboxInfo.tree = ConfigManager.active().register(hitboxInfo.tree).tree var enabled = false - ConfigManager.active().gatherAll("hitbox").forEach { - val name = it.id.substringBeforeLast('.').substringAfterLast('/') - val cls = EntityList.stringToClassMapping[name] - if (cls == null) { - LOGGER.warn("Unknown entity class for name $name") - return@forEach - } - val info = HitboxInfo(it.id) - info.tree.overwrite(it) - if (info.showMode != 2 /* NEVER */) enabled = true - hitboxMap[cls] = info + if (hitboxInfo.showMode != 2) { + enabled = true + } + + //#if FABRIC && MC > 1.14 + net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents.CLIENT_STARTED.register { tick -> + hitboxesEnabled = enabled } - if (hitboxInfo.showMode != 2) enabled = true - hitboxesEnabled = enabled + //#else + //hitboxesEnabled = enabled + //#endif } - fun getHitboxInfo(entity: Entity): HitboxInfo { - val cls = entity::class.java - return hitboxMap[cls] ?: hitboxMap[cls.superclass] ?: hitboxInfo + //#if FORGE && MC >= 1.16.5 + //$$ init { + //$$ setupForgeEvents(FMLJavaModLoadingContext.get().modEventBus) + //$$ } + //#endif + + //#if FORGE-LIKE && MC >= 1.16.5 + //$$ private fun setupForgeEvents(modEventBus: IEventBus) { + //$$ modEventBus.addListener(this::onInitializeClient) + //$$ } + //#endif + + fun getHitboxInfo(): HitboxInfo { + return hitboxInfo } } diff --git a/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitboxConstants.kt b/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitboxConstants.kt new file mode 100644 index 0000000..7440b47 --- /dev/null +++ b/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitboxConstants.kt @@ -0,0 +1,7 @@ +package org.polyfrost.polyhitbox + +object PolyHitboxConstants { + const val ID: String = "@MOD_ID@" + const val NAME: String = "@MOD_NAME@" + const val VERSION: String = "@MOD_VERSION@" +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..bf90f72 --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,23 @@ +{ + "schemaVersion": 1, + "id": "${mod_id}", + "name": "${mod_name}", + "version": "${mod_version}", + "description": "", + "authors": [ + "Polyfrost" + ], + "license": "GPL-3.0", + "environment": "client", + "entrypoints": { + "client": [ + { + "value": "org.polyfrost.polyhitbox.PolyHitbox", + "adapter": "kotlin" + } + ] + }, + "mixins": [ + "mixins.${mod_id}.json" + ] +} \ No newline at end of file diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index d977302..c480170 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,18 +1,18 @@ [ - { - "modid": "${mod_id}", - "name": "${mod_name}", - "description": "", - "version": "${mod_version}", - "mcversion": "${mc_version}", - "url": "", - "updateUrl": "", - "authorList": [ - "Polyfrost" - ], - "credits": "", - "logoFile": "", - "screenshots": [], - "dependencies": [] - } + { + "modid": "${mod_id}", + "name": "${mod_name}", + "description": "", + "version": "${mod_version}", + "mcversion": "${mc_version}", + "url": "", + "updateUrl": "", + "authorList": [ + "Polyfrost" + ], + "credits": "", + "logoFile": "", + "screenshots": [], + "dependencies": [] + } ] \ No newline at end of file diff --git a/src/main/resources/mixins.polyhitbox.json b/src/main/resources/mixins.polyhitbox.json index af0a14f..7d95da0 100644 --- a/src/main/resources/mixins.polyhitbox.json +++ b/src/main/resources/mixins.polyhitbox.json @@ -1,10 +1,10 @@ { - "compatibilityLevel": "JAVA_8", - "minVersion": "0.7", - "package": "org.polyfrost.polyhitbox.mixin", - "refmap": "mixins.polyhitbox.refmap.json", - "verbose": true, - "client": [ - "RenderManagerMixin" - ] + "compatibilityLevel": "JAVA_8", + "minVersion": "0.8", + "package": "org.polyfrost.polyhitbox.mixin", + "refmap": "mixins.polyhitbox.refmap.json", + "verbose": true, + "client": [ + "MixinRenderManager" + ] } \ No newline at end of file diff --git a/src/main/resources/polyhitbox.svg b/src/main/resources/polyhitbox.svg index ab6861f..c46afd6 100644 --- a/src/main/resources/polyhitbox.svg +++ b/src/main/resources/polyhitbox.svg @@ -1,6 +1,9 @@ - - - - + + + + diff --git a/versions/mainProject b/versions/mainProject index dd1433e..685ed77 100644 --- a/versions/mainProject +++ b/versions/mainProject @@ -1 +1 @@ -1.8.9-forge \ No newline at end of file +1.21.5-fabric \ No newline at end of file From ce3b2ccdae3ca9cea8d5463b2dba1dd4664e941d Mon Sep 17 00:00:00 2001 From: lowercasebtw Date: Fri, 3 Oct 2025 20:51:58 -0400 Subject: [PATCH 2/2] Remove unused code & Fix endif line --- .../kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt | 11 ----------- .../kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt | 3 --- 2 files changed, 14 deletions(-) diff --git a/src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt b/src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt index 4e519e4..f4413c1 100644 --- a/src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt +++ b/src/main/kotlin/org/polyfrost/polyhitbox/HitboxRenderer.kt @@ -16,7 +16,6 @@ import dev.deftu.omnicore.api.data.shape.OmniVoxelShapes import dev.deftu.omnicore.api.data.vec.OmniVec3d import dev.deftu.omnicore.api.identifierOrThrow import dev.deftu.omnicore.api.math.OmniVector3f -import net.minecraft.entity.Entity import kotlin.math.abs const val STIPPLE_PATTERN: Short = 0xAAAA.toShort() @@ -181,14 +180,4 @@ private fun renderOutlineBox( val buffer = pipeline.createBufferBuilder() OmniShapeRenderer.SHAPE_OUTLINE.render(buffer, stack, OmniVoxelShapes.cuboid(boundingBox).simplify(), color) buffer.buildOrNull()?.drawAndClose(pipeline, builder) -} - -private fun getEntityId(entity: Entity): String? { - //#if MC >= 1.16.5 - val entityType = entity.type.toString() - val type = entityType.substring(entityType.lastIndexOf("."), entityType.length).replace(".", "") - //#else - //$$ val type = EntityList.getEntityString(entity) ?: return null - //#endif - return type } \ No newline at end of file diff --git a/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt b/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt index 115b0b1..507adc4 100644 --- a/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt +++ b/src/main/kotlin/org/polyfrost/polyhitbox/PolyHitbox.kt @@ -15,7 +15,6 @@ import net.fabricmc.api.ClientModInitializer //#endif import dev.deftu.omnicore.api.client.client -import org.apache.logging.log4j.LogManager import org.polyfrost.oneconfig.api.config.v1.ConfigManager //#if FORGE-LIKE @@ -30,7 +29,6 @@ object PolyHitbox : ClientModInitializer //#endif { - private val LOGGER = LogManager.getLogger("PolyHitbox") private val hitboxInfo = HitboxInfo("hitbox.yaml") private var hitboxesEnabled: Boolean @@ -78,7 +76,6 @@ object PolyHitbox //hitboxesEnabled = enabled //#endif } - //#endif //#if FORGE && MC >= 1.16.5 //$$ init {