From 34408d7a2a01866761c7efa576982f9f5b5f2564 Mon Sep 17 00:00:00 2001 From: Motschen Date: Sat, 25 Jun 2022 21:23:25 +0200 Subject: [PATCH] MidnightControls 1.2.0 - Touchscreen, Modded Keybinds, Bugfixes - Added #40 (Modded keybind support) - Added #20 (Touchscreen support) - Improved #13 (Sodium screen controller support) - Attempt to fix #31 & #38 (Jittery input on low FPS) - Fixed #35 (Front placing being broken) - Fixed #32 (Option to disable double tap to sprint) - Fixed #27 (Auto-adapt controller icons) - Fixed #19 (HUD-scaling on big scales) - Fixed #36 (Crash on game load) - Fixed reset option - Fixed scrolling in trading screens - Disable features that might be considered as cheats (install MidnightControlsExtra to enable) --- README.md | 8 +- build.gradle | 2 +- gradle.properties | 4 +- .../midnightcontrols/ControlsMode.java | 3 +- .../midnightcontrols/MidnightControls.java | 4 +- .../MidnightControlsFeature.java | 2 +- .../client/MidnightControlsClient.java | 72 ++- .../client/MidnightControlsConfig.java | 56 +- .../client/MidnightInput.java | 89 +-- .../client/MidnightReacharound.java | 2 +- .../client/compat/EmotecraftCompat.java | 49 -- .../client/compat/MidnightControlsCompat.java | 4 - .../compat/MidnightControlsMixinPlugin.java | 2 + .../client/compat/SodiumCompat.java | 40 ++ .../mixin/SodiumOptionsGUIAccessor.java | 19 + .../client/controller/ButtonBinding.java | 9 +- .../client/controller/Controller.java | 9 +- .../client/controller/InputHandlers.java | 6 +- .../client/controller/InputManager.java | 8 +- .../client/gui/MidnightControlsHud.java | 17 +- .../client/gui/MidnightControlsRenderer.java | 4 +- .../gui/MidnightControlsSettingsScreen.java | 28 +- .../client/gui/RingScreen.java | 6 +- .../client/gui/TouchscreenOverlay.java | 510 +++++++++--------- .../gui/widget/ControllerControlsWidget.java | 2 + .../widget/SilentTexturedButtonWidget.java | 26 + .../client/mixin/ClientPlayerEntityMixin.java | 9 +- .../CreativeInventoryScreenAccessor.java | 4 +- .../client/mixin/KeyBindingMixin.java | 2 +- .../mixin/KeyBindingRegistryImplAccessor.java | 17 + .../client/mixin/MinecraftClientMixin.java | 22 +- .../client/ring/MidnightRing.java | 20 +- .../client/ring/RingPage.java | 55 ++ .../assets/midnightcontrols/lang/de_de.json | 1 + .../assets/midnightcontrols/lang/en_us.json | 1 + .../resources/midnightcontrols.mixins.json | 3 +- .../midnightcontrols_compat.mixins.json | 1 + .../resourcepacks/bedrock/pack.mcmeta | 2 +- 38 files changed, 653 insertions(+), 465 deletions(-) delete mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/compat/SodiumCompat.java create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/SodiumOptionsGUIAccessor.java create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/SilentTexturedButtonWidget.java create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingRegistryImplAccessor.java diff --git a/README.md b/README.md index 268155f..06a4eaa 100644 --- a/README.md +++ b/README.md @@ -32,16 +32,16 @@ This mod also adds controller support. - Front block placing (be careful with this one) - New controls settings! - Many options in config to change to your liking. -- Many controllers supported and in a simply way your own controller mappings. +- Many controllers supported and in a simple way your own controller mappings. - An easy API for developers to add their own button bindings. ## 🎮 Supported Controllers: -- Dualshock controllers -- Dualsense controllers +- DualShock controllers +- DualSense controllers - Xbox controllers - Switch Pro controllers -- Joycons +- Joy-Cons - Steam controller and Steam Deck (WIP) - And many more! diff --git a/build.gradle b/build.gradle index 853b831..9a0fc90 100644 --- a/build.gradle +++ b/build.gradle @@ -110,7 +110,7 @@ dependencies { // modImplementation "io.github.ennuil:LibZoomer:${project.libzoomer_version}" modImplementation "org.quiltmc:quilt-json5:1.0.0" - //modImplementation "maven.modrinth:sodium:${project.sodium_version}" + modImplementation "maven.modrinth:sodium:${project.sodium_version}" //modImplementation("maven.modrinth:emi:${project.emi_version}") modImplementation "maven.modrinth:emotecraft:${project.emotecraft_version}" modImplementation "io.github.kosmx:bendy-lib:${project.bendylib_version}" diff --git a/gradle.properties b/gradle.properties index ec8cf84..c01b66f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ yarn_mappings=1.19+build.1 loader_version=0.14.7 # Mod Properties -mod_version = 1.1.0 +mod_version = 1.2.0 maven_group = eu.midnightdust archives_base_name = midnightcontrols modrinth_id=bXX9h73M @@ -16,7 +16,7 @@ modrinth_id=bXX9h73M # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api fabric_version=0.55.2+1.19 -sodium_version=mc1.19-0.4.1 +sodium_version=mc1.19-0.4.2 spruceui_version=4.0.0+1.19 midnightlib_version=0.5.2 modmenu_version=4.0.0 diff --git a/src/main/java/eu/midnightdust/midnightcontrols/ControlsMode.java b/src/main/java/eu/midnightdust/midnightcontrols/ControlsMode.java index cb45f8b..fcc4523 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/ControlsMode.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/ControlsMode.java @@ -24,7 +24,8 @@ import java.util.Optional; */ public enum ControlsMode implements Nameable { DEFAULT, - CONTROLLER; + CONTROLLER, + TOUCHSCREEN; /** * Returns the next controls mode available. diff --git a/src/main/java/eu/midnightdust/midnightcontrols/MidnightControls.java b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControls.java index fb1d0ae..063f578 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/MidnightControls.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControls.java @@ -37,14 +37,14 @@ public class MidnightControls implements ModInitializer { public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString()); public static final Identifier FEATURE_CHANNEL = new Identifier(MidnightControlsConstants.FEATURE_CHANNEL.toString()); public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString()); - - public static final Text NOT_BOUND_TEXT = Text.translatable("midnightcontrols.not_bound"); + public static boolean isExtrasLoaded; public final Logger logger = LogManager.getLogger("MidnightControls"); @Override public void onInitialize() { INSTANCE = this; + isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra"); this.log("Initializing MidnightControls..."); ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsFeature.java b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsFeature.java index 18a9cd4..316ad14 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsFeature.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsFeature.java @@ -61,7 +61,7 @@ public class MidnightControlsFeature implements Nameable { * @return {@code true} if this feature is allowed, else {@code false} */ public boolean isAllowed() { - return this.allowed; + return MidnightControls.isExtrasLoaded && this.allowed; } /** diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java index 36147eb..17713b7 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java @@ -16,10 +16,13 @@ import eu.midnightdust.midnightcontrols.MidnightControlsConstants; import eu.midnightdust.midnightcontrols.MidnightControlsFeature; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory; import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsHud; +import eu.midnightdust.midnightcontrols.client.gui.RingScreen; import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; +import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingRegistryImplAccessor; import eu.midnightdust.midnightcontrols.client.ring.KeyBindingRingAction; import eu.midnightdust.midnightcontrols.client.ring.MidnightRing; import dev.lambdaurora.spruceui.hud.HudManager; @@ -51,6 +54,7 @@ import java.io.File; * @since 1.1.0 */ public class MidnightControlsClient extends MidnightControls implements ClientModInitializer { + public static boolean lateInitDone = false; private static MidnightControlsClient INSTANCE; public static final KeyBinding BINDING_LOOK_UP = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_up"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_8, "key.categories.movement"); @@ -60,8 +64,8 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement"); public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_left"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement"); - /*public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(midnightcontrolsConstants.NAMESPACE, "ring"), - InputUtil.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_5, "key.categories.misc");*/ + public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "ring"), + InputUtil.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_5, "key.categories.misc"); public static final Identifier CONTROLLER_BUTTONS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_buttons.png"); public static final Identifier CONTROLLER_EXPANDED = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_expanded.png"); public static final Identifier CONTROLLER_AXIS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_axis.png"); @@ -83,10 +87,10 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo //KeyBindingHelper.registerKeyBinding(BINDING_RING); this.ring.registerAction("keybinding", KeyBindingRingAction.FACTORY); + this.ring.load(); - ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) -> { - responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)); - }); + ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) -> + responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode))); ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> { int features = buf.readVarInt(); for (int i = 0; i < features; i++) { @@ -102,23 +106,22 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave); ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick); - ClientTickEvents.END_CLIENT_TICK.register(this::onTick); + ClientTickEvents.START_CLIENT_TICK.register(this::onTick); OpenScreenCallback.EVENT.register((client, screen) -> { -// if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) { -// screen = new TouchscreenOverlay(this); -// screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); -// client.skipGameRender = false; -// client.currentScreen = screen; -// } else if (screen != null) { + if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) { + screen = new TouchscreenOverlay(this); + screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); + client.skipGameRender = false; + client.currentScreen = screen; + } else if (screen != null) { this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight()); - //} + } }); HudManager.register(this.hud = new MidnightControlsHud(this)); - FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> { - ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL); - }); + FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> + ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL)); } /** @@ -144,6 +147,35 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo MidnightControlsCompat.init(this); } + ButtonCategory category; + /** + * This method is called to initialize keybindings + */ + public void initKeybindings() { + if (lateInitDone) return; + if (KeyBindingRegistryImplAccessor.getModdedKeyBindings() == null || KeyBindingRegistryImplAccessor.getModdedKeyBindings().isEmpty()) return; + for (int i = 0; i < KeyBindingRegistryImplAccessor.getModdedKeyBindings().size(); ++i) { + KeyBinding keyBinding = KeyBindingRegistryImplAccessor.getModdedKeyBindings().get(i); + if (!keyBinding.getTranslationKey().contains("midnightcontrols")) { + category = null; + InputManager.streamCategories().forEach(buttonCategory -> { + if (buttonCategory.getIdentifier().equals(new org.aperlambda.lambdacommon.Identifier("minecraft", keyBinding.getCategory()))) + category = buttonCategory; + }); + if (category == null) { + category = new ButtonCategory(new org.aperlambda.lambdacommon.Identifier("minecraft", keyBinding.getCategory())); + InputManager.registerCategory(category); + } + ButtonBinding buttonBinding = new ButtonBinding.Builder(keyBinding.getTranslationKey()).category(category).linkKeybind(keyBinding).register(); + if (MidnightControlsConfig.debug) { + logger.info(keyBinding.getTranslationKey()); + logger.info(buttonBinding); + } + } + } + InputManager.loadButtonBindings(); + lateInitDone = true; + } /** * This method is called every Minecraft tick. @@ -151,15 +183,15 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo * @param client the client instance */ public void onTick(@NotNull MinecraftClient client) { + this.initKeybindings(); this.input.tick(client); if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput)) this.input.tickController(client); - /*if (BINDING_RING.wasPressed()) { - client.openScreen(new RingScreen()); - }*/ + if (BINDING_RING.wasPressed()) { + client.setScreen(new RingScreen()); + } } - public void onRender(MinecraftClient client) { this.input.onRender(client.getTickDelta(), client); } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java index 35a75b3..c457a4b 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java @@ -11,6 +11,7 @@ package eu.midnightdust.midnightcontrols.client; import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.MidnightControlsFeature; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.Controller; @@ -38,6 +39,7 @@ public class MidnightControlsConfig extends MidnightConfig { @Entry public static HudSide hudSide = HudSide.LEFT; // Gameplay @Entry public static boolean analogMovement = true; + @Entry public static boolean doubleTapToSprint = true; @Entry public static boolean fastBlockPlacing = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers. @Entry public static boolean flyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers. It can also conflict with some other mods. @Entry public static boolean verticalFlyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers. @@ -45,8 +47,6 @@ public class MidnightControlsConfig extends MidnightConfig { @Entry public static boolean verticalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers. @Entry public static boolean shouldRenderReacharoundOutline = true; @Entry public static int[] reacharoundOutlineColor = new int[]{255, 255, 255, 102}; - // Controller - @Entry public static ControllerType controllerType = ControllerType.DEFAULT; @Entry public static double rightDeadZone = 0.25; @Entry public static double leftDeadZone = 0.25; @Entry public static boolean invertRightYAxis = false; @@ -59,6 +59,7 @@ public class MidnightControlsConfig extends MidnightConfig { @Entry public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT; @Entry public static Object controllerID = 0; @Entry public static Object secondControllerID = -1; + @Entry public static ControllerType controllerType = ControllerType.DEFAULT; @Entry public static List mouseScreens = List.of("me.jellysquid.mods.sodium.client.gui","net.coderbot.iris.gui","net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui"); @Entry public static Map BINDINGS = Map.of(); @@ -251,4 +252,55 @@ public class MidnightControlsConfig extends MidnightConfig { public static boolean isMovementAxis(int axis) { return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X; } + + public static void reset() { + controlsMode = ControlsMode.DEFAULT; + autoSwitchMode = true; + debug = false; + hudEnable = true; + hudSide = HudSide.LEFT; + analogMovement = true; + doubleTapToSprint = true; + fastBlockPlacing = false; + flyDrifting = true; + verticalFlyDrifting = true; + horizontalReacharound = false; + verticalReacharound = false; + shouldRenderReacharoundOutline = true; + reacharoundOutlineColor = new int[]{255, 255, 255, 102}; + rightDeadZone = 0.25; + leftDeadZone = 0.25; + invertRightYAxis = false; + invertRightXAxis = false; + DEFAULT_MAX_VALUE = 1; + rotationSpeed = 40.0; + mouseSpeed = 25.0; + unfocusedInput = false; + virtualMouse = false; + virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT; + controllerID = 0; + secondControllerID = -1; + controllerType = ControllerType.DEFAULT; + mouseScreens = List.of("me.jellysquid.mods.sodium.client.gui","net.coderbot.iris.gui","net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui"); + BINDINGS = Map.of(); + maxAnalogValues = new double[]{DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE}; + } + + /** + * Gets the controller type from the controller's identifier. + * + * @return the controller name matches a type, else empty + */ + public static @NotNull ControllerType matchControllerToType() { + String controller = getController().getName().toLowerCase(); + if (controller.contains("xbox 360")) return ControllerType.XBOX_360; + else if (controller.contains("xbox") || controller.contains("afterglow")) return ControllerType.XBOX; + else if (controller.contains("steam deck")) return ControllerType.STEAM_DECK; + else if (controller.contains("steam")) return ControllerType.STEAM_CONTROLLER; + else if (controller.contains("dualsense")) return ControllerType.DUALSENSE; + else if (controller.contains("dualshock") || controller.contains("ps4")) return ControllerType.DUALSHOCK; + else if (controller.contains("switch") || controller.contains("joy-con")) return ControllerType.SWITCH; + else if (controller.contains("ouya")) return ControllerType.OUYA; + else return ControllerType.DEFAULT; + } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java index 241a386..3bc2592 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java @@ -10,7 +10,11 @@ package eu.midnightdust.midnightcontrols.client; import com.google.common.collect.ImmutableSet; +import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget; +import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget; +import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; +import eu.midnightdust.midnightcontrols.client.compat.SodiumCompat; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.InputManager; @@ -28,6 +32,7 @@ import dev.lambdaurora.spruceui.widget.SpruceElement; import dev.lambdaurora.spruceui.widget.SpruceLabelWidget; import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget; import net.fabricmc.fabric.impl.item.group.CreativeGuiExtensions; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.ParentElement; @@ -37,6 +42,7 @@ import net.minecraft.client.gui.screen.advancement.AdvancementTab; import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.screen.ingame.MerchantScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget; import net.minecraft.client.gui.screen.world.WorldListWidget; @@ -277,7 +283,7 @@ public class MidnightInput { } if (action == 0 || action == 2) { - if (client.currentScreen != null && isScreenInteractive(client.currentScreen) + if (client.currentScreen != null && (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)) { if (this.actionGuiCooldown == 0) { @@ -304,11 +310,6 @@ public class MidnightInput { } } - if (this.handleInventory(client, button)) { - this.ignoreNextARelease = true; - return; - } - if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) { if (client.currentScreen != null && client.currentScreen.getClass() != TitleScreen.class) { if (!MidnightControlsCompat.handleMenuBack(client, client.currentScreen)) @@ -341,65 +342,6 @@ public class MidnightInput { } } /** - * Handles inventory interaction. - * - * @param client the client instance - * @param button the button pressed - * @return {@code true} if an inventory interaction was done - */ - private boolean handleInventory(@NotNull MinecraftClient client, int button) { -// if (!(client.currentScreen instanceof HandledScreen screen)) -// return false; -// -// if (client.interactionManager == null || client.player == null) -// return false; -// -// if (this.inventoryInteractionCooldown > 0) -// return true; -// -// if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) { -// client.player.closeHandledScreen(); -// return true; -// } -// -// double x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); -// double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); -// -// var accessor = (HandledScreenAccessor) screen; -// Slot slot = ((HandledScreenAccessor) client.currentScreen).midnightcontrols$getSlotAt(x, y); -// -// int slotId; -// if (slot == null) { -// if (client.player.currentScreenHandler.getCursorStack().isEmpty()) -// return false; -// slotId = accessor.midnightcontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1; -// } else { -// slotId = slot.id; -// } -// -// var actionType = SlotActionType.PICKUP; -// int clickData = GLFW.GLFW_MOUSE_BUTTON_1; -// switch (button) { -// case GLFW_GAMEPAD_BUTTON_A: -// if (screen instanceof CreativeInventoryScreen) -// if (((CreativeInventoryScreenAccessor) screen).midnightcontrols$isCreativeInventorySlot(slot)) -// actionType = SlotActionType.CLONE; -// if (slot != null && MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot))) -// actionType = SlotActionType.CLONE; -// break; -// case GLFW.GLFW_GAMEPAD_BUTTON_X: -// clickData = GLFW_MOUSE_BUTTON_2; -// break; -// case GLFW.GLFW_GAMEPAD_BUTTON_Y: -// actionType = SlotActionType.QUICK_MOVE; -// break; -// default: -// return false; -// } -// -// accessor.midnightcontrols$onMouseClick(slot, slotId, clickData, actionType); - return false; - } /** * Tries to go back. @@ -502,6 +444,14 @@ public class MidnightInput { } return; } + } else if (client.currentScreen instanceof MerchantScreen merchantScreen) { + if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { + // @TODO allow rebinding to left stick + if (absValue >= deadZone) { + merchantScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f)); + } + return; + } } else if (client.currentScreen instanceof AdvancementsScreen advancementsScreen) { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X || axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { var accessor = (AdvancementsScreenAccessor) advancementsScreen; @@ -520,6 +470,14 @@ public class MidnightInput { element.mouseScrolled(0.0, 0.0, -value); return true; }); + client.currentScreen.children().stream().filter(element -> element instanceof SpruceEntryListWidget) + .map(element -> (SpruceEntryListWidget) element) + .filter(element -> element.getType().isFocused()) + .anyMatch(element -> { + MidnightControls.get().log(String.valueOf(value)); + element.mouseScrolled(0.0, 0.0, -value); + return true; + }); return; } } @@ -701,6 +659,7 @@ public class MidnightInput { } return false; } + if (FabricLoader.getInstance().isModLoaded("sodium")) SodiumCompat.handleInput(screen, direction.isLookingForward()); if (!screen.changeFocus(direction.isLookingForward())) { if (screen.changeFocus(direction.isLookingForward())) { this.actionGuiCooldown = 5; diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java index 1a0b10b..6c1f8f4 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java @@ -144,7 +144,7 @@ public class MidnightReacharound { return null; } - return new BlockHitResult(client.crosshairTarget.getPos(), direction, blockPos, false); + return new BlockHitResult(new Vec3d(blockPos.getX(),blockPos.getY(),blockPos.getZ()), direction, blockPos, false); } return null; } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java deleted file mode 100644 index 0c13979..0000000 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright © 2021 LambdAurora - * - * This file is part of midnightcontrols. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package eu.midnightdust.midnightcontrols.client.compat; - -import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; -import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; -import io.github.kosmx.emotes.arch.gui.screen.ingame.FastChosseScreen; -import io.github.kosmx.emotes.main.network.ClientEmotePlay; -import org.jetbrains.annotations.NotNull; - -/** - * Represents a compatibility handler for Emotecraft. - * - * @author Motschen - * @version 1.4.3 - * @since 1.0.0 - */ -public class EmotecraftCompat implements CompatHandler { - @Override - public void handle(@NotNull MidnightControlsClient mod) { - new ButtonBinding.Builder("key.emotecraft.fastchoose") - .buttons(16) - .onlyInGame() - .cooldown(true) - .category(ButtonBinding.MISC_CATEGORY) - .action((client, button, value, action) -> { - client.setScreen(new FastChosseScreen(null)); - return true; - }) - .register(); - new ButtonBinding.Builder("key.emotecraft.stop") - .buttons(17) - .onlyInGame() - .cooldown(true) - .category(ButtonBinding.MISC_CATEGORY) - .action((client, button, value, action) -> { - ClientEmotePlay.clientStopLocalEmote(); - return true; - }) - .register(); - } -} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java index 7c7459a..6f23cb2 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java @@ -53,10 +53,6 @@ public class MidnightControlsCompat { mod.log("Adding HQM compatibility..."); HANDLERS.add(new HQMCompat()); } - if (FabricLoader.getInstance().isModLoaded("emotecraft")) { - mod.log("Adding Emotecraft compatibility..."); - HANDLERS.add(new EmotecraftCompat()); - } HANDLERS.forEach(handler -> handler.handle(mod)); InputManager.loadButtonBindings(); } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java index d746747..f08a33c 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java @@ -9,6 +9,7 @@ package eu.midnightdust.midnightcontrols.client.compat; +import net.fabricmc.loader.api.FabricLoader; import org.jetbrains.annotations.NotNull; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; @@ -33,6 +34,7 @@ public class MidnightControlsMixinPlugin implements IMixinConfigPlugin { this.putConditionalMixin("EntryWidgetAccessor", MidnightControlsCompat.isReiPresent()); this.putConditionalMixin("RecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent()); this.putConditionalMixin("VillagerRecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent()); + this.putConditionalMixin("SodiumOptionsGUIAccessor", FabricLoader.getInstance().isModLoaded("sodium")); } private void putConditionalMixin(@NotNull String path, boolean condition) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/SodiumCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/SodiumCompat.java new file mode 100644 index 0000000..1acf08c --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/SodiumCompat.java @@ -0,0 +1,40 @@ +package eu.midnightdust.midnightcontrols.client.compat; + +import eu.midnightdust.midnightcontrols.MidnightControls; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.compat.mixin.SodiumOptionsGUIAccessor; +import eu.midnightdust.midnightcontrols.client.controller.InputManager; +import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI; +import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; + +public class SodiumCompat { + private static final MinecraftClient client = MinecraftClient.getInstance(); + public static void handleInput(Screen screen, boolean direction) { + if (screen instanceof SodiumOptionsGUI optionsGUI) { + SodiumOptionsGUIAccessor accessor = (SodiumOptionsGUIAccessor) optionsGUI; + final int max = accessor.getControls().size()-1; + + var option = accessor.getControls().stream().filter(ControlElement::isHovered).findFirst().orElse(accessor.getControls().get(0)); + int i = accessor.getControls().indexOf(option); + i = (direction ? ((max > i) ? ++i : 0) : (i > 0 ? --i : max)); + + var dimensions = accessor.getControls().get(i).getDimensions(); + InputManager.INPUT_MANAGER.targetMouseX = (int) (client.getWindow().getScaleFactor() * dimensions.getCenterX()); + InputManager.INPUT_MANAGER.targetMouseY = (int) (client.getWindow().getScaleFactor() * dimensions.getCenterY()); + MidnightControlsClient.get().input.actionGuiCooldown = 5; + MidnightControls.get().log(i+" "+accessor.getControls().size()+" | " + dimensions.getCenterX() + " " + dimensions.getCenterY()); + } + } + public static void handleTabs(Screen screen, boolean direction) { + if (screen instanceof SodiumOptionsGUI optionsGUI) { + SodiumOptionsGUIAccessor accessor = (SodiumOptionsGUIAccessor) optionsGUI; + final int max = accessor.getPages().size()-1; + int i = accessor.getPages().indexOf(accessor.getCurrentPage()); + i = (direction ? ((max > i) ? ++i : 0) : (i > 0 ? --i : max)); + MidnightControls.get().log(""+i); + optionsGUI.setPage(accessor.getPages().get(i)); + } + } +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/SodiumOptionsGUIAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/SodiumOptionsGUIAccessor.java new file mode 100644 index 0000000..eaed0c3 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/SodiumOptionsGUIAccessor.java @@ -0,0 +1,19 @@ +package eu.midnightdust.midnightcontrols.client.compat.mixin; + +import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI; +import me.jellysquid.mods.sodium.client.gui.options.OptionPage; +import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(value = SodiumOptionsGUI.class, remap = false) +public interface SodiumOptionsGUIAccessor { + @Accessor + List> getControls(); + @Accessor + List getPages(); + @Accessor + OptionPage getCurrentPage(); +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java index 422a9eb..0c8e59f 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java @@ -13,6 +13,7 @@ import eu.midnightdust.midnightcontrols.client.ButtonState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.resource.language.I18n; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import org.aperlambda.lambdacommon.utils.function.PairPredicate; @@ -75,9 +76,9 @@ public class ButtonBinding { public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).onlyInGame().register(); public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register(); public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) - .action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register(); + .action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null && client.currentScreen.getClass().toString().contains("sodium"))).cooldown().register(); public static final ButtonBinding TAB_RIGHT = new Builder("tab_next").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) - .action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register(); + .action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null && client.currentScreen.getClass().toString().contains("sodium"))).cooldown().register(); public static final ButtonBinding PAGE_LEFT = new Builder("page_back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)) .action(InputHandlers.handlePage(false)).filter(InputHandlers::inInventory).cooldown().register(); public static final ButtonBinding PAGE_RIGHT = new Builder("page_next").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)) @@ -248,7 +249,7 @@ public class ButtonBinding { * @return the translation key */ public @NotNull String getTranslationKey() { - return "midnightcontrols.action." + this.getName(); + return I18n.hasTranslation("midnightcontrols.action." + this.getName()) ? "midnightcontrols.action." + this.getName() : this.getName(); } public @NotNull Text getText() { @@ -440,7 +441,7 @@ public class ButtonBinding { } public Builder(@NotNull Identifier identifier) { - this(identifier.getNamespace() + "." + identifier.getNamespace()); + this(identifier.getNamespace() + "." + identifier.getPath()); } /** diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/Controller.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/Controller.java index 5859047..87c397b 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/Controller.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/Controller.java @@ -13,6 +13,7 @@ import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.resource.language.I18n; import net.minecraft.client.toast.SystemToast; import net.minecraft.text.Text; import org.aperlambda.lambdacommon.utils.Nameable; @@ -136,7 +137,7 @@ public record Controller(int id) implements Nameable { } } - buffer.flip(); // Force Java 8 >.< + if (buffer != null) buffer.flip(); // Force Java 8 >.< return buffer; } @@ -149,7 +150,6 @@ public record Controller(int id) implements Nameable { File databaseFile = new File("config/gamecontrollerdatabase.txt"); try { BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream()); - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile)); byte[] dataBuffer = new byte[1024]; int bytesRead; @@ -159,11 +159,11 @@ public record Controller(int id) implements Nameable { out.close(); } catch (Exception ignored) {/* Just continue when internet connection is not available */} var database = ioResourceToBuffer(databaseFile.getPath(), 1024); - GLFW.glfwUpdateGamepadMappings(database); + if (database != null) GLFW.glfwUpdateGamepadMappings(database); if (!MidnightControlsClient.MAPPINGS_FILE.exists()) return; var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024); - GLFW.glfwUpdateGamepadMappings(buffer); + if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer); } catch (IOException e) { e.printStackTrace(); } @@ -178,6 +178,7 @@ public record Controller(int id) implements Nameable { if (client != null) { client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT, Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string))); + MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string); } } } catch (Throwable e) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java index 18fb149..b42e4cf 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java @@ -13,11 +13,13 @@ import eu.midnightdust.midnightcontrols.client.ButtonState; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightInput; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; +import eu.midnightdust.midnightcontrols.client.compat.SodiumCompat; import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor; import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor; import eu.midnightdust.midnightcontrols.client.mixin.RecipeBookWidgetAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import net.fabricmc.fabric.impl.item.group.CreativeGuiExtensions; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gl.Framebuffer; import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; @@ -64,7 +66,7 @@ public class InputHandlers { client.player.getInventory().selectedSlot = client.player.getInventory().selectedSlot == 0 ? 8 : client.player.getInventory().selectedSlot - 1; return true; } else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) { - int currentTab = inventory.getSelectedTab(); + int currentTab = CreativeInventoryScreenAccessor.getSelectedTab(); int nextTab = currentTab + (next ? 1 : -1); if (nextTab < 0) nextTab = ItemGroup.GROUPS.length - 1; @@ -105,7 +107,7 @@ public class InputHandlers { } } return true; - } + } else if (FabricLoader.getInstance().isModLoaded("sodium")) SodiumCompat.handleTabs(client.currentScreen, next); return false; }; } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputManager.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputManager.java index 5ed4253..9b8ce30 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputManager.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputManager.java @@ -42,10 +42,10 @@ public class InputManager { private static final List CATEGORIES = new ArrayList<>(); public static final Int2ObjectMap STATES = new Int2ObjectOpenHashMap<>(); public static final Int2FloatMap BUTTON_VALUES = new Int2FloatOpenHashMap(); - private int prevTargetMouseX = 0; - private int prevTargetMouseY = 0; - private int targetMouseX = 0; - private int targetMouseY = 0; + public int prevTargetMouseX = 0; + public int prevTargetMouseY = 0; + public int targetMouseX = 0; + public int targetMouseY = 0; protected InputManager() { } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java index a2b5c3c..127bc8f 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java @@ -53,6 +53,7 @@ public class MidnightControlsHud extends Hud { private String attackAction = ""; private String placeAction = ""; private int ticksDisplayedCrosshair = 0; + private static float scale = 1f; public MidnightControlsHud(@NotNull MidnightControlsClient mod) { super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator")); @@ -71,8 +72,12 @@ public class MidnightControlsHud extends Hud { this.dropItemButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.DROP_ITEM); this.attackButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.ATTACK); this.useButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.USE); + if (client.options.getGuiScale().getValue() >= 4) { + scale = 0.75f * (client.options.getGuiScale().getValue() -3); + } else scale = 1f; } + /** * Renders the midnightcontrols' HUD. */ @@ -80,10 +85,12 @@ public class MidnightControlsHud extends Hud { public void render(MatrixStack matrices, float tickDelta) { if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && this.client.currentScreen == null) { int y = bottom(2); - this.renderFirstIcons(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); - this.renderSecondIcons(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); - this.renderFirstSection(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); - this.renderSecondSection(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); + if (scale != 1f) matrices.scale(scale,scale,scale); + this.renderFirstIcons(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y); + this.renderSecondIcons(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y); + this.renderFirstSection(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y); + this.renderSecondSection(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y); + if (scale != 1f) matrices.scale(1,1,1); } if (this.mod.reacharound.isLastReacharoundVertical()) { @@ -246,7 +253,7 @@ public class MidnightControlsHud extends Hud { } private int bottom(int y) { - return this.client.getWindow().getScaledHeight() - y - MidnightControlsRenderer.ICON_SIZE; + return (int) ((this.client.getWindow().getScaledHeight() * (1/scale)) - y - MidnightControlsRenderer.ICON_SIZE); } private int width(@NotNull ButtonBinding binding) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java index 9cdc41f..c1be1aa 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java @@ -10,6 +10,8 @@ package eu.midnightdust.midnightcontrols.client.gui; import com.mojang.blaze3d.systems.RenderSystem; +import eu.midnightdust.midnightcontrols.MidnightControls; +import eu.midnightdust.midnightcontrols.client.ControllerType; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightInput; @@ -106,7 +108,7 @@ public class MidnightControlsRenderer { second = true; } - int controllerType = MidnightControlsConfig.controllerType.getId(); + int controllerType = MidnightControlsConfig.controllerType == ControllerType.DEFAULT ? MidnightControlsConfig.matchControllerToType().getId() : MidnightControlsConfig.controllerType.getId(); boolean axis = false; int buttonOffset = button * 15; switch (button) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java index 8941f10..a015f22 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java @@ -60,6 +60,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { private final SpruceOption resetOption; // Gameplay options private final SpruceOption analogMovementOption; + private final SpruceOption doubleTapToSprintOption; private final SpruceOption autoJumpOption; private final SpruceOption fastBlockPlacingOption; private final SpruceOption frontBlockPlacingOption; @@ -177,7 +178,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { Text.translatable("midnightcontrols.tooltip.mouse_speed")); this.resetOption = SpruceSimpleActionOption.reset(btn -> { // TODO - MidnightControlsConfig.init("midnightcontrols", MidnightControlsConfig.class); + MidnightControlsConfig.reset(); var client = MinecraftClient.getInstance(); this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); }); @@ -185,6 +186,9 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { this.analogMovementOption = new SpruceToggleBooleanOption("midnightcontrols.menu.analog_movement", () -> MidnightControlsConfig.analogMovement, value -> MidnightControlsConfig.analogMovement = value, Text.translatable("midnightcontrols.tooltip.analog_movement")); + this.doubleTapToSprintOption = new SpruceToggleBooleanOption("midnightcontrols.menu.double_tap_to_sprint", + () -> MidnightControlsConfig.doubleTapToSprint, value -> MidnightControlsConfig.doubleTapToSprint = value, + Text.translatable("midnightcontrols.tooltip.double_tap_to_sprint")); this.autoJumpOption = new SpruceToggleBooleanOption("options.autoJump", () -> this.client.options.getAutoJump().getValue(), newValue -> this.client.options.getAutoJump().setValue(newValue), @@ -292,6 +296,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { public SpruceOptionListWidget buildGeneralTab(int width, int height) { var list = new SpruceOptionListWidget(Position.origin(), width, height); + list.setBackground(new MidnightControlsBackground(130)); list.addSingleOptionEntry(this.inputModeOption); list.addSingleOptionEntry(this.autoSwitchModeOption); list.addSingleOptionEntry(this.rotationSpeedOption); @@ -302,18 +307,21 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { public SpruceOptionListWidget buildGameplayTab(int width, int height) { var list = new SpruceOptionListWidget(Position.origin(), width, height); + list.setBackground(new MidnightControlsBackground(130)); list.addSingleOptionEntry(this.analogMovementOption); - list.addSingleOptionEntry(this.fastBlockPlacingOption); - list.addSingleOptionEntry(this.frontBlockPlacingOption); - list.addSingleOptionEntry(this.verticalReacharoundOption); - list.addSingleOptionEntry(this.flyDriftingOption); - list.addSingleOptionEntry(this.flyVerticalDriftingOption); + list.addSingleOptionEntry(this.doubleTapToSprintOption); + if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.fastBlockPlacingOption); + if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.frontBlockPlacingOption); + if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.verticalReacharoundOption); + if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.flyDriftingOption); + if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.flyVerticalDriftingOption); list.addSingleOptionEntry(this.autoJumpOption); return list; } public SpruceOptionListWidget buildVisualTab(int width, int height) { var list = new SpruceOptionListWidget(Position.origin(), width, height); + list.setBackground(new MidnightControlsBackground(130)); list.addSingleOptionEntry(this.controllerTypeOption); list.addSingleOptionEntry(this.virtualMouseSkinOption); list.addSingleOptionEntry(new SpruceSeparatorOption("midnightcontrols.menu.title.hud", true, null)); @@ -352,6 +360,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { labels.addChild(aboutMappings3); var list = new SpruceOptionListWidget(Position.origin(), width, listHeight); + list.setBackground(new MidnightControlsBackground(130)); list.addSingleOptionEntry(this.controllerOption); list.addSingleOptionEntry(this.secondControllerOption); list.addSingleOptionEntry(this.unfocusedInputOption); @@ -377,6 +386,11 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { } public static class MidnightControlsBackground implements Background { + private int transparency = 160; + public MidnightControlsBackground() {} + public MidnightControlsBackground(int transparency) { + this.transparency = transparency; + } @Override public void render(MatrixStack matrixStack, SpruceWidget widget, int vOffset, int mouseX, int mouseY, float delta) { fill(matrixStack, widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight(), MidnightColorUtil.hex2Rgb("#000000")); @@ -388,7 +402,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen { float r = (float)(color.getRed()) / 255.0F; float g = (float)(color.getGreen()) / 255.0F; float b = (float)(color.getBlue()) / 255.0F; - float t = (float)(160) / 255.0F; + float t = (float)(transparency) / 255.0F; BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer(); RenderSystem.enableBlend(); RenderSystem.disableTexture(); diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/RingScreen.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/RingScreen.java index 8ee1f17..5491e58 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/RingScreen.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/RingScreen.java @@ -46,10 +46,10 @@ public class RingScreen extends Screen { @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { - /*if (midnightcontrolsClient.BINDING_RING.matchesMouse(button)) { - this.onClose(); + if (mod.ring.getCurrentPage().onClick(client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight(), (int) mouseX, (int) mouseY)) { + this.close(); return true; - }*/ + } return false; } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java index 8273a21..9a73ad6 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java @@ -9,18 +9,18 @@ package eu.midnightdust.midnightcontrols.client.gui; -import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget; +import dev.lambdaurora.spruceui.Position; +import dev.lambdaurora.spruceui.widget.SpruceButtonWidget; import eu.midnightdust.midnightcontrols.client.HudSide; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.gui.widget.SilentTexturedButtonWidget; import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.client.gui.screen.GameMenuScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.TexturedButtonWidget; -import net.minecraft.client.option.KeyBinding; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.text.Text; import net.minecraft.util.Arm; @@ -37,265 +37,259 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y; * Represents the touchscreen overlay */ public class TouchscreenOverlay extends Screen { - public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png"); - private MidnightControlsClient mod; - private SpruceTexturedButtonWidget jumpButton; - private SpruceTexturedButtonWidget flyButton; - private SpruceTexturedButtonWidget flyUpButton; - private SpruceTexturedButtonWidget flyDownButton; - private int flyButtonEnableTicks = 0; - private int forwardButtonTick = 0; - private SpruceTexturedButtonWidget forwardLeftButton; - private SpruceTexturedButtonWidget forwardRightButton; - private SpruceTexturedButtonWidget startSneakButton; - private SpruceTexturedButtonWidget endSneakButton; + public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png"); + private MidnightControlsClient mod; + private SilentTexturedButtonWidget jumpButton; + private SilentTexturedButtonWidget flyButton; + private SilentTexturedButtonWidget flyUpButton; + private SilentTexturedButtonWidget flyDownButton; + private int flyButtonEnableTicks = 0; + private int forwardButtonTick = 0; + private SilentTexturedButtonWidget forwardLeftButton; + private SilentTexturedButtonWidget forwardRightButton; + private SilentTexturedButtonWidget startSneakButton; + private SilentTexturedButtonWidget endSneakButton; - public TouchscreenOverlay(@NotNull MidnightControlsClient mod) - { + public TouchscreenOverlay(@NotNull MidnightControlsClient mod) { super(Text.literal("Touchscreen overlay")); this.mod = mod; this.passEvents = true; } -// @Override -// public boolean shouldPause() -// { -// return false; -// } -// -// @Override -// public boolean keyPressed(int keyCode, int scanCode, int modifiers) -// { -// super.keyPressed(keyCode,scanCode,modifiers); -// //return false; -// return true; -// } -// -// private void pauseGame(boolean bl) -// { -// if (this.client == null) -// return; -// boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote(); -// if (bl2) { -// this.client.setScreen(new GameMenuScreen(!bl)); -// this.client.getSoundManager().pauseAll(); -// } else { -// this.client.setScreen(new GameMenuScreen(true)); -// } -// } -// -// /** -// * Updates the forward button ticks cooldown. -// * -// * @param state The button state. -// * -// */ -// private void updateForwardButtonsState(boolean state) -// { -// if (state) -// this.forwardButtonTick = -1; -// else -// this.forwardButtonTick = 20; -// } -// -// /** -// * Updates the jump buttons. -// */ -// private void updateJumpButtons() -// { -// if (this.client == null) -// return; -// if (!this.client.interactionManager.isFlyingLocked()) { -// boolean oldStateFly = this.flyButton.visible; -// this.jumpButton.visible = false; -// this.flyButton.visible = true; -// this.flyUpButton.visible = true; -// this.flyDownButton.visible = true; -// if (oldStateFly != this.flyButton.visible) { -// this.flyButtonEnableTicks = 5; -// this.handleJump(null, false); -// } else if (this.flyButtonEnableTicks > 0) -// this.flyButtonEnableTicks--; -// } else { -// this.jumpButton.visible = true; -// this.flyButton.visible = false; -// this.flyUpButton.visible = false; -// this.flyDownButton.visible = false; -// } -// } -// -// /** -// * Handles the jump button. -// * -// * @param btn The pressed button. -// * @param state The state of the jump button. -// */ -// private void handleJump(ButtonWidget btn, boolean state) -// { -// ((KeyBindingAccessor) this.client.options.keyJump).midnightcontrols$handlePressState(state); -// } -// -// @Override -// public void tick() -// { -// if (this.forwardButtonTick > 0) { -// this.forwardButtonTick--; -// } else if (this.forwardButtonTick == 0) { -// if (this.forwardLeftButton.visible) -// this.forwardLeftButton.visible = false; -// if (this.forwardRightButton.visible) -// this.forwardRightButton.visible = false; -// } -// this.updateJumpButtons(); -// } -// -// @Override -// protected void init() -// { -// super.init(); -// int scaledWidth = this.client.getWindow().getScaledWidth(); -// int scaledHeight = this.client.getWindow().getScaledHeight(); -// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256, -// btn -> this.client.setScreen(new ChatScreen("")), LiteralText.EMPTY)); -// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, -// btn -> this.pauseGame(false))); -// // Inventory buttons. -// int inventoryButtonX = scaledWidth / 2; -// int inventoryButtonY = scaledHeight - 16 - 5; -// if (this.client.options.mainArm == Arm.LEFT) { -// inventoryButtonX = inventoryButtonX - 91 - 24; -// } else { -// inventoryButtonX = inventoryButtonX + 91 + 4; -// } -// this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, -// btn -> { -// if (this.client.interactionManager.hasRidingInventory()) { -// this.client.player.openRidingInventory(); -// } else { -// this.client.getTutorialManager().onInventoryOpened(); -// this.client.openScreen(new InventoryScreen(this.client.player)); -// } -// })); -// int jumpButtonX, swapHandsX, sneakButtonX; -// int sneakButtonY = scaledHeight - 10 - 40 - 5; -// if (MidnightControlsConfig.hudSide == HudSide.LEFT) { -// jumpButtonX = scaledWidth - 20 - 20; -// swapHandsX = jumpButtonX - 5 - 40; -// sneakButtonX = 10 + 20 + 5; -// } else { -// jumpButtonX = 20; -// swapHandsX = jumpButtonX + 5 + 40; -// sneakButtonX = scaledWidth - 10 - 40 - 5; -// } -// // Swap items hand. -// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY, 20, 20, 0, 160, 20, WIDGETS_LOCATION, -// (btn, state) -> { -// if (state) { -// if (!this.client.player.isSpectator()) { -// this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN)); -// } -// } -// })); -// // Drop -// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION, -// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyDrop).midnightcontrols$handlePressState(state))); -// // Jump keys -// this.addDrawableChild(this.jumpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 0, 40, 20, WIDGETS_LOCATION, -// this::handleJump)); -// this.addDrawableChild(this.flyButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 20, 40, 20, WIDGETS_LOCATION, -// (btn, state) -> { -// if (this.flyButtonEnableTicks == 0) this.client..abilities.flying = false; -// })); -// this.addDrawableChild(this.flyUpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION, -// this::handleJump)); -// this.addDrawableChild(this.flyDownButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION, -// (btn, state) -> ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(state))); -// this.updateJumpButtons(); -// // Movements keys -// this.addDrawableChild((this.startSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 0, 120, 20, WIDGETS_LOCATION, -// (btn, state) -> { -// if (state) { -// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(true); -// this.startSneakButton.setVisible(false); -// this.endSneakButton.setVisible(true); -// } -// }))); -// this.addDrawableChild((this.endSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 20, 120, 20, WIDGETS_LOCATION, -// (btn, state) -> { -// if (state) { -// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(false); -// this.endSneakButton.setVisible(false); -// this.startSneakButton.setVisible(true); -// } -// }))); -// this.endSneakButton.setVisible(false); -// this.addDrawableChild(this.forwardLeftButton = new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION, -// (btn, state) -> { -// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); -// ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state); -// this.updateForwardButtonsState(state); -// })); -// this.forwardLeftButton.setVisible(false); -// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION, -// (btn, state) -> { -// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); -// this.updateForwardButtonsState(state); -// this.forwardLeftButton.setVisible(true); -// this.forwardRightButton.setVisible(true); -// })); -// this.addDrawableChild(this.forwardRightButton = new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION, -// (btn, state) -> { -// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); -// ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state); -// this.updateForwardButtonsState(state); -// })); -// this.forwardRightButton.setVisible(true); -// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY, 20, 20, 20, 80, 20, WIDGETS_LOCATION, -// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state))); -// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION, -// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyBack).midnightcontrols$handlePressState(state))); -// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY, 20, 20, 60, 80, 20, WIDGETS_LOCATION, -// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state))); -// -// this.children().forEach(button -> { -// if (button instanceof SpruceTexturedButtonWidget) { -// ((SpruceTexturedButtonWidget) button).setSilent(true); -// } -// }); -// } -// -// @Override -// public boolean mouseClicked(double mouseX, double mouseY, int button) -// { -// if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) { -// int centerX = this.width / 2; -// if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { -// for (int slot = 0; slot < 9; ++slot) { -// int slotX = centerX - 90 + slot * 20 + 2; -// if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { -// this.client.player.getInventory().selectedSlot = slot; -// return true; -// } -// } -// } -// } -// return super.mouseClicked(mouseX, mouseY, button); -// } -// -// @Override -// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) -// { -// if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) { -// if (deltaY > 0.01) -// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2); -// else if (deltaY < 0.01) -// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1); -// -// if (deltaX > 0.01) -// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2); -// else if (deltaX < 0.01) -// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1); -// } -// return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); -// } + @Override + public boolean shouldPause() + { + return false; + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + super.keyPressed(keyCode,scanCode,modifiers); + //return false; + return true; + } + + private void pauseGame(boolean bl) { + if (this.client == null) + return; + boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote(); + if (bl2) { + this.client.setScreen(new GameMenuScreen(!bl)); + this.client.getSoundManager().pauseAll(); + } else { + this.client.setScreen(new GameMenuScreen(true)); + } + } + + /** + * Updates the forward button ticks cooldown. + * + * @param state The button state. + * + */ + private void updateForwardButtonsState(boolean state) { + if (state) + this.forwardButtonTick = -1; + else + this.forwardButtonTick = 20; + } + + /** + * Updates the jump buttons. + */ + private void updateJumpButtons() { + if (this.client == null) + return; + if (!this.client.interactionManager.isFlyingLocked()) { + boolean oldStateFly = this.flyButton.isVisible(); + this.jumpButton.setVisible(false); + this.flyButton.setVisible(true); + this.flyUpButton.setVisible(true); + this.flyDownButton.setVisible(true); + if (oldStateFly != this.flyButton.isVisible()) { + this.flyButtonEnableTicks = 5; + this.setJump(false); + } else if (this.flyButtonEnableTicks > 0) + this.flyButtonEnableTicks--; + } else { + this.jumpButton.setVisible(true); + this.flyButton.setVisible(false); + this.flyUpButton.setVisible(false); + this.flyDownButton.setVisible(false); + } + } + + /** + * Handles the jump button. + * + * @param btn The pressed button. + */ + private void handleJump(SpruceButtonWidget btn) { + ((KeyBindingAccessor) this.client.options.jumpKey).midnightcontrols$handlePressState(btn.isActive()); + } + /** + * Handles the jump button. + * + * @param state The state. + */ + private void setJump(boolean state) { + ((KeyBindingAccessor) this.client.options.jumpKey).midnightcontrols$handlePressState(state); + } + + @Override + public void tick() { + if (this.forwardButtonTick > 0) { + this.forwardButtonTick--; + } else if (this.forwardButtonTick == 0) { + if (this.forwardLeftButton.isVisible()) + this.forwardLeftButton.setVisible(false); + if (this.forwardRightButton.isVisible()) + this.forwardRightButton.setVisible(false); + } + this.updateJumpButtons(); + } + + @Override + protected void init() { + super.init(); + int scaledWidth = this.client.getWindow().getScaledWidth(); + int scaledHeight = this.client.getWindow().getScaledHeight(); + this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, new Identifier("textures/gui/widgets.png"), 256, 256, + btn -> this.client.setScreen(new ChatScreen("")), Text.empty())); + this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, + btn -> this.pauseGame(false))); + // Inventory buttons. + int inventoryButtonX = scaledWidth / 2; + int inventoryButtonY = scaledHeight - 16 - 5; + if (this.client.options.getMainArm().getValue() == Arm.LEFT) { + inventoryButtonX = inventoryButtonX - 91 - 24; + } else { + inventoryButtonX = inventoryButtonX + 91 + 4; + } + this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, + btn -> { + if (this.client.interactionManager.hasRidingInventory()) { + this.client.player.openRidingInventory(); + } else { + this.client.getTutorialManager().onInventoryOpened(); + this.client.setScreen(new InventoryScreen(this.client.player)); + } + })); + int jumpButtonX, swapHandsX, sneakButtonX; + int sneakButtonY = scaledHeight - 10 - 40 - 5; + if (MidnightControlsConfig.hudSide == HudSide.LEFT) { + jumpButtonX = scaledWidth - 20 - 20; + swapHandsX = jumpButtonX - 5 - 40; + sneakButtonX = 10 + 20 + 5; + } else { + jumpButtonX = 20; + swapHandsX = jumpButtonX + 5 + 40; + sneakButtonX = scaledWidth - 10 - 40 - 5; + } + // Swap items hand. + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(swapHandsX, sneakButtonY), 20, 20, Text.empty(), + button -> { + if (button.isActive()) { + if (!this.client.player.isSpectator()) { + this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN)); + } + } + },0, 160, 20, WIDGETS_LOCATION)); + // Drop + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(swapHandsX, sneakButtonY + 5 + 20), 20, 20, Text.empty(), btn -> + ((KeyBindingAccessor) this.client.options.dropKey).midnightcontrols$handlePressState(btn.isActive()), 0, 160, 20, WIDGETS_LOCATION)); + // Jump keys + this.addDrawableChild(this.jumpButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(), this::handleJump, 0, 40, 20, WIDGETS_LOCATION)); + this.addDrawableChild(this.flyButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(),btn -> { + if (this.flyButtonEnableTicks == 0) this.client.player.getAbilities().flying = false; + }, 20, 40, 20, WIDGETS_LOCATION) + ); + this.addDrawableChild(this.flyUpButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY - 5 - 20), 20, 20,Text.empty(), + this::handleJump, 40, 40, 20, WIDGETS_LOCATION + )); + this.addDrawableChild(this.flyDownButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY + 20 + 5), 20, 20, Text.empty(), + btn -> ((KeyBindingAccessor) this.client.options.sneakKey).midnightcontrols$handlePressState(btn.isActive()), 60, 40, 20, WIDGETS_LOCATION + )); + this.updateJumpButtons(); + // Movements keys + this.addDrawableChild((this.startSneakButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY), 20, 20, Text.empty(), btn -> { + if (btn.isActive()) { + ((KeyBindingAccessor) this.client.options.sneakKey).midnightcontrols$handlePressState(true); + this.startSneakButton.setVisible(false); + this.endSneakButton.setVisible(true); + } + }, 0, 120, 20, WIDGETS_LOCATION)) + ); + this.addDrawableChild((this.endSneakButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY), 20, 20, Text.empty(), btn -> { + if (btn.isActive()) { + ((KeyBindingAccessor) this.client.options.sneakKey).midnightcontrols$handlePressState(false); + this.endSneakButton.setVisible(false); + this.startSneakButton.setVisible(true); + } + }, 20, 120, 20, WIDGETS_LOCATION))); + this.endSneakButton.setVisible(false); + this.addDrawableChild(this.forwardLeftButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> { + ((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive()); + ((KeyBindingAccessor) this.client.options.leftKey).midnightcontrols$handlePressState(btn.isActive()); + this.updateForwardButtonsState(btn.isActive()); + }, 80, 80, 20, WIDGETS_LOCATION + )); + this.forwardLeftButton.setVisible(false); + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> { + ((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive()); + this.updateForwardButtonsState(btn.isActive()); + this.forwardLeftButton.setVisible(true); + this.forwardRightButton.setVisible(true); + }, 0, 80, 20, WIDGETS_LOCATION + )); + this.addDrawableChild(this.forwardRightButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> { + ((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive()); + ((KeyBindingAccessor) this.client.options.rightKey).midnightcontrols$handlePressState(btn.isActive()); + this.updateForwardButtonsState(btn.isActive()); + }, 100, 80, 20, WIDGETS_LOCATION + )); + this.forwardRightButton.setVisible(true); + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX + 20 + 5, sneakButtonY), 20, 20, Text.empty(), + btn -> ((KeyBindingAccessor) this.client.options.rightKey).midnightcontrols$handlePressState(btn.isActive()), 20, 80, 20, WIDGETS_LOCATION + )); + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY + 20 + 5), 20, 20, Text.empty(), + btn -> ((KeyBindingAccessor) this.client.options.backKey).midnightcontrols$handlePressState(btn.isActive()), 40, 80, 20, WIDGETS_LOCATION + )); + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX - 20 - 5, sneakButtonY), 20, 20, Text.empty(), + btn -> ((KeyBindingAccessor) this.client.options.leftKey).midnightcontrols$handlePressState(btn.isActive()), 60, 80, 20, WIDGETS_LOCATION + )); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) { + int centerX = this.width / 2; + if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { + for (int slot = 0; slot < 9; ++slot) { + int slotX = centerX - 90 + slot * 20 + 2; + if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { + this.client.player.getInventory().selectedSlot = slot; + return true; + } + } + } + } + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) { + if (deltaY > 0.01) + this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2); + else if (deltaY < 0.01) + this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1); + + if (deltaX > 0.01) + this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2); + else if (deltaX < 0.01) + this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1); + } + return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerControlsWidget.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerControlsWidget.java index ce2c823..aae9340 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerControlsWidget.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerControlsWidget.java @@ -17,6 +17,7 @@ import dev.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget; +import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; @@ -49,6 +50,7 @@ public class ControllerControlsWidget extends SpruceContainerWidget { Text.translatable("midnightcontrols.menu.keyboard_controls"), btn -> this.client.setScreen(new ControlsOptionsScreen(null, this.client.options)))); this.bindingsListWidget = new ControlsListWidget(Position.of(this, 0, 43), this.width, this.height - 43 - 35, this); + this.bindingsListWidget.setBackground(new MidnightControlsSettingsScreen.MidnightControlsBackground(130)); this.addChild(this.bindingsListWidget); this.addChild(this.resetButton = new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150, 20, SpruceTexts.CONTROLS_RESET_ALL, diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/SilentTexturedButtonWidget.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/SilentTexturedButtonWidget.java new file mode 100644 index 0000000..7861ac5 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/SilentTexturedButtonWidget.java @@ -0,0 +1,26 @@ +package eu.midnightdust.midnightcontrols.client.gui.widget; + +import dev.lambdaurora.spruceui.Position; +import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +public class SilentTexturedButtonWidget extends SpruceTexturedButtonWidget { + public SilentTexturedButtonWidget(Position position, int width, int height, Text message, PressAction action, int u, int v, int hoveredVOffset, Identifier texture) { + super(position, width, height, message, action, u, v, hoveredVOffset, texture); + } + + public SilentTexturedButtonWidget(Position position, int width, int height, Text message, boolean showMessage, PressAction action, int u, int v, int hoveredVOffset, Identifier texture) { + super(position, width, height, message, showMessage, action, u, v, hoveredVOffset, texture); + } + + public SilentTexturedButtonWidget(Position position, int width, int height, Text message, PressAction action, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight) { + super(position, width, height, message, action, u, v, hoveredVOffset, texture, textureWidth, textureHeight); + } + + public SilentTexturedButtonWidget(Position position, int width, int height, Text message, boolean showMessage, PressAction action, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight) { + super(position, width, height, message, showMessage, action, u, v, hoveredVOffset, texture, textureWidth, textureHeight); + } + @Override + public void playDownSound() {} +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClientPlayerEntityMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClientPlayerEntityMixin.java index 8872318..c9b8d06 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClientPlayerEntityMixin.java @@ -10,6 +10,7 @@ package eu.midnightdust.midnightcontrols.client.mixin; import com.mojang.authlib.GameProfile; +import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.controller.MovementHandler; @@ -27,6 +28,7 @@ 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** @@ -53,10 +55,13 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity @Shadow protected abstract boolean isCamera(); + @Shadow protected int ticksLeftToDoubleTapSprint; + @Inject(method = "move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V")) public void onMove(MovementType type, Vec3d movement, CallbackInfo ci) { - var mod = MidnightControlsClient.get(); + if (!MidnightControlsConfig.doubleTapToSprint) ticksLeftToDoubleTapSprint = 0; + if (!MidnightControls.isExtrasLoaded) return; if (type == MovementType.SELF) { if (this.getAbilities().flying && (!MidnightControlsConfig.flyDrifting || !MidnightControlsConfig.verticalFlyDrifting)) { if (!this.hasMovementInput()) { @@ -79,7 +84,7 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z")) public void onTickMovement(CallbackInfo ci) { if (this.getAbilities().flying && this.isCamera()) { - if (MidnightControlsConfig.verticalFlyDrifting) + if (MidnightControlsConfig.verticalFlyDrifting || !MidnightControls.isExtrasLoaded) return; int moving = 0; if (this.input.sneaking) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/CreativeInventoryScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/CreativeInventoryScreenAccessor.java index e820aac..14bad62 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/CreativeInventoryScreenAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/CreativeInventoryScreenAccessor.java @@ -29,7 +29,9 @@ public interface CreativeInventoryScreenAccessor { * @return the selected tab index */ @Accessor("selectedTab") - int getSelectedTab(); + static int getSelectedTab() { + return 0; + } /** * Sets the selected tab. diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java index 6d48cf2..0655e90 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java @@ -28,7 +28,7 @@ public class KeyBindingMixin implements KeyBindingAccessor { if (!this.pressed) this.pressed = true; ++this.timesPressed; - return oldPressed != this.pressed; + return !oldPressed; } @Override diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingRegistryImplAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingRegistryImplAccessor.java new file mode 100644 index 0000000..d93e41d --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingRegistryImplAccessor.java @@ -0,0 +1,17 @@ +package eu.midnightdust.midnightcontrols.client.mixin; + +import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl; +import net.minecraft.client.option.KeyBinding; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(value = KeyBindingRegistryImpl.class, remap = false) +public interface KeyBindingRegistryImplAccessor { + @Accessor @Final + static List getModdedKeyBindings() { + return null; + } +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java index 98796f2..b541eb4 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java @@ -54,10 +54,6 @@ public abstract class MinecraftClientMixin { @Nullable public ClientPlayerInteractionManager interactionManager; - @Shadow - @Nullable - public ClientWorld world; - @Shadow @Final public GameRenderer gameRenderer; @@ -104,18 +100,26 @@ public abstract class MinecraftClientMixin { this.midnightcontrols$lastTargetSide = side; } // Removed front placing sprinting as way too cheaty. - /*else if (this.player.isSprinting()) { - hitResult = midnightcontrolsClient.get().reacharound.getLastReacharoundResult(); + else if (this.player.isSprinting()) { + hitResult = MidnightControlsClient.get().reacharound.getLastReacharoundResult(); if (hitResult != null) { if (cooldown > 0) this.itemUseCooldown = 0; } - }*/ + } this.midnightcontrols$lastPos = this.player.getPos(); } - + // Applied three times for smooth camera turning even on low FPS + @Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Recorder;startTick()V", shift = At.Shift.AFTER)) + private void onPreRender(CallbackInfo ci) { + MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this)); + } @Inject(method = "render", at = @At("HEAD")) - private void onRender(boolean fullRender, CallbackInfo ci) { + private void onRender(CallbackInfo ci) { + MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this)); + } + @Inject(method = "render", at = @At("TAIL")) + private void onPostRender(CallbackInfo ci) { MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this)); } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java index df5e966..48b4057 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java @@ -51,16 +51,16 @@ public final class MidnightRing { * Loads the ring from configuration. */ public void load() { -// List configPages = MidnightControlsConfig.ringPages; -// if (configPages != null) { -// this.pages.clear(); -// for (var configPage : configPages) { -// RingPage.parseRingPage(configPage).ifPresent(this.pages::add); -// } -// } -// if (this.pages.isEmpty()) { -// this.pages.add(RingPage.DEFAULT); -// } + List configPages = null; + if (configPages != null) { + this.pages.clear(); + for (var configPage : configPages) { + RingPage.parseRingPage(configPage).ifPresent(this.pages::add); + } + } + if (this.pages.isEmpty()) { + this.pages.add(RingPage.DEFAULT); + } } public @NotNull RingPage getCurrentPage() { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingPage.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingPage.java index 874b113..91ddba8 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingPage.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingPage.java @@ -10,11 +10,15 @@ package eu.midnightdust.midnightcontrols.client.ring; import com.electronwill.nightconfig.core.Config; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.client.util.math.MatrixStack; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -36,6 +40,11 @@ public class RingPage extends DrawableHelper { for (int i = 0; i < 8; i++) { this.actions[i] = null; } + this.actions[0] = new DummyRingAction(null); + this.actions[1] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_UP); + this.actions[2] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_LEFT); + this.actions[3] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_RIGHT); + this.actions[4] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_DOWN); } /** @@ -83,6 +92,52 @@ public class RingPage extends DrawableHelper { private static boolean isHovered(int x, int y, int mouseX, int mouseY) { return mouseX >= x && mouseY >= y && mouseX <= x + MidnightRing.ELEMENT_SIZE && mouseY <= y + MidnightRing.ELEMENT_SIZE; } + /** + * Renders the ring page. + * + * @param width the screen width + * @param height the screen height + * @param mouseX the mouse X-coordinate + * @param mouseY the mouse Y-coordinate + */ + public boolean onClick(int width, int height, int mouseX, int mouseY) { + int centerX = width / 2; + int centerY = height / 2; + + int offset = MidnightRing.ELEMENT_SIZE + (MidnightRing.ELEMENT_SIZE / 2) + 5; + + int y = centerY - offset; + int x = centerX - offset; + for (int i = 0; i < 3; i++) { + var ringAction = this.actions[i]; + if (ringAction != null && isHovered(x,y,mouseX,mouseY)) { + ringAction.activate(RingButtonMode.PRESS); + return true; + } + x += 55; + } + y += 55; + x = centerX - offset; + for (int i = 3; i < 5; i++) { + var ringAction = this.actions[i]; + if (ringAction != null && isHovered(x,y,mouseX,mouseY)) { + ringAction.activate(RingButtonMode.PRESS); + return true; + } + x += 55 * 2; + } + y += 55; + x = centerX - offset; + for (int i = 5; i < 8; i++) { + var ringAction = this.actions[i]; + if (ringAction != null && isHovered(x,y,mouseX,mouseY)) { + ringAction.activate(RingButtonMode.PRESS); + return true; + } + x += 55; + } + return false; + } /** * Tries to parse a ring page configuration. diff --git a/src/main/resources/assets/midnightcontrols/lang/de_de.json b/src/main/resources/assets/midnightcontrols/lang/de_de.json index 0ffa312..9a71fae 100644 --- a/src/main/resources/assets/midnightcontrols/lang/de_de.json +++ b/src/main/resources/assets/midnightcontrols/lang/de_de.json @@ -92,6 +92,7 @@ "midnightcontrols.menu.controller2": "Zweiter Controller", "midnightcontrols.menu.controller_type": "Controller-Typ", "midnightcontrols.menu.controls_mode": "Modus", + "midnightcontrols.menu.double_tap_to_sprint": "Doppel-Tipp zum Sprinten", "midnightcontrols.menu.fast_block_placing": "Schnelles Bauen", "midnightcontrols.menu.fly_drifting": "Flug-Drifting", "midnightcontrols.menu.fly_drifting_vertical": "Vertikales Flug-Drifting", diff --git a/src/main/resources/assets/midnightcontrols/lang/en_us.json b/src/main/resources/assets/midnightcontrols/lang/en_us.json index 7e86297..6415da8 100644 --- a/src/main/resources/assets/midnightcontrols/lang/en_us.json +++ b/src/main/resources/assets/midnightcontrols/lang/en_us.json @@ -96,6 +96,7 @@ "midnightcontrols.menu.controller2": "Second Controller", "midnightcontrols.menu.controller_type": "Controller Type", "midnightcontrols.menu.controls_mode": "Mode", + "midnightcontrols.menu.double_tap_to_sprint": "Double-Tap to Sprint", "midnightcontrols.menu.fast_block_placing": "Fast Block Placing", "midnightcontrols.menu.fly_drifting": "Fly Drifting", "midnightcontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting", diff --git a/src/main/resources/midnightcontrols.mixins.json b/src/main/resources/midnightcontrols.mixins.json index 0faa7c4..bec043d 100644 --- a/src/main/resources/midnightcontrols.mixins.json +++ b/src/main/resources/midnightcontrols.mixins.json @@ -16,7 +16,8 @@ "MinecraftClientMixin", "MouseMixin", "RecipeBookWidgetAccessor", - "WorldRendererMixin" + "WorldRendererMixin", + "KeyBindingRegistryImplAccessor" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/midnightcontrols_compat.mixins.json b/src/main/resources/midnightcontrols_compat.mixins.json index 040f2dc..89110a5 100644 --- a/src/main/resources/midnightcontrols_compat.mixins.json +++ b/src/main/resources/midnightcontrols_compat.mixins.json @@ -4,6 +4,7 @@ "plugin": "eu.midnightdust.midnightcontrols.client.compat.MidnightControlsMixinPlugin", "compatibilityLevel": "JAVA_16", "client": [ + "SodiumOptionsGUIAccessor" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/resourcepacks/bedrock/pack.mcmeta b/src/main/resources/resourcepacks/bedrock/pack.mcmeta index 77bcd3d..9915cb1 100644 --- a/src/main/resources/resourcepacks/bedrock/pack.mcmeta +++ b/src/main/resources/resourcepacks/bedrock/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { - "pack_format": 8, + "pack_format": 9, "description": "Makes the controller buttons look like from Bedrock Edition" } }