Compare commits

..

31 Commits
1.20 ... 1.21.5

Author SHA1 Message Date
daaf911a36
Put the right minecraft version in fabric.mod.json
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-25 23:42:07 +02:00
928e691cc9
Remove createRenderPassRewrite.kt
I forgot it

Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-21 14:23:17 +02:00
8c526473e1
Less stupid workaround
Should fix compatibility with iris

Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-20 17:31:36 +02:00
7b310399cf
Update parchmentmc
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-19 16:14:39 +02:00
2aaeb7b039
Bump version to 0.3.6
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-16 20:24:34 +02:00
6416a03001
Fix my stupid configuration system
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-16 20:20:05 +02:00
e96c2adb68
Fix the mod on neoforge 1.21.5 by notably using the mod loader configuration directories
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-16 17:29:49 +02:00
5d98234d39
Fix and improve UI rendering
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-16 04:41:17 +02:00
6eed08aa53
Add a devBuild gradle property
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-16 03:08:55 +02:00
92c8e36c71
Update to 1.21.5
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-16 02:46:59 +02:00
b56a8b0cad
Finish actually updating to 1.21.2
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-15 15:48:10 +02:00
19304abe03
Fix the fabric TitleScreenMixin on Minecraft 1.21.2
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-15 15:38:41 +02:00
73efd7eaac
Update to 1.21.2 and make gradle not process access wideners
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-15 15:05:36 +02:00
9b0620943d
Convert access wideners to access transformers for forge
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-04-14 09:48:14 +02:00
bff4b936c4
Update architectury-loom to 1.9 2025-04-14 08:20:28 +02:00
12e2e4a1d8
Fix scrolling
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 22:57:20 +01:00
8003a86242
Use the right bus for miscellaneous handlers too
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 22:02:24 +01:00
83b82ba1d9
OOPS! use the mod event bus for initialisation
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 21:54:30 +01:00
e93e06ca97
Use the right event bus on neoforge
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 21:47:51 +01:00
82ace01131
Revert to using buildDir
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 21:31:40 +01:00
930cbc2f6a
Replace OptionValueAccessor.java with an access widener to make it work fine on forge
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 20:56:17 +01:00
9503ac000b
Move KeyMappings and KeyAccessor to fabric, to replace them using a RegisterKeyMappingsEvent in neoforge
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 19:54:44 +01:00
2fa0575f68
Move TitleScreenMixin to fabric, to replace it using a RegisterMenuScreensEvent in neoforge
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 19:48:02 +01:00
febeddb093
Move EndTickMixin to fabric, to replace it using a ClientTickEvent in neoforge
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 19:36:04 +01:00
b4574ef5b8
Fix neoforge.mods.toml
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 18:43:40 +01:00
dc286683a5
Switch to architectury-loom 1.7, fix the port to 1.21
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 18:43:40 +01:00
6535278331
Make mixin compatibility levels higher
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 16:17:22 +01:00
95b912c308
Remove a unused import in Snowy.kt
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 16:05:53 +01:00
48b8904b4d
Accept even more recent proguard versions
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 16:01:03 +01:00
bf317e38f0
Finish porting to 1.21
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2025-02-02 15:58:22 +01:00
c506c9a9d2
Port to 1.21
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2024-07-18 18:16:21 +02:00
39 changed files with 275 additions and 192 deletions

View File

