diff options
author | Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> | 2024-05-07 22:43:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-07 22:43:17 +0200 |
commit | d0345f39230e4f07f061b6c82a381c863e9787d8 (patch) | |
tree | beaf9d162d1ee0b891fefefeb1fb4815d9adb89b /src/main/java/at/hannibal2/skyhanni/utils | |
parent | 912c8d8a8c9ad412b2f94827e09a9cf262e5b69a (diff) | |
download | skyhanni-d0345f39230e4f07f061b6c82a381c863e9787d8.tar.gz skyhanni-d0345f39230e4f07f061b6c82a381c863e9787d8.tar.bz2 skyhanni-d0345f39230e4f07f061b6c82a381c863e9787d8.zip |
Feature: Tunnels maps (#1546)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/utils')
5 files changed, 201 insertions, 38 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt index 53ae224d9..915677bb6 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt @@ -285,4 +285,28 @@ object CollectionUtils { } return destination } + + inline fun <T, R> Iterable<T>.zipWithNext3(transform: (a: T, b: T, c: T) -> R): List<R> { + val iterator = iterator() + if (!iterator.hasNext()) return emptyList() + var one = iterator.next() + if (!iterator.hasNext()) return emptyList() + var two = iterator.next() + val result = mutableListOf<R>() + while (iterator.hasNext()) { + val next = iterator.next() + result.add(transform(one, two, next)) + one = two + two = next + } + return result + } + + fun <T> Iterable<T>.zipWithNext3(): List<Triple<T, T, T>> { + return zipWithNext3 { a, b, c -> Triple(a, b, c) } + } + + fun <K, V : Any> Map<K?, V>.filterNotNullKeys(): Map<K, V> { + return filterKeys { it != null } as Map<K, V> + } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt index 97a1342c1..e5ff47073 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt @@ -9,6 +9,8 @@ object ColorUtils { fun String.toChromaColor() = Color(toChromaColorInt(), true) fun String.toChromaColorInt() = SpecialColour.specialToChromaRGB(this) + fun String.getFirstColorCode() = this.takeIf { it.firstOrNull() == 'ยง' }?.getOrNull(1) + fun getRed(colour: Int) = colour shr 16 and 0xFF fun getGreen(colour: Int) = colour shr 8 and 0xFF diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt index 16fe8cd6e..08de7038a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt @@ -81,5 +81,13 @@ enum class LorenzColor(val chatColorCode: Char, private val color: Color, privat EnumDyeColor.BROWN -> GOLD EnumDyeColor.BLACK -> BLACK } + + fun Char.toLorenzColor(): LorenzColor? = entries.firstOrNull { it.chatColorCode == this } ?: run { + ErrorManager.logErrorWithData( + Exception("Unknown chat color: $this"), + "Unknown chat color: $this" + ) + null + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt index 55be8cd3e..dc143a841 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt @@ -136,6 +136,7 @@ data class LorenzVec( fun clone(): LorenzVec = LorenzVec(x, y, z) fun toDoubleArray(): Array<Double> = arrayOf(x, y, z) + fun toFloatArray(): Array<Float> = arrayOf(x.toFloat(), y.toFloat(), z.toFloat()) fun equalsIgnoreY(other: LorenzVec) = x == other.x && z == other.z diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index d17831fb5..fb97a8357 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -5,13 +5,19 @@ import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getAbsX import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getAbsY import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getDummySize +import at.hannibal2.skyhanni.data.model.Graph +import at.hannibal2.skyhanni.data.model.toPositionsList import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.GuiRenderItemEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.events.RenderGuiItemOverlayEvent import at.hannibal2.skyhanni.features.misc.RoundedRectangleOutlineShader import at.hannibal2.skyhanni.features.misc.RoundedRectangleShader +import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.CollectionUtils.zipWithNext3 +import at.hannibal2.skyhanni.utils.ColorUtils.getFirstColorCode +import at.hannibal2.skyhanni.utils.LorenzColor.Companion.toLorenzColor import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned import at.hannibal2.skyhanni.utils.shader.ShaderManager @@ -35,6 +41,7 @@ import net.minecraft.util.MathHelper import net.minecraft.util.ResourceLocation import org.lwjgl.opengl.GL11 import java.awt.Color +import java.nio.FloatBuffer import kotlin.math.cos import kotlin.math.max import kotlin.math.sin @@ -66,8 +73,9 @@ object RenderUtils { private val beaconBeam = ResourceLocation("textures/entity/beacon_beam.png") - private val matrixBuffer = GLAllocation.createDirectFloatBuffer(16) - private val colourBuffer = GLAllocation.createDirectFloatBuffer(16) + private val matrixBuffer: FloatBuffer = GLAllocation.createDirectFloatBuffer(16); + private val colourBuffer: FloatBuffer = GLAllocation.createDirectFloatBuffer(16) + private val bezier2Buffer: FloatBuffer = GLAllocation.createDirectFloatBuffer(9) infix fun Slot.highlight(color: LorenzColor) { highlight(color.toColor()) @@ -1017,43 +1025,10 @@ object RenderUtils { } } - fun LorenzRenderWorldEvent.draw3DLine(p1: LorenzVec, p2: LorenzVec, color: Color, lineWidth: Int, depth: Boolean) { - GlStateManager.disableCull() - - val render = Minecraft.getMinecraft().renderViewEntity - val worldRenderer = Tessellator.getInstance().worldRenderer - val realX = render.lastTickPosX + (render.posX - render.lastTickPosX) * partialTicks - val realY = render.lastTickPosY + (render.posY - render.lastTickPosY) * partialTicks - val realZ = render.lastTickPosZ + (render.posZ - render.lastTickPosZ) * partialTicks - GlStateManager.pushMatrix() - GlStateManager.translate(-realX, -realY, -realZ) - GlStateManager.disableTexture2D() - GlStateManager.enableBlend() - GlStateManager.disableAlpha() - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) - GL11.glLineWidth(lineWidth.toFloat()) - if (!depth) { - GL11.glDisable(GL11.GL_DEPTH_TEST) - GlStateManager.depthMask(false) - } - GlStateManager.color(color.red / 255f, color.green / 255f, color.blue / 255f, color.alpha / 255f) - worldRenderer.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION) - worldRenderer.pos(p1.x, p1.y, p1.z).endVertex() - worldRenderer.pos(p2.x, p2.y, p2.z).endVertex() - Tessellator.getInstance().draw() - GlStateManager.translate(realX, realY, realZ) - if (!depth) { - GL11.glEnable(GL11.GL_DEPTH_TEST) - GlStateManager.depthMask(true) + fun LorenzRenderWorldEvent.draw3DLine(p1: LorenzVec, p2: LorenzVec, color: Color, lineWidth: Int, depth: Boolean) = + LineDrawer.draw3D(partialTicks) { + draw3DLine(p1, p2, color, lineWidth, depth) } - GlStateManager.disableBlend() - GlStateManager.enableAlpha() - GlStateManager.enableTexture2D() - GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f) - GlStateManager.popMatrix() - GlStateManager.disableLighting() - GlStateManager.enableDepth() - } fun LorenzRenderWorldEvent.exactLocation(entity: Entity) = exactLocation(entity, partialTicks) @@ -1232,6 +1207,159 @@ object RenderUtils { ) } + fun LorenzRenderWorldEvent.draw3DPathWithWaypoint( + path: Graph, + colorLine: Color, + lineWidth: Int, + depth: Boolean, + startAtEye: Boolean = true, + textSize: Double = 1.0, + waypointColor: Color = + (path.lastOrNull()?.name?.getFirstColorCode()?.toLorenzColor() ?: LorenzColor.WHITE).toColor(), + bezierPoint: Double = 1.0, + ) { + if (path.isEmpty()) return + val points = if (startAtEye) { + listOf( + this.exactPlayerEyeLocation() + + Minecraft.getMinecraft().thePlayer.getLook(this.partialTicks) + .toLorenzVec()/* .rotateXZ(-Math.PI / 72.0) */.times(2) + ) + } else { + emptyList() + } + path.toPositionsList().map { it.add(0.5, 0.5, 0.5) } + LineDrawer.draw3D(partialTicks) { + drawPath( + points, + colorLine, + lineWidth, + depth, + bezierPoint + ) + } + path.filter { it.name?.isNotEmpty() == true }.forEach { + this.drawDynamicText(it.position, it.name!!, textSize) + } + val last = path.last() + drawWaypointFilled(last.position, waypointColor, seeThroughBlocks = true) + } + + class LineDrawer @PublishedApi internal constructor(val tessellator: Tessellator) { + val worldRenderer = tessellator.worldRenderer + fun drawPath(path: List<LorenzVec>, color: Color, lineWidth: Int, depth: Boolean, bezierPoint: Double = 1.0) { + if (bezierPoint < 0) { + path.zipWithNext().forEach { + draw3DLine(it.first, it.second, color, lineWidth, depth) + } + } else { + val pathLines = path.zipWithNext() + pathLines.forEachIndexed { index, it -> + val reduce = it.second.minus(it.first).normalize().times(bezierPoint) + draw3DLine( + if (index != 0) it.first + reduce else it.first, + if (index != pathLines.lastIndex) it.second - reduce else it.second, + color, + lineWidth, + depth + ) + } + path.zipWithNext3().forEach { + val p1 = it.second.minus(it.second.minus(it.first).normalize().times(bezierPoint)) + val p3 = it.second.minus(it.second.minus(it.third).normalize().times(bezierPoint)) + val p2 = it.second + drawBezier2(p1, p2, p3, color, lineWidth, depth) + } + } + } + + fun draw3DLine(p1: LorenzVec, p2: LorenzVec, color: Color, lineWidth: Int, depth: Boolean) { + GL11.glLineWidth(lineWidth.toFloat()) + if (!depth) { + GL11.glDisable(GL11.GL_DEPTH_TEST) + GlStateManager.depthMask(false) + } + GlStateManager.color(color.red / 255f, color.green / 255f, color.blue / 255f, color.alpha / 255f) + worldRenderer.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION) + worldRenderer.pos(p1.x, p1.y, p1.z).endVertex() + worldRenderer.pos(p2.x, p2.y, p2.z).endVertex() + tessellator.draw() + if (!depth) { + GL11.glEnable(GL11.GL_DEPTH_TEST) + GlStateManager.depthMask(true) + } + } + + fun drawBezier2( + p1: LorenzVec, + p2: LorenzVec, + p3: LorenzVec, + color: Color, + lineWidth: Int, + depth: Boolean, + segments: Int = 30, + ) { + GL11.glLineWidth(lineWidth.toFloat()) + if (!depth) { + GL11.glDisable(GL11.GL_DEPTH_TEST) + GlStateManager.depthMask(false) + } + GlStateManager.color(color.red / 255f, color.green / 255f, color.blue / 255f, color.alpha / 255f) + val ctrlpoints = p1.toFloatArray() + p2.toFloatArray() + p3.toFloatArray() + bezier2Buffer.clear() + ctrlpoints.forEach { + bezier2Buffer.put(it) + } + bezier2Buffer.flip() + GL11.glMap1f( + GL11.GL_MAP1_VERTEX_3, 0.0f, 1.0f, 3, 3, + bezier2Buffer + ) + + GL11.glEnable(GL11.GL_MAP1_VERTEX_3) + + GL11.glBegin(GL11.GL_LINE_STRIP) + for (i in 0..segments) { + GL11.glEvalCoord1f(i.toFloat() / segments.toFloat()) + } + GL11.glEnd() + if (!depth) { + GL11.glEnable(GL11.GL_DEPTH_TEST) + GlStateManager.depthMask(true) + } + } + + companion object { + inline fun draw3D( + partialTicks: Float = 0F, + crossinline quads: LineDrawer.() -> Unit, + ) { + + GlStateManager.enableBlend() + GlStateManager.disableLighting() + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) + GlStateManager.disableTexture2D() + GlStateManager.disableCull() + GlStateManager.disableAlpha() + + val tessellator = Tessellator.getInstance() + + GlStateManager.pushMatrix() + RenderUtils.translate(getViewerPos(partialTicks).negated()) + getViewerPos(partialTicks) + + quads.invoke(LineDrawer(Tessellator.getInstance())) + + GlStateManager.popMatrix() + + GlStateManager.enableAlpha() + GlStateManager.enableTexture2D() + GlStateManager.enableCull() + GlStateManager.disableBlend() + GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f) + } + } + } + class QuadDrawer @PublishedApi internal constructor(val tessellator: Tessellator) { val worldRenderer = tessellator.worldRenderer inline fun draw( |