Compare commits
No commits in common. "1.21" and "1.18" have entirely different histories.
|
@ -1,8 +1,5 @@
|
|||
pipeline {
|
||||
agent any
|
||||
environment {
|
||||
JAVA_HOME='/usr/lib/jvm/temurin-17-jdk-amd64/'
|
||||
}
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '48', artifactNumToKeepStr: '96'))
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import com.modrinth.minotaur.ModrinthExtension
|
||||
import com.modrinth.minotaur.request.VersionType
|
||||
import com.modrinth.minotaur.dependencies.DependencyType
|
||||
import masecla.modrinth4j.model.version.ProjectVersion.VersionType
|
||||
import net.fabricmc.loom.LoomGradleExtension
|
||||
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath("com.guardsquare:proguard-gradle:[7.5, 7.7[") {
|
||||
classpath("com.guardsquare:proguard-gradle:[7.4, 7.5[") {
|
||||
exclude("com.android.tools.build")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.0.0"
|
||||
kotlin("plugin.serialization") version "2.0.0"
|
||||
kotlin("jvm") version "1.9.22"
|
||||
kotlin("plugin.serialization") version "1.9.22"
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1" apply false
|
||||
id("architectury-plugin") version "[3.4.160, 3.5["
|
||||
id("dev.architectury.loom") version "1.7-SNAPSHOT" apply false
|
||||
id("architectury-plugin") version "[3.4.124, 3.5["
|
||||
id("dev.architectury.loom") version "1.4-SNAPSHOT" apply false
|
||||
id("com.github.ben-manes.versions") version "0.51.0"
|
||||
id("net.kyori.indra.git") version "3.1.3"
|
||||
id("org.cqfn.diktat.diktat-gradle-plugin") version "1.2.5"
|
||||
|
@ -26,17 +25,17 @@ plugins {
|
|||
}
|
||||
|
||||
group = "fr.username404"
|
||||
version = "0.3.5"
|
||||
val groupAndName = "${rootProject.group}.${rootProject.name.lowercase()}"
|
||||
version = "0.3.4"
|
||||
val groupAndName = "${rootProject.group}.${rootProject.name.toLowerCase()}"
|
||||
|
||||
val javaVer: String = "21"
|
||||
val javaVer: String = "17"
|
||||
val sourceJavaVer: String = javaVer
|
||||
val kotlinVer: String by rootProject
|
||||
val kotlinSplitVersion = kotlinVer.split('.')
|
||||
val serializationVer: String by rootProject
|
||||
val minecraftVersion: String = (rootProject.property("minecraft") as String).also {
|
||||
val mcBase: String = (rootProject.property("minecraft") as String).also {
|
||||
architectury { minecraft = it }
|
||||
}
|
||||
}.substring(0..3)
|
||||
val kotlinX: String = "org.jetbrains.kotlinx"
|
||||
|
||||
subprojects {
|
||||
|
@ -51,17 +50,18 @@ subprojects {
|
|||
apply(plugin = "dev.architectury.loom")
|
||||
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
|
||||
extensions.configure<LoomGradleExtension>("loom") {
|
||||
if (this@subprojects.project.name != "common") {
|
||||
accessWidenerPath.set(project(":common").extensions.getByType<LoomGradleExtensionAPI>().accessWidenerPath)
|
||||
}
|
||||
mappingsDep = layered {
|
||||
silentMojangMappingsLicense()
|
||||
officialMojangMappings().parchment("org.parchmentmc.data:parchment-1.21:2024.06.23")
|
||||
officialMojangMappings().parchment("org.parchmentmc.data:parchment-${rootProject.architectury.minecraft}:2022.02.13")
|
||||
}
|
||||
silentMojangMappingsLicense()
|
||||
val refmap = "snowygui-${project.name}-refmap.json"
|
||||
mixin {
|
||||
useLegacyMixinAp = true
|
||||
defaultRefmapName = refmap
|
||||
defaultRefmapName.set(refmap)
|
||||
if (isForge) {
|
||||
forge {
|
||||
mixinConfigs("snowygui-common.mixins.json", "snowygui-forge.mixins.json")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
|
@ -75,8 +75,8 @@ subprojects {
|
|||
implementation("$kotlinX:kotlinx-serialization-core:$serializationVer")
|
||||
implementation("$kotlinX:kotlinx-serialization-json:$serializationVer")
|
||||
listOf(
|
||||
"com.typesafe:config:1.4.3",
|
||||
"io.github.config4k:config4k:0.6.0",
|
||||
"com.typesafe:config:1.4.2",
|
||||
"io.github.config4k:config4k:0.4.2",
|
||||
"com.github.Vatuu:discord-rpc:1.6.2"
|
||||
).forEach { implementation(it); shadowC(it) { isTransitive = false; exclude("com.sun.jna") } }
|
||||
"minecraft"("com.mojang:minecraft:${rootProject.property("minecraft")}")
|
||||
|
@ -86,8 +86,8 @@ subprojects {
|
|||
extensions.configure<ModrinthExtension>("modrinth") {
|
||||
projectId.set("OuGyGg6A")
|
||||
syncBodyFrom.set("$rootDir/README.md")
|
||||
gameVersions.add(minecraftVersion)
|
||||
if (project.name == "forge") dependencies.add(com.modrinth.minotaur.dependencies.ModDependency("ordsPcFz", DependencyType.REQUIRED)) // Kotlinforforge dependency
|
||||
gameVersions.add(mcBase)
|
||||
if (project.name == "forge") dependencies.add(com.modrinth.minotaur.dependencies.VersionDependency("Bxm9xbNJ", DependencyType.REQUIRED)) // Kotlinforforge dependency
|
||||
versionNumber.set(rootProject.version.toString() + "-${project.name}")
|
||||
versionType.set(VersionType.ALPHA.name)
|
||||
detectLoaders.set(false)
|
||||
|
@ -134,7 +134,6 @@ subprojects {
|
|||
flattenpackagehierarchy("$group.snowygui")
|
||||
allowaccessmodification()
|
||||
adaptclassstrings()
|
||||
dontnote() // This is needed to silence warnings about duplicate classes
|
||||
"$group.**".also { dontnote(it); dontwarn(it) }
|
||||
|
||||
// kotlinx-serialization related configuration:
|
||||
|
@ -170,9 +169,9 @@ subprojects {
|
|||
dependsOn(shrinkJar)
|
||||
val shrinkedJar = shrinkJar.get().outJarFileCollection.singleFile
|
||||
archiveBaseName.set(shadowJar.archiveBaseName)
|
||||
archiveVersion.set("[${rootProject.version}+$minecraftVersion]")
|
||||
archiveVersion.set("[${rootProject.version}+$mcBase]")
|
||||
archiveClassifier.set(this@subprojects.name)
|
||||
inputFile.set(shrinkedJar)
|
||||
input.set(shrinkedJar)
|
||||
if (!archiveFileName.get().contains("common")) destinationDirectory.set(file("$rootDir/remappedJars"))
|
||||
}
|
||||
getByName("modrinth").dependsOn(build)
|
||||
|
@ -207,10 +206,9 @@ allprojects {
|
|||
"-Xbackend-threads=0", "-Xno-param-assertions", "-Xno-call-assertions",
|
||||
"-opt-in=kotlin.RequiresOptIn", "-Xextended-compiler-checks", "-Xassertions=jvm", "-progressive"
|
||||
)
|
||||
jvmTarget = javaVer
|
||||
// Uncomment when updating to architectury-loom 1.9
|
||||
//languageVersion = (kotlinSplitVersion[0] + '.' + (kotlinSplitVersion[1].toShort() + 1).toString())
|
||||
//apiVersion = "${kotlinSplitVersion[0]}.${kotlinSplitVersion[1]}"
|
||||
jvmTarget = if (javaVer.toInt() < 9) "1.$javaVer" else javaVer
|
||||
languageVersion = (kotlinSplitVersion[0] + '.' + (kotlinSplitVersion[1].toShort() + 1).toString())
|
||||
apiVersion = "${kotlinSplitVersion[0]}.${kotlinSplitVersion[1]}"
|
||||
}
|
||||
}
|
||||
withType(JavaCompile::class) {
|
||||
|
@ -218,7 +216,7 @@ allprojects {
|
|||
encoding = "UTF-8"
|
||||
isFork = true
|
||||
release.set(javaVer.toInt())
|
||||
sourceCompatibility = sourceJavaVer
|
||||
sourceCompatibility = "11"
|
||||
targetCompatibility = javaVer
|
||||
}
|
||||
}
|
||||
|
@ -230,14 +228,12 @@ allprojects {
|
|||
}
|
||||
val modProperties = mapOf(
|
||||
"mod_version" to (rootProject.version as String),
|
||||
"minecraft_version" to minecraftVersion,
|
||||
"minecraft_version" to mcBase,
|
||||
"java_version" to javaVer,
|
||||
"mod_group" to this@allprojects.group,
|
||||
"fabric_kotlin" to rootProject.property("fabric_language_kotlin"),
|
||||
"kotlinforforge" to rootProject.property("kotlinforforge"),
|
||||
"clothconfig" to rootProject.property("clothconfig_version"),
|
||||
"fabric_loader" to rootProject.property("fabric_loader_version"),
|
||||
"forge_version" to rootProject.property("forge_version")
|
||||
"clothconfig" to rootProject.property("clothconfig_version")
|
||||
)
|
||||
inputs.properties(modProperties)
|
||||
filesNotMatching(listOf("*.png")) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
architectury { common("fabric", "neoforge"); injectInjectables = false }
|
||||
architectury { common(); injectInjectables = false }
|
||||
dependencies {
|
||||
modImplementation("net.fabricmc:fabric-loader:${rootProject.property("fabric_loader_version")}")
|
||||
modImplementation("me.shedaniel.cloth:cloth-config:${rootProject.property("clothconfig_version")}") {
|
||||
|
@ -6,8 +6,4 @@ dependencies {
|
|||
}
|
||||
}
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/${rootProject.name.lowercase()}.accessWidener")
|
||||
}
|
||||
|
||||
tasks.getByName("shrinkJar").enabled = false
|
||||
|
|
|
@ -14,29 +14,17 @@ object ClickGui: SnowyScreen() {
|
|||
private inline fun buttonsContext(args: ColoredElement.() -> Unit) = boxContext { buttons.forEach {
|
||||
if (it.y > y + height) it.args()
|
||||
} }
|
||||
|
||||
private var draggingBox: String? = null
|
||||
private inline fun currentBoxContext(args: ClickBox.() -> Unit): Unit? = draggingBox?.run { boxContext { if (name.string == draggingBox) args() } }
|
||||
private var offsetX: Double = 0.0;
|
||||
private var offsetY: Double = 0.0;
|
||||
override fun mouseClicked(d: Double, e: Double, i: Int): Boolean {
|
||||
if (i == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
|
||||
clickBoxes.find { it.isWithinBounds(d, e) }?.let { draggingBox = it.name.string }
|
||||
currentBoxContext {
|
||||
offsetX = d - (x + width)
|
||||
offsetY = e - (y + height)
|
||||
}
|
||||
}
|
||||
buttonsContext { this.mouseClicked(d, e, i) }; return super.mouseClicked(d, e, i);
|
||||
}
|
||||
override fun mouseReleased(d: Double, e: Double, i: Int): Boolean { draggingBox = null; buttonsContext { this.mouseReleased(d, e, i) }; return false }
|
||||
override fun mouseScrolled(d: Double, e: Double, f: Double, scrollY: Double): Boolean { boxContext { scroll(d, e, scrollY) }; return false }
|
||||
|
||||
override fun mouseClicked(d: Double, e: Double, i: Int): Boolean { buttonsContext { this.mouseClicked(d, e, i) }; return false }
|
||||
override fun mouseReleased(d: Double, e: Double, i: Int): Boolean { buttonsContext { this.mouseReleased(d, e, i) }; return false }
|
||||
override fun mouseScrolled(d: Double, e: Double, f: Double): Boolean { boxContext { scroll(d, e, f) }; return false }
|
||||
override fun mouseDragged(d: Double, e: Double, i: Int, f: Double, g: Double): Boolean {
|
||||
if (i == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
|
||||
currentBoxContext {
|
||||
x = (d + offsetX).coerceIn(0.0..this@ClickGui.width - width.toDouble())
|
||||
y = (e + offsetY).coerceIn(0.0..this@ClickGui.height - height.toDouble())
|
||||
components.forEach {
|
||||
if (it.isWithinBounds(d.minus(f), e.minus(g)) && !isDragging) {
|
||||
isDragging = true
|
||||
it.x = d.minus(f) + (d - (it.x + it.width))
|
||||
it.y = e.minus(g) + (e - (it.y + it.height))
|
||||
} else isDragging = false
|
||||
}
|
||||
}
|
||||
return super.mouseDragged(d, e, i, f, g)
|
||||
|
|
|
@ -4,8 +4,7 @@ import fr.username404.snowygui.config.Configuration
|
|||
import fr.username404.snowygui.gui.feature.ButtonImpl
|
||||
import fr.username404.snowygui.gui.feature.ButtonInfo
|
||||
import fr.username404.snowygui.misc.AddKeyMaps
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.Component.translatable
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import java.lang.reflect.Modifier
|
||||
|
@ -16,7 +15,8 @@ abstract class Snowy {
|
|||
private val displayInitMessage: Boolean by Configuration
|
||||
abstract val annotatedButtons: Set<Class<out ButtonImpl>>
|
||||
companion object {
|
||||
val MissingComponent: Component = translatable("MISSING_COMPONENT")
|
||||
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
|
||||
object MissingComponent: TranslatableComponent(null) { override fun getString(): String = "MISSING_COMPONENT" }
|
||||
@Suppress("JVM_STATIC_ON_CONST_OR_JVM_FIELD") // See KT-39868
|
||||
@JvmStatic
|
||||
protected const val FeaturePackage: String = "fr.username404.snowygui.gui.feature"
|
||||
|
|
|
@ -1,31 +1,35 @@
|
|||
package fr.username404.snowygui.config
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import fr.username404.snowygui.ClickGui
|
||||
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
|
||||
import fr.username404.snowygui.gui.feature.*
|
||||
import fr.username404.snowygui.utils.FontUtil
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import fr.username404.snowygui.gui.feature.Category
|
||||
import fr.username404.snowygui.gui.feature.Colors
|
||||
import fr.username404.snowygui.gui.feature.Macro
|
||||
import fr.username404.snowygui.gui.feature.Keystrokes
|
||||
import fr.username404.snowygui.gui.feature.Zoom
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.Component.translatable
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import java.util.Optional
|
||||
|
||||
private const val confPrefix: String = "screen.snowy.config"
|
||||
private val translationComponent = translatable(confPrefix)
|
||||
private val translationComponent = TranslatableComponent(confPrefix)
|
||||
|
||||
var configScreenParent: Screen? = null
|
||||
|
||||
private fun supplyComponent(string: String?): Optional<Component> = string?.run {
|
||||
Optional.of(translatable(string))
|
||||
Optional.of(TranslatableComponent(string))
|
||||
} ?: Optional.empty()
|
||||
|
||||
val SnowyConfigScreen: Screen = object: Screen(translationComponent) {
|
||||
override fun isPauseScreen(): Boolean = false
|
||||
override fun render(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int, pTick: Float) {
|
||||
super.renderBackground(guiGraphics, mouseX, mouseY, pTick)
|
||||
FontUtil.drawScaled(guiGraphics,
|
||||
override fun render(poseStack: PoseStack, i: Int, j: Int, f: Float) {
|
||||
super.renderBackground(poseStack)
|
||||
FontUtil.drawScaled(poseStack,
|
||||
text = "An appropriate version of the Cloth Config mod is required for the configuration of snowygui.", 16.0, 16.0,
|
||||
color = Colors.WHITE, scaleFactor = 0.85F
|
||||
)
|
||||
|
@ -43,20 +47,20 @@ val SnowyConfigScreen: Screen = object: Screen(translationComponent) {
|
|||
.setShouldListSmoothScroll(true)
|
||||
.setTitle(translationComponent).apply {
|
||||
with(entryBuilder()) {
|
||||
getOrCreateCategory(translatable("$confPrefix.general")).addEntry(startSubCategory(translatable("$confPrefix.behavior")).apply {
|
||||
getOrCreateCategory(TranslatableComponent("$confPrefix.general")).addEntry(startSubCategory(TranslatableComponent("$confPrefix.behavior")).apply {
|
||||
addAll(
|
||||
setOf(
|
||||
startBooleanToggle(translatable("$confPrefix.behavior.sortalphabetically"), sortAlphabetically)
|
||||
startBooleanToggle(TranslatableComponent("$confPrefix.behavior.sortalphabetically"), sortAlphabetically)
|
||||
.setDefaultValue(true).requireRestart()
|
||||
.setSaveConsumer { sortAlphabetically = it }.build(),
|
||||
startDoubleField(translatable("$confPrefix.behavior.zoom.factor"), Zoom.zoomFactor).setSaveConsumer {
|
||||
startDoubleField(TranslatableComponent("$confPrefix.behavior.zoom.factor"), Zoom.zoomFactor).setSaveConsumer {
|
||||
Zoom.zoomFactor = it
|
||||
}.setMin(1.1).build(),
|
||||
startBooleanToggle(translatable("$confPrefix.behavior.zoom.smoothcamera"), Zoom.smoothCameraOnZoom).setSaveConsumer {
|
||||
startBooleanToggle(TranslatableComponent("$confPrefix.behavior.zoom.smoothcamera"), Zoom.smoothCameraOnZoom).setSaveConsumer {
|
||||
Zoom.smoothCameraOnZoom = it
|
||||
Zoom.execAction()
|
||||
}.build(),
|
||||
startEnumSelector(translatable("$confPrefix.behavior.keystrokes.position"), Keystrokes.Position::class.java, Keystrokes.Position.values().find {
|
||||
startEnumSelector(TranslatableComponent("$confPrefix.behavior.keystrokes.position"), Keystrokes.Position::class.java, Keystrokes.Position.values().find {
|
||||
it.value == Keystrokes.currentPosition
|
||||
}).setSaveConsumer {
|
||||
Keystrokes.currentPosition = it.value
|
||||
|
@ -64,7 +68,7 @@ val SnowyConfigScreen: Screen = object: Screen(translationComponent) {
|
|||
)
|
||||
)
|
||||
}.build())
|
||||
.addEntry(startSubCategory(translatable("$confPrefix.colors")).also { builder ->
|
||||
.addEntry(startSubCategory(TranslatableComponent("$confPrefix.colors")).also { builder ->
|
||||
builder.addAll(
|
||||
ClickGui.clickBoxes.map { box ->
|
||||
startColorField(box.name, box.color).setSaveConsumer {
|
||||
|
@ -73,7 +77,7 @@ val SnowyConfigScreen: Screen = object: Screen(translationComponent) {
|
|||
}
|
||||
)
|
||||
}.build()).addEntry(startStrList(
|
||||
Category.MACROS.box.name,
|
||||
TranslatableComponent(Category.MACROS.translationKey),
|
||||
macrosButtons.getTitleCommand()
|
||||
).setInsertInFront(false).setDefaultValue(Configuration.foundMacros.getTitleCommand()).setErrorSupplier { list ->
|
||||
supplyComponent(if (list.size > buttonsMax) "$confPrefix.general.macros.toomuchbuttons" else null)
|
||||
|
@ -89,7 +93,7 @@ val SnowyConfigScreen: Screen = object: Screen(translationComponent) {
|
|||
}
|
||||
)
|
||||
}
|
||||
}.setTooltip(translatable("$confPrefix.general.macros.tooltip")).setSaveConsumer { it.forEach { string ->
|
||||
}.setTooltip(TranslatableComponent("$confPrefix.general.macros.tooltip")).setSaveConsumer { it.forEach { string ->
|
||||
with(string.split(":")) {
|
||||
if (size == 2) Macro(title = component1().trimStart(), command = component2().trim()).let { newMacro ->
|
||||
macrosButtons.removeIf { existingMacro ->
|
||||
|
|
|
@ -29,8 +29,6 @@ import kotlinx.serialization.ExperimentalSerializationApi
|
|||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.network.chat.contents.TranslatableContents
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.isSuperclassOf
|
||||
|
@ -48,9 +46,9 @@ object Configuration {
|
|||
}
|
||||
},
|
||||
"box_colors" to mapOf<String, Int>(*ClickGui.clickBoxes.filter { box ->
|
||||
((box.name.contents as TranslatableContents).key != (MissingComponent.contents as TranslatableContents).key) && Category.fromBox(box)?.categoryColor != box.color
|
||||
(box.name.key != MissingComponent.key) && Category.fromBox(box)?.categoryColor != box.color
|
||||
}.map {
|
||||
(it.name as TranslatableContents).key to it.color
|
||||
it.name.key to it.color
|
||||
}.toTypedArray()),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ import com.mojang.blaze3d.vertex.*
|
|||
import fr.username404.snowygui.Snowy
|
||||
import fr.username404.snowygui.gui.feature.Colors
|
||||
import fr.username404.snowygui.utils.RenderingUtil
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import fr.username404.snowygui.utils.RenderingUtil.colorEnd
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener
|
||||
|
||||
fun interface Renderable {
|
||||
fun render(guiGraphics: GuiGraphics?)
|
||||
fun render(poseStack: PoseStack?)
|
||||
}
|
||||
|
||||
abstract class Element(
|
||||
|
@ -19,22 +19,17 @@ abstract class Element(
|
|||
open var x = xOrigin; open var y = yOrigin
|
||||
fun isWithinBounds(coordinateX: Double, coordinateY: Double, offsetWidth: Double = 0.0, offsetHeight: Double = 0.0): Boolean =
|
||||
(coordinateX in x..(x + width + offsetWidth)) && (coordinateY in y..(y + height + offsetHeight))
|
||||
|
||||
@JvmField
|
||||
protected var focused = false
|
||||
override fun isFocused() = focused
|
||||
override fun setFocused(boolean: Boolean) { focused = boolean }
|
||||
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(guiGraphics: GuiGraphics?) = r.render(guiGraphics)
|
||||
override fun render(poseStack: PoseStack?) = r.render(poseStack)
|
||||
}
|
||||
}
|
||||
}
|
||||
open fun display(guiGraphics: GuiGraphics? = null) {
|
||||
open fun display(stack: PoseStack? = null) {
|
||||
if (!hidden && !caughtError) try {
|
||||
render(guiGraphics)
|
||||
render(stack)
|
||||
} catch (t: Throwable) {
|
||||
with(Snowy.logs) {
|
||||
error("An element from snowy threw an error: \n\t$t")
|
||||
|
@ -54,11 +49,11 @@ abstract class ColoredElement(
|
|||
companion object {
|
||||
@JvmStatic protected fun VertexConsumer.colorIt(color: Int, opacity: Float = 1F): VertexConsumer {
|
||||
with(hextoRGB(color)) {
|
||||
return this@colorIt.setColor(get(0), get(1), get(2), opacity)
|
||||
return this@colorIt.color(get(0), get(1), get(2), opacity)
|
||||
}
|
||||
}
|
||||
}
|
||||
internal fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorIt(color, opacity)
|
||||
internal fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorEnd(color, opacity)
|
||||
protected fun defaultRectFunc() = RenderingUtil.drawRectangle(x, y, height, width, color, opacity)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package fr.username404.snowygui.gui
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.network.chat.Component.translatable
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
|
||||
abstract class SnowyScreen(translatableString: String = "screen.snowy.gui", private val willPauseScreen: Boolean = false): Screen(translatable(translatableString)) {
|
||||
abstract class SnowyScreen(translatableString: String = "screen.snowy.gui", private val willPauseScreen: Boolean = false): Screen(TranslatableComponent(translatableString)) {
|
||||
abstract val components: MutableCollection<Element>
|
||||
override fun render(guiGraphics: GuiGraphics, i: Int, j: Int, f: Float) {
|
||||
components.forEach {
|
||||
it.display(guiGraphics)
|
||||
override fun render(poseStack: PoseStack?, i: Int, j: Int, f: Float) {
|
||||
if (poseStack != null) {
|
||||
components.forEach {
|
||||
it.display(poseStack)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun isPauseScreen(): Boolean = willPauseScreen
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
package fr.username404.snowygui.gui.elements
|
||||
|
||||
import com.mojang.blaze3d.vertex.BufferUploader
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
||||
import com.mojang.blaze3d.vertex.VertexFormat
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import fr.username404.snowygui.Snowy.Companion.MissingComponent
|
||||
import fr.username404.snowygui.config.Configuration
|
||||
import com.mojang.blaze3d.vertex.VertexFormat
|
||||
import fr.username404.snowygui.gui.ColoredElement
|
||||
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.colorShader
|
||||
import fr.username404.snowygui.utils.RenderingUtil.endDraw
|
||||
import fr.username404.snowygui.utils.RenderingUtil.prepareDraw
|
||||
import fr.username404.snowygui.utils.RenderingUtil.tessellator
|
||||
import io.github.config4k.extract
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.Font
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.util.TreeSet
|
||||
import kotlin.collections.LinkedHashSet
|
||||
|
@ -25,17 +27,17 @@ import kotlin.collections.LinkedHashSet
|
|||
@ApiStatus.Internal
|
||||
class ClickBox(
|
||||
x: Double, y: Double,
|
||||
val name: Component = MissingComponent,
|
||||
override var color: Int = savedColors?.get(name.string) ?: Colors.BLUE.hexValue,
|
||||
override var color: Int = Colors.BLUE.hexValue,
|
||||
val name: TranslatableComponent = MissingComponent
|
||||
): ColoredElement(x, y, 80, 10, color, 0.5F) {
|
||||
fun isCategory(c: Category): Boolean = (name.string == c.box.name.string)
|
||||
fun isCategory(c: Category): Boolean = (name.key == c.translationKey)
|
||||
val buttons: MutableSet<ButtonImpl> =
|
||||
if (sortAlphabetically)
|
||||
TreeSet(compareBy(String.CASE_INSENSITIVE_ORDER) { it.title })
|
||||
else LinkedHashSet()
|
||||
override fun display(guiGraphics: GuiGraphics?) {
|
||||
override fun display(stack: PoseStack?) {
|
||||
hidden = buttons.isEmpty() || hidden
|
||||
super.display(guiGraphics)
|
||||
super.display(stack)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
|
@ -45,7 +47,7 @@ class ClickBox(
|
|||
opacity = 0.75F
|
||||
) {
|
||||
override val color: Int get() = this@ClickBox.color
|
||||
override fun render(guiGraphics: GuiGraphics?) {
|
||||
override fun render(poseStack: PoseStack?) {
|
||||
prepareDraw()
|
||||
colorShader(); defaultRectFunc()
|
||||
endDraw()
|
||||
|
@ -75,56 +77,57 @@ class ClickBox(
|
|||
var sortAlphabetically: Boolean by Configuration
|
||||
const val buttonsMax: Short = 16 // TODO Remove the buttons limit
|
||||
const val clickboxHeightOffset: Int = 80
|
||||
private const val inclination: Float = 2.5F
|
||||
private const val inclination: Double = 2.5
|
||||
}
|
||||
override fun render(guiGraphics: GuiGraphics?) {
|
||||
val x = x.toFloat()
|
||||
val y = y.toFloat()
|
||||
val currentHeight = y + (height + clickboxHeightOffset)
|
||||
prepareDraw()
|
||||
with(tessellator.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR)) {
|
||||
// Render the header:
|
||||
addVertex(x, y + height, 0.0F).colorEnd()
|
||||
addVertex(x + width + inclination, y + height, 0.0F).colorEnd()
|
||||
addVertex(x + width, y, 0.0F).colorEnd()
|
||||
addVertex(x + inclination, y, 0.0F).colorEnd()
|
||||
override fun render(poseStack: PoseStack?) {
|
||||
runBlocking {
|
||||
prepareDraw()
|
||||
with(buffer) {
|
||||
begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR)
|
||||
// Render the header:
|
||||
vertex(x, y + height, 0.0).colorEnd()
|
||||
vertex(x + width + inclination, y + height, 0.0).colorEnd()
|
||||
vertex(x + width, y, 0.0).colorEnd()
|
||||
vertex(x + inclination, y, 0.0).colorEnd()
|
||||
|
||||
// Render the box:
|
||||
addVertex(x, currentHeight, 0.0F).colorEnd()
|
||||
addVertex(x + width + inclination, currentHeight, 0.0F).colorEnd()
|
||||
addVertex(x + width + inclination, y + height, 0.0F).colorEnd()
|
||||
BufferUploader.drawWithShader(buildOrThrow())
|
||||
// Render the box:
|
||||
val currentHeight = y + (height + clickboxHeightOffset)
|
||||
vertex(x, currentHeight, 0.0).colorEnd()
|
||||
vertex(x + width + inclination, currentHeight, 0.0).colorEnd()
|
||||
vertex(x + width + inclination, y + height, 0.0).colorEnd()
|
||||
tessellator.end()
|
||||
|
||||
colorShader()
|
||||
with(tessellator.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR)) {
|
||||
addVertex(x + inclination, y + height, 0.0F).colorEnd(Colors.WHITE_LINES.hexValue)
|
||||
addVertex(x + width, y + height, 0.0F).colorEnd(Colors.WHITE_LINES.hexValue)
|
||||
BufferUploader.drawWithShader(buildOrThrow())
|
||||
colorShader()
|
||||
begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR)
|
||||
vertex(x + inclination, y + height, 0.0).colorEnd(Colors.WHITE_LINES.hexValue)
|
||||
vertex(x + width, y + height, 0.0).colorEnd(Colors.WHITE_LINES.hexValue)
|
||||
tessellator.end()
|
||||
}
|
||||
endDraw()
|
||||
|
||||
val renderButtons = if (buttons.isNotEmpty()) launch(start = CoroutineStart.UNDISPATCHED) {
|
||||
buttonsProgressBar.apply {
|
||||
x = this@ClickBox.x + this@ClickBox.width - 3
|
||||
y = this@ClickBox.y + this@ClickBox.height + 3
|
||||
}.display(poseStack)
|
||||
buttons.forEachIndexed { num, button ->
|
||||
val fullHeight = (y + height.toDouble())..(y + height + clickboxHeightOffset)
|
||||
button.also {
|
||||
it.x = x + 3
|
||||
it.y = y + 3 + height + (((num + 1) - barStage) * 9)
|
||||
it.hidden = if ((num + 1) <= 8) ((it.y) !in fullHeight) else ((it.y + it.height) !in fullHeight)
|
||||
}.display(poseStack)
|
||||
}
|
||||
} else null
|
||||
if (poseStack != null) {
|
||||
Minecraft.getInstance().font.draw(poseStack, name.string, x.toFloat() + 5, y.toFloat() + 1.5F, Colors.TRANSPARENT.hexValue)
|
||||
renderButtons?.join()
|
||||
}
|
||||
}
|
||||
endDraw()
|
||||
|
||||
if (buttons.isNotEmpty()) {
|
||||
buttonsProgressBar.apply {
|
||||
this.x = this@ClickBox.x + this@ClickBox.width - 3
|
||||
this.y = this@ClickBox.y + this@ClickBox.height + 3
|
||||
}.display(guiGraphics)
|
||||
buttons.forEachIndexed { num, button ->
|
||||
val fullHeight = (y + height.toDouble())..(this.y + height + clickboxHeightOffset)
|
||||
button.also {
|
||||
it.x = this.x + 3
|
||||
it.y = this.y + 3 + height + (((num + 1) - barStage) * 9)
|
||||
it.hidden = if ((num + 1) <= 8) ((it.y) !in fullHeight) else ((it.y + it.height) !in fullHeight)
|
||||
}.display(guiGraphics)
|
||||
}
|
||||
}
|
||||
guiGraphics?.run {
|
||||
with(Minecraft.getInstance().font) {
|
||||
drawInBatch(name.string,
|
||||
(x + 5), (y + 2), Colors.TRANSPARENT.hexValue, false,
|
||||
pose().last().pose(), bufferSource(), Font.DisplayMode.NORMAL, 0, 15728880, isBidirectional
|
||||
)
|
||||
}
|
||||
}
|
||||
init {
|
||||
savedColors?.get(name.key)?.let {
|
||||
this.color = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package fr.username404.snowygui.gui.feature
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
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.feature.ButtonInfo.Companion.Type
|
||||
import fr.username404.snowygui.utils.FontUtil
|
||||
import fr.username404.snowygui.utils.RenderingUtil.colorShader
|
||||
import fr.username404.snowygui.gui.feature.ButtonInfo.Companion.Type
|
||||
import fr.username404.snowygui.utils.RenderingUtil.endDraw
|
||||
import fr.username404.snowygui.utils.RenderingUtil.prepareDraw
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import fr.username404.snowygui.utils.RenderingUtil.colorShader
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
|
||||
sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) {
|
||||
companion object {
|
||||
internal companion object {
|
||||
private fun addButtons(vararg buttons: ButtonImpl) {
|
||||
buttons.groupBy { impl ->
|
||||
ClickGui.clickBoxes.find { box ->
|
||||
|
@ -90,12 +90,12 @@ sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) {
|
|||
lightDown()
|
||||
}; return false
|
||||
}
|
||||
final override fun render(guiGraphics: GuiGraphics?) {
|
||||
final override fun render(poseStack: PoseStack?) {
|
||||
prepareDraw()
|
||||
colorShader(); defaultRectFunc()
|
||||
endDraw()
|
||||
if (guiGraphics != null) {
|
||||
FontUtil.drawScaled(guiGraphics, title, x + 1, y + 1, 0.75F)
|
||||
if (poseStack != null) {
|
||||
FontUtil.drawScaled(poseStack, title, x + 1, y + 1, 0.75F)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package fr.username404.snowygui.gui.feature
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import fr.username404.snowygui.EventSnowy
|
||||
import fr.username404.snowygui.argsLambda
|
||||
import fr.username404.snowygui.gui.Renderable
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
|
||||
sealed class ButtonImplWithHud: ButtonImpl() {
|
||||
protected abstract val hudRenderLambda: Renderable
|
||||
private val generatedLambda: argsLambda = { hudRenderLambda.render(it.first() as GuiGraphics?) }
|
||||
private val generatedLambda: argsLambda = { hudRenderLambda.render(it.first() as PoseStack?) }
|
||||
final override fun execAction() {
|
||||
EventSnowy["HudRender"].run {
|
||||
if (toggled) add(generatedLambda)
|
||||
|
|
|
@ -2,8 +2,7 @@ package fr.username404.snowygui.gui.feature
|
|||
|
||||
import fr.username404.snowygui.ClickGui
|
||||
import fr.username404.snowygui.gui.elements.ClickBox
|
||||
import net.minecraft.network.chat.Component.translatable
|
||||
import net.minecraft.network.chat.contents.TranslatableContents
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
|
||||
/**
|
||||
* Should be used on classes/objects extending [ButtonImpl]
|
||||
|
@ -23,7 +22,7 @@ annotation class ButtonInfo(
|
|||
TOGGLE,
|
||||
CLICK
|
||||
}
|
||||
enum class Category(translationKey: String, val categoryColor: Int, val shouldHide: Boolean = false) {
|
||||
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),
|
||||
MACROS("snowy.clickbox.macros", Colors.GREEN);
|
||||
|
@ -36,14 +35,14 @@ annotation class ButtonInfo(
|
|||
x = 4.0 + (ordinal - ClickGui.clickBoxes.count { category ->
|
||||
category.hidden
|
||||
}) * 86, y = 4.0,
|
||||
name = translatable(translationKey),
|
||||
name = TranslatableComponent(translationKey),
|
||||
color = categoryColor
|
||||
); private set
|
||||
private fun addBox() = ClickGui.components.add(box.apply { if (shouldHide) hidden = true })
|
||||
constructor(
|
||||
translationKey: String, categoryColor: Colors, condition: Boolean = false
|
||||
): this(translationKey, categoryColor.hexValue, condition)
|
||||
constructor(categoryBox: ClickBox): this(translationKey = (categoryBox.name.contents as TranslatableContents).key, categoryColor = categoryBox.color) {
|
||||
constructor(categoryBox: ClickBox): this(translationKey = categoryBox.name.key, categoryColor = categoryBox.color) {
|
||||
with(ClickGui.components) {
|
||||
remove(this@Category.box)
|
||||
this@Category.box = categoryBox
|
||||
|
|
|
@ -10,8 +10,8 @@ import net.arikia.dev.drpc.DiscordRPC as discord_rpc
|
|||
object DiscordRPC: ButtonImpl() {
|
||||
private val RPCHandlers: DiscordEventHandlers = DiscordEventHandlers.Builder().build()
|
||||
private val RichPresence: DiscordRichPresence.Builder = DiscordRichPresence
|
||||
.Builder("Playing Minecraft ${Minecraft.getInstance().launchedVersion}")
|
||||
.setDetails("Launched with ${Minecraft.getInstance().versionType}")
|
||||
.Builder("Playing Minecraft ${Minecraft.getInstance().game.version.name}")
|
||||
.setDetails("Launched with ${Minecraft.getInstance().launchedVersion}")
|
||||
.setBigImage("icon", "SnowyGUI")
|
||||
override fun execAction() {
|
||||
if (toggled) discord_rpc.discordUpdatePresence(RichPresence.build())
|
||||
|
|
|
@ -8,12 +8,10 @@ object GammaBoost: ButtonImpl() {
|
|||
private var oldGamma = 0.0
|
||||
override fun execAction() {
|
||||
with(Minecraft.getInstance().options) {
|
||||
val gamma = gamma().get()
|
||||
gamma().value =
|
||||
if (toggled) {
|
||||
if (gamma < boost) oldGamma = gamma
|
||||
boost
|
||||
} else oldGamma
|
||||
gamma = if (toggled) {
|
||||
if (gamma < boost) oldGamma = gamma
|
||||
boost
|
||||
} else oldGamma
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package fr.username404.snowygui.gui.feature
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import fr.username404.snowygui.config.Configuration
|
||||
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
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
|
||||
@ButtonInfo(Category.HUD)
|
||||
object Keystrokes: ButtonImplWithHud() {
|
||||
|
@ -41,14 +41,14 @@ object Keystrokes: ButtonImplWithHud() {
|
|||
return dynamicOpacity[i]
|
||||
}
|
||||
|
||||
private fun drawKey(x: Double, y: Double, key: Int, guiGraphics: GuiGraphics?) {
|
||||
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()
|
||||
guiGraphics?.let {
|
||||
poseStack?.let {
|
||||
FontUtil.drawScaled(
|
||||
it, keysArray.first[key].translatedKeyMessage.string.uppercase(),
|
||||
x + height.toDouble() / 5.5, y + height.toDouble() / 6.5,
|
||||
|
@ -57,11 +57,11 @@ object Keystrokes: ButtonImplWithHud() {
|
|||
}
|
||||
}
|
||||
private fun getNewPos(i: Int) = x + (i * (2 + (height / 2)))
|
||||
override fun render(guiGraphics: GuiGraphics?) = with(RenderingUtil) {
|
||||
override fun render(poseStack: PoseStack?) = with(RenderingUtil) {
|
||||
for (i in 0 until 3) {
|
||||
drawKey(getNewPos(i), y, i, guiGraphics)
|
||||
drawKey(getNewPos(i), y, i, poseStack)
|
||||
}
|
||||
drawKey(getNewPos(1), y - (height / 2) - 2, 3, guiGraphics)
|
||||
drawKey(getNewPos(1), y - (height / 2) - 2, 3, poseStack)
|
||||
}
|
||||
}
|
||||
override val hudRenderLambda = Renderable {
|
||||
|
|
|
@ -15,12 +15,12 @@ data class Macro(
|
|||
override var title: String = command
|
||||
): ButtonImpl() {
|
||||
override fun execAction(): Unit = with(Minecraft.getInstance().player!!) {
|
||||
connection.run {
|
||||
command.let {
|
||||
if (it.startsWith("say") && !hasPermissions(2)) {
|
||||
sendChat(it.drop(4))
|
||||
} else sendCommand(it)
|
||||
chat(
|
||||
"/$command".let {
|
||||
if (it.startsWith("/say") && !hasPermissions(2)) {
|
||||
it.drop(5)
|
||||
} else it
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,14 +1,13 @@
|
|||
package fr.username404.snowygui.utils
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.Minecraft
|
||||
import fr.username404.snowygui.gui.feature.Colors
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
|
||||
object FontUtil {
|
||||
fun drawScaled(guiGraphics: GuiGraphics, text: String, x: Double, y: Double, scaleFactor: Float, color: Colors = Colors.BLACK) {
|
||||
val stack = guiGraphics.pose()
|
||||
fun drawScaled(stack: PoseStack, text: String, x: Double, y: Double, scaleFactor: Float, color: Colors = Colors.BLACK) {
|
||||
stack.scale(scaleFactor, scaleFactor, scaleFactor)
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, text, (x / scaleFactor).toInt(), (y / scaleFactor).toInt(), color.hexValue, false)
|
||||
Minecraft.getInstance().font.draw(stack, text, (x / scaleFactor).toFloat(), (y / scaleFactor).toFloat(), color.hexValue)
|
||||
val factorToOriginal = 1F / scaleFactor
|
||||
stack.scale(factorToOriginal, factorToOriginal, factorToOriginal)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package fr.username404.snowygui.utils
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.BufferUploader
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
||||
import com.mojang.blaze3d.vertex.Tesselator
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
|
@ -12,32 +12,36 @@ import net.minecraft.client.renderer.GameRenderer
|
|||
|
||||
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 {
|
||||
setColor(get(0), get(1), get(2), opacity)
|
||||
color(get(0), get(1), get(2), opacity)
|
||||
}
|
||||
fun VertexConsumer.colorEnd(color: Int, opacity: Float = 1F) = colorIt(color, opacity).endVertex()
|
||||
fun colorShader() {
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
|
||||
}
|
||||
fun prepareDraw() {
|
||||
colorShader()
|
||||
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 = tessellator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR).run {
|
||||
fun VertexConsumer.colorIt() = colorIt(color, opacity)
|
||||
val x = x.toFloat() ; val y = y.toFloat()
|
||||
addVertex(x, y + height, 0.0F).colorIt()
|
||||
addVertex(x + width, y + height, 0.0F).colorIt()
|
||||
addVertex(x + width, y, 0.0F).colorIt()
|
||||
addVertex(x, y, 0.0F).colorIt()
|
||||
BufferUploader.drawWithShader(buildOrThrow())
|
||||
): Unit = buffer.run {
|
||||
fun VertexConsumer.colorEnd() = colorEnd(color, opacity)
|
||||
begin(VertexFormat.Mode.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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "fr.username404.snowygui.mixins",
|
||||
"compatibilityLevel": "JAVA_18",
|
||||
"client": [],
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"client": [
|
||||
"KeysAccessor",
|
||||
"KeyMappings",
|
||||
"EndTickMixin",
|
||||
"TitleScreenMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
accessWidener v2 named
|
||||
accessible field net/minecraft/client/OptionInstance value Ljava/lang/Object;
|
||||
mutable field net/minecraft/client/OptionInstance value Ljava/lang/Object;
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"accessWidener": "snowygui.accessWidener"
|
||||
}
|
|
@ -23,7 +23,7 @@ dependencies {
|
|||
exclude(group = Groups.FabricApi, module = "fabric-api-base")
|
||||
exclude(group = Groups.FabricApi, module = "fabric-resource-loader-v0")
|
||||
}
|
||||
implementation(project(path = ":common", configuration = "namedElements")) { isTransitive = false }
|
||||
implementation(project(path = ":common")) { isTransitive = false }
|
||||
add("developmentFabric", project(path = ":common")) { isTransitive = false }
|
||||
shadowC(project(path = ":common", configuration = "transformProductionFabric")) { isTransitive = false }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package fr.username404.snowygui.fabric
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import fr.username404.snowygui.EventSnowy
|
||||
import fr.username404.snowygui.Snowy
|
||||
import fr.username404.snowygui.gui.feature.ButtonImpl
|
||||
|
@ -7,13 +8,10 @@ import net.fabricmc.api.ClientModInitializer
|
|||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback.EVENT
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import net.minecraft.client.DeltaTracker
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.listDirectoryEntries
|
||||
import kotlin.io.path.pathString
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
class FabricInit: Snowy(), ClientModInitializer {
|
||||
override fun onInitializeClient() {
|
||||
|
@ -21,12 +19,12 @@ class FabricInit: Snowy(), ClientModInitializer {
|
|||
EVENT.register(
|
||||
object: HudRenderCallback, EventSnowy {
|
||||
override val type: String = "HudRender"
|
||||
override fun onHudRender(guiGraphics: GuiGraphics?, tickCounter: DeltaTracker?) = fire(guiGraphics)
|
||||
override fun onHudRender(matrixStack: PoseStack?, tickDelta: Float) = fire(matrixStack)
|
||||
}
|
||||
)
|
||||
}
|
||||
override val annotatedButtons = FabricLoader.getInstance().allMods.mapNotNull {
|
||||
it.findPath(FeaturePackage.replace('.', '/')).getOrNull()
|
||||
override val annotatedButtons = FabricLoader.getInstance().allMods.map {
|
||||
it.getPath(FeaturePackage.replace('.', '/'))
|
||||
}.filter { it.exists() && it.isDirectory() }.flatMap { buttonsDirectory ->
|
||||
mutableSetOf<Class<out ButtonImpl>>().apply {
|
||||
buttonsDirectory.listDirectoryEntries("*.class").forEach { file ->
|
||||
|
|
|
@ -6,9 +6,15 @@ import net.fabricmc.loader.api.FabricLoader
|
|||
@JvmField
|
||||
var isOkZoomerPresent: Boolean = FabricLoader.getInstance().isModLoaded("okzoomer")
|
||||
private val okZoomerPairs by lazy {
|
||||
with(Class.forName("io.github.ennuil.okzoomer.utils.ZoomUtils").getDeclaredField("ZOOMER_ZOOM")) {
|
||||
get(null).javaClass.run {
|
||||
(getDeclaredField("zoomDivisor") to this@with.get(null)) to (getDeclaredField("zoom") to this@with.get(null))
|
||||
try {
|
||||
with(Class.forName("io.github.joaoh1.okzoomer.client.utils.ZoomUtils")) {
|
||||
(getField("zoomDivisor") to null) to (getField("zoomState") to null)
|
||||
}
|
||||
} catch (e: ClassNotFoundException) {
|
||||
with(Class.forName("io.github.ennuil.okzoomer.utils.ZoomUtils").getDeclaredField("zoomerZoom")) {
|
||||
get(null).javaClass.run {
|
||||
(getDeclaredField("zoomDivisor") to this@with.get(null)) to (getDeclaredField("zoom") to this@with.get(null))
|
||||
}
|
||||
}
|
||||
}.apply { first.first.isAccessible = true; second.first.isAccessible = true; }
|
||||
}
|
||||
|
@ -16,7 +22,7 @@ private val okZoomerPairs by lazy {
|
|||
fun fabricZoom() {
|
||||
try {
|
||||
with(okZoomerPairs) {
|
||||
first.run { first.setFloat(second, Zoom.zoomFactor.toFloat()) }
|
||||
first.run { first.setDouble(second, Zoom.zoomFactor) }
|
||||
second.run { first.setBoolean(second, Zoom.toggled) }
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
|
|
@ -32,13 +32,12 @@
|
|||
"snowygui-common.mixins.json",
|
||||
"snowygui-fabric.mixins.json"
|
||||
],
|
||||
"accessWidener": "snowygui.accessWidener",
|
||||
"depends": {
|
||||
"fabricloader": ">=${fabric_loader}",
|
||||
"fabricloader": ">=0.11.0",
|
||||
"fabric-language-kotlin": ">=${fabric_kotlin}",
|
||||
"fabric-resource-loader-v0": "*",
|
||||
"fabric-rendering-v1": "*",
|
||||
"minecraft": ">=1.19-alpha.22.16.b"
|
||||
"minecraft": ">=${minecraft_version}"
|
||||
},
|
||||
"recommends": {
|
||||
"cloth-config2": ">=${clothconfig}"
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "fr.username404.snowygui.mixins",
|
||||
"compatibilityLevel": "JAVA_18",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"client": [
|
||||
"EndTickMixin",
|
||||
"TitleScreenMixin",
|
||||
"KeysAccessor",
|
||||
"KeyMappings",
|
||||
"ZoomMixin",
|
||||
"OkZoomerAlternativeMixin"
|
||||
],
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
architectury { platformSetupLoomIde(); forge() }
|
||||
repositories {
|
||||
maven(url = "https://thedarkcolour.github.io/KotlinForForge/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
forge("net.minecraftforge:forge:${rootProject.architectury.minecraft}-${rootProject.property("forge_version")}.+")
|
||||
implementation("thedarkcolour:kotlinforforge:${rootProject.property("kotlinforforge")}")
|
||||
modApi("me.shedaniel.cloth:cloth-config-forge:${rootProject.property("clothconfig_version")}")
|
||||
implementation(project(path = ":common")) { isTransitive = false }
|
||||
add("developmentForge", project(path = ":common")) { isTransitive = false }
|
||||
shadowC(project(path = ":common", configuration = "transformProductionForge")) { isTransitive = false }
|
||||
}; loom {
|
||||
if (JavaVersion.current().isJava9Compatible) {
|
||||
runs {
|
||||
val args: MutableList<String> = mutableListOf("-Dfml.earlyprogresswindow=false")
|
||||
args += if (JavaVersion.current() < JavaVersion.VERSION_17) {
|
||||
listOf("--add-exports java.base/sun.security.util=ALL-UNNAMED", "--add-opens java.base/java.util.jar=ALL-UNNAMED")
|
||||
} else listOf("--illegal-access=permit")
|
||||
this.forEach {
|
||||
it.vmArgs(args)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
loom.platform=forge
|
|
@ -4,19 +4,25 @@ import fr.username404.snowygui.Snowy
|
|||
import fr.username404.snowygui.config.SnowyConfigScreen
|
||||
import fr.username404.snowygui.config.configScreenParent
|
||||
import fr.username404.snowygui.gui.feature.ButtonImpl
|
||||
import net.neoforged.fml.ModContainer
|
||||
import net.neoforged.fml.ModList
|
||||
import net.neoforged.fml.common.Mod
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
|
||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory
|
||||
import net.neoforged.neoforge.common.NeoForge
|
||||
import net.neoforged.neoforgespi.language.ModFileScanData
|
||||
import net.minecraftforge.fml.ModList
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
|
||||
import net.minecraftforge.client.ConfigGuiHandler
|
||||
import net.minecraftforge.forgespi.language.ModFileScanData
|
||||
import org.objectweb.asm.Type
|
||||
import thedarkcolour.kotlinforforge.forge.FORGE_BUS
|
||||
import thedarkcolour.kotlinforforge.forge.LOADING_CONTEXT
|
||||
import thedarkcolour.kotlinforforge.forge.MOD_BUS
|
||||
|
||||
@Mod("snowygui")
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
class ForgeInit(container: ModContainer): Snowy() {
|
||||
class ForgeInit: Snowy() {
|
||||
private fun initSetup(event: FMLClientSetupEvent) = atInit()
|
||||
private fun configSetup(event: FMLClientSetupEvent) {
|
||||
LOADING_CONTEXT.registerExtensionPoint(
|
||||
ConfigGuiHandler.ConfigGuiFactory::class.java
|
||||
) { ConfigGuiHandler.ConfigGuiFactory { _, parent -> configScreenParent = parent; SnowyConfigScreen } }
|
||||
}
|
||||
override val annotatedButtons = ModList.get() // Forge-specific reflection
|
||||
.allScanData
|
||||
.flatMap { obj: ModFileScanData -> obj.classes }
|
||||
|
@ -28,18 +34,13 @@ class ForgeInit(container: ModContainer): Snowy() {
|
|||
.map { Class.forName((it!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(it) as Type).className).asSubclass(ButtonImpl::class.java)}
|
||||
.toSet()
|
||||
init {
|
||||
container.eventBus!!.run {
|
||||
with(MOD_BUS) {
|
||||
addListener(this@ForgeInit::initSetup)
|
||||
register(MiscModBusHandlers)
|
||||
addListener(this@ForgeInit::configSetup)
|
||||
}
|
||||
NeoForge.EVENT_BUS.run {
|
||||
register(EndTickHandler)
|
||||
with(FORGE_BUS) {
|
||||
register(HudHandler)
|
||||
register(ZoomHandler)
|
||||
}
|
||||
container.registerExtensionPoint(
|
||||
IConfigScreenFactory::class.java,
|
||||
IConfigScreenFactory { _, parent -> configScreenParent = parent; SnowyConfigScreen }
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package fr.username404.snowygui.forge
|
||||
|
||||
import fr.username404.snowygui.EventSnowy
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
|
||||
object HudHandler: EventSnowy {
|
||||
override val type: String = "HudRender"
|
||||
@SubscribeEvent
|
||||
fun handleRendering(event: RenderGameOverlayEvent.Post) {
|
||||
if (event.type == RenderGameOverlayEvent.ElementType.ALL) {
|
||||
fire(event.matrixStack)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package fr.username404.snowygui.forge
|
||||
|
||||
import fr.username404.snowygui.gui.feature.Zoom
|
||||
import net.minecraftforge.client.event.EntityViewRenderEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
|
||||
object ZoomHandler {
|
||||
@SubscribeEvent
|
||||
fun onFOVEvent(event: EntityViewRenderEvent.FieldOfView) {
|
||||
if (Zoom.toggled) event.fov = Zoom.getNewZoom(event.fov)
|
||||
}
|
||||
}
|
|
@ -14,16 +14,16 @@ A cross-platform mod offering a useful interface.
|
|||
logoFile = "icon.png"
|
||||
|
||||
[[dependencies.snowygui]]
|
||||
modId = "cloth_config"
|
||||
modId = "cloth-config"
|
||||
mandatory = false
|
||||
versionRange = "[${clothconfig},)"
|
||||
ordering = "BEFORE"
|
||||
side = "CLIENT"
|
||||
|
||||
[[dependencies.snowygui]]
|
||||
modId = "neoforge"
|
||||
modId = "forge"
|
||||
mandatory = true
|
||||
versionRange = "[${forge_version},)"
|
||||
versionRange = "[37,)"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
|
||||
|
@ -32,10 +32,4 @@ modId = "minecraft"
|
|||
mandatory = true
|
||||
versionRange = "[${minecraft_version},)"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
|
||||
[[mixins]]
|
||||
config = "snowygui-common.mixins.json"
|
||||
|
||||
[[mixins]]
|
||||
config = "snowygui-neoforge.mixins.json"
|
||||
side = "BOTH"
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"required": false,
|
||||
"package": "fr.username404.snowygui.mixins",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"client": [],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
|
@ -7,16 +7,16 @@ org.gradle.parallel=true
|
|||
org.gradle.unsafe.configuration-cache=on
|
||||
org.gradle.vfs.watch=true
|
||||
|
||||
minecraft=1.21
|
||||
forge_version=21.0.143
|
||||
kotlinforforge=5.4.0
|
||||
kotlinVer=2.0.0
|
||||
kotlin_coroutines_version=1.7.1
|
||||
serializationVer=1.7.0
|
||||
fabric_loader_version=0.14.20
|
||||
fabric_language_kotlin=1.11.0+kotlin.2.0.0
|
||||
fabric_resource_loader_version=1.1.3+b559734490
|
||||
fabric_rendering_api_version=5.0.3+d132107690
|
||||
fabric_api_base_version=0.4.42+6573ed8c90
|
||||
clothconfig_version=15.0.127
|
||||
modmenu_version=11.0.0
|
||||
minecraft=1.18.1
|
||||
forge_version=39.1
|
||||
kotlinforforge=3.1.0
|
||||
kotlinVer=1.6.0
|
||||
kotlin_coroutines_version=1.5.0
|
||||
serializationVer=1.2.1
|
||||
fabric_loader_version=0.11.7
|
||||
fabric_language_kotlin=1.7.0+kotlin.1.6.0
|
||||
fabric_resource_loader_version=0.4.14+713c266865
|
||||
fabric_rendering_api_version=1.10.6+713c266865
|
||||
fabric_api_base_version=0.3.0+a02b4463d5
|
||||
clothconfig_version=6.2.57
|
||||
modmenu_version=3.0.1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-rc-1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
architectury { platformSetupLoomIde(); neoForge() }
|
||||
repositories {
|
||||
maven(url = "https://maven.neoforged.net/releases/")
|
||||
maven(url = "https://thedarkcolour.github.io/KotlinForForge/")
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
neoForge("net.neoforged:neoforge:${rootProject.property("forge_version").toString().let {
|
||||
return@let if (it.length > 4) it else "$it.+"
|
||||
}}")
|
||||
implementation("thedarkcolour:kotlinforforge:${rootProject.property("kotlinforforge")}")
|
||||
modApi("me.shedaniel.cloth:cloth-config-neoforge:${rootProject.property("clothconfig_version")}")
|
||||
implementation(project(path = ":common", configuration = "namedElements")) { isTransitive = false }
|
||||
|
||||
add("developmentNeoForge", project(path = ":common")) { isTransitive = false }
|
||||
shadowC(project(path = ":common", configuration = "transformProductionNeoForge")) { isTransitive = false }
|
||||
}; loom {
|
||||
runs {
|
||||
val args: MutableList<String> = mutableListOf("-Dfml.earlyprogresswindow=false")
|
||||
args += listOf("--illegal-access=permit")
|
||||
this.forEach {
|
||||
it.vmArgs(args)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
loom.platform=neoforge
|
|
@ -1,11 +0,0 @@
|
|||
package fr.username404.snowygui.forge
|
||||
|
||||
import fr.username404.snowygui.EventSnowy
|
||||
import net.neoforged.bus.api.SubscribeEvent
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent
|
||||
|
||||
object EndTickHandler: EventSnowy {
|
||||
override val type: String = "EndTick"
|
||||
@SubscribeEvent
|
||||
fun handleEndTick(event: ClientTickEvent.Post) = fire<Any>()
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package fr.username404.snowygui.forge
|
||||
|
||||
import fr.username404.snowygui.EventSnowy
|
||||
import net.neoforged.bus.api.SubscribeEvent
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent
|
||||
|
||||
object HudHandler: EventSnowy {
|
||||
override val type: String = "HudRender"
|
||||
@SubscribeEvent
|
||||
fun handleRendering(event: RenderGuiEvent.Post) {
|
||||
fire(event.guiGraphics)
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package fr.username404.snowygui.forge
|
||||
|
||||
import fr.username404.snowygui.ClickGui
|
||||
import fr.username404.snowygui.gui.feature.ButtonImpl
|
||||
import fr.username404.snowygui.misc.AddKeyMaps
|
||||
import net.neoforged.bus.api.SubscribeEvent
|
||||
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent
|
||||
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent
|
||||
|
||||
object MiscModBusHandlers {
|
||||
@SubscribeEvent
|
||||
fun handleClickGuiInit(event: RegisterMenuScreensEvent) {
|
||||
ClickGui.tick()
|
||||
ButtonImpl.initButtons()
|
||||
}
|
||||
@SubscribeEvent
|
||||
fun handleKeys(event: RegisterKeyMappingsEvent) {
|
||||
AddKeyMaps.list.forEach {
|
||||
event.register(it.key)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package fr.username404.snowygui.forge
|
||||
|
||||
import fr.username404.snowygui.gui.feature.Zoom
|
||||
import net.neoforged.bus.api.SubscribeEvent
|
||||
import net.neoforged.neoforge.client.event.ComputeFovModifierEvent
|
||||
|
||||
object ZoomHandler {
|
||||
@SubscribeEvent
|
||||
fun onFOVEvent(event: ComputeFovModifierEvent) {
|
||||
if (Zoom.toggled) event.newFovModifier = Zoom.getNewZoom(event.newFovModifier.toDouble()).toFloat()
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ pluginManagement {
|
|||
repositories {
|
||||
maven(url = "https://maven.fabricmc.net/")
|
||||
maven(url = "https://maven.architectury.dev/")
|
||||
maven(url = "https://maven.neoforged.net/releases/")
|
||||
maven(url = "https://maven.minecraftforge.net/")
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
gradlePluginPortal()
|
||||
|
@ -11,7 +11,7 @@ pluginManagement {
|
|||
|
||||
include("common")
|
||||
include("fabric")
|
||||
include("neoforge")
|
||||
include("forge")
|
||||
|
||||
rootProject.name = "SnowyGUI"
|
||||
|
||||
|
|
Loading…
Reference in New Issue