From e5f0cd0ab2d1e69b8ae42975b5b0360ebedaee90 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 17 Jul 2021 22:58:21 +0200 Subject: [PATCH] Add RenderUtil.kt, fix a logic issue in the setter of ButtonImpl.toggled, add keystrokes and set the version number to 0.3.0 --- build.gradle.kts | 2 +- .../kotlin/fr/username404/snowygui/Snowy.kt | 3 +- .../snowygui/config/ConfigScreen.kt | 2 +- .../fr/username404/snowygui/gui/Element.kt | 37 +++--------- .../snowygui/gui/elements/ClickBox.kt | 5 +- .../snowygui/gui/feature/ButtonImpl.kt | 7 +-- .../snowygui/gui/feature/ButtonImplWithHud.kt | 17 ++++++ .../snowygui/gui/feature/ButtonInfo.kt | 3 +- .../username404/snowygui/gui/feature/Clock.kt | 26 ++++---- .../snowygui/gui/feature/Colors.kt | 4 +- .../snowygui/gui/feature/Keystrokes.kt | 59 +++++++++++++++++++ .../snowygui/{gui => utils}/FontUtil.kt | 2 +- .../snowygui/utils/RenderingUtil.kt | 41 +++++++++++++ .../resources/assets/snowygui/lang/en_us.json | 1 + .../resources/assets/snowygui/lang/fr_fr.json | 1 + 15 files changed, 153 insertions(+), 57 deletions(-) create mode 100644 common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImplWithHud.kt create mode 100644 common/src/main/kotlin/fr/username404/snowygui/gui/feature/Keystrokes.kt rename common/src/main/kotlin/fr/username404/snowygui/{gui => utils}/FontUtil.kt (93%) create mode 100644 common/src/main/kotlin/fr/username404/snowygui/utils/RenderingUtil.kt diff --git a/build.gradle.kts b/build.gradle.kts index 0f66001..096e06f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,7 +26,7 @@ plugins { } group = "fr.username404" -version = "0.2.7" +version = "0.3.0" val groupAndName = "${rootProject.group}.${rootProject.name.toLowerCase()}" architectury { diff --git a/common/src/main/kotlin/fr/username404/snowygui/Snowy.kt b/common/src/main/kotlin/fr/username404/snowygui/Snowy.kt index 7e93fef..9a0fa6c 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/Snowy.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/Snowy.kt @@ -16,8 +16,9 @@ abstract class Snowy { private val displayInitMessage: Boolean by Configuration companion object { val MissingComponent: TranslatableComponent = object: TranslatableComponent(null) { override fun getString(): String = "MISSING_COMPONENT" } + @Suppress("JVM_STATIC_ON_CONST_OR_JVM_FIELD") // See KT-39868 @JvmStatic - protected val FeaturePackage: String = ButtonInfo::class.java.packageName + protected const val FeaturePackage: String = "fr.username404.snowygui.gui.feature" lateinit var annotatedButtons: Set> fun onEvent(e: Any, lambda: argsLambda) = useKey(e.toString()).add(lambda) @JvmField diff --git a/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt b/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt index a893caa..9f4ca05 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt @@ -2,7 +2,7 @@ package fr.username404.snowygui.config import com.mojang.blaze3d.vertex.PoseStack import fr.username404.snowygui.ClickGui -import fr.username404.snowygui.gui.FontUtil +import fr.username404.snowygui.utils.FontUtil import fr.username404.snowygui.gui.elements.ClickBox import fr.username404.snowygui.gui.elements.ClickBox.Companion.buttonsMax import fr.username404.snowygui.gui.elements.ClickBox.Companion.sortAlphabetically diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/Element.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/Element.kt index 8d6ebeb..7489457 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/Element.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/Element.kt @@ -1,32 +1,20 @@ package fr.username404.snowygui.gui -import com.mojang.blaze3d.vertex.* +import com.mojang.blaze3d.vertex.PoseStack +import com.mojang.blaze3d.vertex.VertexConsumer import fr.username404.snowygui.Snowy import fr.username404.snowygui.gui.feature.Colors +import fr.username404.snowygui.utils.RenderingUtil +import fr.username404.snowygui.utils.RenderingUtil.colorEnd import net.minecraft.client.gui.components.events.GuiEventListener -import org.lwjgl.opengl.GL20 fun interface Renderable { - companion object Rendering { - @JvmStatic val tessellator: Tesselator = Tesselator.getInstance() - @JvmStatic val buffer: BufferBuilder = tessellator.builder - fun ColoredElement.defaultRectFunc() { - with(buffer) { - begin(GL20.GL_QUADS, DefaultVertexFormat.POSITION_COLOR) - vertex(x, y + height, 0.0).colorEnd() - vertex(x + width, y + height, 0.0).colorEnd() - vertex(x + width, y, 0.0).colorEnd() - vertex(x, y, 0.0).colorEnd() - tessellator.end() - } - } - } fun render(poseStack: PoseStack?) } abstract class Element( @JvmField val xOrigin: Double, @JvmField val yOrigin: Double, - val originalWidth: Int, val originalHeight: Int + @JvmField val originalWidth: Int, @JvmField val originalHeight: Int ): Renderable, GuiEventListener { open var width = originalWidth; open var height = originalHeight open var x = xOrigin; open var y = yOrigin @@ -34,11 +22,6 @@ abstract class Element( (coordinateX in x..(x + width + offsetWidth)) && (coordinateY in y..(y + height + offsetHeight)) companion object { private var caughtError: Boolean = false - fun fromRenderable(r: Renderable, x: Double, y: Double, width: Int, height: Int): Element { - return object: Element(x, y, width, height) { - override fun render(poseStack: PoseStack?) = r.render(poseStack) - } - } } open fun display(stack: PoseStack? = null) { if (!hidden && !caughtError) try { @@ -59,14 +42,8 @@ abstract class ColoredElement( x: Double, y: Double, width: Int, height: Int, open val color: Int = Colors.TRANSPARENT.hexValue, protected var opacity: Float, ) : Element(x, y, width, height) { - companion object { - @JvmStatic protected fun VertexConsumer.colorIt(color: Int, opacity: Float = 1F): VertexConsumer { - with(hextoRGB(color)) { - return this@colorIt.color(get(0), get(1), get(2), opacity) - } - } - } - internal fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorIt(color, opacity).endVertex() + protected fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorEnd(color, opacity) + protected fun defaultRectFunc() = RenderingUtil.drawRectangle(x, y, height, width, color, opacity) } fun hextoRGB(hex: Int): MutableList { diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/elements/ClickBox.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/elements/ClickBox.kt index 30ca61a..6f24fa1 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/elements/ClickBox.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/elements/ClickBox.kt @@ -6,12 +6,11 @@ import com.mojang.blaze3d.vertex.PoseStack import fr.username404.snowygui.Snowy.Companion.MissingComponent import fr.username404.snowygui.config.Configuration import fr.username404.snowygui.gui.ColoredElement -import fr.username404.snowygui.gui.Renderable.Rendering.buffer -import fr.username404.snowygui.gui.Renderable.Rendering.defaultRectFunc -import fr.username404.snowygui.gui.Renderable.Rendering.tessellator import fr.username404.snowygui.gui.feature.ButtonImpl import fr.username404.snowygui.gui.feature.Category import fr.username404.snowygui.gui.feature.Colors +import fr.username404.snowygui.utils.RenderingUtil.buffer +import fr.username404.snowygui.utils.RenderingUtil.tessellator import io.github.config4k.extract import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.launch diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt index 6dcf884..44a8d79 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt @@ -6,8 +6,7 @@ import fr.username404.snowygui.ClickGui import fr.username404.snowygui.Snowy import fr.username404.snowygui.config.Configuration import fr.username404.snowygui.gui.ColoredElement -import fr.username404.snowygui.gui.FontUtil -import fr.username404.snowygui.gui.Renderable.Rendering.defaultRectFunc +import fr.username404.snowygui.utils.FontUtil import fr.username404.snowygui.gui.feature.ButtonInfo.Companion.Type import kotlin.reflect.full.findAnnotation @@ -55,7 +54,7 @@ sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) { } @JvmField val info = this::class.findAnnotation() ?: throw Exception("Missing @ButtonInfo annotaton") - override var color = info.parent.categoryColor; get() { + final override var color = info.parent.categoryColor; get() { return info.parent.box.color.let { if (field == it) field else it } @@ -64,8 +63,8 @@ sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) { protected open fun execAction() = Unit private var wasWithinBounds: Boolean = false var toggled: Boolean = false; private set(value) { - if (value) lightUp() else if (field) lightDown() if (field xor value) { + if (value) lightUp() else lightDown() field = value execAction() } else field = value diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImplWithHud.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImplWithHud.kt new file mode 100644 index 0000000..32d4bb7 --- /dev/null +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImplWithHud.kt @@ -0,0 +1,17 @@ +package fr.username404.snowygui.gui.feature + +import com.mojang.blaze3d.vertex.PoseStack +import fr.username404.snowygui.EventSnowy.Companion.useKey +import fr.username404.snowygui.argsLambda +import fr.username404.snowygui.gui.Renderable + +sealed class ButtonImplWithHud: ButtonImpl() { + protected abstract val hudRenderLambda: Renderable + private val generatedLambda: argsLambda = { hudRenderLambda.render(it.first() as PoseStack?) } + final override fun execAction() { + useKey("HudRender").run { + if (toggled) add(generatedLambda) + else remove(generatedLambda) + } + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonInfo.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonInfo.kt index 47d18a0..0b1f222 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonInfo.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonInfo.kt @@ -16,13 +16,14 @@ annotation class ButtonInfo( val ignored: Boolean = false /** Excludes a class from button collection */ ) { companion object { - internal var lightningFactor: Float = 0.33F + const val lightningFactor: Float = 0.33F enum class Type { TOGGLE, CLICK } enum class Category(val translationKey: String, val categoryColor: Int, val shouldHide: Boolean = false) { MISC("snowy.clickbox.misc", Colors.BLUE), + HUD("snowy.clickbox.hud", Colors.DARK_PURPLE), RISKY("snowy.clickbox.risky", Colors.RED, !riskyCheats), MACROS("snowy.clickbox.macros", Colors.GREEN); companion object { diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Clock.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Clock.kt index aa0f995..1bc872f 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Clock.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Clock.kt @@ -1,26 +1,24 @@ package fr.username404.snowygui.gui.feature -import com.mojang.blaze3d.vertex.PoseStack -import fr.username404.snowygui.Snowy.Companion.onEvent -import fr.username404.snowygui.gui.FontUtil +import fr.username404.snowygui.gui.Renderable +import fr.username404.snowygui.utils.FontUtil import java.time.LocalDateTime -@ButtonInfo(Category.MISC) -object Clock: ButtonImpl() { +@ButtonInfo(Category.HUD) +object Clock: ButtonImplWithHud() { override fun toString(): String = LocalDateTime.now().run { arrayOf(hour, minute, second).map { (it.takeIf { (it >= 10) } ?: "0$it").toString() }.reduce { previous, current -> "$previous:$current"} } - init { - onEvent("HudRender") { - if (toggled) { - FontUtil.drawScaled(it.first() as PoseStack, - this@Clock.toString(), - 5.0, 5.0, - 0.85F, color = Colors.GOLD - ) - } + + override val hudRenderLambda = Renderable { poseStack -> + poseStack?.let { + FontUtil.drawScaled( + it, this@Clock.toString(), + 5.0, 5.0, + 0.85F, color = Colors.GOLD + ) } } } diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt index 26425ed..ee156db 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt @@ -12,6 +12,8 @@ enum class Colors(val hexValue: Int) { RED(0x660000), GREEN(0x00FF7F), ORANGE(0xf18e33), - PURPLE(0xA97BFF); + PURPLE(0xA97BFF), + DARK_PURPLE(0x3C204C); + operator fun invoke() = hexValue fun asTextColor(): TextColor = TextColor.fromRgb(hexValue) } diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Keystrokes.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Keystrokes.kt new file mode 100644 index 0000000..80a3b98 --- /dev/null +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Keystrokes.kt @@ -0,0 +1,59 @@ +package fr.username404.snowygui.gui.feature + +import com.mojang.blaze3d.vertex.PoseStack +import fr.username404.snowygui.gui.ColoredElement +import fr.username404.snowygui.gui.Renderable +import fr.username404.snowygui.utils.FontUtil +import fr.username404.snowygui.utils.RenderingUtil +import net.minecraft.client.Minecraft + +@ButtonInfo(Category.HUD) +object Keystrokes: ButtonImplWithHud() { + private val hud = object : ColoredElement(x = 135.0, y = 325.0, height = 36, width = 36, color = Colors.BLACK(), opacity = 0.5F) { + private val keysArray by lazy { + Minecraft.getInstance().options.run { + arrayOf(keyLeft, keyDown, keyRight, keyUp) to arrayOf(0.5, 0.5, 0.5, 0.5) + } + } + private val minimumOpacity = opacity.toDouble() + private fun getDynamicOpacity(i: Int): Double { + val dynamicOpacity = keysArray.second + if (keysArray.first[i].isDown) { + if (dynamicOpacity[i] < 1) { + dynamicOpacity[i] += 0.05 + } + } else { + if (dynamicOpacity[i] > minimumOpacity) { + dynamicOpacity[i] -= 0.05 + } + } + return dynamicOpacity[i] + } + + private fun drawKey(x: Double, y: Double, key: Int, poseStack: PoseStack? = null) { + RenderingUtil.prepareDraw() + RenderingUtil.drawRectangle( + x, y, height / 2, height / 2, + color = color, opacity = getDynamicOpacity(key).toFloat() + ) + RenderingUtil.endDraw() + poseStack?.let { + FontUtil.drawScaled( + it, keysArray.first[key].translatedKeyMessage.string.uppercase(), + x + height.toDouble() / 5.5, y + height.toDouble() / 6.5, + scaleFactor = 1F, color = Colors.WHITE + ) + } + } + private fun getNewPos(i: Int) = x + (i * (2 + (height / 2))) + override fun render(poseStack: PoseStack?) = with(RenderingUtil) { + for (i in 0 until 3) { + drawKey(getNewPos(i), y, i, poseStack) + } + drawKey(getNewPos(1), y - (height / 2) - 2, 3, poseStack) + } + } + override val hudRenderLambda = Renderable { + hud.display(it) + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/FontUtil.kt b/common/src/main/kotlin/fr/username404/snowygui/utils/FontUtil.kt similarity index 93% rename from common/src/main/kotlin/fr/username404/snowygui/gui/FontUtil.kt rename to common/src/main/kotlin/fr/username404/snowygui/utils/FontUtil.kt index a617692..f74e683 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/FontUtil.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/utils/FontUtil.kt @@ -1,4 +1,4 @@ -package fr.username404.snowygui.gui +package fr.username404.snowygui.utils import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.Minecraft diff --git a/common/src/main/kotlin/fr/username404/snowygui/utils/RenderingUtil.kt b/common/src/main/kotlin/fr/username404/snowygui/utils/RenderingUtil.kt new file mode 100644 index 0000000..6a35fe3 --- /dev/null +++ b/common/src/main/kotlin/fr/username404/snowygui/utils/RenderingUtil.kt @@ -0,0 +1,41 @@ +package fr.username404.snowygui.utils + +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.BufferBuilder +import com.mojang.blaze3d.vertex.DefaultVertexFormat +import com.mojang.blaze3d.vertex.Tesselator +import com.mojang.blaze3d.vertex.VertexConsumer +import fr.username404.snowygui.gui.feature.Colors +import fr.username404.snowygui.gui.hextoRGB +import org.lwjgl.opengl.GL20 + +object RenderingUtil { + @JvmField val tessellator: Tesselator = Tesselator.getInstance() + @JvmField val buffer: BufferBuilder = tessellator.builder + @JvmStatic + fun VertexConsumer.colorIt(color: Int, opacity: Float = 1F): VertexConsumer = hextoRGB(color).run { + color(get(0), get(1), get(2), opacity) + } + fun VertexConsumer.colorEnd(color: Int, opacity: Float = 1F) = colorIt(color, opacity).endVertex() + fun prepareDraw() { + RenderSystem.disableTexture() + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + } + fun endDraw() { + RenderSystem.enableTexture() + RenderSystem.disableBlend() + } + fun drawRectangle( + x: Double, y: Double, height: Int, width: Int, + color: Int = Colors.TRANSPARENT(), opacity: Float = 1F + ): Unit = buffer.run { + fun VertexConsumer.colorEnd() = colorEnd(color, opacity) + begin(GL20.GL_QUADS, DefaultVertexFormat.POSITION_COLOR) + vertex(x, y + height, 0.0).colorEnd() + vertex(x + width, y + height, 0.0).colorEnd() + vertex(x + width, y, 0.0).colorEnd() + vertex(x, y, 0.0).colorEnd() + tessellator.end() + } +} diff --git a/common/src/main/resources/assets/snowygui/lang/en_us.json b/common/src/main/resources/assets/snowygui/lang/en_us.json index 0e64961..d9fb993 100644 --- a/common/src/main/resources/assets/snowygui/lang/en_us.json +++ b/common/src/main/resources/assets/snowygui/lang/en_us.json @@ -17,6 +17,7 @@ "key.snowy.opengui": "Open the snowy gui", "key.snowy.configkey": "Open the snowy configuration screen", "snowy.clickbox.misc": "Miscellaneous", + "snowy.clickbox.hud": "HUD", "snowy.clickbox.risky": "Risky", "snowy.clickbox.macros": "Macros" } \ No newline at end of file diff --git a/common/src/main/resources/assets/snowygui/lang/fr_fr.json b/common/src/main/resources/assets/snowygui/lang/fr_fr.json index 40ddb4b..ac9b767 100644 --- a/common/src/main/resources/assets/snowygui/lang/fr_fr.json +++ b/common/src/main/resources/assets/snowygui/lang/fr_fr.json @@ -17,6 +17,7 @@ "key.snowy.opengui": "Ouvrir l'interface de snowy", "key.snowy.configkey": "Ouvrir l'écran de configuration de snowy", "snowy.clickbox.misc": "Divers", + "snowy.clickbox.hud": "ATH", "snowy.clickbox.risky": "Risqué", "snowy.clickbox.macros": "Macros" } \ No newline at end of file