diff --git a/src/main/java/net/moonleay/gimbal/client/ClientMain.kt b/src/main/java/net/moonleay/gimbal/client/ClientMain.kt index 2af8b59..d3f1823 100644 --- a/src/main/java/net/moonleay/gimbal/client/ClientMain.kt +++ b/src/main/java/net/moonleay/gimbal/client/ClientMain.kt @@ -46,6 +46,9 @@ internal object ClientMain : ClientModInitializer { val gimbalConfigPath = FabricLoader.getInstance().configDir.resolve(BuildConstants.modId + "/client.json") CONFIG = ClientConfigHolder(gimbalConfigPath) LOGGER.info("Config has been loaded.") + LOGGER.info("Applying Config to client.") + ClientEditor.applyConfig(CONFIG.config) + LOGGER.info("Config has been applied.") LOGGER.info("Gimbal has been initialized on the client side.") } diff --git a/src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt b/src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt index 0b7769e..4ad504d 100644 --- a/src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt +++ b/src/main/java/net/moonleay/gimbal/client/config/ClientConfigHolder.kt @@ -22,6 +22,7 @@ import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.encodeToStream +import net.moonleay.gimbal.client.editor.ClientEditor import java.nio.file.Path import kotlin.io.path.* @@ -36,6 +37,7 @@ class ClientConfigHolder(private val path: Path) { fun updateConfig(new: GimbalClientConfig) { this.config = new this.save(config) + ClientEditor.applyConfig(config) } @OptIn(ExperimentalSerializationApi::class) diff --git a/src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt b/src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt index f673f28..5fd641c 100644 --- a/src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt +++ b/src/main/java/net/moonleay/gimbal/client/config/GimbalClientConfig.kt @@ -20,9 +20,13 @@ package net.moonleay.gimbal.client.config import kotlinx.serialization.Serializable import net.moonleay.gimbal.client.config.enums.ToastSettings +import net.moonleay.gimbal.editor.state.mode.Mode @Serializable data class GimbalClientConfig( val guiSettings: GimbalGuiSettings = GimbalGuiSettings(), val toastSettings: ToastSettings = ToastSettings.ALL, + val playerFlySpeed: Int = 100, + val shouldEscResetMode: Boolean = true, + val defaultMode: Mode = Mode.NORMAL ) diff --git a/src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt b/src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt index acf9a70..40d04aa 100644 --- a/src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt +++ b/src/main/java/net/moonleay/gimbal/client/config/ScaledRes.kt @@ -22,6 +22,6 @@ import kotlinx.serialization.Serializable @Serializable data class ScaledRes( - val scaledX: Double, - val scaledY: Double, + val scaledX: Double, // offsetX + val scaledY: Double, // offsetY ) diff --git a/src/main/java/net/moonleay/gimbal/client/editor/ClientEditor.kt b/src/main/java/net/moonleay/gimbal/client/editor/ClientEditor.kt index 2982db4..42d54c4 100644 --- a/src/main/java/net/moonleay/gimbal/client/editor/ClientEditor.kt +++ b/src/main/java/net/moonleay/gimbal/client/editor/ClientEditor.kt @@ -40,17 +40,25 @@ import org.apache.logging.log4j.LogManager object ClientEditor { private var POLICY = GimbalPolicyType.NOT_PRESENT - private var CURRENT_MODE = Mode.NORMAL + private lateinit var CURRENT_MODE: Mode private var TEMP_DISABLED_MODE = Mode.UNKNOWN private val CURRENT_MODE_MODIFIER = mutableListOf() private val TEMP_DISABLED_MODIFIERS = mutableListOf() - private val DISABLED_MODIFIERS_STORAGE = mutableListOf() private val LOGGER = LogManager.getLogger(BuildConstants.modName) + fun applyConfig(config: GimbalClientConfig, isBoot: Boolean = true) { + if (isBoot) { + this.CURRENT_MODE = config.defaultMode + return + } + if (!config.shouldEscResetMode) return + this.CURRENT_MODE = config.defaultMode + onUpdated() + } fun onConnectedToNewWorld() { POLICY = GimbalPolicyType.NOT_PRESENT @@ -107,7 +115,7 @@ object ClientEditor { } fun isInNonDefaultMode(): Boolean { - return CURRENT_MODE != Mode.NORMAL + return CURRENT_MODE != ClientMain.CONFIG.config.defaultMode } /* diff --git a/src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt b/src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt index b7682d7..0155e35 100644 --- a/src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt +++ b/src/main/java/net/moonleay/gimbal/client/screen/GimbalEditHudGui.kt @@ -86,7 +86,10 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig verticalAnchor = anchor.second, hudOptions = oldConf.guiSettings.hudOptions ), - toastSettings = oldConf.toastSettings + toastSettings = oldConf.toastSettings, + playerFlySpeed = oldConf.playerFlySpeed, + shouldEscResetMode = oldConf.shouldEscResetMode, + defaultMode = oldConf.defaultMode ) cfg.updateConfig(newConf) diff --git a/src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt b/src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt index c2cd5c0..4e11df4 100644 --- a/src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt +++ b/src/main/java/net/moonleay/gimbal/client/screen/GimbalSettingsGui.kt @@ -29,17 +29,24 @@ import net.moonleay.gimbal.client.config.GimbalClientConfig 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.client.screen.widgets.GimbalSliderWidget +import net.moonleay.gimbal.client.util.NumberUtil import net.moonleay.gimbal.constants.TranslationKeys +import net.moonleay.gimbal.editor.state.mode.Mode class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfigHolder) : Screen(Text.translatable(TranslationKeys.Gui.Config.SCREEN_NAME)) { private var hudOptions: HudOptions private var toastSettings: ToastSettings + private var playerFlySpeed: Int + private var defaultMode: Mode init { this.hudOptions = cfg.config.guiSettings.hudOptions this.toastSettings = cfg.config.toastSettings + this.playerFlySpeed = cfg.config.playerFlySpeed + this.defaultMode = cfg.config.defaultMode } override fun init() { @@ -65,7 +72,10 @@ class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfi ) val newConf = GimbalClientConfig( guiSettings = newGui, - toastSettings = cfg.config.toastSettings + toastSettings = cfg.config.toastSettings, + playerFlySpeed = cfg.config.playerFlySpeed, + shouldEscResetMode = cfg.config.shouldEscResetMode, + defaultMode = cfg.config.defaultMode ) cfg.updateConfig(newConf) }) @@ -123,7 +133,10 @@ class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfi offset = oldGuiConfig.offset, hudOptions = this.hudOptions ), - toastSettings = oldConfig.toastSettings + toastSettings = oldConfig.toastSettings, + playerFlySpeed = oldConfig.playerFlySpeed, + shouldEscResetMode = oldConfig.shouldEscResetMode, + defaultMode = oldConfig.defaultMode ) cfg.updateConfig(newConfig) } @@ -166,15 +179,99 @@ class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfi val oldConfig = cfg.config val newConfig = GimbalClientConfig( guiSettings = oldConfig.guiSettings, - toastSettings = this.toastSettings + toastSettings = this.toastSettings, + playerFlySpeed = oldConfig.playerFlySpeed, + shouldEscResetMode = oldConfig.shouldEscResetMode, + defaultMode = oldConfig.defaultMode ) cfg.updateConfig(newConfig) } ) + this.addDrawableChild(GimbalSliderWidget( + this.width / 2 - 155, + this.height / 6 + 24 * 2, + 150, + 20, + Text.translatable(TranslationKeys.Gui.Config.PLAYER_FLY_SPEED), + NumberUtil.linearInterpolate(this.playerFlySpeed.toDouble(), 100.0, 1000.0, 0.0, 1.0), + 100.0, + 1000.0, + ) { value -> + this.playerFlySpeed = NumberUtil.linearInterpolate(value, 0.0, 1.0, 100.0, 1000.0).toInt() + + if (client!!.player != null && client!!.player!!.isCreative) { + client!!.player!!.abilities.flySpeed = (this.playerFlySpeed / 100) * 0.05f + } + + val oldConfig = cfg.config + val newConfig = GimbalClientConfig( + guiSettings = oldConfig.guiSettings, + toastSettings = this.toastSettings, + playerFlySpeed = this.playerFlySpeed, + shouldEscResetMode = oldConfig.shouldEscResetMode, + defaultMode = oldConfig.defaultMode + ) + cfg.updateConfig(newConfig) + }) + + this.addDrawableChild(CyclingButtonWidget.onOffBuilder() + .initially(cfg.config.shouldEscResetMode) + .build( + this.width / 2 - 155, + this.height / 6 + 24 * 3, + 150, + 20, + Text.translatable(TranslationKeys.Gui.Config.SHOULD_ESC_RESET_MODE) + ) { _: CyclingButtonWidget?, isEnabled: Boolean? -> + val newConf = GimbalClientConfig( + guiSettings = cfg.config.guiSettings, + toastSettings = cfg.config.toastSettings, + playerFlySpeed = cfg.config.playerFlySpeed, + shouldEscResetMode = isEnabled?: true, + defaultMode = cfg.config.defaultMode + ) + cfg.updateConfig(newConf) + }) + this.addDrawableChild>( + CyclingButtonWidget.builder { value: Mode? -> + if (value == null) { + return@builder Text.literal(Mode.UNKNOWN.displayName) + } + return@builder Text.literal(value.displayName) + } + .values(Mode.entries) + .initially(this.defaultMode) + .build( + this.width / 2 - 155 + 160, + this.height / 6 + 24 * 3, + 150, + 20, + Text.translatable(TranslationKeys.Gui.Config.DEFAULT_MODE) + ) { b: CyclingButtonWidget?, requestedMode: Mode -> + if (requestedMode.hidden){ + b!!.value = Mode.NORMAL + this.defaultMode = Mode.NORMAL + } + else { + this.defaultMode = requestedMode + } + + val oldConfig = cfg.config + val newConfig = GimbalClientConfig( + guiSettings = oldConfig.guiSettings, + toastSettings = oldConfig.toastSettings, + playerFlySpeed = oldConfig.playerFlySpeed, + shouldEscResetMode = oldConfig.shouldEscResetMode, + defaultMode = this.defaultMode + ) + cfg.updateConfig(newConfig) + } + ) + // Done button this.addDrawableChild(ButtonWidget( this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE diff --git a/src/main/java/net/moonleay/gimbal/client/screen/widgets/GimbalSliderWidget.kt b/src/main/java/net/moonleay/gimbal/client/screen/widgets/GimbalSliderWidget.kt new file mode 100644 index 0000000..c244615 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/screen/widgets/GimbalSliderWidget.kt @@ -0,0 +1,50 @@ +/* + * 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.widgets + +import net.minecraft.client.gui.widget.SliderWidget +import net.minecraft.text.Text +import net.moonleay.gimbal.client.util.NumberUtil + +class GimbalSliderWidget( + x: Int, + y: Int, + width: Int, + height: Int, + private val text: Text, + value: Double, + private val lowerEnd: Double, + private val upperEnd: Double, + private val setValue: (Double) -> Unit, +) : + SliderWidget(x, y, width, height, text, value) { + init { + this.message = this.text.copy() + .append(": " + (NumberUtil.linearInterpolate(this.value, 0.0, 1.0, this.lowerEnd, this.upperEnd).toInt())) + } + + override fun updateMessage() { + this.message = this.text.copy() + .append(": " + (NumberUtil.linearInterpolate(this.value, 0.0, 1.0, this.lowerEnd, this.upperEnd).toInt())) + } + + override fun applyValue() { + this.setValue(this.value) + } +} diff --git a/src/main/java/net/moonleay/gimbal/client/util/NumberUtil.kt b/src/main/java/net/moonleay/gimbal/client/util/NumberUtil.kt new file mode 100644 index 0000000..e335842 --- /dev/null +++ b/src/main/java/net/moonleay/gimbal/client/util/NumberUtil.kt @@ -0,0 +1,44 @@ +/* + * 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 + +object NumberUtil { + + /** + * Interpolate a number between two numbers in a linear way + */ + fun linearInterpolate(number: Double, min: Double, max: Double, lowerEnd: Double, upperEnd: Double): Double { + val subtractFromNr = (0 - min) * -1 + val minMaxDiff = max - min + val onePercent = minMaxDiff / 100.0 + val percentOfNumber = (number - subtractFromNr) / onePercent + + val toAddToLowerEnd = (0 - lowerEnd) * -1 + val upperLowerDiff = upperEnd - lowerEnd + val onePercentOfEnd = upperLowerDiff / 100.0 + return (percentOfNumber * onePercentOfEnd) + toAddToLowerEnd + } + + /** + * Interpolate a number between two numbers in a logarithmic way + */ + fun logarithmicInterpolate(number: Double, min: Double, max: Double, lowerEnd: Double, upperEnd: Double): Double { + TODO("Not impl.") + } +} diff --git a/src/main/java/net/moonleay/gimbal/constants/TranslationKeys.kt b/src/main/java/net/moonleay/gimbal/constants/TranslationKeys.kt index 6d4c355..0db8509 100644 --- a/src/main/java/net/moonleay/gimbal/constants/TranslationKeys.kt +++ b/src/main/java/net/moonleay/gimbal/constants/TranslationKeys.kt @@ -31,6 +31,10 @@ object TranslationKeys { const val GENERIC_ENABLED = "${BASE}enabled" const val GENERIC_DISABLED = "${BASE}disabled" + const val PLAYER_FLY_SPEED = "${BASE}flySpeed" + const val SHOULD_ESC_RESET_MODE = "${BASE}shouldESCResetMode" + const val DEFAULT_MODE = "${BASE}defaultMode" + object Hud { const val BASE = "${TranslationKeys.Gui.Config.BASE}hud." diff --git a/src/main/java/net/moonleay/gimbal/datagen/DataGenerator.kt b/src/main/java/net/moonleay/gimbal/datagen/DataGenerator.kt index b328d97..bd2452e 100644 --- a/src/main/java/net/moonleay/gimbal/datagen/DataGenerator.kt +++ b/src/main/java/net/moonleay/gimbal/datagen/DataGenerator.kt @@ -28,6 +28,6 @@ internal class DataGenerator : DataGeneratorEntrypoint { override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) { LOGGER.info("Starting Data Generation") - fabricDataGenerator.addProvider(En_us_GimbalLanguageProvider(fabricDataGenerator)) + fabricDataGenerator.addProvider(EnUsLanguageProvider(fabricDataGenerator)) } } diff --git a/src/main/java/net/moonleay/gimbal/datagen/En_us_GimbalLanguageProvider.kt b/src/main/java/net/moonleay/gimbal/datagen/EnUsLanguageProvider.kt similarity index 91% rename from src/main/java/net/moonleay/gimbal/datagen/En_us_GimbalLanguageProvider.kt rename to src/main/java/net/moonleay/gimbal/datagen/EnUsLanguageProvider.kt index 666e1fe..00279a1 100644 --- a/src/main/java/net/moonleay/gimbal/datagen/En_us_GimbalLanguageProvider.kt +++ b/src/main/java/net/moonleay/gimbal/datagen/EnUsLanguageProvider.kt @@ -22,7 +22,7 @@ import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider import net.moonleay.gimbal.constants.TranslationKeys -class En_us_GimbalLanguageProvider(dataGenerator: FabricDataGenerator?) : +class EnUsLanguageProvider(dataGenerator: FabricDataGenerator?) : FabricLanguageProvider(dataGenerator, "en_us") { override fun generateTranslations(translationBuilder: TranslationBuilder?) { @@ -50,10 +50,15 @@ class En_us_GimbalLanguageProvider(dataGenerator: FabricDataGenerator?) : //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_TOGGLE, "Only Toggle") + translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_SYSTEM, "Only System") translationBuilder.add(TranslationKeys.Gui.Config.Toasts.SHOW_NONE, "None") + // Gimbal Generic Settings + translationBuilder.add(TranslationKeys.Gui.Config.PLAYER_FLY_SPEED, "Fly Speed") + translationBuilder.add(TranslationKeys.Gui.Config.SHOULD_ESC_RESET_MODE, "ESC Resets Mode") + translationBuilder.add(TranslationKeys.Gui.Config.DEFAULT_MODE, "Default Mode") + // Gimbal Generic Gui translationBuilder.add(TranslationKeys.Gui.Config.GENERIC_ENABLED, "Enabled") translationBuilder.add(TranslationKeys.Gui.Config.GENERIC_DISABLED, "Disabled") diff --git a/src/main/java/net/moonleay/gimbal/editor/ServerEditorManager.kt b/src/main/java/net/moonleay/gimbal/editor/ServerEditorManager.kt index 5bb3f96..c0a1801 100644 --- a/src/main/java/net/moonleay/gimbal/editor/ServerEditorManager.kt +++ b/src/main/java/net/moonleay/gimbal/editor/ServerEditorManager.kt @@ -32,7 +32,7 @@ object ServerEditorManager { fun updateEditorState(playerUUID: UUID, editorState: EditorState) { STATEMAP[playerUUID] = editorState - LOGGER.info("$playerUUID: ${editorState.editorMode} with ${editorState.editorModifier}") + LOGGER.debug("{}: {} with {}", playerUUID, editorState.editorMode, editorState.editorModifier) } diff --git a/src/main/java/net/moonleay/gimbal/editor/state/mode/Mode.kt b/src/main/java/net/moonleay/gimbal/editor/state/mode/Mode.kt index 157cfa3..5481b22 100644 --- a/src/main/java/net/moonleay/gimbal/editor/state/mode/Mode.kt +++ b/src/main/java/net/moonleay/gimbal/editor/state/mode/Mode.kt @@ -18,10 +18,11 @@ package net.moonleay.gimbal.editor.state.mode -enum class Mode(val displayName: String, val color: Int, val incompatibleModifiers: List){ - UNKNOWN("UNKNOWN", 0x000000, listOf()), // Unknown mode. This mode cannot be entered - NORMAL("NORMAL", 0x90a959, listOf(ModeModifier.NO_UPDATES, ModeModifier.BULLDOZER, ModeModifier.FORCE_PLACE)), // Do nothing - INSERT("INSERT", 0xf4bf75, listOf()), // Place and break blocks - REPLACE("REPLACE", 0xac4242, listOf(ModeModifier.NO_UPDATES)), // Replace blocks - VISUAL("VISUAL", 0x6a9fb5, listOf(ModeModifier.BULLDOZER)), // Do fancy stuff with WE +enum class Mode(val displayName: String, val color: Int, val hidden: Boolean, val incompatibleModifiers: List){ + UNKNOWN("UNKNOWN", 0x000000, true, listOf()), // Unknown mode. This mode cannot be entered + NORMAL("NORMAL", 0x90a959, false, listOf(ModeModifier.NO_UPDATES, ModeModifier.BULLDOZER, ModeModifier.FORCE_PLACE)), // Do nothing + INSERT("INSERT", 0xf4bf75, false, listOf()), // Place and break blocks + REPLACE("REPLACE", 0xac4242, false, listOf(ModeModifier.NO_UPDATES)), // Replace blocks + // Add hidden modes after this comment + VISUAL("VISUAL", 0x6a9fb5, true, listOf(ModeModifier.BULLDOZER)), // Do fancy stuff with WE } diff --git a/src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin.java b/src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin.java index a89604a..df682c2 100644 --- a/src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin.java +++ b/src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin.java @@ -20,9 +20,13 @@ package net.moonleay.gimbal.mixin; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.moonleay.gimbal.client.editor.ClientEditor; import net.moonleay.gimbal.editor.state.mode.Capability; import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -32,30 +36,49 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Objects; -@Mixin(MinecraftClient.class) public abstract class BulldozerMixin { - @Shadow protected int attackCooldown; + @Mixin(MinecraftClient.class) + public static abstract class MinecraftClientMixin { + @Shadow + @Nullable + public ClientPlayerEntity player; + @Shadow + protected int attackCooldown; - @Shadow - @Nullable - public ClientPlayerEntity player; - - @Inject(method = "doAttack", at = @At(value = "HEAD")) - private void func(CallbackInfoReturnable cir) { - if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.player).isCreative()) { - return; + @Inject(method = "doAttack", at = @At(value = "HEAD")) + private void func(CallbackInfoReturnable cir) { + if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.player).isCreative()) { + return; + } + this.attackCooldown = 0; + } + + @Inject(method = "handleBlockBreaking", at = @At(value = "HEAD")) + private void func2(boolean breaking, CallbackInfo ci) { + if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !breaking || !Objects.requireNonNull(this.player).isCreative()) { + return; + } + this.attackCooldown = 0; } - this.attackCooldown = 0; } - @Inject(method = "handleBlockBreaking", at = @At(value = "HEAD")) - private void func2(boolean breaking, CallbackInfo ci) { - if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !breaking || !Objects.requireNonNull(this.player).isCreative()) { - return; + @Mixin(ClientPlayerInteractionManager.class) + public static abstract class ClientPlayerInteractionManagerMixin { + + @Shadow + private int blockBreakingCooldown; + + @Shadow + @Final + private MinecraftClient client; + + @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD")) + private void func(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { + if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.client.player).isCreative()) { + return; + } + this.blockBreakingCooldown = 0; } - this.attackCooldown = 0; } - - } diff --git a/src/main/java/net/moonleay/gimbal/mixin/NoClipCameraFixMixin.java b/src/main/java/net/moonleay/gimbal/mixin/NoClipCameraFixMixin.java deleted file mode 100644 index 55a8882..0000000 --- a/src/main/java/net/moonleay/gimbal/mixin/NoClipCameraFixMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.MinecraftClient; -import net.minecraft.client.render.Camera; -import net.moonleay.gimbal.client.editor.ClientEditor; -import net.moonleay.gimbal.editor.state.mode.Capability; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(Camera.class) -public class NoClipCameraFixMixin { - - @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) - private void fixCameraInNoClip(double desiredCameraDistance, CallbackInfoReturnable cir) { - if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP) || (!(MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().player.isCreative()))) { - return; - } - cir.setReturnValue(desiredCameraDistance); - cir.cancel(); - } -} diff --git a/src/main/java/net/moonleay/gimbal/mixin/NoClipMixin.java b/src/main/java/net/moonleay/gimbal/mixin/NoClipMixin.java index fafab39..8e9a80a 100644 --- a/src/main/java/net/moonleay/gimbal/mixin/NoClipMixin.java +++ b/src/main/java/net/moonleay/gimbal/mixin/NoClipMixin.java @@ -19,12 +19,15 @@ package net.moonleay.gimbal.mixin; import com.mojang.authlib.GameProfile; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.Camera; import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerAbilities; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.world.World; +import net.moonleay.gimbal.client.editor.ClientEditor; import net.moonleay.gimbal.editor.ServerEditorManager; import net.moonleay.gimbal.editor.state.mode.Capability; import org.spongepowered.asm.mixin.Mixin; @@ -32,51 +35,72 @@ import org.spongepowered.asm.mixin.Shadow; 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; import java.util.UUID; -@Mixin(PlayerEntity.class) -public abstract class NoClipMixin extends LivingEntity { - @Shadow public abstract GameProfile getGameProfile(); +public abstract class NoClipMixin { - @Shadow public abstract PlayerAbilities getAbilities(); - - @Shadow - public abstract boolean isCreative(); - - protected NoClipMixin(EntityType entityType, World world) { - super(entityType, world); - } // Server side - - - @Inject(method = "tick", at = @At(value = "FIELD", - target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z", shift = At.Shift.AFTER) - ) private void enoClip(CallbackInfo ci) { - if (!this.isCreative()) - return; - UUID uuid = this.getGameProfile().getId(); - - if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) { - return; // NoClip is not enabled + @Mixin(PlayerEntity.class) // Serverside, allows clipping + public static abstract class PlayerEntityMixin extends LivingEntity { + protected PlayerEntityMixin(EntityType entityType, World world) { + super(entityType, world); } - if (!this.getAbilities().flying) { - return; + + @Shadow + public abstract GameProfile getGameProfile(); + + @Shadow + public abstract PlayerAbilities getAbilities(); + + @Shadow + public abstract boolean isCreative(); + + @Inject(method = "tick", at = @At(value = "FIELD", + target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z", shift = At.Shift.AFTER) + ) + private void enoClip(CallbackInfo ci) { + if (!this.isCreative()) + return; + UUID uuid = this.getGameProfile().getId(); + + if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) { + return; // NoClip is not enabled + } + if (!this.getAbilities().flying) { + return; + } + // Enable NoClip + this.noClip = true; + } + + @Inject(method = "updatePose", at = @At("HEAD")) + private void onUpdatePose(CallbackInfo ci) { + UUID uuid = this.getGameProfile().getId(); + + if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) + return; // NoClip is not enabled + if (!this.getAbilities().flying) + return; + + // Force standing pose in NoClip mode + + this.setPose(EntityPose.STANDING); } - // Enable NoClip - this.noClip = true; } - @Inject(method = "updatePose", at = @At("HEAD")) - private void onUpdatePose(CallbackInfo ci) { - UUID uuid = this.getGameProfile().getId(); - if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) - return; // NoClip is not enabled - if (!this.getAbilities().flying) - return; + @Mixin(Camera.class) // Clientside, fixes camera + public static abstract class CameraMixin { - // Force standing pose in NoClip mode - - this.setPose(EntityPose.STANDING); + @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) + private void fixCameraInNoClip(double desiredCameraDistance, CallbackInfoReturnable cir) { + if (!ClientEditor.INSTANCE.shouldClient(Capability.NO_CLIP) || (!(MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().player.isCreative()))) { + return; + } + cir.setReturnValue(desiredCameraDistance); + cir.cancel(); + } } + } diff --git a/src/main/java/net/moonleay/gimbal/mixin/NormalModeMixin.java b/src/main/java/net/moonleay/gimbal/mixin/NormalModeMixin.java index 7dc6232..d8f769a 100644 --- a/src/main/java/net/moonleay/gimbal/mixin/NormalModeMixin.java +++ b/src/main/java/net/moonleay/gimbal/mixin/NormalModeMixin.java @@ -21,9 +21,9 @@ package net.moonleay.gimbal.mixin; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.option.GameOptions; +import net.moonleay.gimbal.client.ClientMain; import net.moonleay.gimbal.client.editor.ClientEditor; import net.moonleay.gimbal.editor.state.mode.Capability; -import net.moonleay.gimbal.editor.state.mode.Mode; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -43,12 +43,12 @@ public class NormalModeMixin { public ClientPlayerEntity player; @Inject(method = "openPauseMenu", at = @At("HEAD"), cancellable = true) - private void setNormalMode(boolean pause, CallbackInfo ci) { - if (ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) { + private void setDefaultMode(boolean pause, CallbackInfo ci) { + if (ClientMain.CONFIG.getConfig().getShouldEscResetMode() && ClientEditor.INSTANCE.isInNonDefaultMode() && ClientEditor.INSTANCE.isAllowed()) { assert this.player != null; if (this.player.isCreative()) { // Set the editor mode to normal - ClientEditor.INSTANCE.setMode(Mode.NORMAL); + ClientEditor.INSTANCE.setMode(ClientMain.CONFIG.getConfig().getDefaultMode()); ci.cancel(); } } diff --git a/src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin2.java b/src/main/java/net/moonleay/gimbal/mixin/PlayerFlySpeedMixin.java similarity index 58% rename from src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin2.java rename to src/main/java/net/moonleay/gimbal/mixin/PlayerFlySpeedMixin.java index 19f1378..e846c91 100644 --- a/src/main/java/net/moonleay/gimbal/mixin/BulldozerMixin2.java +++ b/src/main/java/net/moonleay/gimbal/mixin/PlayerFlySpeedMixin.java @@ -19,34 +19,27 @@ package net.moonleay.gimbal.mixin; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.moonleay.gimbal.client.editor.ClientEditor; -import net.moonleay.gimbal.editor.state.mode.Capability; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.network.packet.s2c.play.PlayerAbilitiesS2CPacket; +import net.moonleay.gimbal.client.ClientMain; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Objects; - -@Mixin(ClientPlayerInteractionManager.class) -public class BulldozerMixin2 { - - @Shadow private int blockBreakingCooldown; +@Mixin(ClientPlayNetworkHandler.class) +public abstract class PlayerFlySpeedMixin { @Shadow @Final private MinecraftClient client; - @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD")) - private void func(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - if (!ClientEditor.INSTANCE.shouldClient(Capability.BULLDOZER) || !Objects.requireNonNull(this.client.player).isCreative()) { - return; - } - this.blockBreakingCooldown = 0; + @Inject(method = "onPlayerAbilities", at = @At(value = "RETURN")) + private void func(PlayerAbilitiesS2CPacket packet, CallbackInfo ci) { + this.client.player.getAbilities().setFlySpeed((ClientMain.CONFIG.getConfig().getPlayerFlySpeed() / 100) * 0.05f); + //client!!.player!!.abilities.flySpeed = (this.playerFlySpeed / 100) * 0.05f } + } diff --git a/src/main/java/net/moonleay/gimbal/mixin/ReplaceModeMixin.java b/src/main/java/net/moonleay/gimbal/mixin/ReplaceModeMixin.java index 8e2a4fa..8a28216 100644 --- a/src/main/java/net/moonleay/gimbal/mixin/ReplaceModeMixin.java +++ b/src/main/java/net/moonleay/gimbal/mixin/ReplaceModeMixin.java @@ -18,50 +18,87 @@ package net.moonleay.gimbal.mixin; +import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsageContext; +import net.minecraft.item.*; +import net.minecraft.state.property.Property; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.moonleay.gimbal.editor.ServerEditorManager; import net.moonleay.gimbal.editor.state.mode.Capability; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.UUID; -@Mixin(ItemPlacementContext.class) -public abstract class ReplaceModeMixin extends ItemUsageContext { +public abstract class ReplaceModeMixin { - @Shadow - protected boolean canReplaceExisting; + @Mixin(ItemPlacementContext.class) + public static abstract class ItemPlacementContextMixin extends ItemUsageContext { + @Shadow + protected boolean canReplaceExisting; - @Mutable - @Shadow - @Final - private BlockPos placementPos; + @Mutable + @Shadow + @Final + private BlockPos placementPos; - public ReplaceModeMixin(PlayerEntity player, Hand hand, BlockHitResult hit) { - super(player, hand, hit); + public ItemPlacementContextMixin(PlayerEntity player, Hand hand, BlockHitResult hit) { + super(player, hand, hit); + } + + @Inject(method = "(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/Hand;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/hit/BlockHitResult;)V", at = @At(value = "RETURN")) + private void func(World world, PlayerEntity playerEntity, Hand hand, ItemStack itemStack, BlockHitResult blockHitResult, CallbackInfo ci) { + if (playerEntity == null) + return; + UUID id = playerEntity.getGameProfile().getId(); + if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.REPLACE)) + return; + + this.canReplaceExisting = true; + this.placementPos = blockHitResult.getBlockPos(); + } } - @Inject(method = "(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/Hand;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/hit/BlockHitResult;)V", at = @At(value = "RETURN")) - private void func(World world, PlayerEntity playerEntity, Hand hand, ItemStack itemStack, BlockHitResult blockHitResult, CallbackInfo ci) { - if (playerEntity == null) - return; - UUID id = playerEntity.getGameProfile().getId(); - if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.REPLACE)) - return; + @Mixin(BlockItem.class) + public static abstract class BlockItemMixin extends Item { - this.canReplaceExisting = true; - this.placementPos = blockHitResult.getBlockPos(); + public BlockItemMixin(Settings settings) { + super(settings); + } + + @Shadow + protected abstract boolean place(ItemPlacementContext context, BlockState state); + + @Redirect(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;place(Lnet/minecraft/item/ItemPlacementContext;Lnet/minecraft/block/BlockState;)Z")) + private boolean func(BlockItem instance, ItemPlacementContext context, BlockState state) { + if (context.getPlayer() == null) + return this.place(context, state); + UUID id = context.getPlayer().getGameProfile().getId(); + if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.REPLACE)) + return this.place(context, state); + BlockState oldState = context.getWorld().getBlockState(context.getBlockPos()); + return this.place(context, getTargetBlockState(oldState, instance.getBlock().getDefaultState())); + } + + @Unique + public BlockState getTargetBlockState(BlockState oldState, BlockState newBlock) { + var oldManager = oldState.getBlock().getStateManager(); + var newManager = newBlock.getBlock().getStateManager(); + for (var prop : oldManager.getProperties()) { + var matchingProp = newManager.getProperty(prop.getName()); + if (matchingProp != null) { + //noinspection rawtypes,unchecked + newBlock = newBlock.with((Property) matchingProp, oldState.get(matchingProp)); + } + } + return newBlock; + } } + } diff --git a/src/main/java/net/moonleay/gimbal/mixin/ReplaceStateUpdaterMixin.java b/src/main/java/net/moonleay/gimbal/mixin/ReplaceStateUpdaterMixin.java deleted file mode 100644 index 255604a..0000000 --- a/src/main/java/net/moonleay/gimbal/mixin/ReplaceStateUpdaterMixin.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.block.BlockState; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.state.property.Property; -import net.moonleay.gimbal.editor.ServerEditorManager; -import net.moonleay.gimbal.editor.state.mode.Capability; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.UUID; - -@Mixin(BlockItem.class) -public abstract class ReplaceStateUpdaterMixin extends Item { - - public ReplaceStateUpdaterMixin(Settings settings) { - super(settings); - } - - @Shadow - protected abstract boolean place(ItemPlacementContext context, BlockState state); - - @Redirect(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;place(Lnet/minecraft/item/ItemPlacementContext;Lnet/minecraft/block/BlockState;)Z")) - private boolean func(BlockItem instance, ItemPlacementContext context, BlockState state) { - if (context.getPlayer() == null) - return this.place(context, state); - UUID id = context.getPlayer().getGameProfile().getId(); - if (!ServerEditorManager.INSTANCE.shouldPlayer(id, Capability.REPLACE)) - return this.place(context, state); - BlockState oldState = context.getWorld().getBlockState(context.getBlockPos()); - return this.place(context, getTargetBlockState(oldState, instance.getBlock().getDefaultState())); - } - - @Unique - public BlockState getTargetBlockState(BlockState oldState, BlockState newBlock) { - var oldManager = oldState.getBlock().getStateManager(); - var newManager = newBlock.getBlock().getStateManager(); - for (var prop : oldManager.getProperties()) { - var matchingProp = newManager.getProperty(prop.getName()); - if (matchingProp != null) { - //noinspection rawtypes,unchecked - newBlock = newBlock.with((Property) matchingProp, oldState.get(matchingProp)); - } - } - return newBlock; - } -} diff --git a/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java b/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java index f86f610..efa2a9c 100644 --- a/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java +++ b/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin.java @@ -20,6 +20,7 @@ package net.moonleay.gimbal.mixin; import net.minecraft.client.gui.screen.GameMenuScreen; 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; @@ -33,35 +34,71 @@ 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 { +public class YouInjectButtonMixin { // Go my god. - @Unique - private static final Identifier GIMBAL_TEXTURE = new Identifier(BuildConstants.modId, "textures/gimbal_options_texture_button.png"); + @Mixin(TitleScreen.class) + public static abstract class TitleScreenMixin extends Screen { - protected YouInjectButtonMixin(Text title) { - super(title); + @Unique + private static final Identifier GIMBAL_TEXTURE = new Identifier(BuildConstants.modId, "textures/gimbal_options_texture_button.png"); + + protected TitleScreenMixin(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(TranslationKeys.Gui.Config.SCREEN_NAME) + ) + ); + } } - @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(TranslationKeys.Gui.Config.SCREEN_NAME) - ) - ); + + @Mixin(GameMenuScreen.class) + public static abstract class GameMenuScreenMixin extends Screen { + @Unique + private static final Identifier GIMBAL_TEXTURE = new Identifier(BuildConstants.modId, "textures/gimbal_options_texture_button.png"); + + protected GameMenuScreenMixin(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(TranslationKeys.Gui.Config.SCREEN_NAME) + ) + ); + } } + } diff --git a/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin2.java b/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin2.java deleted file mode 100644 index b25789d..0000000 --- a/src/main/java/net/moonleay/gimbal/mixin/YouInjectButtonMixin2.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 net.moonleay.gimbal.constants.TranslationKeys; -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(TranslationKeys.Gui.Config.SCREEN_NAME) - ) - ); - } -} diff --git a/src/main/resources/gimbal.mixins.json b/src/main/resources/gimbal.mixins.json index 479b9ab..9de8288 100644 --- a/src/main/resources/gimbal.mixins.json +++ b/src/main/resources/gimbal.mixins.json @@ -6,18 +6,19 @@ "mixins": [ "ForcePlaceMixin", "NoBlockUpdatesMixin", - "NoClipMixin", - "ReplaceModeMixin", - "ReplaceStateUpdaterMixin" + "NoClipMixin$PlayerEntityMixin", + "ReplaceModeMixin$BlockItemMixin", + "ReplaceModeMixin$ItemPlacementContextMixin" ], "client": [ - "BulldozerMixin", - "BulldozerMixin2", + "BulldozerMixin$ClientPlayerInteractionManagerMixin", + "BulldozerMixin$MinecraftClientMixin", "HudMixin", - "NoClipCameraFixMixin", + "NoClipMixin$CameraMixin", "NormalModeMixin", - "YouInjectButtonMixin", - "YouInjectButtonMixin2" + "PlayerFlySpeedMixin", + "YouInjectButtonMixin$GameMenuScreenMixin", + "YouInjectButtonMixin$TitleScreenMixin" ], "injectors": { "defaultRequire": 1