feat: added settings and a config system

refactor: Reworked translation key system

Signed-off-by: moonleay <contact@moonleay.net>
This commit is contained in:
moonleay 2024-05-06 02:52:28 +02:00
parent e7355f9781
commit 6002af93a5
Signed by: moonleay
GPG key ID: 82667543CCD715FB
21 changed files with 517 additions and 93 deletions

View file

@ -47,6 +47,7 @@ class ClientConfigHolder(private val path: Path) {
} }
} }
// TODO: Support incomplete config files
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
fun save(conf: GimbalClientConfig) { fun save(conf: GimbalClientConfig) {
if (!path.isWritable()) { if (!path.isWritable()) {

View file

@ -19,9 +19,10 @@
package net.moonleay.gimbal.client.config package net.moonleay.gimbal.client.config
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.moonleay.gimbal.client.config.enums.ToastSettings
@Serializable @Serializable
data class GimbalClientConfig( data class GimbalClientConfig(
val guiSettings: GimbalGuiSettings = GimbalGuiSettings(), val guiSettings: GimbalGuiSettings = GimbalGuiSettings(),
val showToasts: Boolean = true, val toastSettings: ToastSettings = ToastSettings.ALL,
) )

View file

@ -19,6 +19,9 @@
package net.moonleay.gimbal.client.config package net.moonleay.gimbal.client.config
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.moonleay.gimbal.client.config.enums.HorizontalAnchor
import net.moonleay.gimbal.client.config.enums.HudOptions
import net.moonleay.gimbal.client.config.enums.VerticalAnchor
@Serializable @Serializable
data class GimbalGuiSettings( data class GimbalGuiSettings(
@ -26,4 +29,5 @@ data class GimbalGuiSettings(
val offset: ScaledRes = ScaledRes(4.0, 4.0), val offset: ScaledRes = ScaledRes(4.0, 4.0),
val horizontalAnchor: HorizontalAnchor = HorizontalAnchor.LEFT, val horizontalAnchor: HorizontalAnchor = HorizontalAnchor.LEFT,
val verticalAnchor: VerticalAnchor = VerticalAnchor.TOP, val verticalAnchor: VerticalAnchor = VerticalAnchor.TOP,
val hudOptions: HudOptions = HudOptions.ALL,
) )

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.moonleay.gimbal.client.config package net.moonleay.gimbal.client.config.enums
enum class Centerpoint { enum class Centerpoint {
TOP_LEFT, TOP_LEFT,

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.moonleay.gimbal.client.config package net.moonleay.gimbal.client.config.enums
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View file

@ -0,0 +1,31 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.moonleay.gimbal.client.config.enums
import kotlinx.serialization.Serializable
import net.minecraft.text.Text
import net.moonleay.gimbal.constants.TranslationKeys
@Serializable
enum class HudOptions(val translatableText: Text) {
ALL(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_ALL)),
NUMBER(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_NUMBER)),
INITIAL(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_INITIALS)),
ONLY_MODE(Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODE_ONLY)),
}

View file

@ -0,0 +1,32 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.moonleay.gimbal.client.config.enums
import kotlinx.serialization.Serializable
import net.minecraft.text.Text
import net.moonleay.gimbal.client.util.ToastType
import net.moonleay.gimbal.constants.TranslationKeys
@Serializable
enum class ToastSettings(val translatableText: Text, val allowedTypes: List<ToastType>) {
ALL(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_ALL), listOf(ToastType.SYSTEM, ToastType.TOGGLE)),
ONLY_TOGGLE(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_TOGGLE), listOf(ToastType.TOGGLE)),
ONLY_SYSTEM(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_SYSTEM), listOf(ToastType.SYSTEM)),
NONE(Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_NONE), listOf())
}

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.moonleay.gimbal.client.config package net.moonleay.gimbal.client.config.enums
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View file