@ -1,23 +1,24 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.modrinth.minotaur.ModrinthExtension
import masecla.modrinth4j.model.version.ProjectVersion.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.4, 7.5[") {
classpath("com.guardsquare:proguard-gradle:[7.5, 7.7[") {
exclude("com.android.tools.build")
}
}
}
plugins {
kotlin("jvm") version "1.9.24"
kotlin("plugin.serialization") version "1.9.24"
kotlin("jvm") version "2.0.0"
kotlin("plugin.serialization") version "2.0.0"
id("com.github.johnrengelman.shadow") version "8.1.1" apply false
id("architectury-plugin") version "[3.4.124, 3.5["
id("dev.architectury.loom") version "1.5-SNAPSHOT" apply false
id("architectury-plugin") version "[3.4.160, 3.5["
id("dev.architectury.loom") version "1.10-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"
@ -25,10 +26,10 @@ plugins {
}
group = "fr.username404"
version = "0.3.7"
val groupAndName = "${rootProject.group}.${rootProject.name.toLowerCase()}"
version = "0.3.6"
val groupAndName = "${rootProject.group}.${rootProject.name.lowercase()}"
val javaVer: String = "17"
val javaVer: String = "21"
val sourceJavaVer: String = javaVer
val kotlinVer: String by rootProject
val kotlinSplitVersion = kotlinVer.split('.')
@ -37,6 +38,7 @@ val minecraftVersion: String = (rootProject.property("minecraft") as String).als
architectury { minecraft = it }
}
val kotlinX: String = "org.jetbrains.kotlinx"
val devBuild = rootProject.hasProperty("devBuild") && rootProject.property("devBuild").toString().toBoolean()
subprojects {
group = rootProject.group.toString()
@ -50,18 +52,17 @@ subprojects {
apply(plugin = "dev.architectury.loom")
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
extensions.configure<LoomGradleExtension>("loom") {
mappingsDep = layered {
officialMojangMappings().parchment("org.parchmentmc.data:parchment-1.20.1:2023.06.26")
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.5:2025.04.19")
}
silentMojangMappingsLicense()
val refmap = "snowygui-${project.name}-refmap.json"
mixin {
defaultRefmapName.set(refmap)
if (isForge) {
forge {
mixinConfigs("snowygui-common.mixins.json", "snowygui-forge.mixins.json")
}
}
useLegacyMixinAp = true
defaultRefmapName = refmap
}
}
apply(plugin = "com.github.johnrengelman.shadow")
@ -167,12 +168,16 @@ subprojects {
mergeinterfacesaggressively()
}
withType(net.fabricmc.loom.task.RemapJarTask::class) {
dependsOn(shrinkJar)
val shrinkedJar = shrinkJar.get().outJarFileCollection.singleFile
if (!devBuild) {
dependsOn(shrinkJar)
val shrinkedJar = shrinkJar.get().outJarFileCollection.singleFile
inputFile.set(shrinkedJar)
} else inputFile.set(shadowJar.archiveFile)
archiveBaseName.set(shadowJar.archiveBaseName)
archiveVersion.set("[${rootProject.version}+$minecraftVersion]")
archiveClassifier.set(this@subprojects.name)
inputFile.set(shrinkedJar)
if (this@subprojects.name.contains("forge"))
atAccessWideners.set(listOf("${rootProject.name.lowercase()}.accessWidener"))
if (!archiveFileName.get().contains("common")) destinationDirectory.set(file("$rootDir/remappedJars"))
}
getByName("modrinth").dependsOn(build)
@ -208,8 +213,9 @@ allprojects {
"-opt-in=kotlin.RequiresOptIn", "-Xextended-compiler-checks", "-Xassertions=jvm", "-progressive"
)
jvmTarget = javaVer
languageVersion = (kotlinSplitVersion[0] + '.' + (kotlinSplitVersion[1].toShort() + 1).toString())
apiVersion = "${kotlinSplitVersion[0]}.${kotlinSplitVersion[1]}"
// Uncomment when updating to architectury-loom 1.9
//languageVersion = (kotlinSplitVersion[0] + '.' + (kotlinSplitVersion[1].toShort() + 1).toString())
//apiVersion = "${kotlinSplitVersion[0]}.${kotlinSplitVersion[1]}"
}
}
withType(JavaCompile::class) {
@ -236,10 +242,10 @@ allprojects {
"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").toString().dropLast(2)
"forge_version" to rootProject.property("forge_version")
)
inputs.properties(modProperties)
filesNotMatching(listOf("*.png")) {
filesNotMatching(listOf("*.png", "*.accessWidener")) {
expand(modProperties)
}
}

View File

