From 05db012b8564528479b032c743f0f92559bf9822 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 22 Apr 2024 04:44:06 +0200 Subject: [PATCH] feat: added basic groundwork for modes and modifier, added Replace Mode --- .../mods/gimble/client/editor/Editor.kt | 78 +++++++++++++ .../mods/gimble/client/editor/modes/Mode.kt | 8 ++ .../client/editor/modes/ModeModifier.kt | 9 ++ .../client/keybindings/KeybindingManager.kt | 26 +++++ .../client/keybindings/KeybindingRegistrar.kt | 110 ++++++++++++++++++ .../client/keybindings/impl/GimbleShortcut.kt | 9 ++ .../editormode/EnableInsertModeShortcut.kt | 16 +++ .../editormode/EnableReplaceModeShortcut.kt | 16 +++ .../editormode/EnableVisualModeShortcut.kt | 16 +++ .../ToggleBulldozerModifierShortcut.kt | 15 +++ .../ToggleForcePlaceModifierShortcut.kt | 15 +++ .../ToggleNoClipModifierShortcut.kt | 15 +++ .../ToggleNoUpdatesModifierShortcut.kt | 15 +++ .../impl/gamemode/CreativeModeShortcut.kt | 12 ++ .../impl/gamemode/SpectatorModeShortcut.kt | 12 ++ .../impl/gamemode/SurvivalModeShortcut.kt | 14 +++ .../mods/gimble/client/util/ChatUtil.kt | 20 ++++ .../moonleay/mods/gimble/mixin/HudMixin.java | 66 +++++++++++ .../moonleay/mods/gimble/mixin/KeyMixin.java | 16 +++ .../mods/gimble/mixin/NormalModeMixin.java | 23 ++++ .../mods/gimble/mixin/ReplaceModeMixin.java | 68 +++++++++++ 21 files changed, 579 insertions(+) create mode 100644 src/main/java/net/moonleay/mods/gimble/client/editor/Editor.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/editor/modes/Mode.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/editor/modes/ModeModifier.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingManager.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingRegistrar.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/GimbleShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleBulldozerModifierShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleForcePlaceModifierShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoClipModifierShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoUpdatesModifierShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/CreativeModeShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SpectatorModeShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SurvivalModeShortcut.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/client/util/ChatUtil.kt create mode 100644 src/main/java/net/moonleay/mods/gimble/mixin/HudMixin.java create mode 100644 src/main/java/net/moonleay/mods/gimble/mixin/KeyMixin.java create mode 100644 src/main/java/net/moonleay/mods/gimble/mixin/NormalModeMixin.java create mode 100644 src/main/java/net/moonleay/mods/gimble/mixin/ReplaceModeMixin.java diff --git a/src/main/java/net/moonleay/mods/gimble/client/editor/Editor.kt b/src/main/java/net/moonleay/mods/gimble/client/editor/Editor.kt new file mode 100644 index 0000000..386337f --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/editor/Editor.kt @@ -0,0 +1,78 @@ +package net.moonleay.mods.gimble.client.editor + +import net.minecraft.client.MinecraftClient +import net.moonleay.mods.gimble.client.util.ChatUtil +import net.moonleay.mods.gimble.client.editor.modes.Mode +import net.moonleay.mods.gimble.client.editor.modes.ModeModifier + +object Editor { + var CURRENT_MODE = Mode.NORMAL + val CURRENT_MODE_MODIFIER = mutableListOf() + private val TEMP_DISABLED_MODIFIERS = mutableListOf() + + + fun toggleModifier(mod: ModeModifier) { + if (CURRENT_MODE.incompatibleModifiers.contains(mod)){ + if (TEMP_DISABLED_MODIFIERS.contains(mod)) + TEMP_DISABLED_MODIFIERS.remove(mod) + else + TEMP_DISABLED_MODIFIERS.add(mod) + } + else { + if (CURRENT_MODE_MODIFIER.contains(mod)) + CURRENT_MODE_MODIFIER.remove(mod) + else + CURRENT_MODE_MODIFIER.add(mod) + } + + this.onModifiersUpdated() + } + + fun onModifiersUpdated() { + CURRENT_MODE_MODIFIER.sort() + this.checkForIncompatibleModeModifiers() + } + + fun checkForIncompatibleModeModifiers() { + if (TEMP_DISABLED_MODIFIERS.size > 0) { + CURRENT_MODE_MODIFIER.addAll(TEMP_DISABLED_MODIFIERS) + TEMP_DISABLED_MODIFIERS.clear() + } + + val incompatibleModeModifiers = CURRENT_MODE.incompatibleModifiers + for (mod in CURRENT_MODE_MODIFIER) { + if (incompatibleModeModifiers.contains(mod)) { + TEMP_DISABLED_MODIFIERS.add(mod) + } + } + for (mod in TEMP_DISABLED_MODIFIERS) { + if (CURRENT_MODE_MODIFIER.contains(mod)) { // This check is probably useless. + CURRENT_MODE_MODIFIER.remove(mod) + } + } + + if(TEMP_DISABLED_MODIFIERS.isNotEmpty()) { + ChatUtil.addToChatHistory("The following modifiers are not supported by this editor mode and are therefore currently disabled: " + + this.getListAsString(TEMP_DISABLED_MODIFIERS), MinecraftClient.getInstance()) + } + } + + private fun getListAsString(list: List): String{ + if(list.isEmpty()) + return "Empty list" + val sb = StringBuilder() + for (mod in list) { + sb.append(mod.displayName) + sb.append(" ") + } + return sb.toString().dropLast(1) + } + + fun getCurrentMode(): Mode { + return CURRENT_MODE + } + + fun getCurrentModifier(): List { + return CURRENT_MODE_MODIFIER + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/editor/modes/Mode.kt b/src/main/java/net/moonleay/mods/gimble/client/editor/modes/Mode.kt new file mode 100644 index 0000000..b94a313 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/editor/modes/Mode.kt @@ -0,0 +1,8 @@ +package net.moonleay.mods.gimble.client.editor.modes + +enum class Mode(val displayName: String, val color: Int, val incompatibleModifiers: List){ + 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()), // Replace blocks + VISUAL("VISUAL", 0x6a9fb5, listOf(ModeModifier.BULLDOZER)), // Do fancy stuff with WE +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/editor/modes/ModeModifier.kt b/src/main/java/net/moonleay/mods/gimble/client/editor/modes/ModeModifier.kt new file mode 100644 index 0000000..1ad5966 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/editor/modes/ModeModifier.kt @@ -0,0 +1,9 @@ +package net.moonleay.mods.gimble.client.editor.modes + +enum class ModeModifier(val displayName: String) { +// NONE("None"), // No Modifiers - default behavior + NO_UPDATES("NO UPDATES"), // Do not update blocks when placing + BULLDOZER("BULLDOZER"), // Break blocks fast + FORCE_PLACE("FORCE"), // Ignore block placement restrictions + NO_CLIP("NO CLIP"), // Do not collide with blocks +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingManager.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingManager.kt new file mode 100644 index 0000000..ec3ca68 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingManager.kt @@ -0,0 +1,26 @@ +package net.moonleay.mods.gimble.client.keybindings + +import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut + +object KeybindingManager { + + private val shortcuts = mutableListOf() + + /** + * Register a shortcut. This will also register the keybinding. + * */ + fun registerShortcut(shortcut: GimbleShortcut) { + shortcuts.add(shortcut) + KeyBindingRegistryImpl.registerKeyBinding(shortcut.keyBinding) + } + + fun onClientTick(client: MinecraftClient){ + // Sadly, this cannot be done without iterating over all shortcuts :madge: + for (shortcut in shortcuts) + if (shortcut.keyBinding.wasPressed()) + shortcut.onPressed(client) + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingRegistrar.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingRegistrar.kt new file mode 100644 index 0000000..86f6d32 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/KeybindingRegistrar.kt @@ -0,0 +1,110 @@ +package net.moonleay.mods.gimble.client.keybindings + +import net.minecraft.client.option.KeyBinding +import net.minecraft.client.util.InputUtil +import net.moonleay.mods.gimble.build.BuildConstants +import net.moonleay.mods.gimble.client.keybindings.impl.editormode.EnableInsertModeShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.editormode.EnableReplaceModeShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.editormode.EnableVisualModeShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier.ToggleBulldozerModifierShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier.ToggleForcePlaceModifierShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier.ToggleNoClipModifierShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier.ToggleNoUpdatesModifierShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.gamemode.CreativeModeShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.gamemode.SpectatorModeShortcut +import net.moonleay.mods.gimble.client.keybindings.impl.gamemode.SurvivalModeShortcut +import org.apache.logging.log4j.LogManager +import org.lwjgl.glfw.GLFW + +object KeybindingRegistrar { + + private val LOGGER = LogManager.getLogger(BuildConstants.modName) + + fun registerKeybindings() { + LOGGER.info("Registering keybindings...") + registerSetGameModeKeybindings() + registerSetEditorModeKeybindings() + registerSetEditorModeModifierKeybindings() + LOGGER.info("Keybindings have been registered.") + } + + private fun registerSetEditorModeModifierKeybindings() { + val toggleBulldozerModifierShortcut = KeyBinding( + "gimble.key.editor.modifier.bulldozer", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_B, + "category.gimble.editormodifier" + ) + val toggleForcePlaceModifierShortcut = KeyBinding( + "gimble.key.editor.modifier.forceplace", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_F, + "category.gimble.editormodifier" + ) + val toggleNoUpdatesModifierShortcut = KeyBinding( + "gimble.key.editor.modifier.noupdates", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_N, + "category.gimble.editormodifier" + ) + val toggleNoClipModifierShortcut = KeyBinding( + "gimble.key.editor.modifier.noclip", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_C, + "category.gimble.editormodifier" + ) + + KeybindingManager.registerShortcut(ToggleBulldozerModifierShortcut(toggleBulldozerModifierShortcut)) + KeybindingManager.registerShortcut(ToggleForcePlaceModifierShortcut(toggleForcePlaceModifierShortcut)) + KeybindingManager.registerShortcut(ToggleNoUpdatesModifierShortcut(toggleNoUpdatesModifierShortcut)) + KeybindingManager.registerShortcut(ToggleNoClipModifierShortcut(toggleNoClipModifierShortcut)) + } + + private fun registerSetEditorModeKeybindings() { + val insertKeyBinding = KeyBinding( + "gimble.key.editor.mode.insert", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_I, + "category.gimble.editormode" + ) + val replaceKeyBinding = KeyBinding( + "gimble.key.editor.mode.replace", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_R, + "category.gimble.editormode" + ) + val visualKeyBinding = KeyBinding( + "gimble.key.editor.mode.visual", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_V, + "category.gimble.editormode" + ) + KeybindingManager.registerShortcut(EnableInsertModeShortcut(insertKeyBinding)) + KeybindingManager.registerShortcut(EnableReplaceModeShortcut(replaceKeyBinding)) + KeybindingManager.registerShortcut(EnableVisualModeShortcut(visualKeyBinding)) + } + + private fun registerSetGameModeKeybindings() { + val survivalKeyBinding = KeyBinding( + "gimble.key.game.mode.survival", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_UNKNOWN, + "category.gimble.gamemode" + ) + val creativeKeyBinding = KeyBinding( + "gimble.key.game.mode.creative", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_UNKNOWN, + "category.gimble.gamemode" + ) + val spectatorKeyBinding = KeyBinding( + "gimble.key.game.mode.spectator", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_UNKNOWN, + "category.gimble.gamemode" + ) + KeybindingManager.registerShortcut(SurvivalModeShortcut(survivalKeyBinding)) + KeybindingManager.registerShortcut(CreativeModeShortcut(creativeKeyBinding)) + KeybindingManager.registerShortcut(SpectatorModeShortcut(spectatorKeyBinding)) + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/GimbleShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/GimbleShortcut.kt new file mode 100644 index 0000000..6b97bd0 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/GimbleShortcut.kt @@ -0,0 +1,9 @@ +package net.moonleay.mods.gimble.client.keybindings.impl + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding + +abstract class GimbleShortcut(val keyBinding: KeyBinding) { + + abstract fun onPressed(client: MinecraftClient) +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt new file mode 100644 index 0000000..b2baebb --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableInsertModeShortcut.kt @@ -0,0 +1,16 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.editormode + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.editor.Editor +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.editor.modes.Mode + + +class EnableInsertModeShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + Editor.CURRENT_MODE = Mode.INSERT + + Editor.checkForIncompatibleModeModifiers() + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt new file mode 100644 index 0000000..9d53d5a --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableReplaceModeShortcut.kt @@ -0,0 +1,16 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.editormode + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.editor.Editor +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.editor.modes.Mode + + +class EnableReplaceModeShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + Editor.CURRENT_MODE = Mode.REPLACE + + Editor.checkForIncompatibleModeModifiers() + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt new file mode 100644 index 0000000..a866f83 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormode/EnableVisualModeShortcut.kt @@ -0,0 +1,16 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.editormode + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.editor.Editor +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.editor.modes.Mode + + +class EnableVisualModeShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + Editor.CURRENT_MODE = Mode.VISUAL + + Editor.checkForIncompatibleModeModifiers() + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleBulldozerModifierShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleBulldozerModifierShortcut.kt new file mode 100644 index 0000000..3cccc6a --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleBulldozerModifierShortcut.kt @@ -0,0 +1,15 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.editor.Editor +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.editor.modes.ModeModifier + +class ToggleBulldozerModifierShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + Editor.toggleModifier(ModeModifier.BULLDOZER) + + Editor.onModifiersUpdated() + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleForcePlaceModifierShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleForcePlaceModifierShortcut.kt new file mode 100644 index 0000000..9b62517 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleForcePlaceModifierShortcut.kt @@ -0,0 +1,15 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.editor.Editor +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.editor.modes.ModeModifier + +class ToggleForcePlaceModifierShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + Editor.toggleModifier(ModeModifier.FORCE_PLACE) + + Editor.onModifiersUpdated() + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoClipModifierShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoClipModifierShortcut.kt new file mode 100644 index 0000000..134a37e --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoClipModifierShortcut.kt @@ -0,0 +1,15 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.editor.Editor +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.editor.modes.ModeModifier + +class ToggleNoClipModifierShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + Editor.toggleModifier(ModeModifier.NO_CLIP) + + Editor.onModifiersUpdated() + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoUpdatesModifierShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoUpdatesModifierShortcut.kt new file mode 100644 index 0000000..f51366e --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/editormodemodifier/ToggleNoUpdatesModifierShortcut.kt @@ -0,0 +1,15 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.editormodemodifier + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.editor.Editor +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.editor.modes.ModeModifier + +class ToggleNoUpdatesModifierShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + Editor.toggleModifier(ModeModifier.NO_UPDATES) + + Editor.onModifiersUpdated() + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/CreativeModeShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/CreativeModeShortcut.kt new file mode 100644 index 0000000..f09b081 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/CreativeModeShortcut.kt @@ -0,0 +1,12 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.gamemode + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.util.ChatUtil + +class CreativeModeShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + ChatUtil.sendCommand("/gamemode creative", client, false) + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SpectatorModeShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SpectatorModeShortcut.kt new file mode 100644 index 0000000..4006b16 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SpectatorModeShortcut.kt @@ -0,0 +1,12 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.gamemode + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.util.ChatUtil + +class SpectatorModeShortcut(key: KeyBinding): GimbleShortcut(key) { + override fun onPressed(client: MinecraftClient) { + ChatUtil.sendCommand("/gamemode spectator", client, false) + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SurvivalModeShortcut.kt b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SurvivalModeShortcut.kt new file mode 100644 index 0000000..14eb41b --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/keybindings/impl/gamemode/SurvivalModeShortcut.kt @@ -0,0 +1,14 @@ +package net.moonleay.mods.gimble.client.keybindings.impl.gamemode + +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.KeyBinding +import net.moonleay.mods.gimble.client.keybindings.impl.GimbleShortcut +import net.moonleay.mods.gimble.client.util.ChatUtil + + +class SurvivalModeShortcut(key: KeyBinding) : GimbleShortcut(key) { + + override fun onPressed(client: MinecraftClient) { + ChatUtil.sendCommand("/gamemode survival", client, false) + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/client/util/ChatUtil.kt b/src/main/java/net/moonleay/mods/gimble/client/util/ChatUtil.kt new file mode 100644 index 0000000..5cbd58b --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/client/util/ChatUtil.kt @@ -0,0 +1,20 @@ +package net.moonleay.mods.gimble.client.util + +import net.minecraft.client.MinecraftClient +import net.minecraft.text.Text + +object ChatUtil { + /** + * Note: command arg should contain "/" at the beginning. + * */ + fun sendCommand(command: String, client: MinecraftClient, addToHistory: Boolean = true): Boolean { + if (addToHistory) { + client.inGameHud.chatHud.addToMessageHistory(command) + } + return client.player?.sendCommand(command.substring(1))?: false + } + + fun addToChatHistory(message: String, client: MinecraftClient) { + client.inGameHud.chatHud.addMessage(Text.of(message)) + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/mixin/HudMixin.java b/src/main/java/net/moonleay/mods/gimble/mixin/HudMixin.java new file mode 100644 index 0000000..724d542 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/mixin/HudMixin.java @@ -0,0 +1,66 @@ +package net.moonleay.mods.gimble.mixin; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import net.moonleay.mods.gimble.client.editor.Editor; +import net.moonleay.mods.gimble.client.editor.modes.Mode; +import net.moonleay.mods.gimble.client.editor.modes.ModeModifier; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(InGameHud.class) +public class HudMixin { + + @Shadow @Final private MinecraftClient client; + + @Inject(method = "renderStatusEffectOverlay", at = @At("HEAD")) + private void render(MatrixStack matrices, CallbackInfo ci) { + Mode currentMode = Editor.INSTANCE.getCurrentMode(); + StringBuilder displayText = getStringBuilder(currentMode); + + MinecraftClient mc = MinecraftClient.getInstance(); + TextRenderer tr = mc.textRenderer; +// int screenWidth = mc.getWindow().getWidth(); +// int screenHeight = mc.getWindow().getHeight(); +// int scale = (mc.options.getGuiScale().getValue() == 0 ? 1 : mc.options.getGuiScale().getValue()); +// int bottomY = screenHeight / scale - 4 - tr.fontHeight - 12; + + tr.drawWithShadow(matrices, + Text.of(displayText.toString()), + 4, 4, + currentMode.getColor()); + } + + @Unique + private static @NotNull StringBuilder getStringBuilder(Mode currentMode) { + List currentModifier = Editor.INSTANCE.getCurrentModifier(); + StringBuilder displayText = new StringBuilder(currentMode.getDisplayName()); + if (!currentModifier.isEmpty()) { + displayText.append(" ["); + for (int i = 0; i < currentModifier.size(); i++) { + displayText.append(currentModifier.get(i).getDisplayName()); + if (i != currentModifier.size() - 1) { + displayText.append(", "); + } + } + displayText.append("]"); + } + return displayText; + } + + @Unique + private int getXRight(String txt, int screenWidth) { + return screenWidth / (MinecraftClient.getInstance().options.getGuiScale().getValue() == 0 ? 1 : MinecraftClient.getInstance().options.getGuiScale().getValue()) - 4 - MinecraftClient.getInstance().textRenderer.getWidth(Text.of(txt)); + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/mixin/KeyMixin.java b/src/main/java/net/moonleay/mods/gimble/mixin/KeyMixin.java new file mode 100644 index 0000000..634808f --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/mixin/KeyMixin.java @@ -0,0 +1,16 @@ +package net.moonleay.mods.gimble.mixin; + +import net.minecraft.client.Keyboard; +import org.lwjgl.glfw.GLFW; +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.CallbackInfo; + +@Mixin(Keyboard.class) +public class KeyMixin { +// This Mixin is not registered. This will be used to handle key events with static Buttons. + @Inject(method = "onKey", at = @At("TAIL")) + private void onKey(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) { + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/mixin/NormalModeMixin.java b/src/main/java/net/moonleay/mods/gimble/mixin/NormalModeMixin.java new file mode 100644 index 0000000..1c9425a --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/mixin/NormalModeMixin.java @@ -0,0 +1,23 @@ +package net.moonleay.mods.gimble.mixin; + +import net.minecraft.client.MinecraftClient; +import net.moonleay.mods.gimble.client.editor.Editor; +import net.moonleay.mods.gimble.client.editor.modes.Mode; +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.CallbackInfo; + +@Mixin(MinecraftClient.class) +public class NormalModeMixin { + + @Inject(method = "openPauseMenu", at = @At("HEAD"), cancellable = true) + private void setNormalMode(boolean pause, CallbackInfo ci) { + if (Editor.INSTANCE.getCURRENT_MODE() != Mode.NORMAL){ + // Set the editor mode to normal + Editor.INSTANCE.setCURRENT_MODE(Mode.NORMAL); + Editor.INSTANCE.checkForIncompatibleModeModifiers(); + ci.cancel(); + } + } +} diff --git a/src/main/java/net/moonleay/mods/gimble/mixin/ReplaceModeMixin.java b/src/main/java/net/moonleay/mods/gimble/mixin/ReplaceModeMixin.java new file mode 100644 index 0000000..83e0140 --- /dev/null +++ b/src/main/java/net/moonleay/mods/gimble/mixin/ReplaceModeMixin.java @@ -0,0 +1,68 @@ +package net.moonleay.mods.gimble.mixin; + +import net.minecraft.block.BlockState; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.client.particle.ParticleManager; +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.moonleay.mods.gimble.client.editor.Editor; +import net.moonleay.mods.gimble.client.editor.modes.Mode; +import net.moonleay.mods.gimble.client.util.ChatUtil; +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; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MinecraftClient.class) +public abstract class ReplaceModeMixin { + + + @Shadow protected abstract void handleBlockBreaking(boolean breaking); + + @Shadow @Nullable public ClientPlayerInteractionManager interactionManager; + + @Shadow @Final public ParticleManager particleManager; + + @Shadow @Nullable public ClientPlayerEntity player; + + @Shadow @Nullable public HitResult crosshairTarget; + + @Inject(method = "doItemUse", at = @At("HEAD")) + private void replaceBlock(CallbackInfo ci) { + // Check if should run + if (!Editor.INSTANCE.getCURRENT_MODE().equals(Mode.REPLACE)) + return; // Mode is not REPLACE, ignore + MinecraftClient client = MinecraftClient.getInstance(); + assert this.interactionManager != null; + if (!this.interactionManager.getCurrentGameMode().isCreative()) + return; + if (!(this.crosshairTarget instanceof BlockHitResult)) + return; + BlockHitResult blockHitResult = (BlockHitResult)this.crosshairTarget; + if (blockHitResult == null) + return; + + // Gather data + BlockPos pos = blockHitResult.getBlockPos(); + Direction direction = blockHitResult.getSide(); + BlockState blockState = client.world.getBlockState(pos); + + // Start sending shit + client.getTutorialManager().onBlockBreaking(client.world, pos, blockState, 1.0F); + this.interactionManager.sendSequencedPacket(client.world, sequence -> { + this.interactionManager.breakBlock(pos); + return new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence); + }); + this.player.swingHand(Hand.MAIN_HAND); + } + +}