@ -21,7 +21,11 @@ package net.moonleay.gimbal.client.editor
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.text.Text import net.minecraft.text.Text
import net.moonleay.gimbal.build.BuildConstants import net.moonleay.gimbal.build.BuildConstants
import net.moonleay.gimbal.client.ClientMain
import net.moonleay.gimbal.client.config.GimbalClientConfig
import net.moonleay.gimbal.client.config.enums.HudOptions
import net.moonleay.gimbal.client.util.ChatUtil import net.moonleay.gimbal.client.util.ChatUtil
import net.moonleay.gimbal.client.util.ToastType
import net.moonleay.gimbal.editor.ServerEditorManager import net.moonleay.gimbal.editor.ServerEditorManager
import net.moonleay.gimbal.editor.state.EditorState import net.moonleay.gimbal.editor.state.EditorState
import net.moonleay.gimbal.editor.state.GimbalPolicyType import net.moonleay.gimbal.editor.state.GimbalPolicyType
@ -121,7 +125,13 @@ object ClientEditor {
* */ * */
fun setMode(mode: Mode) { fun setMode(mode: Mode) {
if (!isAllowed()) { if (!isAllowed()) {
ChatUtil.showToastToSelf("Gimbal is disabled", "You cannot change modes", MinecraftClient.getInstance()) ChatUtil.showToastToSelf(
"Gimbal is disabled",
"You cannot change modes",
ToastType.SYSTEM,
ClientMain.CONFIG.config,
MinecraftClient.getInstance()
)
return return
} }
if (!MinecraftClient.getInstance().player!!.isCreative) if (!MinecraftClient.getInstance().player!!.isCreative)
@ -136,23 +146,44 @@ object ClientEditor {
* */ * */
fun toggleModifier(mod: ModeModifier) { fun toggleModifier(mod: ModeModifier) {
if (!isAllowed()) { if (!isAllowed()) {
ChatUtil.showToastToSelf("Gimbal is disabled", "You cannot change modifiers", MinecraftClient.getInstance()) ChatUtil.showToastToSelf(
"Gimbal is disabled",
"You cannot change modifiers",
ToastType.SYSTEM,
ClientMain.CONFIG.config,
MinecraftClient.getInstance()
)
return return
} }
if (!MinecraftClient.getInstance().player!!.isCreative) if (!MinecraftClient.getInstance().player!!.isCreative)
return return
if (CURRENT_MODE.incompatibleModifiers.contains(mod)){ if (CURRENT_MODE.incompatibleModifiers.contains(mod)){
if (TEMP_DISABLED_MODIFIERS.contains(mod)) if (TEMP_DISABLED_MODIFIERS.contains(mod)) {
TEMP_DISABLED_MODIFIERS.remove(mod) TEMP_DISABLED_MODIFIERS.remove(mod)
else } else {
TEMP_DISABLED_MODIFIERS.add(mod) TEMP_DISABLED_MODIFIERS.add(mod)
}
} }
else { else {
if (CURRENT_MODE_MODIFIER.contains(mod)) if (CURRENT_MODE_MODIFIER.contains(mod)) {
CURRENT_MODE_MODIFIER.remove(mod) CURRENT_MODE_MODIFIER.remove(mod)
else ChatUtil.showToastToSelf(
"Disabled ${mod.displayName}",
"[${this.getDisplayNameListAsString(CURRENT_MODE_MODIFIER)}]",
ToastType.TOGGLE, ClientMain.CONFIG.config,
MinecraftClient.getInstance()
)
} else {
CURRENT_MODE_MODIFIER.add(mod) CURRENT_MODE_MODIFIER.add(mod)
ChatUtil.showToastToSelf(
"Enabled ${mod.displayName}",
"[${this.getDisplayNameListAsString(CURRENT_MODE_MODIFIER)}]",
ToastType.TOGGLE, ClientMain.CONFIG.config,
MinecraftClient.getInstance()
)
}
} }
onUpdated() onUpdated()
@ -199,14 +230,17 @@ object ClientEditor {
if(TEMP_DISABLED_MODIFIERS.isNotEmpty()) { if(TEMP_DISABLED_MODIFIERS.isNotEmpty()) {
ChatUtil.showToastToSelf( ChatUtil.showToastToSelf(
"${CURRENT_MODE.displayName} Mode disabled", "${CURRENT_MODE.displayName} Mode disabled",
getListAsString(TEMP_DISABLED_MODIFIERS), MinecraftClient.getInstance() getDisplayNameListAsString(TEMP_DISABLED_MODIFIERS),
ToastType.SYSTEM,
ClientMain.CONFIG.config,
MinecraftClient.getInstance()
) )
} }
} }
private fun getListAsString(list: List<ModeModifier>): String{ private fun getDisplayNameListAsString(list: List<ModeModifier>): String {
if(list.isEmpty()) if(list.isEmpty())
return "Empty list" return ""
val sb = StringBuilder() val sb = StringBuilder()
for (mod in list) { for (mod in list) {
sb.append(mod.displayName) sb.append(mod.displayName)
@ -215,25 +249,53 @@ object ClientEditor {
return sb.toString().dropLast(2) return sb.toString().dropLast(2)
} }
private fun getShortNameListAsString(list: List<ModeModifier>): String {
if (list.isEmpty())
return ""
val sb = StringBuilder()
for (mod in list) {
sb.append(mod.shortName)
sb.append(", ")
}
return sb.toString().dropLast(2)
}
/* /*
* Get the display text to display in the HUD * Get the display text to display in the HUD
* */ * */
fun getModeDisplayText(): Text { fun getModeDisplayText(config: GimbalClientConfig): Text {
val displayText = StringBuilder(CURRENT_MODE.displayName) val displayText = StringBuilder(CURRENT_MODE.displayName)
if (CURRENT_MODE_MODIFIER.isNotEmpty() && isAllowed() && MinecraftClient.getInstance().player?.isCreative == true) { if (isAllowed() && MinecraftClient.getInstance().player?.isCreative == true) {
displayText.append(" [") when (config.guiSettings.hudOptions) {
for (i in CURRENT_MODE_MODIFIER.indices) { HudOptions.ALL -> {
displayText.append(CURRENT_MODE_MODIFIER[i].displayName) if (CURRENT_MODE_MODIFIER.size > 0) {
if (i != CURRENT_MODE_MODIFIER.size - 1) { displayText.append(" [")
displayText.append(", ") displayText.append(this.getDisplayNameListAsString(CURRENT_MODE_MODIFIER))
displayText.append("]")
}
return Text.of(displayText.toString())
} }
HudOptions.NUMBER -> {
displayText.append(" (")
displayText.append(CURRENT_MODE_MODIFIER.size)
displayText.append(")")
return Text.of(displayText.toString())
}
HudOptions.INITIAL -> {
if (CURRENT_MODE_MODIFIER.size > 0) {
displayText.append(" [")
displayText.append(this.getShortNameListAsString(CURRENT_MODE_MODIFIER))
displayText.append("]")
}
return Text.of(displayText.toString())
}
HudOptions.ONLY_MODE -> return Text.of(displayText.toString())
} }
displayText.append("]")
} else if (!isAllowed() || !MinecraftClient.getInstance().player?.isCreative!!) {
displayText.clear()
displayText.append("[GIMBAL DISABLED]")
} }
return Text.of(displayText.toString()) return Text.of("[GIMBAL DISABLED]")
} }
fun getCurrentColor(): Int { fun getCurrentColor(): Int {

View file

@ -30,6 +30,7 @@ import net.moonleay.gimbal.client.keybindings.impl.editormodemodifier.ToggleNoUp
import net.moonleay.gimbal.client.keybindings.impl.gamemode.CreativeModeShortcut import net.moonleay.gimbal.client.keybindings.impl.gamemode.CreativeModeShortcut
import net.moonleay.gimbal.client.keybindings.impl.gamemode.SpectatorModeShortcut import net.moonleay.gimbal.client.keybindings.impl.gamemode.SpectatorModeShortcut
import net.moonleay.gimbal.client.keybindings.impl.gamemode.SurvivalModeShortcut import net.moonleay.gimbal.client.keybindings.impl.gamemode.SurvivalModeShortcut
import net.moonleay.gimbal.constants.TranslationKeys
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import org.lwjgl.glfw.GLFW import org.lwjgl.glfw.GLFW
@ -47,28 +48,28 @@ object KeybindingRegistrar {
private fun registerSetEditorModeModifierKeybindings() { private fun registerSetEditorModeModifierKeybindings() {
val toggleBulldozerModifierShortcut = KeyBinding( val toggleBulldozerModifierShortcut = KeyBinding(
"gimbal.key.editor.modifier.bulldozer", TranslationKeys.Keybindings.Binding.Editor.Modifier.BULLDOZER,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"gimbal.category.editormodifier" TranslationKeys.Keybindings.Category.Editor.MODIFIER
) )
val toggleForcePlaceModifierShortcut = KeyBinding( val toggleForcePlaceModifierShortcut = KeyBinding(
"gimbal.key.editor.modifier.forceplace", TranslationKeys.Keybindings.Binding.Editor.Modifier.FORCE_PLACE,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"gimbal.category.editormodifier" TranslationKeys.Keybindings.Category.Editor.MODIFIER
) )
val toggleNoUpdatesModifierShortcut = KeyBinding( val toggleNoUpdatesModifierShortcut = KeyBinding(
"gimbal.key.editor.modifier.noupdates", TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_UPDATES,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"gimbal.category.editormodifier" TranslationKeys.Keybindings.Category.Editor.MODIFIER
) )
val toggleNoClipModifierShortcut = KeyBinding( val toggleNoClipModifierShortcut = KeyBinding(
"gimbal.key.editor.modifier.noclip", TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_CLIP,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"gimbal.category.editormodifier" TranslationKeys.Keybindings.Category.Editor.MODIFIER
) )
KeybindingManager.registerShortcut(ToggleBulldozerModifierShortcut(toggleBulldozerModifierShortcut)) KeybindingManager.registerShortcut(ToggleBulldozerModifierShortcut(toggleBulldozerModifierShortcut))
@ -79,16 +80,16 @@ object KeybindingRegistrar {
private fun registerSetEditorModeKeybindings() { private fun registerSetEditorModeKeybindings() {
val insertKeyBinding = KeyBinding( val insertKeyBinding = KeyBinding(
"gimbal.key.editor.mode.insert", TranslationKeys.Keybindings.Binding.Editor.Mode.INSERT,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_I, GLFW.GLFW_KEY_I,
"gimbal.category.editormode" TranslationKeys.Keybindings.Category.Editor.MODE
) )
val replaceKeyBinding = KeyBinding( val replaceKeyBinding = KeyBinding(
"gimbal.key.editor.mode.replace", TranslationKeys.Keybindings.Binding.Editor.Mode.REPLACE,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_R, GLFW.GLFW_KEY_R,
"gimbal.category.editormode" TranslationKeys.Keybindings.Category.Editor.MODE
) )
// val visualKeyBinding = KeyBinding( // val visualKeyBinding = KeyBinding(
// "gimbal.key.editor.mode.visual", // "gimbal.key.editor.mode.visual",
@ -103,22 +104,22 @@ object KeybindingRegistrar {
private fun registerSetGameModeKeybindings() { private fun registerSetGameModeKeybindings() {
val survivalKeyBinding = KeyBinding( val survivalKeyBinding = KeyBinding(
"gimbal.key.game.mode.survival", TranslationKeys.Keybindings.Binding.Game.Mode.SURVIVAL,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"gimbal.category.gamemode" TranslationKeys.Keybindings.Category.Game.GAMEMODE
) )
val creativeKeyBinding = KeyBinding( val creativeKeyBinding = KeyBinding(
"gimbal.key.game.mode.creative", TranslationKeys.Keybindings.Binding.Game.Mode.CREATIVE,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"gimbal.category.gamemode" TranslationKeys.Keybindings.Category.Game.GAMEMODE
) )
val spectatorKeyBinding = KeyBinding( val spectatorKeyBinding = KeyBinding(
"gimbal.key.game.mode.spectator", TranslationKeys.Keybindings.Binding.Game.Mode.SPECTATOR,
InputUtil.Type.KEYSYM, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"gimbal.category.gamemode" TranslationKeys.Keybindings.Category.Game.GAMEMODE
) )
KeybindingManager.registerShortcut(SurvivalModeShortcut(survivalKeyBinding)) KeybindingManager.registerShortcut(SurvivalModeShortcut(survivalKeyBinding))
KeybindingManager.registerShortcut(CreativeModeShortcut(creativeKeyBinding)) KeybindingManager.registerShortcut(CreativeModeShortcut(creativeKeyBinding))

View file

@ -29,10 +29,11 @@ import net.moonleay.gimbal.client.config.GimbalClientConfig
import net.moonleay.gimbal.client.config.GimbalGuiSettings import net.moonleay.gimbal.client.config.GimbalGuiSettings
import net.moonleay.gimbal.client.config.ScaledRes import net.moonleay.gimbal.client.config.ScaledRes
import net.moonleay.gimbal.client.util.screen.ScreenUtil import net.moonleay.gimbal.client.util.screen.ScreenUtil
import net.moonleay.gimbal.constants.TranslationKeys
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfigHolder) : class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfigHolder) :
Screen(Text.translatable("gimbal.gui.edithud")) { Screen(Text.translatable(TranslationKeys.Gui.Config.Hud.EDIT_HUD)) {
private val LOGGER = LogManager.getLogger(BuildConstants.modName) private val LOGGER = LogManager.getLogger(BuildConstants.modName)
private var tempXOffset = 4.0 private var tempXOffset = 4.0
@ -47,7 +48,7 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
override fun init() { override fun init() {
super.init() super.init()
this.addDrawableChild(ButtonWidget( this.addDrawableChild(ButtonWidget(
this.width / 2 + 10, this.height - 27, 90, 20, Text.translatable("gimbal.gui.resethud") this.width / 2 + 10, this.height - 27, 90, 20, Text.translatable(TranslationKeys.Gui.Config.Hud.RESET_HUD)
) { _: ButtonWidget? -> ) { _: ButtonWidget? ->
tempXOffset = 4.0 tempXOffset = 4.0
tempYOffset = 4.0 tempYOffset = 4.0
@ -75,7 +76,6 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset) val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset)
val newConf = GimbalClientConfig( val newConf = GimbalClientConfig(
showToasts = oldConf.showToasts,
guiSettings = GimbalGuiSettings( guiSettings = GimbalGuiSettings(
showHud = oldConf.guiSettings.showHud, showHud = oldConf.guiSettings.showHud,
offset = ScaledRes( offset = ScaledRes(
@ -83,8 +83,10 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
scaledY = this.tempYOffset, scaledY = this.tempYOffset,
), ),
horizontalAnchor = anchor.first, horizontalAnchor = anchor.first,
verticalAnchor = anchor.second verticalAnchor = anchor.second,
) hudOptions = oldConf.guiSettings.hudOptions
),
toastSettings = oldConf.toastSettings
) )
cfg.updateConfig(newConf) cfg.updateConfig(newConf)
@ -104,8 +106,6 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
if (!ScreenUtil.isPositionOutOfBounds(wantedX, wantedY)) { if (!ScreenUtil.isPositionOutOfBounds(wantedX, wantedY)) {
this.tempXOffset = wantedX this.tempXOffset = wantedX
this.tempYOffset = wantedY this.tempYOffset = wantedY
} else {
LOGGER.info("Text is oob. wantedX: ${wantedX}, wantedY: ${wantedY}, width: ${this.client!!.window.width}, height: ${this.client!!.window.height}")
} }
} }
} }
@ -130,11 +130,11 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset) val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset)
this.textRenderer.drawWithShadow( this.textRenderer.drawWithShadow(
matrices, matrices,
Text.translatable("gimbal.gui.examplehud"), Text.translatable(TranslationKeys.Gui.Config.Hud.EXAMPLE_HUD_TEXT),
ScreenUtil.getXForAnchor( ScreenUtil.getXForAnchor(
ScreenUtil.getReal(this.client!!.window.width, this.tempXOffset) / scaleFactor, ScreenUtil.getReal(this.client!!.window.width, this.tempXOffset) / scaleFactor,
anchor.first, anchor.first,
this.textRenderer.getWidth(Text.translatable("gimbal.gui.examplehud")) this.textRenderer.getWidth(Text.translatable(TranslationKeys.Gui.Config.Hud.EXAMPLE_HUD_TEXT))
), ),
ScreenUtil.getYForAnchor( ScreenUtil.getYForAnchor(
ScreenUtil.getReal(this.client!!.window.height, this.tempYOffset) / scaleFactor, ScreenUtil.getReal(this.client!!.window.height, this.tempYOffset) / scaleFactor,
@ -142,11 +142,7 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
this.textRenderer.fontHeight this.textRenderer.fontHeight
), ),
0xFFFFFF 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) super.render(matrices, mouseX, mouseY, delta)
} }
} }

View file

@ -27,9 +27,21 @@ import net.minecraft.text.Text
import net.moonleay.gimbal.client.config.ClientConfigHolder import net.moonleay.gimbal.client.config.ClientConfigHolder
import net.moonleay.gimbal.client.config.GimbalClientConfig import net.moonleay.gimbal.client.config.GimbalClientConfig
import net.moonleay.gimbal.client.config.GimbalGuiSettings import net.moonleay.gimbal.client.config.GimbalGuiSettings
import net.moonleay.gimbal.client.config.enums.HudOptions
import net.moonleay.gimbal.client.config.enums.ToastSettings
import net.moonleay.gimbal.constants.TranslationKeys
class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfigHolder) : class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfigHolder) :
Screen(Text.translatable("gimbal.gui.settings")) { Screen(Text.translatable(TranslationKeys.Gui.Config.SCREEN_NAME)) {
private var hudOptions: HudOptions
private var toastSettings: ToastSettings
init {
this.hudOptions = cfg.config.guiSettings.hudOptions
this.toastSettings = cfg.config.toastSettings
}
override fun init() { override fun init() {
this.addDrawableChild(CyclingButtonWidget.onOffBuilder( this.addDrawableChild(CyclingButtonWidget.onOffBuilder(
// Text.translatable("gimbal.gui.enabled"), // Text.translatable("gimbal.gui.enabled"),
@ -41,7 +53,7 @@ class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfi
this.height / 6 + 24 * 0, this.height / 6 + 24 * 0,
150, 150,
20, 20,
Text.translatable("gimbal.gui.hud") Text.translatable(TranslationKeys.Gui.Config.Hud.SHOW_HUD)
) { _: CyclingButtonWidget<Boolean?>?, isEnabled: Boolean? -> ) { _: CyclingButtonWidget<Boolean?>?, isEnabled: Boolean? ->
val oldGui = cfg.config.guiSettings val oldGui = cfg.config.guiSettings
val newGui = GimbalGuiSettings( val newGui = GimbalGuiSettings(
@ -49,24 +61,120 @@ class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfi
offset = oldGui.offset, offset = oldGui.offset,
horizontalAnchor = oldGui.horizontalAnchor, horizontalAnchor = oldGui.horizontalAnchor,
verticalAnchor = oldGui.verticalAnchor, verticalAnchor = oldGui.verticalAnchor,
hudOptions = oldGui.hudOptions
) )
val newConf = GimbalClientConfig( val newConf = GimbalClientConfig(
guiSettings = newGui, guiSettings = newGui,
showToasts = cfg.config.showToasts toastSettings = cfg.config.toastSettings
) )
cfg.updateConfig(newConf) cfg.updateConfig(newConf)
}) })
this.addDrawableChild(ButtonWidget( this.addDrawableChild(ButtonWidget(
this.width / 2 - 155 + 160, this.width / 2 - 155 + 160,
this.height / 6 + 24 * 0, this.height / 6 + 24 * 0,
150, 150,
20, 20,
Text.translatable("gimbal.gui.edithud") Text.translatable(TranslationKeys.Gui.Config.Hud.EDIT_HUD)
) { _: ButtonWidget? -> ) { _: ButtonWidget? ->
this.client!!.setScreen(GimbalEditHudGui(this, cfg)) this.client!!.setScreen(GimbalEditHudGui(this, cfg))
} })
this.addDrawableChild<CyclingButtonWidget<HudOptions>>(
CyclingButtonWidget.builder<HudOptions> { value: HudOptions? ->
when (value) {
HudOptions.ALL -> {
return@builder HudOptions.ALL.translatableText
}
HudOptions.NUMBER -> {
return@builder HudOptions.NUMBER.translatableText
}
HudOptions.INITIAL -> {
return@builder HudOptions.INITIAL.translatableText
}
HudOptions.ONLY_MODE -> {
return@builder HudOptions.ONLY_MODE.translatableText
}
else -> return@builder Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_ALL)
}
}
.values(HudOptions.entries)
.initially(this.hudOptions)
.build(
this.width / 2 - 155,
this.height / 6 + 24 * 1,
150,
20,
Text.translatable(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODIFIERS)
) { _: CyclingButtonWidget<HudOptions>?, hudDO: HudOptions ->
this.hudOptions = hudDO
val oldConfig = cfg.config
val oldGuiConfig = oldConfig.guiSettings
val newConfig = GimbalClientConfig(
guiSettings = GimbalGuiSettings(
horizontalAnchor = oldGuiConfig.horizontalAnchor,
verticalAnchor = oldGuiConfig.verticalAnchor,
showHud = oldGuiConfig.showHud,
offset = oldGuiConfig.offset,
hudOptions = this.hudOptions
),
toastSettings = oldConfig.toastSettings
)
cfg.updateConfig(newConfig)
}
) )
this.addDrawableChild<CyclingButtonWidget<ToastSettings>>(
CyclingButtonWidget.builder<ToastSettings> { value: ToastSettings? ->
when (value) {
ToastSettings.ALL -> {
return@builder ToastSettings.ALL.translatableText
}
ToastSettings.ONLY_TOGGLE -> {
return@builder ToastSettings.ONLY_TOGGLE.translatableText
}
ToastSettings.ONLY_SYSTEM -> {
return@builder ToastSettings.ONLY_SYSTEM.translatableText
}
ToastSettings.NONE -> {
return@builder ToastSettings.NONE.translatableText
}
else -> return@builder Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_ALL)
}
}
.values(ToastSettings.entries)
.initially(this.toastSettings)
.build(
this.width / 2 - 155 + 160,
this.height / 6 + 24 * 1,
150,
20,
Text.translatable(TranslationKeys.Gui.Config.Toasts.SHOW_TOASTS)
) { _: CyclingButtonWidget<ToastSettings>?, toastStng: ToastSettings ->
this.toastSettings = toastStng
val oldConfig = cfg.config
val newConfig = GimbalClientConfig(
guiSettings = oldConfig.guiSettings,
toastSettings = this.toastSettings
)
cfg.updateConfig(newConfig)
}
)
// Done button // Done button
this.addDrawableChild(ButtonWidget( this.addDrawableChild(ButtonWidget(
this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE

View file

@ -21,6 +21,7 @@ package net.moonleay.gimbal.client.util
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.toast.SystemToast import net.minecraft.client.toast.SystemToast
import net.minecraft.text.Text import net.minecraft.text.Text
import net.moonleay.gimbal.client.config.GimbalClientConfig
object ChatUtil { object ChatUtil {
/** /**
@ -37,7 +38,16 @@ object ChatUtil {
client.inGameHud.chatHud.addMessage(Text.of(message)) client.inGameHud.chatHud.addMessage(Text.of(message))
} }
fun showToastToSelf(title: String, description: String, client: MinecraftClient) { fun showToastToSelf(
title: String,
description: String,
type: ToastType,
config: GimbalClientConfig,
client: MinecraftClient,
) {
if (!config.toastSettings.allowedTypes.contains(type))
return
val toast = SystemToast(SystemToast.Type.PERIODIC_NOTIFICATION, Text.of(title), Text.of(description)) val toast = SystemToast(SystemToast.Type.PERIODIC_NOTIFICATION, Text.of(title), Text.of(description))
client.toastManager.add(toast) client.toastManager.add(toast)
} }

View file

@ -0,0 +1,24 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.moonleay.gimbal.client.util
enum class ToastType {
TOGGLE,
SYSTEM,
}

View file

@ -18,8 +18,8 @@
package net.moonleay.gimbal.client.util.screen package net.moonleay.gimbal.client.util.screen
import net.moonleay.gimbal.client.config.HorizontalAnchor import net.moonleay.gimbal.client.config.enums.HorizontalAnchor
import net.moonleay.gimbal.client.config.VerticalAnchor import net.moonleay.gimbal.client.config.enums.VerticalAnchor
object ScreenUtil { object ScreenUtil {

View file

@ -0,0 +1,123 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.moonleay.gimbal.constants
import net.moonleay.gimbal.build.BuildConstants
object TranslationKeys {
object Gui {
const val BASE = "gui.${BuildConstants.modId}."
object Config {
const val BASE = "${TranslationKeys.Gui.BASE}conf."
const val SCREEN_NAME = "${BASE}settings"
const val GENERIC_ENABLED = "${BASE}enabled"
const val GENERIC_DISABLED = "${BASE}disabled"
object Hud {
const val BASE = "${TranslationKeys.Gui.Config.BASE}hud."
const val SHOW_HUD = "${BASE}show"
const val EDIT_HUD = "${BASE}edit"
const val RESET_HUD = "${BASE}reset"
const val EXAMPLE_HUD_TEXT = "${BASE}example"
object Modifiers {
const val BASE = "${TranslationKeys.Gui.Config.Hud.BASE}modifiers."
const val SHOW_MODIFIERS = "${BASE}show"
const val SHOW_ALL = "${BASE}all"
const val SHOW_NUMBER = "${BASE}number"
const val SHOW_INITIALS = "${BASE}initials"
const val SHOW_MODE_ONLY = "${BASE}modeOnly"
}
}
object Toasts {
const val BASE = "${TranslationKeys.Gui.Config.BASE}toasts."
const val SHOW_TOASTS = "${BASE}show"
const val SHOW_ALL = "${BASE}all"
const val SHOW_TOGGLE = "${BASE}toggle"
const val SHOW_SYSTEM = "${BASE}system"
const val SHOW_NONE = "${BASE}none"
}
}
}
object Keybindings {
// No base here, Categories and Bindings have separate BASEs
object Category {
const val BASE = "category.${BuildConstants.modId}."
object Editor {
const val BASE = "${TranslationKeys.Keybindings.Category.BASE}editor."
const val MODE = "${BASE}mode"
const val MODIFIER = "${BASE}modifier"
}
object Game {
const val BASE = "${TranslationKeys.Keybindings.Category.BASE}game."
const val GAMEMODE = "${BASE}mode"
}
}
object Binding {
const val BASE = "key.${BuildConstants.modId}."
object Editor {
const val BASE = "${TranslationKeys.Keybindings.Binding.BASE}editor."
object Mode {
const val BASE = "${TranslationKeys.Keybindings.Binding.Editor.BASE}mode."
const val INSERT = "${BASE}insert"
const val REPLACE = "${BASE}replace"
const val VISUAL = "${BASE}visual"
}
object Modifier {
const val BASE = "${TranslationKeys.Keybindings.Binding.Editor.BASE}modifier."
const val BULLDOZER = "${BASE}autoClicker"
const val FORCE_PLACE = "${BASE}forcePlace"
const val NO_UPDATES = "${BASE}noUpdates"
const val NO_CLIP = "${BASE}noClip"
}
}
object Game {
const val BASE = "${TranslationKeys.Keybindings.Binding.BASE}game."
object Mode {
const val BASE = "${TranslationKeys.Keybindings.Binding.Game.BASE}mode."
const val SURVIVAL = "${BASE}survival"
const val CREATIVE = "${BASE}creative"
const val SPECTATOR = "${BASE}spectator"
}
}
}
}
}

View file

@ -20,6 +20,7 @@ package net.moonleay.gimbal.datagen
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider
import net.moonleay.gimbal.constants.TranslationKeys
class En_us_GimbalLanguageProvider(dataGenerator: FabricDataGenerator?) : class En_us_GimbalLanguageProvider(dataGenerator: FabricDataGenerator?) :
FabricLanguageProvider(dataGenerator, "en_us") { FabricLanguageProvider(dataGenerator, "en_us") {
@ -28,35 +29,63 @@ class En_us_GimbalLanguageProvider(dataGenerator: FabricDataGenerator?) :
if (translationBuilder == null) return if (translationBuilder == null) return
/// Screens /// Screens
// Gimbal settings screen // Gimbal settings screen
translationBuilder.add("gimbal.gui.settings", "Gimbal Settings") translationBuilder.add(TranslationKeys.Gui.Config.SCREEN_NAME, "Gimbal Settings")
translationBuilder.add("gimbal.gui.hud", "Show HUD")
translationBuilder.add("gimbal.gui.edithud", "Edit HUD Layout...") // Hud
translationBuilder.add("gimbal.gui.resethud", "Reset Layout") translationBuilder.add(TranslationKeys.Gui.Config.Hud.SHOW_HUD, "Show HUD")
translationBuilder.add("gimbal.gui.examplehud", "EXAMPLE [No Clip, Force]")
translationBuilder.add("gimbal.gui.enabled", "Enabled") //Gimbal HUD pos edit
translationBuilder.add("gimbal.gui.disabled", "Disabled") translationBuilder.add(TranslationKeys.Gui.Config.Hud.EDIT_HUD, "Edit HUD Layout...")
translationBuilder.add(TranslationKeys.Gui.Config.Hud.RESET_HUD, "Reset Layout")
translationBuilder.add(TranslationKeys.Gui.Config.Hud.EXAMPLE_HUD_TEXT, "EXAMPLE [No Clip, Force]")
//Gimbal HUD Content
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODIFIERS, "Show Modifiers")
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_ALL, "All")
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_NUMBER, "Number")
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_INITIALS, "Short")
translationBuilder.add(TranslationKeys.Gui.Config.Hud.Modifiers.SHOW_MODE_ONLY, "None")
//Gimbal Toasts
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_TOASTS, "Show Toasts")
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_ALL, "All")
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_TOGGLE, "Only toggle")
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_SYSTEM, "Only system")
translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_NONE, "None")
// Gimbal Generic Gui
translationBuilder.add(TranslationKeys.Gui.Config.GENERIC_ENABLED, "Enabled")
translationBuilder.add(TranslationKeys.Gui.Config.GENERIC_DISABLED, "Disabled")
/// Options /// Options
// Editor modes // Editor modes
translationBuilder.add("gimbal.category.editormode", "Editor Modes") translationBuilder.add(TranslationKeys.Keybindings.Category.Editor.MODE, "Editor Modes")
translationBuilder.add("gimbal.key.editor.mode.insert", "Enter Insert Mode") translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Mode.INSERT, "Enter Insert Mode")
translationBuilder.add("gimbal.key.editor.mode.replace", "Enter Replace Mode") translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Mode.REPLACE, "Enter Replace Mode")
translationBuilder.add("gimbal.key.editor.mode.visual", "Enter Visual Mode") translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Mode.VISUAL, "Enter Visual Mode")
// Editor mode modifiers // Editor mode modifiers
translationBuilder.add("gimbal.category.editormodifier", "Editor Mode Modifiers") translationBuilder.add(TranslationKeys.Keybindings.Category.Editor.MODIFIER, "Editor Mode Modifiers")
translationBuilder.add("gimbal.key.editor.modifier.bulldozer", "Toggle Bulldozer Modifier") translationBuilder.add(
translationBuilder.add("gimbal.key.editor.modifier.forceplace", "Toggle Force Place Modifier") TranslationKeys.Keybindings.Binding.Editor.Modifier.BULLDOZER,
translationBuilder.add("gimbal.key.editor.modifier.noupdates", "Toggle No Updates Modifier") "Toggle Bulldozer Modifier"
translationBuilder.add("gimbal.key.editor.modifier.noclip", "Toggle No Clip Modifier") )
translationBuilder.add(
TranslationKeys.Keybindings.Binding.Editor.Modifier.FORCE_PLACE,
"Toggle Force Place Modifier"
)
translationBuilder.add(
TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_UPDATES,
"Toggle No Updates Modifier"
)
translationBuilder.add(TranslationKeys.Keybindings.Binding.Editor.Modifier.NO_CLIP, "Toggle No Clip Modifier")
// Game mode // Game mode
translationBuilder.add("gimbal.category.gamemode", "Game Mode") translationBuilder.add(TranslationKeys.Keybindings.Category.Game.GAMEMODE, "Game Mode")
translationBuilder.add("gimbal.key.game.mode.survival", "Enable Survival Mode") translationBuilder.add(TranslationKeys.Keybindings.Binding.Game.Mode.SURVIVAL, "Enable Survival Mode")
translationBuilder.add("gimbal.key.game.mode.creative", "Enable Creative Mode") translationBuilder.add(TranslationKeys.Keybindings.Binding.Game.Mode.CREATIVE, "Enable Creative Mode")
translationBuilder.add("gimbal.key.game.mode.spectator", "Enable Spectator Mode") translationBuilder.add(TranslationKeys.Keybindings.Binding.Game.Mode.SPECTATOR, "Enable Spectator Mode")
} }
} }

View file

@ -18,10 +18,10 @@
package net.moonleay.gimbal.editor.state.mode package net.moonleay.gimbal.editor.state.mode
enum class ModeModifier(val displayName: String) { enum class ModeModifier(val displayName: String, val shortName: String) {
// NONE("None"), // No Modifiers - default behavior // NONE("None"), // No Modifiers - default behavior
NO_UPDATES("NO UPDATES"), // Do not update blocks when placing NO_UPDATES("NO UPDATES", "NU"), // Do not update blocks when placing
BULLDOZER("BULLDOZER"), // Break blocks fast BULLDOZER("BULLDOZER", "BLR"), // Break blocks fast
FORCE_PLACE("FORCE"), // Ignore block placement restrictions FORCE_PLACE("FORCE", "FP"), // Ignore block placement restrictions
NO_CLIP("NO CLIP"), // Do not collide with blocks NO_CLIP("NO CLIP", "NC"), // Do not collide with blocks
} }

View file

@ -50,7 +50,7 @@ public abstract class HudMixin {
this.client.options.getGuiScale().getValue(), this.client.options.getGuiScale().getValue(),
this.client.forcesUnicodeFont() this.client.forcesUnicodeFont()
); );
Text displayText = ClientEditor.INSTANCE.getModeDisplayText(); Text displayText = ClientEditor.INSTANCE.getModeDisplayText(ClientMain.CONFIG.getConfig());
tr.drawWithShadow( tr.drawWithShadow(
matrices, matrices,
displayText, displayText,

View file

@ -26,6 +26,7 @@ import net.minecraft.util.Identifier;
import net.moonleay.gimbal.build.BuildConstants; import net.moonleay.gimbal.build.BuildConstants;
import net.moonleay.gimbal.client.ClientMain; import net.moonleay.gimbal.client.ClientMain;
import net.moonleay.gimbal.client.screen.GimbalSettingsGui; import net.moonleay.gimbal.client.screen.GimbalSettingsGui;
import net.moonleay.gimbal.constants.TranslationKeys;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -59,7 +60,7 @@ public class YouInjectButtonMixin extends Screen {
20, 20,
40, 40,
button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)), button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)),
Text.translatable("gimbal.gui.settings") Text.translatable(TranslationKeys.Gui.Config.SCREEN_NAME)
) )
); );
} }

View file

@ -26,6 +26,7 @@ import net.minecraft.util.Identifier;
import net.moonleay.gimbal.build.BuildConstants; import net.moonleay.gimbal.build.BuildConstants;
import net.moonleay.gimbal.client.ClientMain; import net.moonleay.gimbal.client.ClientMain;
import net.moonleay.gimbal.client.screen.GimbalSettingsGui; import net.moonleay.gimbal.client.screen.GimbalSettingsGui;
import net.moonleay.gimbal.constants.TranslationKeys;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -58,7 +59,7 @@ public class YouInjectButtonMixin2 extends Screen {
20, 20,
40, 40,
button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)), button -> this.client.setScreen(new GimbalSettingsGui(this, ClientMain.CONFIG)),
Text.translatable("gimbal.gui.settings") Text.translatable(TranslationKeys.Gui.Config.SCREEN_NAME)
) )
); );
} }