@ -1,4 +1,4 @@
architectury { common("fabric", "forge"); injectInjectables = true }
architectury { common("fabric", "neoforge"); injectInjectables = true }
dependencies {
modImplementation("net.fabricmc:fabric-loader:${rootProject.property("fabric_loader_version")}")
modImplementation("me.shedaniel.cloth:cloth-config:${rootProject.property("clothconfig_version")}") {
@ -6,4 +6,8 @@ dependencies {
}
}
loom {
accessWidenerPath = file("src/main/resources/${rootProject.name.lowercase()}.accessWidener")
}
tasks.getByName("shrinkJar").enabled = false

View File

@ -1,11 +0,0 @@
package fr.username404.snowygui.mixins;
import net.minecraft.client.OptionInstance;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(OptionInstance.class)
public interface OptionValueAccessor {
@Accessor("value")
void setValue(Object value);
}

View File

@ -30,7 +30,7 @@ object ClickGui: SnowyScreen() {
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): Boolean { boxContext { scroll(d, e, f) }; return false }
override fun mouseScrolled(d: Double, e: Double, f: Double, scrollY: Double): Boolean { boxContext { scroll(d, e, scrollY) }; return false }
override fun mouseDragged(d: Double, e: Double, i: Int, f: Double, g: Double): Boolean {
if (i == GLFW.GLFW_MOUSE_BUTTON_LEFT) {

View File

@ -2,7 +2,6 @@ package fr.username404.snowygui
import fr.username404.snowygui.config.Configuration
import fr.username404.snowygui.gui.feature.ButtonImpl
import fr.username404.snowygui.gui.feature.ButtonImpl.Companion.initButtons
import fr.username404.snowygui.gui.feature.ButtonInfo
import fr.username404.snowygui.misc.AddKeyMaps
import net.minecraft.network.chat.Component

View File

@ -4,11 +4,7 @@ import fr.username404.snowygui.ClickGui
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.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 fr.username404.snowygui.gui.feature.*
import fr.username404.snowygui.utils.FontUtil
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.Screen
@ -27,8 +23,8 @@ private fun supplyComponent(string: String?): Optional<Component> = string?.run
val SnowyConfigScreen: Screen = object: Screen(translationComponent) {
override fun isPauseScreen(): Boolean = false
override fun render(guiGraphics: GuiGraphics, i: Int, j: Int, f: Float) {
super.renderBackground(guiGraphics)
override fun render(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int, pTick: Float) {
super.renderBackground(guiGraphics, mouseX, mouseY, pTick)
FontUtil.drawScaled(guiGraphics,
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
@ -53,9 +49,9 @@ val SnowyConfigScreen: Screen = object: Screen(translationComponent) {
startBooleanToggle(translatable("$confPrefix.behavior.sortalphabetically"), sortAlphabetically)
.setDefaultValue(true).requireRestart()
.setSaveConsumer { sortAlphabetically = it }.build(),
startDoubleField(translatable("$confPrefix.behavior.zoom.factor"), Zoom.zoomFactor).setSaveConsumer {
startFloatField(translatable("$confPrefix.behavior.zoom.factor"), Zoom.zoomFactor).setSaveConsumer {
Zoom.zoomFactor = it
}.setMin(1.1).build(),
}.setMin(1.1F).build(),
startBooleanToggle(translatable("$confPrefix.behavior.zoom.smoothcamera"), Zoom.smoothCameraOnZoom).setSaveConsumer {
Zoom.smoothCameraOnZoom = it
Zoom.execAction()

View File

@ -56,7 +56,7 @@ object Configuration {
getMethod("getConfigDir").invoke(getMethod("getInstance").invoke(null))
}
} else {
Class.forName("net.minecraftforge.fml.loading.FMLPaths")
Class.forName("net.neoforged.fml.loading.FMLPaths")
.getField("CONFIGDIR")
.get(null)
.let { enum ->

View File

@ -4,7 +4,6 @@ import com.mojang.blaze3d.vertex.*
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.GuiGraphics
import net.minecraft.client.gui.components.events.GuiEventListener
@ -55,11 +54,11 @@ abstract class ColoredElement(
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)
return this@colorIt.setColor(get(0), get(1), get(2), opacity)
}
}
}
internal fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorEnd(color, opacity)
internal fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorIt(color, opacity)
protected fun defaultRectFunc() = RenderingUtil.drawRectangle(x, y, height, width, color, opacity)
}

View File

@ -1,22 +1,20 @@
package fr.username404.snowygui.gui.elements
import com.mojang.blaze3d.vertex.DefaultVertexFormat
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 fr.username404.snowygui.utils.RenderingUtil.renderBufferWithPipeline
import io.github.config4k.extract
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.Font
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.renderer.RenderPipelines
import net.minecraft.network.chat.Component
import org.jetbrains.annotations.ApiStatus
import java.util.TreeSet
@ -75,52 +73,55 @@ 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: Double = 2.5
private const val inclination: Float = 2.5F
}
override fun render(guiGraphics: GuiGraphics?) {
val x = x.toFloat()
val y = y.toFloat()
val currentHeight = y + (height + clickboxHeightOffset)
prepareDraw()
with(buffer) {
begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR)
renderBufferWithPipeline(renderPipeline = RenderPipelines.DEBUG_TRIANGLE_FAN) {
// 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()
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()
}
renderBufferWithPipeline(renderPipeline = RenderPipelines.DEBUG_TRIANGLE_FAN) {
// Render the box:
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()
addVertex(x, currentHeight, 0.0F).colorEnd()
addVertex(x + width + inclination, currentHeight, 0.0F).colorEnd()
addVertex(x + width + inclination, y + height, 0.0F).colorEnd()
addVertex(x, y + height, 0.0F).colorEnd()
}
renderBufferWithPipeline(renderPipeline = RenderPipelines.DEBUG_LINE_STRIP) {
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()
addVertex(x + inclination, y + height, 0.0F).colorEnd(Colors.WHITE_LINES.hexValue)
addVertex(x + width, y + height, 0.0F).colorEnd(Colors.WHITE_LINES.hexValue)
}
endDraw()
if (buttons.isNotEmpty()) {
buttonsProgressBar.apply {
x = this@ClickBox.x + this@ClickBox.width - 3
y = this@ClickBox.y + this@ClickBox.height + 3
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())..(y + height + clickboxHeightOffset)
val fullHeight = (y + height.toDouble())..(this.y + height + clickboxHeightOffset)
button.also {
it.x = x + 3
it.y = y + 3 + height + (((num + 1) - barStage) * 9)
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).toFloat(), (y + 2).toFloat(), Colors.TRANSPARENT.hexValue, false,
pose().last().pose(), bufferSource(), Font.DisplayMode.NORMAL, 0, 15728880, isBidirectional
drawInBatch(Component.nullToEmpty(name.string),
(x + 5), (y + 2), Colors.TRANSPARENT.hexValue, false,
pose().last().pose(), bufferSource, Font.DisplayMode.NORMAL, 0, 15728880, isBidirectional
)
}
}

View File

@ -13,7 +13,7 @@ import net.minecraft.client.gui.GuiGraphics
import kotlin.reflect.full.findAnnotation
sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) {
internal companion object {
companion object {
private fun addButtons(vararg buttons: ButtonImpl) {
buttons.groupBy { impl ->
ClickGui.clickBoxes.find { box ->

View File

@ -1,6 +1,5 @@
package fr.username404.snowygui.gui.feature
import fr.username404.snowygui.mixins.OptionValueAccessor
import net.minecraft.client.Minecraft
@ButtonInfo(Category.MISC)
@ -10,11 +9,11 @@ object GammaBoost: ButtonImpl() {
override fun execAction() {
with(Minecraft.getInstance().options) {
val gamma = gamma().get()
@Suppress("KotlinConstantConditions")
(gamma() as OptionValueAccessor).setValue(if (toggled) {
if (gamma < boost) oldGamma = gamma
boost
} else oldGamma)
gamma().value =
if (toggled) {
if (gamma < boost) oldGamma = gamma
boost
} else oldGamma
}
}
}

View File

@ -6,9 +6,9 @@ import net.minecraft.client.Minecraft
@ButtonInfo(Category.MISC, shouldSave = false)
object Zoom: ButtonImpl() {
var smoothCameraOnZoom: Boolean by Configuration
var zoomFactor: Double by Configuration
var zoomFactor: Float by Configuration
@JvmStatic
fun getNewZoom(fov: Double): Double = fov / zoomFactor
fun getNewZoom(fov: Float): Float = fov / zoomFactor
public override fun execAction() {
Minecraft.getInstance().options.smoothCamera = toggled && smoothCameraOnZoom
}

View File

@ -1,45 +1,84 @@
package fr.username404.snowygui.utils
import com.mojang.blaze3d.buffers.BufferType
import com.mojang.blaze3d.buffers.BufferUsage
import com.mojang.blaze3d.opengl.GlCommandEncoder
import com.mojang.blaze3d.opengl.GlStateManager
import com.mojang.blaze3d.pipeline.RenderPipeline
import com.mojang.blaze3d.pipeline.RenderTarget
import com.mojang.blaze3d.systems.RenderPass
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 com.mojang.blaze3d.vertex.VertexFormat
import fr.username404.snowygui.gui.feature.Colors
import fr.username404.snowygui.gui.hextoRGB
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.RenderPipelines
import java.util.OptionalInt
import java.util.OptionalDouble
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)
setColor(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.enableBlend()
RenderSystem.defaultBlendFunc()
GlStateManager._enableBlend()
}
fun endDraw() {
RenderSystem.disableBlend()
GlStateManager._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(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()
): Unit = renderBufferWithPipeline(renderPipeline = RenderPipelines.DEBUG_QUADS) {
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()
}
fun renderBufferWithPipeline(
name: String? = "Dynamic vertex buffer",
renderPipeline: RenderPipeline,
renderTarget: RenderTarget = Minecraft.getInstance().mainRenderTarget,
uniformAndSamplerConsumer: ((RenderPass) -> Unit)? = null,
bufferBuilderConsumer: BufferBuilder.() -> Unit,
) {
val mode = renderPipeline.vertexFormatMode
val builder = Tesselator.getInstance().begin(mode, renderPipeline.vertexFormat)
bufferBuilderConsumer(builder)
builder.buildOrThrow().use { meshData ->
val encoder = RenderSystem.getDevice().createCommandEncoder() as GlCommandEncoder
encoder.createRenderPass(
renderTarget.colorTexture!!,
OptionalInt.empty(),
renderTarget.depthTexture,
OptionalDouble.empty()
).use { renderPass ->
encoder.inRenderPass = false;
RenderSystem.getDevice().createBuffer(
{ name }, BufferType.VERTICES, BufferUsage.DYNAMIC_WRITE, meshData.vertexBuffer()
).use { buffer ->
val autoStorageIndexBuffer = RenderSystem.getSequentialBuffer(mode)
renderPass.setPipeline(renderPipeline)
renderPass.setVertexBuffer(0, buffer)
renderPass.setIndexBuffer(
autoStorageIndexBuffer.getBuffer(meshData.drawState().indexCount()),
autoStorageIndexBuffer.type()
)
uniformAndSamplerConsumer?.invoke(renderPass)
renderPass.drawIndexed(0, meshData.drawState().indexCount())
}
encoder.inRenderPass = false;
}
}
}
}

View File

@ -1,14 +1,8 @@
{
"required": true,
"package": "fr.username404.snowygui.mixins",
"compatibilityLevel": "JAVA_8",
"client": [
"KeysAccessor",
"KeyMappings",
"EndTickMixin",
"TitleScreenMixin",
"OptionValueAccessor"
],
"compatibilityLevel": "JAVA_18",
"client": [],
"injectors": {
"defaultRequire": 1
},

View File

@ -0,0 +1,9 @@
accessWidener v2 named
accessible field net/minecraft/client/OptionInstance value Ljava/lang/Object;
mutable field net/minecraft/client/OptionInstance value Ljava/lang/Object;
accessible field net/minecraft/client/gui/GuiGraphics bufferSource Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;
accessible field com/mojang/blaze3d/opengl/GlCommandEncoder inRenderPass Z
mutable field com/mojang/blaze3d/opengl/GlCommandEncoder inRenderPass Z

View File

@ -0,0 +1,3 @@
{
"accessWidener": "snowygui.accessWidener"
}

View File

@ -4,16 +4,17 @@ import fr.username404.snowygui.ClickGui;
import fr.username404.snowygui.gui.feature.ButtonImpl;
import net.minecraft.client.gui.screens.TitleScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(TitleScreen.class)
abstract class TitleScreenMixin {
private static boolean buttonsInitialized = false;
private static synchronized void setButtonsInitialized() { buttonsInitialized = true; }
@Unique private static boolean buttonsInitialized = false;
@Unique private static synchronized void setButtonsInitialized() { buttonsInitialized = true; }
@Inject(method = "createNormalMenuOptions", at = @At(value = "RETURN"))
public void createNormalMenuOptions(int i, int j, CallbackInfo ci) {
public void createNormalMenuOptions(int i, int j, CallbackInfoReturnable<Integer> cir) {
if (!buttonsInitialized) {
ClickGui.INSTANCE.tick();
ButtonImpl.initButtons();

View File

@ -11,8 +11,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(GameRenderer.class)
abstract class ZoomMixin {
@Inject(at = @At(value = "RETURN"), method = "getFov(Lnet/minecraft/client/Camera;FZ)D", cancellable = true)
private void getFov(Camera camera, float f, boolean bl, CallbackInfoReturnable<Double> cir) {
@Inject(at = @At(value = "RETURN"), method = "getFov(Lnet/minecraft/client/Camera;FZ)F", cancellable = true)
private void getFov(Camera camera, float f, boolean bl, CallbackInfoReturnable<Float> cir) {
if (Zoom.INSTANCE.getToggled() && !OkZoomerCompatKt.isOkZoomerPresent) {
cir.setReturnValue(Zoom.getNewZoom(cir.getReturnValue()));
}

View File

@ -1,6 +1,5 @@
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
@ -8,6 +7,7 @@ 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
@ -21,7 +21,7 @@ class FabricInit: Snowy(), ClientModInitializer {
EVENT.register(
object: HudRenderCallback, EventSnowy {
override val type: String = "HudRender"
override fun onHudRender(guiGraphics: GuiGraphics?, tickDelta: Float) = fire(guiGraphics)
override fun onHudRender(guiGraphics: GuiGraphics?, tickCounter: DeltaTracker?) = fire(guiGraphics)
}
)
}

View File

@ -32,6 +32,7 @@
"snowygui-common.mixins.json",
"snowygui-fabric.mixins.json"
],
"accessWidener": "snowygui.accessWidener",
"depends": {
"fabricloader": ">=${fabric_loader}",
"fabric-language-kotlin": ">=${fabric_kotlin}",

View File

@ -1,8 +1,12 @@
{
"required": true,
"package": "fr.username404.snowygui.mixins",
"compatibilityLevel": "JAVA_8",
"compatibilityLevel": "JAVA_18",
"client": [
"EndTickMixin",
"TitleScreenMixin",
"KeysAccessor",
"KeyMappings",
"ZoomMixin",
"OkZoomerAlternativeMixin"
],

View File

@ -1,25 +0,0 @@
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", configuration = "namedElements")) { 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)
}
}
}
}

View File

@ -1 +0,0 @@
loom.platform=forge

View File

@ -7,16 +7,16 @@ org.gradle.parallel=true
org.gradle.unsafe.configuration-cache=on
org.gradle.vfs.watch=true
minecraft=1.20
forge_version=46.0
kotlinforforge=4.3.0
kotlinVer=1.8.22
kotlin_coroutines_version=1.7.1
serializationVer=1.5.1
fabric_loader_version=0.14.19
fabric_language_kotlin=1.9.5+kotlin.1.8.22
fabric_resource_loader_version=0.11.7+f7923f6d27
fabric_rendering_api_version=3.0.6+b3afc78b27
fabric_api_base_version=0.4.29+b04edc7a27
clothconfig_version=11.0.99
modmenu_version=7.0.0
minecraft=1.21.5
forge_version=21.5.40-beta
kotlinforforge=5.7.0
kotlinVer=2.1.0
kotlin_coroutines_version=1.9.0
serializationVer=1.7.3
fabric_loader_version=0.14.20
fabric_language_kotlin=1.13.0+kotlin.2.1.0
fabric_resource_loader_version=3.1.6+02ca679607
fabric_rendering_api_version=11.1.11+081cc04307
fabric_api_base_version=0.4.62+73a52b4b07
clothconfig_version=18.0.145
modmenu_version=14.0.0-rc.2

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-rc-1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

26
neoforge/build.gradle.kts Normal file
View File

@ -0,0 +1,26 @@
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)
}
}
}

View File

@ -0,0 +1 @@
loom.platform=neoforge

View File

@ -0,0 +1,11 @@
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>()
}

View File

@ -4,25 +4,19 @@ 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.minecraftforge.fml.ModList
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.client.ConfigScreenHandler
import net.minecraftforge.forgespi.language.ModFileScanData
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 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: Snowy() {
class ForgeInit(container: ModContainer): Snowy() {
private fun initSetup(event: FMLClientSetupEvent) = atInit()
private fun configSetup(event: FMLClientSetupEvent) {
LOADING_CONTEXT.registerExtensionPoint(
ConfigScreenHandler.ConfigScreenFactory::class.java
) { ConfigScreenHandler.ConfigScreenFactory { _, parent -> configScreenParent = parent; SnowyConfigScreen } }
}
override val annotatedButtons = ModList.get() // Forge-specific reflection
.allScanData
.flatMap { obj: ModFileScanData -> obj.classes }
@ -34,13 +28,18 @@ class ForgeInit: Snowy() {
.map { Class.forName((it!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(it) as Type).className).asSubclass(ButtonImpl::class.java)}
.toSet()
init {
with(MOD_BUS) {
container.eventBus!!.run {
addListener(this@ForgeInit::initSetup)
addListener(this@ForgeInit::configSetup)
register(MiscModBusHandlers)
}
with(FORGE_BUS) {
NeoForge.EVENT_BUS.run {
register(EndTickHandler)
register(HudHandler)
register(ZoomHandler)
}
container.registerExtensionPoint(
IConfigScreenFactory::class.java,
IConfigScreenFactory { _, parent -> configScreenParent = parent; SnowyConfigScreen }
)
}
}

View File

@ -1,8 +1,8 @@
package fr.username404.snowygui.forge
import fr.username404.snowygui.EventSnowy
import net.minecraftforge.client.event.RenderGuiEvent
import net.minecraftforge.eventbus.api.SubscribeEvent
import net.neoforged.bus.api.SubscribeEvent
import net.neoforged.neoforge.client.event.RenderGuiEvent
object HudHandler: EventSnowy {
override val type: String = "HudRender"

View File

@ -0,0 +1,22 @@
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)
}
}
}

View File

@ -1,12 +1,12 @@
package fr.username404.snowygui.forge
import fr.username404.snowygui.gui.feature.Zoom
import net.minecraftforge.client.event.ComputeFovModifierEvent
import net.minecraftforge.eventbus.api.SubscribeEvent
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()
if (Zoom.toggled) event.newFovModifier = Zoom.getNewZoom(event.newFovModifier)
}
}

View File

@ -14,14 +14,14 @@ 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 = "forge"
modId = "neoforge"
mandatory = true
versionRange = "[${forge_version},)"
ordering = "NONE"
@ -33,3 +33,9 @@ mandatory = true
versionRange = "[${minecraft_version},)"
ordering = "NONE"
side = "BOTH"
[[mixins]]
config = "snowygui-common.mixins.json"
[[mixins]]
config = "snowygui-neoforge.mixins.json"

View File

@ -1,7 +1,7 @@
{
"required": false,
"package": "fr.username404.snowygui.mixins",
"compatibilityLevel": "JAVA_8",
"compatibilityLevel": "JAVA_21",
"client": [],
"injectors": {
"defaultRequire": 1

View File

@ -2,7 +2,7 @@ pluginManagement {
repositories {
maven(url = "https://maven.fabricmc.net/")
maven(url = "https://maven.architectury.dev/")
maven(url = "https://maven.minecraftforge.net/")
maven(url = "https://maven.neoforged.net/releases/")
mavenCentral()
mavenLocal()
gradlePluginPortal()
@ -11,7 +11,7 @@ pluginManagement {
include("common")
include("fabric")
include("forge")
include("neoforge")
rootProject.name = "SnowyGUI"