From 5c77165d17d6c89f8a729f95d1af669a464c73dc Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 5 May 2024 05:11:33 +0200 Subject: [PATCH] feat: added config, added config ui, started working on HUD configurator Signed-off-by: moonleay --- .../net/moonleay/gimbal/client/ClientMain.kt | 7 + .../gimbal/client/config/AnchorPoint.kt | 30 ++++ .../gimbal/client/config/Centerpoint.kt | 27 ++++ .../client/config/ClientConfigHolder.kt | 70 +++++++++ .../client/config/GimbalClientConfig.kt | 27 ++++ .../gimbal/client/config/GimbalGuiSettings.kt | 28 ++++ .../gimbal/client/config/ScaledRes.kt | 27 ++++ .../gimbal/client/screen/GimbalEditHudGui.kt | 135 ++++++++++++++++++ .../gimbal/client/screen/GimbalSettingsGui.kt | 84 +++++++++++ .../gimbal/client/util/screen/ScreenUtil.kt | 61 ++++++++ .../datagen/En_us_GimbalLanguageProvider.kt | 14 +- .../gimbal/mixin/YouInjectButtonMixin.java | 66 +++++++++ .../gimbal/mixin/YouInjectButtonMixin2.java | 65 +++++++++ .../gimbal_options_texture_button.png | Bin 0 -> 1228 bytes src/main/resources/gimbal.mixins.json | 4 +- 15 files changed, 643 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/moonleay/gimbal/client/config/AnchorPoint.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/config/Centerpoint.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/config/GimbalGuiSettings.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt create mode 100644 src/main/java/net/moonleay/gimbal/client/util/screen/ScreenUtil.kt create mode 100644 src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java create mode 100644 src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin2.java create mode 100644 src/main/resources/assets/gimbal/textures/gimbal_options_texture_button.png diff --git a/src/main/java/net/moonleay/gimbal/client/ClientMain.kt b/src/main/java/net/moonleay/gimbal/client/ClientMain.kt index 0f6f156..2af8b59 100644 --- a/src/main/java/net/moonleay/gimbal/client/ClientMain.kt +++ b/src/main/java/net/moonleay/gimbal/client/ClientMain.kt @@ -21,7 +21,9 @@ package net.moonleay.gimbal.client import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.fabricmc.fabric.api.client.networking.v1.ClientLoginConnectionEvents +import net.fabricmc.loader.api.FabricLoader import net.moonleay.gimbal.build.BuildConstants +import net.moonleay.gimbal.client.config.ClientConfigHolder import net.moonleay.gimbal.client.editor.ClientEditor import net.moonleay.gimbal.client.keybindings.KeybindingManager import net.moonleay.gimbal.client.keybindings.KeybindingRegistrar @@ -30,6 +32,7 @@ import org.apache.logging.log4j.LogManager internal object ClientMain : ClientModInitializer { private val LOGGER = LogManager.getLogger(BuildConstants.modName) + lateinit var CONFIG: ClientConfigHolder override fun onInitializeClient() { @@ -39,6 +42,10 @@ internal object ClientMain : ClientModInitializer { LOGGER.info("Registering packets...") GimbalClient.registerPacketHandlers() LOGGER.info("Packets have been registered.") + LOGGER.info("Loading client config.") + val gimbalConfigPath = FabricLoader.getInstance().configDir.resolve(BuildConstants.modId + "/client.json") + CONFIG = ClientConfigHolder(gimbalConfigPath) + LOGGER.info("Config has been loaded.") LOGGER.info("Gimbal has been initialized on the client side.") } diff --git a/src/main/java/net/moonleay/gimbal/client/config/AnchorPoint.kt b/src/main/java/net/moonleay/gimbal/client/config/AnchorPoint.kt new file mode 100644 index 0000000..29f34a2 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/config/AnchorPoint.kt @@ -0,0 +1,30 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.config + +import kotlinx.serialization.Serializable + +@Serializable +enum class AnchorPoint { + TOP_LEFT, + TOP_RIGHT, + BOTTOM_RIGHT, + BOTTOM_LEFT, + CENTER +} diff --git a/src/main/java/net/moonleay/gimbal/client/config/Centerpoint.kt b/src/main/java/net/moonleay/gimbal/client/config/Centerpoint.kt new file mode 100644 index 0000000..2cb8029 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/config/Centerpoint.kt @@ -0,0 +1,27 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.config + +enum class Centerpoint { + TOP_LEFT, + TOP_RIGHT, + BOTTOM_RIGHT, + BOTTOM_LEFT, + CENTER +} diff --git a/src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt b/src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt new file mode 100644 index 0000000..c385f49 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt @@ -0,0 +1,70 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.config + +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream +import kotlinx.serialization.json.encodeToStream +import java.nio.file.Path +import kotlin.io.path.* + +class ClientConfigHolder(private val path: Path) { + var config: GimbalClientConfig + private set + + init { + config = load() + } + + fun updateConfig(new: GimbalClientConfig) { + config = new + save(config) + } + + @OptIn(ExperimentalSerializationApi::class) + fun load(): GimbalClientConfig { + if (!path.isReadable()) + save(GimbalClientConfig()) + return path.inputStream().use { + Json.decodeFromStream(it) + } + } + + @OptIn(ExperimentalSerializationApi::class) + fun save(conf: GimbalClientConfig) { + if (!path.isWritable()) { + if (!path.parent.exists()) { + path.parent.createDirectory() + } + if (!path.parent.isWritable()) { + throw Exception("Parent of path ${path.parent.pathString} is not writable.") + } + if (!path.exists()) + path.createFile() + if (!path.isWritable()) { + throw Exception("Path (${path.pathString}) exists, but is not writable.") + } + } + path.outputStream().use { + Json.encodeToStream(conf, it) + } + } + +} diff --git a/src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt b/src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt new file mode 100644 index 0000000..b0184d7 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt @@ -0,0 +1,27 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.config + +import kotlinx.serialization.Serializable + +@Serializable +data class GimbalClientConfig( + val guiSettings: GimbalGuiSettings = GimbalGuiSettings(), + val showToasts: Boolean = true, +) diff --git a/src/main/java/net/moonleay/gimbal/client/config/GimbalGuiSettings.kt b/src/main/java/net/moonleay/gimbal/client/config/GimbalGuiSettings.kt new file mode 100644 index 0000000..2a274b0 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/config/GimbalGuiSettings.kt @@ -0,0 +1,28 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.config + +import kotlinx.serialization.Serializable + +@Serializable +data class GimbalGuiSettings( + val showHud: Boolean = true, + val scaledRes: ScaledRes = ScaledRes(4.0, 4.0), + val anchorPoint: AnchorPoint = AnchorPoint.TOP_LEFT, +) diff --git a/src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt b/src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt new file mode 100644 index 0000000..acf9a70 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt @@ -0,0 +1,27 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.config + +import kotlinx.serialization.Serializable + +@Serializable +data class ScaledRes( + val scaledX: Double, + val scaledY: Double, +) diff --git a/src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt b/src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt new file mode 100644 index 0000000..0b7fd61 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt @@ -0,0 +1,135 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.screen + +import net.minecraft.client.gui.screen.Screen +import net.minecraft.client.gui.widget.ButtonWidget +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.screen.ScreenTexts +import net.minecraft.text.Text +import net.moonleay.gimbal.build.BuildConstants +import net.moonleay.gimbal.client.config.* +import net.moonleay.gimbal.client.util.screen.ScreenUtil +import org.apache.logging.log4j.LogManager + +class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfigHolder) : + Screen(Text.translatable("gimbal.gui.edithud")) { + private val LOGGER = LogManager.getLogger(BuildConstants.modName) + + private var tempXOffset = 4.0 + private var tempYOffset = 4.0 + private var shouldFollow = false + + init { + this.tempXOffset = cfg.config.guiSettings.scaledRes.scaledX + this.tempYOffset = cfg.config.guiSettings.scaledRes.scaledY + } + + override fun init() { + super.init() + this.addDrawableChild(ButtonWidget( + this.width / 2 + 10, this.height - 27, 90, 20, Text.translatable("gimbal.gui.resethud") + ) { _: ButtonWidget? -> + tempXOffset = 4.0 + tempYOffset = 4.0 + shouldFollow = false + }) + + this.addDrawableChild(ButtonWidget( + this.width / 2 - 100, this.height - 27, 90, 20, ScreenTexts.DONE + ) { _: ButtonWidget? -> + this.save() + this.client!!.setScreen( + this.parent + ) + }) + } + + private fun save() { + val oldConf = cfg.config + if (ScreenUtil.isPositionOutOfBounds(this.tempXOffset, this.tempYOffset)) { + LOGGER.info("Text is not in bounds. This will not be saved in order to keep the user from making the hud inaccessible.") + return + } + LOGGER.info("Saving Pos...") + + val newConf = GimbalClientConfig( + showToasts = oldConf.showToasts, + guiSettings = GimbalGuiSettings( + showHud = oldConf.guiSettings.showHud, + scaledRes = ScaledRes( + scaledX = this.tempXOffset, + scaledY = this.tempYOffset, + ) + ) + ) + + cfg.updateConfig(newConf) + } + + override fun close() { + this.save() + this.client!!.setScreen(this.parent) + } + + override fun tick() { + super.tick() + if (this.shouldFollow) { + val mouse = this.client?.mouse!! + val scaleFactor = this.client!!.window.calculateScaleFactor( + this.client!!.options.guiScale.value, + this.client!!.forcesUnicodeFont() + ) + this.tempXOffset = ScreenUtil.getScaled(this.width, mouse.x.toFloat() / scaleFactor) + this.tempYOffset = ScreenUtil.getScaled(this.height, mouse.y.toFloat() / scaleFactor) + } + } + + override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { + this.shouldFollow = true + return super.mouseClicked(mouseX, mouseY, button) + } + + override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean { + this.shouldFollow = false + return super.mouseReleased(mouseX, mouseY, button) + } + + override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) { + this.renderBackground(matrices) + drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215) + this.textRenderer.drawWithShadow( + matrices, + Text.translatable("gimbal.gui.examplehud"), + ScreenUtil.getXForRender( + ScreenUtil.getReal(this.width, this.tempXOffset), + AnchorPoint.CENTER, + this.textRenderer.getWidth(Text.translatable("gimbal.gui.examplehud")) + ), + ScreenUtil.getYForRender( + ScreenUtil.getReal(this.height, this.tempYOffset), + AnchorPoint.CENTER, + this.textRenderer.fontHeight + ), + 0xFFFFFF + ) // TODO: improve placement when changing the scaling +// LOGGER.info("width: ${this.width}, height: ${this.height}, posX: ${ScreenUtil.getReal(this.width, this.tempXOffset)}, posY: ${ScreenUtil.getReal(this.height, this.tempYOffset)}, scaleX: ${this.tempXOffset}, scaleY: ${this.tempYOffset}") + super.render(matrices, mouseX, mouseY, delta) + } +} diff --git a/src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt b/src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt new file mode 100644 index 0000000..99cedbb --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt @@ -0,0 +1,84 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.screen + +import net.minecraft.client.gui.screen.Screen +import net.minecraft.client.gui.widget.ButtonWidget +import net.minecraft.client.gui.widget.CyclingButtonWidget +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.screen.ScreenTexts +import net.minecraft.text.Text +import net.moonleay.gimbal.client.config.ClientConfigHolder +import net.moonleay.gimbal.client.config.GimbalClientConfig +import net.moonleay.gimbal.client.config.GimbalGuiSettings + +class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfigHolder) : + Screen(Text.translatable("gimbal.gui.settings")) { + override fun init() { + this.addDrawableChild(CyclingButtonWidget.onOffBuilder( +// Text.translatable("gimbal.gui.enabled"), +// Text.translatable("gimbal.gui.disabled") + ) + .initially(cfg.config.guiSettings.showHud) + .build( + this.width / 2 - 155, + this.height / 6 + 24 * 0, + 150, + 20, + Text.translatable("gimbal.gui.hud") + ) { _: CyclingButtonWidget?, isEnabled: Boolean? -> + val oldGui = cfg.config.guiSettings + val newGui = GimbalGuiSettings( + showHud = isEnabled ?: true, + scaledRes = oldGui.scaledRes, + anchorPoint = oldGui.anchorPoint + ) + val newConf = GimbalClientConfig( + guiSettings = newGui, + showToasts = cfg.config.showToasts + ) + cfg.updateConfig(newConf) + }) + this.addDrawableChild(ButtonWidget( + this.width / 2 - 155 + 160, + this.height / 6 + 24 * 0, + 150, + 20, + Text.translatable("gimbal.gui.edithud") + ) { _: ButtonWidget? -> + this.client!!.setScreen(GimbalEditHudGui(this, cfg)) + } + ) + + // Done button + this.addDrawableChild(ButtonWidget( + this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE + ) { _: ButtonWidget? -> + this.client!!.setScreen( + this.parent + ) + }) + } + + override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) { + this.renderBackground(matrices) + drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215) + super.render(matrices, mouseX, mouseY, delta) + } +} diff --git a/src/main/java/net/moonleay/gimbal/client/util/screen/ScreenUtil.kt b/src/main/java/net/moonleay/gimbal/client/util/screen/ScreenUtil.kt new file mode 100644 index 0000000..c9166cb --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/util/screen/ScreenUtil.kt @@ -0,0 +1,61 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.client.util.screen + +import net.moonleay.gimbal.client.config.AnchorPoint + +object ScreenUtil { + + fun getXForRender(x: Float, anchor: AnchorPoint, textWidth: Int): Float { + return when (anchor) { + AnchorPoint.TOP_LEFT -> x + AnchorPoint.BOTTOM_LEFT -> x + AnchorPoint.TOP_RIGHT -> x - textWidth + AnchorPoint.BOTTOM_RIGHT -> x - textWidth + AnchorPoint.CENTER -> x - textWidth / 2 + } + } + + fun getYForRender(y: Float, anchor: AnchorPoint, textHeight: Int): Float { + return when (anchor) { + AnchorPoint.TOP_LEFT -> y + AnchorPoint.TOP_RIGHT -> y + AnchorPoint.BOTTOM_RIGHT -> y - textHeight + AnchorPoint.BOTTOM_LEFT -> y - textHeight + AnchorPoint.CENTER -> y - textHeight / 2 + } + } + + fun getScaled(length: Int, real: Float): Double { + val scale = length / 100.0 + return real / scale + } + + fun getReal(length: Int, scaled: Double): Float { + val scale = length / 100.0 + return (scaled * scale).toFloat() + } + + fun isPositionOutOfBounds(x: Double, y: Double): Boolean { + val tooBig = 100 < x || 100 < y + val tooSmall = 0 > x || 0 > y + return tooBig || tooSmall + } + +} diff --git a/src/main/java/net/moonleay/gimbal/datagen/En_us_GimbalLanguageProvider.kt b/src/main/java/net/moonleay/gimbal/datagen/En_us_GimbalLanguageProvider.kt index 34d0fce..0082df9 100644 --- a/src/main/java/net/moonleay/gimbal/datagen/En_us_GimbalLanguageProvider.kt +++ b/src/main/java/net/moonleay/gimbal/datagen/En_us_GimbalLanguageProvider.kt @@ -26,13 +26,25 @@ class En_us_GimbalLanguageProvider(dataGenerator: FabricDataGenerator?) : override fun generateTranslations(translationBuilder: TranslationBuilder?) { if (translationBuilder == null) return + /// Screens + // Gimbal settings screen + translationBuilder.add("gimbal.gui.settings", "Gimbal Settings") + translationBuilder.add("gimbal.gui.hud", "Show HUD") + translationBuilder.add("gimbal.gui.edithud", "Edit HUD Layout...") + translationBuilder.add("gimbal.gui.resethud", "Reset Layout") + translationBuilder.add("gimbal.gui.examplehud", "EXAMPLE [No Clip, Force]") + + + translationBuilder.add("gimbal.gui.enabled", "Enabled") + translationBuilder.add("gimbal.gui.disabled", "Disabled") + + /// Options // Editor modes translationBuilder.add("gimbal.category.editormode", "Editor Modes") translationBuilder.add("gimbal.key.editor.mode.insert", "Enter Insert Mode") translationBuilder.add("gimbal.key.editor.mode.replace", "Enter Replace Mode") translationBuilder.add("gimbal.key.editor.mode.visual", "Enter Visual Mode") - // Editor mode modifiers translationBuilder.add("gimbal.category.editormodifier", "Editor Mode Modifiers") translationBuilder.add("gimbal.key.editor.modifier.bulldozer", "Toggle Bulldozer Modifier") diff --git a/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java b/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java new file mode 100644 index 0000000..861ecd3 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java @@ -0,0 +1,66 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.mixin; + +import net.minecraft.client.gui.screen.GameMenuScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.TexturedButtonWidget; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.moonleay.gimbal.build.BuildConstants; +import net.moonleay.gimbal.client.ClientMain; +import net.moonleay.gimbal.client.screen.GimbalSettingsGui; +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; + +@Mixin(GameMenuScreen.class) +// What is my purpose? +public class YouInjectButtonMixin extends Screen { + // Go my god. + + @Unique + private static final Identifier GIMBAL_TEXTURE = new Identifier(BuildConstants.modId, "textures/gimbal_options_texture_button.png"); + + protected YouInjectButtonMixin(Text title) { + super(title); + } + + @Inject(method = "initWidgets", at = @At(value = "RETURN")) + private void func(CallbackInfo ci) { + this.addDrawableChild( + new TexturedButtonWidget( + this.width / 2 - 124, + this.height / 4 + 96 + -16, + 20, + 20, + 0, + 0, + 20, + GIMBAL_TEXTURE, + 20, + 40, + button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)), + Text.translatable("gimbal.gui.settings") + ) + ); + } +} diff --git a/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin2.java b/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin2.java new file mode 100644 index 0000000..70af1f4 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin2.java @@ -0,0 +1,65 @@ +/* + * Gimbal + * Copyright (C) 2024 moonleay + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.moonleay.gimbal.mixin; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.TitleScreen; +import net.minecraft.client.gui.widget.TexturedButtonWidget; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.moonleay.gimbal.build.BuildConstants; +import net.moonleay.gimbal.client.ClientMain; +import net.moonleay.gimbal.client.screen.GimbalSettingsGui; +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; + +@Mixin(TitleScreen.class) +public class YouInjectButtonMixin2 extends Screen { + + @Unique + private static final Identifier GIMBAL_TEXTURE = new Identifier(BuildConstants.modId, "textures/gimbal_options_texture_button.png"); + + protected YouInjectButtonMixin2(Text title) { + super(title); + } + + @Inject(method = "init", at = @At(value = "RETURN")) + private void func(CallbackInfo ci) { + int l = this.height / 4 + 48; + this.addDrawableChild( + new TexturedButtonWidget( + this.width / 2 - 124 - 24, + l + 72 + 12, + 20, + 20, + 0, + 0, + 20, + GIMBAL_TEXTURE, + 20, + 40, + button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)), + Text.translatable("gimbal.gui.settings") + ) + ); + } +} diff --git a/src/main/resources/assets/gimbal/textures/gimbal_options_texture_button.png b/src/main/resources/assets/gimbal/textures/gimbal_options_texture_button.png new file mode 100644 index 0000000000000000000000000000000000000000..e11bf08f97c6518a69b22dfe74fc0cfd0f052465 GIT binary patch literal 1228 zcmV;-1T*`IP)Px(hDk(0R7i=nm0fHURTRg6b7y9|3-kjDY$Gj{no2AokdP2H6;UBRfyOk5K;XlmM8f34rH$2q7kQ)Y{rgO-)V8p}#Sa zDW&i{57RU;3+4HL=pU3)Vp)2Ny%(GG`mu#)^?GyBF#sIL z(HZzp%TLEJ3~bxRbzOuIyn5*zhaY*46FoZsh;%;-z_BM@;8^D_wm$GNmSvGlCXrI2 zluA3y)W)`L9LM3%stwfl>|p)cJpdeF0gf}uJ10(&Sd~CZh2uB~A+T*5+qMA^0Iutz zl+t=7R$QgNcNfpBei?u}cZLB71Z)oMT)^IoO$;w zU%Q9Ayj%csb7$!cg25o~Zk^8?$A9C_%I{H1Wo4*Wep$3dPx5Hlc1mX#)89WpFc{2= za%99|WMqUxt2XfF2Y-yK3ISjkhAs<$(JNuTdb@>quVSVfAQ%iXZ{A!Mhr{H~4Pu=h zNv9|Tj+44XJM{Id@7=}f=tgD?bpkMWuAjEH>%@-SLWDee68*&9kEUdZwR3*u!|c7- zglU@O+eg@newivvsQlXRHnV>_3#Dn$1( zz^3^hQs0~Eju*=%vfjh_HNwD9oQD?7p(I>DhgnXCnI0TRE31%W{SROOYTv$nM5C#4 z@H`LKbqNFlK&pET!@#mEeeq=0(9n?jDURdl%|IYPUS3|h41~}sA1oTE1RG6_=>(uAY=ByIUIhbIEs;GsV|IO36>^%PBKuU|I9@ zG397w)$}q&57aTHB$LUsLtnqz?&|wy%I=m%Ow-hv=#)pFzXAL=rpT(U>1Rqj9?y0d zJX@|K%e1L5#r~p9r~LmjC2;ydgb>{R@%%lR(ivJhwle`!{F(St@h8-FZv$Z4Qi<2- zG5qs|ET(jZmeLtY502WWHfJ+MDW&%B->;b>rNnhz%~{uV_2Bq7rqtEdjb}