From 47b0cfdad4526173d921e8d4a8c7fab95c2b32f1 Mon Sep 17 00:00:00 2001 From: LambdAurora Date: Sat, 1 Feb 2020 00:44:13 +0100 Subject: [PATCH] :bookmark: LambdaControls v1.1.0: Chording update. --- CHANGELOG.md | 47 + README.md | 37 +- core/build.gradle | 2 +- .../lambdacontrols/ControlsMode.java | 10 +- .../LambdaControlsConstants.java | 7 +- .../lambdacontrols/LambdaControlsFeature.java | 159 +++ .../event/PlayerControlsModeEvent.java | 12 +- fabric/build.gradle | 9 +- .../lambdacontrols/LambdaControls.java | 63 +- .../lambdacontrols/client/ButtonState.java | 4 +- .../lambdacontrols/client/ControllerType.java | 12 +- .../lambdacontrols/client/HudSide.java | 10 +- .../client/LambdaControlsClient.java | 173 ++- .../client/LambdaControlsConfig.java | 328 ++--- .../lambdacontrols/client/LambdaInput.java | 557 ++++---- .../client/compat/LambdaControlsCompat.java | 4 +- .../client/compat/OkZoomerCompat.java | 11 +- .../client/controller/ButtonBinding.java | 427 ++++-- .../client/controller/ButtonCategory.java | 24 +- .../client/controller/Controller.java | 44 +- .../client/controller/InputHandlers.java | 176 ++- .../client/controller/InputManager.java | 197 ++- .../client/controller/PressAction.java | 2 +- .../client/gui/ControllerButtonWidget.java | 28 +- ...een.java => ControllerControlsScreen.java} | 48 +- .../client/gui/ControlsListWidget.java | 112 +- .../client/gui/LambdaControlsHud.java | 49 +- .../gui/LambdaControlsSettingsScreen.java | 249 ++-- .../gui/ReloadControllerMappingsOption.java | 8 +- .../client/gui/TouchscreenOverlay.java | 236 ++-- .../mixin/AbstractButtonWidgetAccessor.java | 2 +- .../mixin/AdvancementsScreenAccessor.java | 35 + .../mixin/ClientPlayNetworkHandlerMixin.java | 32 + .../client/mixin/ClientPlayerEntityMixin.java | 47 +- ...enMixin.java => ContainerScreenMixin.java} | 26 +- .../mixin/ControlsOptionsScreenMixin.java | 10 +- .../CreativeInventoryScreenAccessor.java | 15 +- .../client/mixin/EntryListWidgetAccessor.java | 2 +- .../client/mixin/GameRendererMixin.java | 6 +- .../client/mixin/KeyBindingMixin.java | 11 +- .../client/mixin/MinecraftClientMixin.java | 69 +- .../client/mixin/MouseMixin.java | 6 +- .../client/mixin/SettingsScreenMixin.java | 10 +- ...ssor.java => ContainerScreenAccessor.java} | 8 +- .../client/util/KeyBindingAccessor.java | 7 +- .../client/util/MouseAccessor.java | 2 +- .../PlayerChangeControlsModeCallback.java | 6 +- .../assets/lambdacontrols/lang/en_us.json | 2 + .../assets/lambdacontrols/lang/fr_ca.json | 2 + .../assets/lambdacontrols/lang/fr_fr.json | 2 + fabric/src/main/resources/config.toml | 24 +- fabric/src/main/resources/fabric.mod.json | 2 +- .../main/resources/lambdacontrols.mixins.json | 4 +- gradle.properties | 12 +- settings.gradle | 2 +- spigot/build.gradle | 50 + .../lambdacontrols/LambdaControlsConfig.java | 41 + .../lambdacontrols/LambdaControlsSpigot.java | 148 +++ .../lambdacontrols/NettyPacketBuffer.java | 102 ++ .../lambdacontrols/PacketBuffer.java | 1153 +++++++++++++++++ .../event/PlayerChangeControlsModeEvent.java | 65 + spigot/src/main/resources/plugin.yml | 6 + spigot/src/main/resources/server_config.toml | 6 + 63 files changed, 3726 insertions(+), 1234 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsFeature.java rename fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/{LambdaControlsControlsScreen.java => ControllerControlsScreen.java} (55%) create mode 100644 fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AdvancementsScreenAccessor.java create mode 100644 fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayNetworkHandlerMixin.java rename fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/{AbstractContainerScreenMixin.java => ContainerScreenMixin.java} (51%) rename fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/{AbstractContainerScreenAccessor.java => ContainerScreenAccessor.java} (81%) create mode 100644 spigot/build.gradle create mode 100644 spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java create mode 100644 spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsSpigot.java create mode 100644 spigot/src/main/java/me/lambdaurora/lambdacontrols/NettyPacketBuffer.java create mode 100644 spigot/src/main/java/me/lambdaurora/lambdacontrols/PacketBuffer.java create mode 100644 spigot/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeEvent.java create mode 100644 spigot/src/main/resources/plugin.yml create mode 100644 spigot/src/main/resources/server_config.toml diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ba0630c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ +# Changelog + +## v1.0.0 + +:tada: First release! :tada: + +- Added controller support. +- Added new controls settings GUI. +- Added experimental touchscreen support. +- Added controller controls GUI. +- Added a lot of options. +- Added key bindings for look around. +- And more! + +### v1.0.1 + +- Fixed tutorial toast to look around not affected by camera movement done with a controller. ([#2](https://github.com/LambdAurora/LambdaControls/issues/2)) + +### v1.0.2 (Unofficial) + +This update was never pushed but was aiming to fix [#4](https://github.com/LambdAurora/LambdaControls/issues/4). + +- Fixed the toggle sneak button binding. +- Fixed broken chat arrow keys. +- Optimized a little bit the button indicator. (need more work) + +## v1.1.0 - Chording update + +This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAurora/LambdaControls/issues/9)). + +- Rewrote everything (almost). +- Added [networking](https://github.com/LambdAurora/LambdaControls/wiki/LambdaControls-Networking) for some features. +- Added second controller support (Joycons supported now hopefully). +- Added chording. +- Added better developer API +- Added hover messages ([#5](https://github.com/LambdAurora/LambdaControls/issues/5)). +- Added hotbar button bindings ([#7](https://github.com/LambdAurora/LambdaControls/issues/7)). +- Added front block placing feature ([#8](https://github.com/LambdAurora/LambdaControls/issues/8)). +- Added no creative fly drifting ([#8](https://github.com/LambdAurora/LambdaControls/issues/8)). +- Added option to enable controller focus. +- Added [OkZoomer](https://github.com/joaoh1/OkZoomer) compatibility. +- Added D-pad movements in inventories. +- Increased max speed ranges. +- Added [SpruceUI](https://github.com/LambdAurora/SpruceUI) for cleaner custom UI widgets. +- Added reset settings button. +- HUD side affects button indicators now. +- Added support for Advancements tabs. diff --git a/README.md b/README.md index 050f1b6..4b9d2a8 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,39 @@ ![Java 8](https://img.shields.io/badge/language-Java%208-9B599A.svg?style=flat-square) [![GitHub license](https://img.shields.io/github/license/LambdAurora/LambdaControls?style=flat-square)](https://raw.githubusercontent.com/LambdAurora/LambdaControls/master/LICENSE) ![Environment: Client](https://img.shields.io/badge/environment-client-1976d2?style=flat-square) +![Mod loader: Fabric](https://img.shields.io/badge/modloader-Fabric-1976d2?style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE4LTEyLTE2VDE2OjU0OjE3LTA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wNy0yOFQyMToxNzo0OC0wNzowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wNy0yOFQyMToxNzo0OC0wNzowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowZWRiMWMyYy1mZjhjLWU0NDEtOTMxZi00OTVkNGYxNGM3NjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MGVkYjFjMmMtZmY4Yy1lNDQxLTkzMWYtNDk1ZDRmMTRjNzYwIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MGVkYjFjMmMtZmY4Yy1lNDQxLTkzMWYtNDk1ZDRmMTRjNzYwIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowZWRiMWMyYy1mZjhjLWU0NDEtOTMxZi00OTVkNGYxNGM3NjAiIHN0RXZ0OndoZW49IjIwMTgtMTItMTZUMTY6NTQ6MTctMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4/HiGMAAAAtUlEQVRYw+XXrQqAMBQF4D2P2eBL+QIG8RnEJFaNBjEum+0+zMQLtwwv+wV3ZzhhMDgfJ0wUSinxZUQWgKos1JP/AbD4OneIDyQPwCFniA+EJ4CaXm4TxAXCC0BNHgLhAdAnx9hC8PwGSRtAFVMQjF7cNTWED8B1cgwW20yfJgAvrssAsZ1cB3g/xckAxr6FmCDU5N6f488BrpCQ4rQBJkiMYh4ACmLzwOQF0CExinkCsvw7vgGikl+OotaKRwAAAABJRU5ErkJggg==) ![Version](https://img.shields.io/github/v/tag/LambdAurora/LambdaControls?label=version&style=flat-square) -[![CurseForge](https://cf.way2muchnoise.eu/title/lambdacontrols.svg)](https://www.curseforge.com/minecraft/mc-mods/lambdacontrols) +[![CurseForge](https://cf.way2muchnoise.eu/title/354231.svg)](https://www.curseforge.com/minecraft/mc-mods/lambdacontrols) -A Fabric Minecraft mod which adds better controls. -It allows the use of a controller or the touchscreen. +A Fabric Minecraft mod which adds better controls like controller support. + +## What's this mod? + +Haven't you dreamed to travel in your modded Minecraft world with your controller? Yes? Then this mod is made for you! + +This mod adds a controller support (and an experimental touchscreen support). + +## ✅ Features: + + - Controller support + - Touchscreen support (very experimental and buggy). + - Keyboard controls to look around. + - Toggleable on screen button indicator (like in Bedrock Edition). + - Many Bedrock Edition features: + - Toggleable fly drifting + - 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. + +## 🎮 Supported Controllers: + + - Dualshock controllers + - Xbox controllers + - Switch Pro controllers + - Joycons + - And many more! + +## Build + +Just do `./gradlew :fabric:build` and everything should build just fine! diff --git a/core/build.gradle b/core/build.gradle index 19892bf..92e20eb 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -6,7 +6,7 @@ archivesBaseName = project.archives_base_name + "-core" dependencies { api "org.jetbrains:annotations:17.0.0" - api "org.aperlambda:lambdajcommon:1.7.2" + api "org.aperlambda:lambdajcommon:1.8.0" api "com.electronwill.night-config:core:3.5.3" api "com.electronwill.night-config:toml:3.5.3" } diff --git a/core/src/main/java/me/lambdaurora/lambdacontrols/ControlsMode.java b/core/src/main/java/me/lambdaurora/lambdacontrols/ControlsMode.java index 113a9d7..f81b89a 100644 --- a/core/src/main/java/me/lambdaurora/lambdacontrols/ControlsMode.java +++ b/core/src/main/java/me/lambdaurora/lambdacontrols/ControlsMode.java @@ -47,13 +47,13 @@ public enum ControlsMode implements Nameable * @return The translated key of this controls mode. * @since 1.1.0 */ - public String get_translation_key() + public String getTranslationKey() { - return "lambdacontrols.controls_mode." + this.get_name(); + return "lambdacontrols.controls_mode." + this.getName(); } @Override - public @NotNull String get_name() + public @NotNull String getName() { return this.name().toLowerCase(); } @@ -64,8 +64,8 @@ public enum ControlsMode implements Nameable * @param id The identifier of the controls mode. * @return The controls mode if found, else empty. */ - public static Optional by_id(@NotNull String id) + public static Optional byId(@NotNull String id) { - return Arrays.stream(values()).filter(mode -> mode.get_name().equalsIgnoreCase(id)).findFirst(); + return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst(); } } diff --git a/core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConstants.java b/core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConstants.java index e0c0c22..78eed35 100644 --- a/core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConstants.java +++ b/core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConstants.java @@ -9,6 +9,8 @@ package me.lambdaurora.lambdacontrols; +import org.aperlambda.lambdacommon.Identifier; + /** * Represents the constants used by LambdaControls. * @@ -18,5 +20,8 @@ package me.lambdaurora.lambdacontrols; */ public class LambdaControlsConstants { - public static final String NAMESPACE = "lambdacontrols"; + public static final String NAMESPACE = "lambdacontrols"; + public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(NAMESPACE, "controls_mode"); + public static final Identifier FEATURE_CHANNEL = new Identifier(NAMESPACE, "feature"); + public static final Identifier HELLO_CHANNEL = new Identifier(NAMESPACE, "hello"); } diff --git a/core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsFeature.java b/core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsFeature.java new file mode 100644 index 0000000..7e7c4e0 --- /dev/null +++ b/core/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsFeature.java @@ -0,0 +1,159 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols; + +import org.aperlambda.lambdacommon.utils.Nameable; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * Represents a feature. + * + * @author LambdAurora + * @version 1.1.0 + * @since 1.1.0 + */ +public class LambdaControlsFeature implements Nameable +{ + private static final List FEATURES = new ArrayList<>(); + public static final LambdaControlsFeature FRONT_BLOCK_PLACING = new LambdaControlsFeature("front_block_placing", true, false); + + private final String key; + private final boolean defaultAllowed; + private boolean allowed; + private final boolean defaultEnabled; + private boolean enabled; + + public LambdaControlsFeature(@NotNull String key, boolean allowed, boolean enabled) + { + Objects.requireNonNull(key, "Feature key cannot be null."); + this.key = key; + this.setAllowed(this.defaultAllowed = allowed); + this.setEnabled(this.defaultEnabled = enabled); + } + + public LambdaControlsFeature(@NotNull String key) + { + this(key, false, false); + } + + /** + * Allows the feature. + */ + public void allow() + { + this.setAllowed(true); + } + + /** + * Returns whether this feature is allowed. + * + * @return True if this feature is allowed, else false. + */ + public boolean isAllowed() + { + return this.allowed; + } + + /** + * Sets whether this feature is allowed. + * + * @param allowed True if this feature is allowed, else false. + */ + public void setAllowed(boolean allowed) + { + this.allowed = allowed; + } + + /** + * Resets allowed state to default. + */ + public void resetAllowed() + { + this.setAllowed(this.defaultAllowed); + } + + /** + * Returns whether this feature is enabled. + * + * @return True if this feature is enabled, else false. + */ + public boolean isEnabled() + { + return this.enabled; + } + + /** + * Returns whether this feature is enabled. + * + * @param enabled True if this feature is enabled, else false. + */ + public void setEnabled(boolean enabled) + { + this.enabled = enabled; + } + + /** + * Returns whether this feature is available or not. + * + * @return True if this feature is available, else false. + * @see #isAllowed() + * @see #isEnabled() + */ + public boolean isAvailable() + { + return this.isAllowed() && this.isEnabled(); + } + + /** + * Resets the feature to its default values. + */ + public void reset() + { + this.resetAllowed(); + this.setEnabled(this.defaultEnabled); + } + + @Override + public @NotNull String getName() + { + return this.key; + } + + public static @NotNull Optional fromName(@NotNull String key) + { + Objects.requireNonNull(key, "Cannot find features with a null name."); + return FEATURES.parallelStream().filter(feature -> feature.getName().equals(key)).findFirst(); + } + + /** + * Resets all features to their default values. + */ + public static void resetAll() + { + FEATURES.parallelStream().forEach(LambdaControlsFeature::reset); + } + + /** + * Resets all features to allow state. + */ + public static void resetAllAllowed() + { + FEATURES.parallelStream().forEach(LambdaControlsFeature::resetAllowed); + } + + static { + FEATURES.add(FRONT_BLOCK_PLACING); + } +} diff --git a/elytra/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerControlsModeEvent.java b/elytra/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerControlsModeEvent.java index 31dbd7d..9b3ff55 100644 --- a/elytra/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerControlsModeEvent.java +++ b/elytra/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerControlsModeEvent.java @@ -27,12 +27,12 @@ import org.mcelytra.core.event.player.PlayerEvent; public class PlayerControlsModeEvent extends PlayerEvent { private static final HandlerList HANDLERS = new HandlerList(); - private final ControlsMode controls_mode; + private final ControlsMode controlsMode; - public PlayerControlsModeEvent(@NotNull EntityPlayer player, @NotNull ControlsMode controls_mode) + public PlayerControlsModeEvent(@NotNull EntityPlayer player, @NotNull ControlsMode controlsMode) { super(new Identifier(LambdaControlsConstants.NAMESPACE, "player_controls_mode"), player, true); - this.controls_mode = controls_mode; + this.controlsMode = controlsMode; } /** @@ -40,13 +40,13 @@ public class PlayerControlsModeEvent extends PlayerEvent * * @return The player's controls mode. */ - public ControlsMode get_controls_mode() + public ControlsMode getControlsMode() { - return this.controls_mode; + return this.controlsMode; } @Override - public @NotNull HandlerList get_handlers() + public @NotNull HandlerList getHandlers() { return HANDLERS; } diff --git a/fabric/build.gradle b/fabric/build.gradle index a3274c3..f66b5aa 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -42,17 +42,20 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modApi "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - modCompile "io.github.prospector:modmenu:1.8.0+build.16" + modCompile "io.github.prospector:modmenu:1.8.5+build.23" modCompile "com.github.lambdaurora:spruceui:${project.spruceui_version}" include "com.github.lambdaurora:spruceui:${project.spruceui_version}" // Compatibility mods - modCompile "io.github.joaoh1:okzoomer:2.0.1" + modCompile "io.github.joaoh1:okzoomer:2.1.0-beta.2" api project(":core") shadow project(":core") include "org.jetbrains:annotations:17.0.0" - include "org.aperlambda:lambdajcommon:1.7.2" + include("org.aperlambda:lambdajcommon:1.8.0") { + exclude group: 'com.google.code.gson' + exclude group: 'com.google.guava' + } include "com.electronwill.night-config:core:3.5.3" include "com.electronwill.night-config:toml:3.5.3" } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java index dfb2cc3..5dfbc81 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java @@ -9,12 +9,20 @@ package me.lambdaurora.lambdacontrols; +import io.netty.buffer.Unpooled; import me.lambdaurora.lambdacontrols.event.PlayerChangeControlsModeCallback; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; +import java.util.Optional; /** * Represents the LambdaControls mod. @@ -26,7 +34,9 @@ import org.apache.logging.log4j.Logger; public class LambdaControls implements ModInitializer { private static LambdaControls INSTANCE; - public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(LambdaControlsConstants.NAMESPACE, "controls_mode"); + public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(LambdaControlsConstants.CONTROLS_MODE_CHANNEL.toString()); + public static final Identifier FEATURE_CHANNEL = new Identifier(LambdaControlsConstants.FEATURE_CHANNEL.toString()); + public static final Identifier HELLO_CHANNEL = new Identifier(LambdaControlsConstants.HELLO_CHANNEL.toString()); public final Logger logger = LogManager.getLogger("LambdaControls"); @@ -36,10 +46,19 @@ public class LambdaControls implements ModInitializer INSTANCE = this; this.log("Initializing LambdaControls..."); + ServerSidePacketRegistry.INSTANCE.register(HELLO_CHANNEL, + (context, attachedData) -> { + String version = attachedData.readString(16); + ControlsMode.byId(attachedData.readString(32)) + .ifPresent(controlsMode -> context.getTaskQueue() + .execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode))); + context.getTaskQueue().execute(() -> + ServerSidePacketRegistry.INSTANCE.sendToPlayer(context.getPlayer(), FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.FRONT_BLOCK_PLACING))); + }); ServerSidePacketRegistry.INSTANCE.register(CONTROLS_MODE_CHANNEL, - (context, attached_data) -> ControlsMode.by_id(attached_data.readString(32)) - .ifPresent(controls_mode -> context.getTaskQueue() - .execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controls_mode)))); + (context, attachedData) -> ControlsMode.byId(attachedData.readString(32)) + .ifPresent(controlsMode -> context.getTaskQueue() + .execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode)))); } /** @@ -62,6 +81,42 @@ public class LambdaControls implements ModInitializer this.logger.info("[LambdaControls] " + warning); } + /** + * Returns a packet byte buffer made for the lambdacontrols:controls_mode plugin message. + * + * @param controlsMode The controls mode to send. + * @return The packet byte buffer. + */ + public PacketByteBuf makeControlsModeBuffer(@NotNull ControlsMode controlsMode) + { + Objects.requireNonNull(controlsMode, "Controls mode cannot be null."); + return new PacketByteBuf(Unpooled.buffer()).writeString(controlsMode.getName(), 32); + } + + /** + * Returns a packet byte buffer made for the lambdacontrols:feature plugin message. + * + * @param feature The feature data to send. + * @return The packet byte buffer. + */ + public PacketByteBuf makeFeatureBuffer(@NotNull LambdaControlsFeature feature) + { + Objects.requireNonNull(feature, "Feature cannot be null."); + PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer()).writeString(feature.getName(), 64); + buffer.writeBoolean(feature.isAllowed()); + return buffer; + } + + public PacketByteBuf makeHello(@NotNull ControlsMode controlsMode) + { + String version = ""; + Optional container; + if ((container = FabricLoader.getInstance().getModContainer(LambdaControlsConstants.NAMESPACE)).isPresent()) { + version = container.get().getMetadata().getVersion().getFriendlyString(); + } + return new PacketByteBuf(Unpooled.buffer()).writeString(version, 16).writeString(controlsMode.getName(), 32); + } + /** * Gets the LambdaControls instance. * diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ButtonState.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ButtonState.java index 37b291c..3f3daeb 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ButtonState.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ButtonState.java @@ -35,7 +35,7 @@ public enum ButtonState * * @return True if this state is a pressed state, else false. */ - public boolean is_pressed() + public boolean isPressed() { return this == PRESS || this == REPEAT; } @@ -45,7 +45,7 @@ public enum ButtonState * * @return True if this state is an unpressed state, else false. */ - public boolean is_unpressed() + public boolean isUnpressed() { return this == RELEASE || this == NONE; } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ControllerType.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ControllerType.java index be2a21b..d0aa396 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ControllerType.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/ControllerType.java @@ -44,7 +44,7 @@ public enum ControllerType implements Nameable * * @return The controller type's identifier. */ - public int get_id() + public int getId() { return this.id; } @@ -67,13 +67,13 @@ public enum ControllerType implements Nameable * * @return The translated name of this controller type. */ - public String get_translated_name() + public String getTranslatedName() { - return I18n.translate("lambdacontrols.controller_type." + this.get_name()); + return I18n.translate("lambdacontrols.controller_type." + this.getName()); } @Override - public @NotNull String get_name() + public @NotNull String getName() { return this.name().toLowerCase(); } @@ -84,8 +84,8 @@ public enum ControllerType implements Nameable * @param id The identifier of the controller type. * @return The controller type if found, else empty. */ - public static Optional by_id(@NotNull String id) + public static Optional byId(@NotNull String id) { - return Arrays.stream(values()).filter(mode -> mode.get_name().equalsIgnoreCase(id)).findFirst(); + return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst(); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/HudSide.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/HudSide.java index 2d939cb..7252e81 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/HudSide.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/HudSide.java @@ -46,13 +46,13 @@ public enum HudSide implements Nameable * * @return The translated name of this hud side. */ - public String get_translated_name() + public String getTranslatedName() { - return I18n.translate("lambdacontrols.hud_side." + this.get_name()); + return I18n.translate("lambdacontrols.hud_side." + this.getName()); } @Override - public @NotNull String get_name() + public @NotNull String getName() { return this.name().toLowerCase(); } @@ -63,8 +63,8 @@ public enum HudSide implements Nameable * @param id The identifier of the hud side. * @return The hud side if found, else empty. */ - public static Optional by_id(@NotNull String id) + public static Optional byId(@NotNull String id) { - return Arrays.stream(values()).filter(mode -> mode.get_name().equalsIgnoreCase(id)).findFirst(); + return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst(); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java index 742c86f..cffe81c 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java @@ -13,14 +13,19 @@ import com.mojang.blaze3d.platform.GlStateManager; import me.lambdaurora.lambdacontrols.ControlsMode; import me.lambdaurora.lambdacontrols.LambdaControls; import me.lambdaurora.lambdacontrols.LambdaControlsConstants; +import me.lambdaurora.lambdacontrols.LambdaControlsFeature; import me.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding; import me.lambdaurora.lambdacontrols.client.controller.Controller; import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsHud; +import me.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay; +import me.lambdaurora.spruceui.event.OpenScreenCallback; +import me.lambdaurora.spruceui.hud.HudManager; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding; import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry; -import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.fabricmc.fabric.api.event.client.ClientTickCallback; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawableHelper; @@ -57,7 +62,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni public final LambdaControlsConfig config = new LambdaControlsConfig(this); public final LambdaInput input = new LambdaInput(this); private LambdaControlsHud hud; - private ControlsMode previous_controls_mode; + private ControlsMode previousControlsMode; @Override public void onInitializeClient() @@ -68,32 +73,52 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_DOWN); KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_LEFT); - HudRenderCallback.EVENT.register(delta -> this.hud.render()); + ClientSidePacketRegistry.INSTANCE.register(CONTROLS_MODE_CHANNEL, (context, attachedData) -> context.getTaskQueue() + .execute(() -> ClientSidePacketRegistry.INSTANCE.sendToServer(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(this.config.getControlsMode())))); + ClientSidePacketRegistry.INSTANCE.register(FEATURE_CHANNEL, (context, attachedData) -> { + String name = attachedData.readString(64); + boolean allowed = attachedData.readBoolean(); + LambdaControlsFeature.fromName(name).ifPresent(feature -> context.getTaskQueue().execute(() -> feature.setAllowed(allowed))); + }); + + ClientTickCallback.EVENT.register(this::onTick); + + OpenScreenCallback.EVENT.register((client, screen) -> { + if (screen == null && this.config.getControlsMode() == 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 LambdaControlsHud(this)); } /** * This method is called when Minecraft is initializing. */ - public void on_mc_init(@NotNull MinecraftClient client) + public void onMcInit(@NotNull MinecraftClient client) { ButtonBinding.init(client.options); this.config.load(); - Controller.update_mappings(); + this.hud.setVisible(this.config.isHudEnabled()); + Controller.updateMappings(); GLFW.glfwSetJoystickCallback((jid, event) -> { if (event == GLFW.GLFW_CONNECTED) { - Controller controller = Controller.by_id(jid); + Controller controller = Controller.byId(jid); client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.connected", jid), - new LiteralText(controller.get_name()))); + new LiteralText(controller.getName()))); } else if (event == GLFW.GLFW_DISCONNECTED) { client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.disconnected", jid), null)); } - this.switch_controls_mode(); + this.switchControlsMode(); }); - this.hud = new LambdaControlsHud(client, this); - LambdaControlsCompat.init(this); } @@ -102,37 +127,56 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni * * @param client The client instance. */ - public void on_tick(@NotNull MinecraftClient client) + public void onTick(@NotNull MinecraftClient client) { - this.input.on_tick(client); - if (this.config.get_controls_mode() == ControlsMode.CONTROLLER && (client.isWindowFocused() || this.config.has_unfocused_input())) - this.input.on_controller_tick(client); + this.input.onTick(client); + if (this.config.getControlsMode() == ControlsMode.CONTROLLER && (client.isWindowFocused() || this.config.hasUnfocusedInput())) + this.input.onControllerTick(client); } - public void on_render(MinecraftClient client) + public void onRender(MinecraftClient client) { - this.input.on_render(client); + this.input.onRender(client); + } + + /** + * Called when leaving a server. + */ + public void onLeave() + { + LambdaControlsFeature.resetAllAllowed(); } /** * Switches the controls mode if the auto switch is enabled. */ - public void switch_controls_mode() + public void switchControlsMode() { - if (this.config.has_auto_switch_mode()) { - if (this.config.get_controller().is_gamepad()) { - this.previous_controls_mode = this.config.get_controls_mode(); - this.config.set_controls_mode(ControlsMode.CONTROLLER); + if (this.config.hasAutoSwitchMode()) { + if (this.config.getController().isGamepad()) { + this.previousControlsMode = this.config.getControlsMode(); + this.config.setControlsMode(ControlsMode.CONTROLLER); } else { - if (this.previous_controls_mode == null) { - this.previous_controls_mode = ControlsMode.DEFAULT; + if (this.previousControlsMode == null) { + this.previousControlsMode = ControlsMode.DEFAULT; } - this.config.set_controls_mode(this.previous_controls_mode); + this.config.setControlsMode(this.previousControlsMode); } } } + /** + * Sets whether the HUD is enabled or not. + * + * @param enabled True if the HUD is enabled, else false. + */ + public void setHudEnabled(boolean enabled) + { + this.config.setHudEnabled(enabled); + this.hud.setVisible(enabled); + } + /** * Gets the LambdaControls client instance. * @@ -143,31 +187,32 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni return INSTANCE; } - public static Pair draw_button(int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) + public static Pair drawButton(int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) { - return draw_button(x, y, button.get_button(), client); + return drawButton(x, y, button.getButton(), client); } - public static Pair draw_button(int x, int y, int[] buttons, @NotNull MinecraftClient client) + public static Pair drawButton(int x, int y, int[] buttons, @NotNull MinecraftClient client) { int height = 0; int length = 0; - int current_x = x; + int currentX = x; for (int i = 0; i < buttons.length; i++) { int btn = buttons[i]; - Pair size = draw_button(current_x, y, btn, client); - if (size.get_key() > height) - height = size.get_value(); - length += size.get_key(); + Pair size = drawButton(currentX, y, btn, client); + if (size.key > height) + height = size.key; + length += size.key; if (i + 1 < buttons.length) { length += 2; - current_x = x + length; + currentX = x + length; } } return Pair.of(length, height); } - public static Pair draw_button(int x, int y, int button, @NotNull MinecraftClient client) + @SuppressWarnings("deprecated") + public static Pair drawButton(int x, int y, int button, @NotNull MinecraftClient client) { boolean second = false; if (button == -1) @@ -177,70 +222,70 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni second = true; } - int controller_type = get().config.get_controller_type().get_id(); + int controllerType = get().config.getControllerType().getId(); boolean axis = false; - int button_offset = button * 15; + int buttonOffset = button * 15; switch (button) { case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: - button_offset = 7 * 15; + buttonOffset = 7 * 15; break; case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: - button_offset = 8 * 15; + buttonOffset = 8 * 15; break; case GLFW.GLFW_GAMEPAD_BUTTON_BACK: - button_offset = 4 * 15; + buttonOffset = 4 * 15; break; case GLFW.GLFW_GAMEPAD_BUTTON_START: - button_offset = 6 * 15; + buttonOffset = 6 * 15; break; case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE: - button_offset = 5 * 15; + buttonOffset = 5 * 15; break; case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB: - button_offset = 15 * 15; + buttonOffset = 15 * 15; break; case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: - button_offset = 16 * 15; + buttonOffset = 16 * 15; break; case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100: - button_offset = 0; + buttonOffset = 0; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100: - button_offset = 18; + buttonOffset = 18; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100: - button_offset = 2 * 18; + buttonOffset = 2 * 18; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100: - button_offset = 3 * 18; + buttonOffset = 3 * 18; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200: - button_offset = 4 * 18; + buttonOffset = 4 * 18; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200: - button_offset = 5 * 18; + buttonOffset = 5 * 18; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200: - button_offset = 6 * 18; + buttonOffset = 6 * 18; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200: - button_offset = 7 * 18; + buttonOffset = 7 * 18; axis = true; break; case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100: case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200: - button_offset = 9 * 15; + buttonOffset = 9 * 15; break; case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100: case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200: - button_offset = 10 * 15; + buttonOffset = 10 * 15; break; } @@ -248,34 +293,34 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni GlStateManager.disableDepthTest(); GlStateManager.color4f(1.0F, second ? 0.0F : 1.0F, 1.0F, 1.0F); - DrawableHelper.blit(x, y, (float) button_offset, (float) (controller_type * (axis ? 18 : 15)), axis ? 18 : 15, axis ? 18 : 15, 256, 256); + DrawableHelper.blit(x, y, (float) buttonOffset, (float) (controllerType * (axis ? 18 : 15)), axis ? 18 : 15, axis ? 18 : 15, 256, 256); GlStateManager.enableDepthTest(); return axis ? Pair.of(18, 18) : Pair.of(15, 15); } - public static int draw_button_tip(int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client) + public static int drawButtonTip(int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client) { - return draw_button_tip(x, y, button.get_button(), button.get_translation_key(), display, client); + return drawButtonTip(x, y, button.getButton(), button.getTranslationKey(), display, client); } - public static int draw_button_tip(int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client) + public static int drawButtonTip(int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client) { if (display) { - int button_width = draw_button(x, y, button, client).get_key(); + int buttonWidth = drawButton(x, y, button, client).key; - String translated_action = I18n.translate(action); - int text_y = (15 - client.textRenderer.fontHeight) / 2; - client.textRenderer.drawWithShadow(translated_action, (float) (x + button_width + 5), (float) (y + text_y), 14737632); + String translatedAction = I18n.translate(action); + int textY = (15 - client.textRenderer.fontHeight) / 2; + client.textRenderer.drawWithShadow(translatedAction, (float) (x + buttonWidth + 5), (float) (y + textY), 14737632); - return get_button_tip_width(translated_action, client.textRenderer); + return getButtonTipWidth(translatedAction, client.textRenderer); } return -10; } - private static int get_button_tip_width(@NotNull String action, @NotNull TextRenderer text_renderer) + private static int getButtonTipWidth(@NotNull String action, @NotNull TextRenderer textRenderer) { - return 15 + 5 + text_renderer.getStringWidth(action); + return 15 + 5 + textRenderer.getStringWidth(action); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java index 4ab97d7..e66f037 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java @@ -11,6 +11,7 @@ package me.lambdaurora.lambdacontrols.client; import com.electronwill.nightconfig.core.file.FileConfig; import me.lambdaurora.lambdacontrols.ControlsMode; +import me.lambdaurora.lambdacontrols.LambdaControlsFeature; import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding; import me.lambdaurora.lambdacontrols.client.controller.Controller; import me.lambdaurora.lambdacontrols.client.controller.InputManager; @@ -33,35 +34,36 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y; public class LambdaControlsConfig { // General - private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT; - private static final boolean DEFAULT_AUTO_SWITCH_MODE = false; + private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT; + private static final boolean DEFAULT_AUTO_SWITCH_MODE = false; // HUD - private static final boolean DEFAULT_HUD_ENABLE = true; - private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT; + private static final boolean DEFAULT_HUD_ENABLE = true; + private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT; // Gameplay - private static final boolean DEFAULT_FRONT_BLOCK_PLACING = false; - private static final boolean DEFAULT_FLY_DRIFTING = false; + private static final boolean DEFAULT_FRONT_BLOCK_PLACING = false; + private static final boolean DEFAULT_FLY_DRIFTING = false; + private static final boolean DEFAULT_FLY_VERTICAL_DRIFTING = true; // Controller - private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT; - private static final double DEFAULT_DEAD_ZONE = 0.25; - private static final double DEFAULT_ROTATION_SPEED = 40.0; - private static final double DEFAULT_MOUSE_SPEED = 25.0; - private static final boolean DEFAULT_UNFOCUSED_INPUT = false; + private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT; + private static final double DEFAULT_DEAD_ZONE = 0.25; + private static final double DEFAULT_ROTATION_SPEED = 40.0; + private static final double DEFAULT_MOUSE_SPEED = 25.0; + private static final boolean DEFAULT_UNFOCUSED_INPUT = false; private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?"); protected final FileConfig config = FileConfig.builder("config/lambdacontrols.toml").concurrent().defaultResource("/config.toml").build(); private final LambdaControlsClient mod; - private ControlsMode controls_mode; - private ControllerType controller_type; + private ControlsMode controlsMode; + private ControllerType controllerType; // HUD settings. - private boolean hud_enable; - private HudSide hud_side; + private boolean hudEnable; + private HudSide hudSide; // Controller settings - private double dead_zone; - private double rotation_speed; - private double mouse_speed; - private boolean unfocused_input; + private double deadZone; + private double rotationSpeed; + private double mouseSpeed; + private boolean unfocusedInput; public LambdaControlsConfig(@NotNull LambdaControlsClient mod) { @@ -74,20 +76,22 @@ public class LambdaControlsConfig public void load() { this.config.load(); - this.check_and_fix(); + this.checkAndFix(); this.mod.log("Configuration loaded."); - this.controls_mode = ControlsMode.by_id(this.config.getOrElse("controls", DEFAULT_CONTROLS_MODE.get_name())).orElse(DEFAULT_CONTROLS_MODE); + this.controlsMode = ControlsMode.byId(this.config.getOrElse("controls", DEFAULT_CONTROLS_MODE.getName())).orElse(DEFAULT_CONTROLS_MODE); // HUD settings. - this.hud_enable = this.config.getOrElse("hud.enable", DEFAULT_HUD_ENABLE); - this.hud_side = HudSide.by_id(this.config.getOrElse("hud.side", DEFAULT_HUD_SIDE.get_name())).orElse(DEFAULT_HUD_SIDE); + this.hudEnable = this.config.getOrElse("hud.enable", DEFAULT_HUD_ENABLE); + this.hudSide = HudSide.byId(this.config.getOrElse("hud.side", DEFAULT_HUD_SIDE.getName())).orElse(DEFAULT_HUD_SIDE); + // Gameplay + LambdaControlsFeature.FRONT_BLOCK_PLACING.setEnabled(this.config.getOrElse("gameplay.front_block_placing", DEFAULT_FRONT_BLOCK_PLACING)); // Controller settings. - this.controller_type = ControllerType.by_id(this.config.getOrElse("controller.type", DEFAULT_CONTROLLER_TYPE.get_name())).orElse(DEFAULT_CONTROLLER_TYPE); - this.dead_zone = this.config.getOrElse("controller.dead_zone", DEFAULT_DEAD_ZONE); - this.rotation_speed = this.config.getOrElse("controller.rotation_speed", DEFAULT_ROTATION_SPEED); - this.mouse_speed = this.config.getOrElse("controller.mouse_speed", DEFAULT_MOUSE_SPEED); - this.unfocused_input = this.config.getOrElse("controller.unfocused_input", DEFAULT_UNFOCUSED_INPUT); + this.controllerType = ControllerType.byId(this.config.getOrElse("controller.type", DEFAULT_CONTROLLER_TYPE.getName())).orElse(DEFAULT_CONTROLLER_TYPE); + this.deadZone = this.config.getOrElse("controller.dead_zone", DEFAULT_DEAD_ZONE); + this.rotationSpeed = this.config.getOrElse("controller.rotation_speed", DEFAULT_ROTATION_SPEED); + this.mouseSpeed = this.config.getOrElse("controller.mouse_speed", DEFAULT_MOUSE_SPEED); + this.unfocusedInput = this.config.getOrElse("controller.unfocused_input", DEFAULT_UNFOCUSED_INPUT); // Controller controls. - InputManager.load_button_bindings(this); + InputManager.loadButtonBindings(this); } /** @@ -95,18 +99,18 @@ public class LambdaControlsConfig */ public void save() { - this.config.set("controller.dead_zone", this.dead_zone); - this.config.set("controller.rotation_speed", this.rotation_speed); - this.config.set("controller.mouse_speed", this.mouse_speed); - this.config.set("controller.unfocused_input", this.unfocused_input); + this.config.set("controller.dead_zone", this.deadZone); + this.config.set("controller.rotation_speed", this.rotationSpeed); + this.config.set("controller.mouse_speed", this.mouseSpeed); + this.config.set("controller.unfocused_input", this.unfocusedInput); this.config.save(); this.mod.log("Configuration saved."); } - public void check_and_fix() + public void checkAndFix() { - InputManager.stream_bindings().forEach(binding -> { - String path = "controller.controls." + binding.get_name(); + InputManager.streamBindings().forEach(binding -> { + String path = "controller.controls." + binding.getName(); Object raw = this.config.getRaw(path); if (raw instanceof Number) { this.mod.warn("Invalid data at \"" + path + "\", fixing..."); @@ -121,23 +125,24 @@ public class LambdaControlsConfig public void reset() { // General - this.set_controls_mode(DEFAULT_CONTROLS_MODE); - this.set_auto_switch_mode(DEFAULT_AUTO_SWITCH_MODE); + this.setControlsMode(DEFAULT_CONTROLS_MODE); + this.setAutoSwitchMode(DEFAULT_AUTO_SWITCH_MODE); // HUD - this.set_hud_enabled(DEFAULT_HUD_ENABLE); - this.set_hud_side(DEFAULT_HUD_SIDE); + this.setHudEnabled(DEFAULT_HUD_ENABLE); + this.setHudSide(DEFAULT_HUD_SIDE); // Gameplay - this.set_front_block_placing(DEFAULT_FRONT_BLOCK_PLACING); - this.set_fly_drifting(DEFAULT_FLY_DRIFTING); + this.setFrontBlockPlacing(DEFAULT_FRONT_BLOCK_PLACING); + this.setFlyDrifting(DEFAULT_FLY_DRIFTING); + this.setFlyVerticalDrifting(DEFAULT_FLY_VERTICAL_DRIFTING); // Controller - this.set_controller_type(DEFAULT_CONTROLLER_TYPE); - this.set_dead_zone(DEFAULT_DEAD_ZONE); - this.set_rotation_speed(DEFAULT_ROTATION_SPEED); - this.set_mouse_speed(DEFAULT_MOUSE_SPEED); - this.set_unfocused_input(DEFAULT_UNFOCUSED_INPUT); + this.setControllerType(DEFAULT_CONTROLLER_TYPE); + this.setDeadZone(DEFAULT_DEAD_ZONE); + this.setRotationSpeed(DEFAULT_ROTATION_SPEED); + this.setMouseSpeed(DEFAULT_MOUSE_SPEED); + this.setUnfocusedInput(DEFAULT_UNFOCUSED_INPUT); // Collect prevents concurrent modification. - InputManager.stream_bindings().collect(Collectors.toList()).forEach(binding -> this.set_button_binding(binding, binding.get_default_button())); + InputManager.streamBindings().collect(Collectors.toList()).forEach(binding -> this.setButtonBinding(binding, binding.getDefaultButton())); } /** @@ -145,20 +150,20 @@ public class LambdaControlsConfig * * @return The controls mode. */ - public @NotNull ControlsMode get_controls_mode() + public @NotNull ControlsMode getControlsMode() { - return this.controls_mode; + return this.controlsMode; } /** * Sets the controls mode in the configuration. * - * @param controls_mode The controls mode. + * @param controlsMode The controls mode. */ - public void set_controls_mode(@NotNull ControlsMode controls_mode) + public void setControlsMode(@NotNull ControlsMode controlsMode) { - this.controls_mode = controls_mode; - this.config.set("controls", controls_mode.get_name()); + this.controlsMode = controlsMode; + this.config.set("controls", controlsMode.getName()); } /** @@ -166,7 +171,7 @@ public class LambdaControlsConfig * * @return True if the auto switch mode is enabled, else false. */ - public boolean has_auto_switch_mode() + public boolean hasAutoSwitchMode() { return this.config.getOrElse("auto_switch_mode", DEFAULT_AUTO_SWITCH_MODE); } @@ -174,11 +179,11 @@ public class LambdaControlsConfig /** * Sets whether the auto switch mode is enabled or not. * - * @param auto_switch_mode True if the auto switch mode is enabled, else false. + * @param autoSwitchMode True if the auto switch mode is enabled, else false. */ - public void set_auto_switch_mode(boolean auto_switch_mode) + public void setAutoSwitchMode(boolean autoSwitchMode) { - this.config.set("auto_switch_mode", auto_switch_mode); + this.config.set("auto_switch_mode", autoSwitchMode); } /* @@ -190,9 +195,9 @@ public class LambdaControlsConfig * * @return True if the HUD is enabled, else false. */ - public boolean is_hud_enabled() + public boolean isHudEnabled() { - return this.hud_enable; + return this.hudEnable; } /** @@ -200,10 +205,10 @@ public class LambdaControlsConfig * * @param enable True if the HUD is enabled, else false. */ - public void set_hud_enabled(boolean enable) + public void setHudEnabled(boolean enable) { - this.hud_enable = enable; - this.config.set("hud.enable", this.hud_enable); + this.hudEnable = enable; + this.config.set("hud.enable", this.hudEnable); } /** @@ -211,20 +216,20 @@ public class LambdaControlsConfig * * @return The HUD side. */ - public @NotNull HudSide get_hud_side() + public @NotNull HudSide getHudSide() { - return this.hud_side; + return this.hudSide; } /** * Sets the HUD side in the configuration. * - * @param hud_side The HUD side. + * @param hudSide The HUD side. */ - public void set_hud_side(@NotNull HudSide hud_side) + public void setHudSide(@NotNull HudSide hudSide) { - this.hud_side = hud_side; - this.config.set("hud.side", hud_side.get_name()); + this.hudSide = hudSide; + this.config.set("hud.side", hudSide.getName()); } /* @@ -236,9 +241,9 @@ public class LambdaControlsConfig * * @return True if front block placing is enabled, else false. */ - public boolean has_front_block_placing() + public boolean hasFrontBlockPlacing() { - return this.config.getOrElse("gameplay.front_block_placing", DEFAULT_FRONT_BLOCK_PLACING); + return LambdaControlsFeature.FRONT_BLOCK_PLACING.isEnabled(); } /** @@ -246,8 +251,9 @@ public class LambdaControlsConfig * * @param enable True if front block placing is enabled, else false. */ - public void set_front_block_placing(boolean enable) + public void setFrontBlockPlacing(boolean enable) { + LambdaControlsFeature.FRONT_BLOCK_PLACING.setEnabled(enable); this.config.set("gameplay.front_block_placing", enable); } @@ -256,19 +262,39 @@ public class LambdaControlsConfig * * @return True if fly drifting is enabled, else false. */ - public boolean has_fly_drifting() + public boolean hasFlyDrifting() { - return this.config.getOrElse("gameplay.fly_drifting", DEFAULT_FLY_DRIFTING); + return this.config.getOrElse("gameplay.fly.drifting", DEFAULT_FLY_DRIFTING); } /** * Sets whether fly drifting is enabled or not. * - * @param fly_drifting True if fly drifting is enabled, else false. + * @param flyDrifting True if fly drifting is enabled, else false. */ - public void set_fly_drifting(boolean fly_drifting) + public void setFlyDrifting(boolean flyDrifting) { - this.config.set("gameplay.fly_drifting", fly_drifting); + this.config.set("gameplay.fly.drifting", flyDrifting); + } + + /** + * Returns whether vertical fly drifting is enabled or not. + * + * @return True if vertical fly drifting is enabled, else false. + */ + public boolean hasFlyVerticalDrifting() + { + return this.config.getOrElse("gameplay.fly.vertical_drifting", DEFAULT_FLY_VERTICAL_DRIFTING); + } + + /** + * Sets whether vertical fly drifting is enabled or not. + * + * @param flyDrifting True if vertical fly drifting is enabled, else false. + */ + public void setFlyVerticalDrifting(boolean flyDrifting) + { + this.config.set("gameplay.fly.vertical_drifting", flyDrifting); } /* @@ -280,15 +306,15 @@ public class LambdaControlsConfig * * @return The used controller. */ - public @NotNull Controller get_controller() + public @NotNull Controller getController() { Object raw = this.config.getRaw("controller.id"); if (raw instanceof Number) { - return Controller.by_id((Integer) raw); + return Controller.byId((Integer) raw); } else if (raw instanceof String) { - return Controller.by_guid((String) raw).orElse(Controller.by_id(GLFW.GLFW_JOYSTICK_1)); + return Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1)); } - return Controller.by_id(GLFW.GLFW_JOYSTICK_1); + return Controller.byId(GLFW.GLFW_JOYSTICK_1); } /** @@ -296,9 +322,9 @@ public class LambdaControlsConfig * * @param controller The used controller. */ - public void set_controller(@NotNull Controller controller) + public void setController(@NotNull Controller controller) { - this.config.set("controller.id", controller.get_id()); + this.config.set("controller.id", controller.getId()); } /** @@ -306,15 +332,15 @@ public class LambdaControlsConfig * * @return The second controller. */ - public @NotNull Optional get_second_controller() + public @NotNull Optional getSecondController() { Object raw = this.config.getRaw("controller.id2"); if (raw instanceof Number) { if ((int) raw == -1) return Optional.empty(); - return Optional.of(Controller.by_id((Integer) raw)); + return Optional.of(Controller.byId((Integer) raw)); } else if (raw instanceof String) { - return Optional.of(Controller.by_guid((String) raw).orElse(Controller.by_id(GLFW.GLFW_JOYSTICK_1))); + return Optional.of(Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1))); } return Optional.empty(); } @@ -324,9 +350,9 @@ public class LambdaControlsConfig * * @param controller The second controller. */ - public void set_second_controller(@Nullable Controller controller) + public void setSecondController(@Nullable Controller controller) { - this.config.set("controller.id2", controller == null ? -1 : controller.get_id()); + this.config.set("controller.id2", controller == null ? -1 : controller.getId()); } /** @@ -334,20 +360,20 @@ public class LambdaControlsConfig * * @return The controller's type. */ - public @NotNull ControllerType get_controller_type() + public @NotNull ControllerType getControllerType() { - return this.controller_type; + return this.controllerType; } /** * Sets the controller's type. * - * @param controller_type The controller's type. + * @param controllerType The controller's type. */ - public void set_controller_type(@NotNull ControllerType controller_type) + public void setControllerType(@NotNull ControllerType controllerType) { - this.controller_type = controller_type; - this.config.set("controller.type", controller_type.get_name()); + this.controllerType = controllerType; + this.config.set("controller.type", controllerType.getName()); } /** @@ -355,19 +381,19 @@ public class LambdaControlsConfig * * @return The controller's dead zone value. */ - public double get_dead_zone() + public double getDeadZone() { - return this.dead_zone; + return this.deadZone; } /** * Sets the controller's dead zone in the configuration. * - * @param dead_zone The new controller's dead zone value. + * @param deadZone The new controller's dead zone value. */ - public void set_dead_zone(double dead_zone) + public void setDeadZone(double deadZone) { - this.dead_zone = dead_zone; + this.deadZone = deadZone; } /** @@ -375,19 +401,19 @@ public class LambdaControlsConfig * * @return The rotation speed. */ - public double get_rotation_speed() + public double getRotationSpeed() { - return this.rotation_speed; + return this.rotationSpeed; } /** * Sets the controller's rotation speed. * - * @param rotation_speed The rotation speed. + * @param rotationSpeed The rotation speed. */ - public void set_rotation_speed(double rotation_speed) + public void setRotationSpeed(double rotationSpeed) { - this.rotation_speed = rotation_speed; + this.rotationSpeed = rotationSpeed; } /** @@ -395,19 +421,19 @@ public class LambdaControlsConfig * * @return The mouse speed. */ - public double get_mouse_speed() + public double getMouseSpeed() { - return this.mouse_speed; + return this.mouseSpeed; } /** * Sets the controller's mouse speed. * - * @param mouse_speed The mouse speed. + * @param mouseSpeed The mouse speed. */ - public void set_mouse_speed(double mouse_speed) + public void setMouseSpeed(double mouseSpeed) { - this.mouse_speed = mouse_speed; + this.mouseSpeed = mouseSpeed; } /** @@ -415,7 +441,7 @@ public class LambdaControlsConfig * * @return True if the right X axis is inverted, else false. */ - public boolean does_invert_right_x_axis() + public boolean doesInvertRightXAxis() { return this.config.getOrElse("controller.invert_right_x_axis", false); } @@ -425,7 +451,7 @@ public class LambdaControlsConfig * * @param invert True if the right X axis is inverted, else false. */ - public void set_invert_right_x_axis(boolean invert) + public void setInvertRightXAxis(boolean invert) { this.config.set("controller.invert_right_x_axis", invert); } @@ -435,7 +461,7 @@ public class LambdaControlsConfig * * @return True if the right Y axis is inverted, else false. */ - public boolean does_invert_right_y_axis() + public boolean doesInvertRightYAxis() { return this.config.getOrElse("controller.invert_right_y_axis", false); } @@ -445,7 +471,7 @@ public class LambdaControlsConfig * * @param invert True if the right Y axis is inverted, else false. */ - public void set_invert_right_y_axis(boolean invert) + public void setInvertRightYAxis(boolean invert) { this.config.set("controller.invert_right_y_axis", invert); } @@ -455,19 +481,19 @@ public class LambdaControlsConfig * * @return True if unfocused controller input is allowed, else false. */ - public boolean has_unfocused_input() + public boolean hasUnfocusedInput() { - return this.unfocused_input; + return this.unfocusedInput; } /** * Sets whether unfocused controller input is allowed or not. * - * @param unfocused_input True if unfocused controller input is allowed, else false. + * @param unfocusedInput True if unfocused controller input is allowed, else false. */ - public void set_unfocused_input(boolean unfocused_input) + public void setUnfocusedInput(boolean unfocusedInput) { - this.unfocused_input = unfocused_input; + this.unfocusedInput = unfocusedInput; } /** @@ -475,9 +501,9 @@ public class LambdaControlsConfig * * @return The right X axis sign. */ - public double get_right_x_axis_sign() + public double getRightXAxisSign() { - return this.does_invert_right_x_axis() ? -1.0 : 1.0; + return this.doesInvertRightXAxis() ? -1.0 : 1.0; } /** @@ -485,9 +511,9 @@ public class LambdaControlsConfig * * @return The right Y axis sign. */ - public double get_right_y_axis_sign() + public double getRightYAxisSign() { - return this.does_invert_right_y_axis() ? -1.0 : 1.0; + return this.doesInvertRightYAxis() ? -1.0 : 1.0; } /** @@ -495,12 +521,12 @@ public class LambdaControlsConfig * * @param button The button binding. */ - public void load_button_binding(@NotNull ButtonBinding button) + public void loadButtonBinding(@NotNull ButtonBinding button) { - button.set_button(button.get_default_button()); - String button_code = this.config.getOrElse("controller.controls." + button.get_name(), button.get_button_code()); + button.setButton(button.getDefaultButton()); + String code = this.config.getOrElse("controller.controls." + button.getName(), button.getButtonCode()); - Matcher matcher = BUTTON_BINDING_PATTERN.matcher(button_code); + Matcher matcher = BUTTON_BINDING_PATTERN.matcher(code); try { int[] buttons = new int[1]; @@ -510,27 +536,27 @@ public class LambdaControlsConfig if (count > buttons.length) buttons = Arrays.copyOf(buttons, count); String current; - if (!this.check_validity(button, button_code, current = matcher.group(1))) + if (!this.checkValidity(button, code, current = matcher.group(1))) return; buttons[count - 1] = Integer.parseInt(current); } if (count == 0) { - this.mod.warn("Malformed config value \"" + button_code + "\" for binding \"" + button.get_name() + "\"."); - this.set_button_binding(button, new int[]{-1}); + this.mod.warn("Malformed config value \"" + code + "\" for binding \"" + button.getName() + "\"."); + this.setButtonBinding(button, new int[]{-1}); } - button.set_button(buttons); + button.setButton(buttons); } catch (Exception e) { - this.mod.warn("Malformed config value \"" + button_code + "\" for binding \"" + button.get_name() + "\"."); - this.config.set("controller.controls." + button.get_name(), button.get_button_code()); + this.mod.warn("Malformed config value \"" + code + "\" for binding \"" + button.getName() + "\"."); + this.config.set("controller.controls." + button.getName(), button.getButtonCode()); } } - private boolean check_validity(@NotNull ButtonBinding binding, @NotNull String input, String group) + private boolean checkValidity(@NotNull ButtonBinding binding, @NotNull String input, String group) { if (group == null) { - this.mod.warn("Malformed config value \"" + input + "\" for binding \"" + binding.get_name() + "\"."); - this.config.set("controller.controls." + binding.get_name(), binding.get_button_code()); + this.mod.warn("Malformed config value \"" + input + "\" for binding \"" + binding.getName() + "\"."); + this.config.set("controller.controls." + binding.getName(), binding.getButtonCode()); return false; } return true; @@ -542,38 +568,38 @@ public class LambdaControlsConfig * @param binding The button binding. * @param button The button. */ - public void set_button_binding(@NotNull ButtonBinding binding, int[] button) + public void setButtonBinding(@NotNull ButtonBinding binding, int[] button) { - binding.set_button(button); - this.config.set("controller.controls." + binding.get_name(), binding.get_button_code()); + binding.setButton(button); + this.config.set("controller.controls." + binding.getName(), binding.getButtonCode()); } - public boolean is_back_button(int btn, boolean is_btn, int state) + public boolean isBackButton(int btn, boolean isBtn, int state) { - if (!is_btn && state == 0) + if (!isBtn && state == 0) return false; - return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_Y, false) == ButtonBinding.axis_as_button(btn, state == 1); + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false) == ButtonBinding.axisAsButton(btn, state == 1); } - public boolean is_forward_button(int btn, boolean is_btn, int state) + public boolean isForwardButton(int btn, boolean isBtn, int state) { - if (!is_btn && state == 0) + if (!isBtn && state == 0) return false; - return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_Y, true) == ButtonBinding.axis_as_button(btn, state == 1); + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true) == ButtonBinding.axisAsButton(btn, state == 1); } - public boolean is_left_button(int btn, boolean is_btn, int state) + public boolean isLeftButton(int btn, boolean isBtn, int state) { - if (!is_btn && state == 0) + if (!isBtn && state == 0) return false; - return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_X, false) == ButtonBinding.axis_as_button(btn, state == 1); + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false) == ButtonBinding.axisAsButton(btn, state == 1); } - public boolean is_right_button(int btn, boolean is_btn, int state) + public boolean isRightButton(int btn, boolean isBtn, int state) { - if (!is_btn && state == 0) + if (!isBtn && state == 0) return false; - return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_X, true) == ButtonBinding.axis_as_button(btn, state == 1); + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true) == ButtonBinding.axisAsButton(btn, state == 1); } /** @@ -582,7 +608,7 @@ public class LambdaControlsConfig * @param axis The axis index. * @return True if the axis is used for movements, else false. */ - public boolean is_movement_axis(int axis) + public boolean isMovementAxis(int axis) { return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X; } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java index 04ddda5..adf9a96 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java @@ -12,18 +12,19 @@ package me.lambdaurora.lambdacontrols.client; import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding; import me.lambdaurora.lambdacontrols.client.controller.Controller; import me.lambdaurora.lambdacontrols.client.controller.InputManager; -import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsControlsScreen; +import me.lambdaurora.lambdacontrols.client.gui.ControllerControlsScreen; import me.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay; +import me.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccessor; import me.lambdaurora.lambdacontrols.client.mixin.EntryListWidgetAccessor; -import me.lambdaurora.lambdacontrols.client.util.AbstractContainerScreenAccessor; -import me.lambdaurora.lambdacontrols.client.util.MouseAccessor; +import me.lambdaurora.lambdacontrols.client.util.ContainerScreenAccessor; import me.lambdaurora.spruceui.SpruceLabelWidget; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.ParentElement; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; -import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen; +import net.minecraft.client.gui.screen.ingame.ContainerScreen; +import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget; import net.minecraft.client.gui.screen.world.WorldListWidget; @@ -46,7 +47,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -import static me.lambdaurora.lambdacontrols.client.controller.ButtonBinding.axis_as_button; +import static me.lambdaurora.lambdacontrols.client.controller.ButtonBinding.axisAsButton; +import static me.lambdaurora.lambdacontrols.client.controller.InputManager.INPUT_MANAGER; import static org.lwjgl.glfw.GLFW.*; /** @@ -58,24 +60,22 @@ import static org.lwjgl.glfw.GLFW.*; */ public class LambdaInput { - private static final Map BUTTON_COOLDOWNS = new HashMap<>(); + private static final Map BUTTON_COOLDOWNS = new HashMap<>(); private final LambdaControlsConfig config; // Cooldowns - private int action_gui_cooldown = 0; - private int ignore_next_a = 0; + private int actionGuiCooldown = 0; + private int ignoreNextA = 0; // Sneak state. - private double prev_target_yaw = 0.0; - private double prev_target_pitch = 0.0; - private double target_yaw = 0.0; - private double target_pitch = 0.0; - private float prev_x_axis = 0.F; - private float prev_y_axis = 0.F; - private int prev_target_mouse_x = 0; - private int prev_target_mouse_y = 0; - private int target_mouse_x = 0; - private int target_mouse_y = 0; - private float mouse_speed_x = 0.F; - private float mouse_speed_y = 0.F; + private double prevTargetYaw = 0.0; + private double prevTargetPitch = 0.0; + private double targetYaw = 0.0; + private double targetPitch = 0.0; + private float prevXAxis = 0.F; + private float prevYAxis = 0.F; + private int targetMouseX = 0; + private int targetMouseY = 0; + private float mouseSpeedX = 0.F; + private float mouseSpeedY = 0.F; public LambdaInput(@NotNull LambdaControlsClient mod) { @@ -87,22 +87,24 @@ public class LambdaInput * * @param client The client instance. */ - public void on_tick(@NotNull MinecraftClient client) + public void onTick(@NotNull MinecraftClient client) { - this.prev_target_yaw = this.target_yaw; - this.prev_target_pitch = this.target_pitch; + this.prevTargetYaw = this.targetYaw; + this.prevTargetPitch = this.targetPitch; // Handles the key bindings. if (LambdaControlsClient.BINDING_LOOK_UP.isPressed()) { - this.handle_look(client, GLFW_GAMEPAD_AXIS_RIGHT_Y, 0.8F, 2); + this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_Y, 0.8F, 2); } else if (LambdaControlsClient.BINDING_LOOK_DOWN.isPressed()) { - this.handle_look(client, GLFW_GAMEPAD_AXIS_RIGHT_Y, 0.8F, 1); + this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_Y, 0.8F, 1); } if (LambdaControlsClient.BINDING_LOOK_LEFT.isPressed()) { - this.handle_look(client, GLFW_GAMEPAD_AXIS_RIGHT_X, 0.8F, 2); + this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_X, 0.8F, 2); } else if (LambdaControlsClient.BINDING_LOOK_RIGHT.isPressed()) { - this.handle_look(client, GLFW_GAMEPAD_AXIS_RIGHT_X, 0.8F, 1); + this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_X, 0.8F, 1); } + + INPUT_MANAGER.tick(client); } /** @@ -110,49 +112,47 @@ public class LambdaInput * * @param client The client instance. */ - public void on_controller_tick(@NotNull MinecraftClient client) + public void onControllerTick(@NotNull MinecraftClient client) { BUTTON_COOLDOWNS.entrySet().stream().filter(entry -> entry.getValue() > 0).forEach(entry -> BUTTON_COOLDOWNS.put(entry.getKey(), entry.getValue() - 1)); // Decreases the cooldown for GUI actions. - if (this.action_gui_cooldown > 0) - --this.action_gui_cooldown; - this.prev_target_mouse_x = this.target_mouse_x; - this.prev_target_mouse_y = this.target_mouse_y; + if (this.actionGuiCooldown > 0) + --this.actionGuiCooldown; - InputManager.update_states(); + InputManager.updateStates(); - Controller controller = this.config.get_controller(); - if (controller.is_connected()) { - GLFWGamepadState state = controller.get_state(); - this.fetch_button_input(client, state, false); - this.fetch_axe_input(client, state, false); + Controller controller = this.config.getController(); + if (controller.isConnected()) { + GLFWGamepadState state = controller.getState(); + this.fetchButtonInput(client, state, false); + this.fetchAxeInput(client, state, false); } - this.config.get_second_controller().filter(Controller::is_connected) + this.config.getSecondController().filter(Controller::isConnected) .ifPresent(joycon -> { - GLFWGamepadState state = joycon.get_state(); - this.fetch_button_input(client, state, true); - this.fetch_axe_input(client, state, true); + GLFWGamepadState state = joycon.getState(); + this.fetchButtonInput(client, state, true); + this.fetchAxeInput(client, state, true); }); - boolean allow_input = true; + boolean allowInput = true; - if (client.currentScreen instanceof LambdaControlsControlsScreen && ((LambdaControlsControlsScreen) client.currentScreen).focused_binding != null) - allow_input = false; + if (client.currentScreen instanceof ControllerControlsScreen && ((ControllerControlsScreen) client.currentScreen).focusedBinding != null) + allowInput = false; - if (allow_input) - InputManager.update_bindings(client); + if (allowInput) + InputManager.updateBindings(client); - if (this.ignore_next_a > 0) - this.ignore_next_a--; + if (this.ignoreNextA > 0) + this.ignoreNextA--; - if (client.currentScreen instanceof LambdaControlsControlsScreen && InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::is_unpressed)) { - LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen; - if (controls_screen.focused_binding != null && !controls_screen.waiting) { - int[] buttons = new int[controls_screen.current_buttons.size()]; - for (int i = 0; i < controls_screen.current_buttons.size(); i++) - buttons[i] = controls_screen.current_buttons.get(i); - controls_screen.focused_binding.set_button(buttons); - controls_screen.focused_binding = null; + if (client.currentScreen instanceof ControllerControlsScreen && InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::isUnpressed)) { + ControllerControlsScreen screen = (ControllerControlsScreen) client.currentScreen; + if (screen.focusedBinding != null && !screen.waiting) { + int[] buttons = new int[screen.currentButtons.size()]; + for (int i = 0; i < screen.currentButtons.size(); i++) + buttons[i] = screen.currentButtons.get(i); + screen.focusedBinding.setButton(buttons); + screen.focusedBinding = null; } } } @@ -163,15 +163,10 @@ public class LambdaInput * @param client The client instance. * @param screen The screen to render. */ - public void on_pre_render_screen(@NotNull MinecraftClient client, @NotNull Screen screen) + public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen) { - if (!is_screen_interactive(screen)) { - if (this.prev_target_mouse_x != this.target_mouse_x || this.prev_target_mouse_y != this.target_mouse_y) { - double mouse_x = this.prev_target_mouse_x + (this.target_mouse_x - this.prev_target_mouse_x) * client.getTickDelta() + 0.5; - double mouse_y = this.prev_target_mouse_y + (this.target_mouse_y - this.prev_target_mouse_y) * client.getTickDelta() + 0.5; - GLFW.glfwSetCursorPos(client.getWindow().getHandle(), mouse_x, mouse_y); - ((MouseAccessor) client.mouse).lambdacontrols_on_cursor_pos(client.getWindow().getHandle(), mouse_x, mouse_y); - } + if (!isScreenInteractive(screen)) { + INPUT_MANAGER.updateMousePosition(client); } } @@ -180,113 +175,112 @@ public class LambdaInput * * @param client The client instance. */ - public void on_render(@NotNull MinecraftClient client) + public void onRender(@NotNull MinecraftClient client) { if ((client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay) && - (this.prev_target_yaw != this.target_yaw || this.prev_target_pitch != this.target_pitch)) { - float delta_yaw = (float) ((this.target_yaw - client.player.prevYaw) * client.getTickDelta()); - float delta_pitch = (float) ((this.target_pitch - client.player.prevPitch) * client.getTickDelta()); - float rotation_yaw = client.player.prevYaw + delta_yaw; - float rotation_pitch = client.player.prevPitch + delta_pitch; - client.player.yaw = rotation_yaw; - client.player.pitch = MathHelper.clamp(rotation_pitch, -90.F, 90.F); + (this.prevTargetYaw != this.targetYaw || this.prevTargetPitch != this.targetPitch)) { + float deltaYaw = (float) ((this.targetYaw - client.player.prevYaw) * client.getTickDelta()); + float deltaPitch = (float) ((this.targetPitch - client.player.prevPitch) * client.getTickDelta()); + float rotationYaw = client.player.prevYaw + deltaYaw; + float rotationPitch = client.player.prevPitch + deltaPitch; + client.player.yaw = rotationYaw; + client.player.pitch = MathHelper.clamp(rotationPitch, -90.F, 90.F); if (client.player.isRiding()) { client.player.getVehicle().copyPositionAndRotation(client.player); } - client.getTutorialManager().onUpdateMouse(delta_pitch, delta_yaw); + client.getTutorialManager().onUpdateMouse(deltaPitch, deltaYaw); } } /** * This method is called when a Screen is opened. * - * @param client The client instance. - * @param window_width The window width. - * @param window_height The window height. + * @param client The client instance. + * @param windowWidth The window width. + * @param windowHeight The window height. */ - public void on_screen_open(@NotNull MinecraftClient client, int window_width, int window_height) + public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight) { if (client.currentScreen == null) { - this.mouse_speed_x = this.mouse_speed_y = 0.0F; - this.target_mouse_x = this.prev_target_mouse_x = (int) (window_width / 2.F); - this.target_mouse_y = this.prev_target_mouse_y = (int) (window_height / 2.F); + this.mouseSpeedX = this.mouseSpeedY = 0.0F; + INPUT_MANAGER.resetMousePosition(windowWidth, windowHeight); } } - private void fetch_button_input(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepad_state, boolean left_joycon) + private void fetchButtonInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) { - ByteBuffer buffer = gamepad_state.buttons(); + ByteBuffer buffer = gamepadState.buttons(); for (int i = 0; i < buffer.limit(); i++) { - int btn = left_joycon ? ButtonBinding.controller2_button(i) : i; - boolean btn_state = buffer.get() == (byte) 1; - ButtonState current_state = ButtonState.NONE; - ButtonState previous_state = InputManager.STATES.getOrDefault(btn, ButtonState.NONE); + int btn = leftJoycon ? ButtonBinding.controller2Button(i) : i; + boolean btnState = buffer.get() == (byte) 1; + ButtonState state = ButtonState.NONE; + ButtonState previousState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE); - if (btn_state != previous_state.is_pressed()) { - current_state = btn_state ? ButtonState.PRESS : ButtonState.RELEASE; - this.handle_button(client, btn, btn_state ? 0 : 1, btn_state); - if (btn_state) + if (btnState != previousState.isPressed()) { + state = btnState ? ButtonState.PRESS : ButtonState.RELEASE; + this.handleButton(client, btn, btnState ? 0 : 1, btnState); + if (btnState) BUTTON_COOLDOWNS.put(btn, 5); - } else if (btn_state) { - current_state = ButtonState.REPEAT; + } else if (btnState) { + state = ButtonState.REPEAT; if (BUTTON_COOLDOWNS.getOrDefault(btn, 0) == 0) { BUTTON_COOLDOWNS.put(btn, 5); - this.handle_button(client, btn, 2, true); + this.handleButton(client, btn, 2, true); } } - InputManager.STATES.put(btn, current_state); + InputManager.STATES.put(btn, state); } } - private void fetch_axe_input(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepad_state, boolean left_joycon) + private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) { - FloatBuffer buffer = gamepad_state.axes(); + FloatBuffer buffer = gamepadState.axes(); for (int i = 0; i < buffer.limit(); i++) { - int axis = left_joycon ? ButtonBinding.controller2_button(i) : i; + int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i; float value = buffer.get(); - float abs_value = Math.abs(value); + float absValue = Math.abs(value); if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y) value *= -1.0F; - int state = value > this.config.get_dead_zone() ? 1 : (value < -this.config.get_dead_zone() ? 2 : 0); - this.handle_axe(client, axis, value, abs_value, state); + int state = value > this.config.getDeadZone() ? 1 : (value < -this.config.getDeadZone() ? 2 : 0); + this.handleAxe(client, axis, value, absValue, state); } } - private void handle_button(@NotNull MinecraftClient client, int button, int action, boolean state) + private void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state) { - if (client.currentScreen instanceof LambdaControlsControlsScreen) { - LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen; - if (controls_screen.focused_binding != null) { - if (action == 0 && !controls_screen.current_buttons.contains(button)) { - controls_screen.current_buttons.add(button); + if (client.currentScreen instanceof ControllerControlsScreen) { + ControllerControlsScreen screen = (ControllerControlsScreen) client.currentScreen; + if (screen.focusedBinding != null) { + if (action == 0 && !screen.currentButtons.contains(button)) { + screen.currentButtons.add(button); - int[] buttons = new int[controls_screen.current_buttons.size()]; - for (int i = 0; i < controls_screen.current_buttons.size(); i++) - buttons[i] = controls_screen.current_buttons.get(i); - controls_screen.focused_binding.set_button(buttons); + int[] buttons = new int[screen.currentButtons.size()]; + for (int i = 0; i < screen.currentButtons.size(); i++) + buttons[i] = screen.currentButtons.get(i); + screen.focusedBinding.setButton(buttons); - controls_screen.waiting = false; + screen.waiting = false; } return; } } if (action == 0 || action == 2) { - if (client.currentScreen != null && is_screen_interactive(client.currentScreen) + if (client.currentScreen != null && isScreenInteractive(client.currentScreen) && (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.action_gui_cooldown == 0) { + if (this.actionGuiCooldown == 0) { if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP) { - this.change_focus(client.currentScreen, false); + this.changeFocus(client.currentScreen, false); } else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) { - this.change_focus(client.currentScreen, true); + this.changeFocus(client.currentScreen, true); } else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT) { - this.handle_left_right(client.currentScreen, false); + this.handleLeftRight(client.currentScreen, false); } else { - this.handle_left_right(client.currentScreen, true); + this.handleLeftRight(client.currentScreen, true); } } return; @@ -295,33 +289,38 @@ public class LambdaInput if (action == 1) { if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) { - if (this.action_gui_cooldown == 0) { + if (this.actionGuiCooldown == 0) { Element focused = client.currentScreen.getFocused(); - if (focused != null && is_screen_interactive(client.currentScreen)) { - if (this.handle_a_button(client.currentScreen, focused)) { - this.action_gui_cooldown = 5; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. + if (focused != null && isScreenInteractive(client.currentScreen)) { + if (this.handleAButton(client.currentScreen, focused)) { + this.actionGuiCooldown = 5; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. return; } } } } - if (client.currentScreen instanceof AbstractContainerScreen && client.interactionManager != null && client.player != null) { - double pos_x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); - double pos_y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); - Slot slot = ((AbstractContainerScreenAccessor) client.currentScreen).lambdacontrols_get_slot_at(pos_x, pos_y); + if (client.currentScreen instanceof ContainerScreen && client.interactionManager != null && client.player != null) { + 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(); + Slot slot = ((ContainerScreenAccessor) client.currentScreen).lambdacontrols_getSlotAt(x, y); + SlotActionType slotAction = SlotActionType.PICKUP; if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && slot != null) { - client.interactionManager.clickSlot(((AbstractContainerScreen) client.currentScreen).getContainer().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_1, SlotActionType.PICKUP, client.player); - this.action_gui_cooldown = 5; + if (client.currentScreen instanceof CreativeInventoryScreen) { + if (((CreativeInventoryScreenAccessor) client.currentScreen).lambdacontrols_isCreativeInventorySlot(slot)) + slotAction = SlotActionType.CLONE; + } + client.interactionManager.clickSlot(((ContainerScreen) client.currentScreen).getContainer().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_1, slotAction, client.player); + this.actionGuiCooldown = 5; return; } else if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) { client.player.closeContainer(); return; } else if (button == GLFW.GLFW_GAMEPAD_BUTTON_X && slot != null) { - client.interactionManager.clickSlot(((AbstractContainerScreen) client.currentScreen).getContainer().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_2, SlotActionType.PICKUP, client.player); + client.interactionManager.clickSlot(((ContainerScreen) client.currentScreen).getContainer().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_2, SlotActionType.PICKUP, client.player); return; } else if (button == GLFW.GLFW_GAMEPAD_BUTTON_Y && slot != null) { - client.interactionManager.clickSlot(((AbstractContainerScreen) client.currentScreen).getContainer().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_1, SlotActionType.QUICK_MOVE, client.player); + client.interactionManager.clickSlot(((ContainerScreen) client.currentScreen).getContainer().syncId, slot.id, GLFW.GLFW_MOUSE_BUTTON_1, SlotActionType.QUICK_MOVE, client.player); return; } } else if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) { @@ -332,158 +331,152 @@ public class LambdaInput } } - if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !is_screen_interactive(client.currentScreen) && this.action_gui_cooldown == 0 && this.ignore_next_a == 0) { - double mouse_x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); - double mouse_y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); + if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen) && this.actionGuiCooldown == 0 && this.ignoreNextA == 0) { + double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); + double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); if (action == 0) { - client.currentScreen.mouseClicked(mouse_x, mouse_y, GLFW.GLFW_MOUSE_BUTTON_1); + client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1); } else if (action == 1) { - client.currentScreen.mouseReleased(mouse_x, mouse_y, GLFW.GLFW_MOUSE_BUTTON_1); + client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1); } - this.action_gui_cooldown = 5; + this.actionGuiCooldown = 5; } } - private void handle_axe(@NotNull MinecraftClient client, int axis, float value, float abs_value, int state) + private void handleAxe(@NotNull MinecraftClient client, int axis, float value, float absValue, int state) { - int as_button_state = value > 0.5F ? 1 : (value < -0.5F ? 2 : 0); + int asButtonState = value > 0.5F ? 1 : (value < -0.5F ? 2 : 0); - if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER || axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) || - axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) - if (as_button_state == 2) - as_button_state = 0; + if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER || axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) || + axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) + if (asButtonState == 2) + asButtonState = 0; { - boolean current_plus_state = as_button_state == 1; - boolean current_minus_state = as_button_state == 2; - ButtonState previous_plus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, true), ButtonState.NONE); - ButtonState previous_minus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, false), ButtonState.NONE); + boolean currentPlusState = asButtonState == 1; + boolean currentMinusState = asButtonState == 2; + ButtonState previousPlusState = InputManager.STATES.getOrDefault(axisAsButton(axis, true), ButtonState.NONE); + ButtonState previousMinusState = InputManager.STATES.getOrDefault(axisAsButton(axis, false), ButtonState.NONE); - if (current_plus_state != previous_plus_state.is_pressed()) { - InputManager.STATES.put(axis_as_button(axis, true), current_plus_state ? ButtonState.PRESS : ButtonState.RELEASE); - if (current_plus_state) - BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5); - } else if (current_plus_state) { - InputManager.STATES.put(axis_as_button(axis, true), ButtonState.REPEAT); - if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, true), 0) == 0) { - BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5); + if (currentPlusState != previousPlusState.isPressed()) { + InputManager.STATES.put(axisAsButton(axis, true), currentPlusState ? ButtonState.PRESS : ButtonState.RELEASE); + if (currentPlusState) + BUTTON_COOLDOWNS.put(axisAsButton(axis, true), 5); + } else if (currentPlusState) { + InputManager.STATES.put(axisAsButton(axis, true), ButtonState.REPEAT); + if (BUTTON_COOLDOWNS.getOrDefault(axisAsButton(axis, true), 0) == 0) { + BUTTON_COOLDOWNS.put(axisAsButton(axis, true), 5); } } - if (current_minus_state != previous_minus_state.is_pressed()) { - InputManager.STATES.put(axis_as_button(axis, false), current_minus_state ? ButtonState.PRESS : ButtonState.RELEASE); - if (current_minus_state) - BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5); - } else if (current_minus_state) { - InputManager.STATES.put(axis_as_button(axis, false), ButtonState.REPEAT); - if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, false), 0) == 0) { - BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5); + if (currentMinusState != previousMinusState.isPressed()) { + InputManager.STATES.put(axisAsButton(axis, false), currentMinusState ? ButtonState.PRESS : ButtonState.RELEASE); + if (currentMinusState) + BUTTON_COOLDOWNS.put(axisAsButton(axis, false), 5); + } else if (currentMinusState) { + InputManager.STATES.put(axisAsButton(axis, false), ButtonState.REPEAT); + if (BUTTON_COOLDOWNS.getOrDefault(axisAsButton(axis, false), 0) == 0) { + BUTTON_COOLDOWNS.put(axisAsButton(axis, false), 5); } } } - if (client.currentScreen instanceof LambdaControlsControlsScreen) { - LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen; - if (controls_screen.focused_binding != null) { - if (as_button_state != 0 && !controls_screen.current_buttons.contains(axis_as_button(axis, as_button_state == 1))) { + if (client.currentScreen instanceof ControllerControlsScreen) { + ControllerControlsScreen screen = (ControllerControlsScreen) client.currentScreen; + if (screen.focusedBinding != null) { + if (asButtonState != 0 && !screen.currentButtons.contains(axisAsButton(axis, asButtonState == 1))) { - controls_screen.current_buttons.add(axis_as_button(axis, as_button_state == 1)); + screen.currentButtons.add(axisAsButton(axis, asButtonState == 1)); - int[] buttons = new int[controls_screen.current_buttons.size()]; - for (int i = 0; i < controls_screen.current_buttons.size(); i++) - buttons[i] = controls_screen.current_buttons.get(i); - controls_screen.focused_binding.set_button(buttons); + int[] buttons = new int[screen.currentButtons.size()]; + for (int i = 0; i < screen.currentButtons.size(); i++) + buttons[i] = screen.currentButtons.get(i); + screen.focusedBinding.setButton(buttons); - controls_screen.waiting = false; + screen.waiting = false; } return; } } - double dead_zone = this.config.get_dead_zone(); + double deadZone = this.config.getDeadZone(); if (client.currentScreen == null) { // Handles the look direction. - this.handle_look(client, axis, (float) (abs_value / (1.0 - this.config.get_dead_zone())), state); + this.handleLook(client, axis, (float) (absValue / (1.0 - this.config.getDeadZone())), state); } else { - boolean allow_mouse_control = true; + boolean allowMouseControl = true; - if (this.action_gui_cooldown == 0 && this.config.is_movement_axis(axis) && is_screen_interactive(client.currentScreen)) { - if (this.config.is_forward_button(axis, false, as_button_state)) { - allow_mouse_control = this.change_focus(client.currentScreen, false); - } else if (this.config.is_back_button(axis, false, as_button_state)) { - allow_mouse_control = this.change_focus(client.currentScreen, true); - } else if (this.config.is_left_button(axis, false, as_button_state)) { - allow_mouse_control = this.handle_left_right(client.currentScreen, false); - } else if (this.config.is_right_button(axis, false, as_button_state)) { - allow_mouse_control = this.handle_left_right(client.currentScreen, true); + if (this.actionGuiCooldown == 0 && this.config.isMovementAxis(axis) && isScreenInteractive(client.currentScreen)) { + if (this.config.isForwardButton(axis, false, asButtonState)) { + allowMouseControl = this.changeFocus(client.currentScreen, false); + } else if (this.config.isBackButton(axis, false, asButtonState)) { + allowMouseControl = this.changeFocus(client.currentScreen, true); + } else if (this.config.isLeftButton(axis, false, asButtonState)) { + allowMouseControl = this.handleLeftRight(client.currentScreen, false); + } else if (this.config.isRightButton(axis, false, asButtonState)) { + allowMouseControl = this.handleLeftRight(client.currentScreen, true); } } - float movement_x = 0.0F; - float movement_y = 0.0F; + float movementX = 0.0F; + float movementY = 0.0F; - if (this.config.is_back_button(axis, false, (value > 0 ? 1 : 2))) { - movement_y = abs_value; - } else if (this.config.is_forward_button(axis, false, (value > 0 ? 1 : 2))) { - movement_y = -abs_value; - } else if (this.config.is_left_button(axis, false, (value > 0 ? 1 : 2))) { - movement_x = -abs_value; - } else if (this.config.is_right_button(axis, false, (value > 0 ? 1 : 2))) { - movement_x = abs_value; + if (this.config.isBackButton(axis, false, (value > 0 ? 1 : 2))) { + movementY = absValue; + } else if (this.config.isForwardButton(axis, false, (value > 0 ? 1 : 2))) { + movementY = -absValue; + } else if (this.config.isLeftButton(axis, false, (value > 0 ? 1 : 2))) { + movementX = -absValue; + } else if (this.config.isRightButton(axis, false, (value > 0 ? 1 : 2))) { + movementX = absValue; } - if (client.currentScreen != null && allow_mouse_control) { - boolean moving = Math.abs(movement_y) >= dead_zone || Math.abs(movement_x) >= dead_zone; + if (client.currentScreen != null && allowMouseControl) { + boolean moving = Math.abs(movementY) >= deadZone || Math.abs(movementX) >= deadZone; if (moving) { /* Updates the target mouse position when the initial movement stick movement is detected. It prevents the cursor to jump to the old target mouse position if the user moves the cursor with the mouse. */ - if (Math.abs(prev_x_axis) < dead_zone && Math.abs(prev_y_axis) < dead_zone) { - double mouse_x = client.mouse.getX(); - double mouse_y = client.mouse.getY(); - this.prev_target_mouse_x = this.target_mouse_x = (int) mouse_x; - this.prev_target_mouse_y = this.target_mouse_y = (int) mouse_y; + if (Math.abs(prevXAxis) < deadZone && Math.abs(prevYAxis) < deadZone) { + INPUT_MANAGER.resetMouseTarget(client); } - if (Math.abs(movement_x) >= dead_zone) - this.mouse_speed_x = movement_x; + if (Math.abs(movementX) >= deadZone) + this.mouseSpeedX = movementX; else - this.mouse_speed_x = 0.F; + this.mouseSpeedX = 0.F; - if (Math.abs(movement_y) >= dead_zone) - this.mouse_speed_y = movement_y; + if (Math.abs(movementY) >= deadZone) + this.mouseSpeedY = movementY; else - this.mouse_speed_y = 0.F; + this.mouseSpeedY = 0.F; } else { - this.mouse_speed_x = 0.F; - this.mouse_speed_y = 0.F; + this.mouseSpeedX = 0.F; + this.mouseSpeedY = 0.F; } - if (Math.abs(this.mouse_speed_x) >= .05F || Math.abs(this.mouse_speed_y) >= .05F) { - this.target_mouse_x += this.mouse_speed_x * this.config.get_mouse_speed(); - this.target_mouse_x = MathHelper.clamp(this.target_mouse_x, 0, client.getWindow().getWidth()); - this.target_mouse_y += this.mouse_speed_y * this.config.get_mouse_speed(); - this.target_mouse_y = MathHelper.clamp(this.target_mouse_y, 0, client.getWindow().getHeight()); + if (Math.abs(this.mouseSpeedX) >= .05F || Math.abs(this.mouseSpeedY) >= .05F) { + InputManager.queueMoveMousePosition(this.mouseSpeedX * this.config.getMouseSpeed(), this.mouseSpeedY * this.config.getMouseSpeed()); } - this.move_mouse_to_closest_slot(client, client.currentScreen); + this.moveMouseToClosestSlot(client, client.currentScreen); } - this.prev_x_axis = movement_x; - this.prev_y_axis = movement_y; + this.prevXAxis = movementX; + this.prevYAxis = movementY; } } - private boolean handle_a_button(@NotNull Screen screen, @NotNull Element focused) + private boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) { if (focused instanceof AbstractPressableButtonWidget) { - AbstractPressableButtonWidget button_widget = (AbstractPressableButtonWidget) focused; - button_widget.playDownSound(MinecraftClient.getInstance().getSoundManager()); - button_widget.onPress(); + AbstractPressableButtonWidget widget = (AbstractPressableButtonWidget) focused; + widget.playDownSound(MinecraftClient.getInstance().getSoundManager()); + widget.onPress(); return true; } else if (focused instanceof SpruceLabelWidget) { - ((SpruceLabelWidget) focused).on_press(); + ((SpruceLabelWidget) focused).onPress(); return true; } else if (focused instanceof WorldListWidget) { WorldListWidget list = (WorldListWidget) focused; @@ -497,9 +490,9 @@ public class LambdaInput ((MultiplayerScreen) screen).connect(); } } else if (focused instanceof ParentElement) { - Element child_focused = ((ParentElement) focused).getFocused(); - if (child_focused != null) - return this.handle_a_button(screen, child_focused); + Element childFocused = ((ParentElement) focused).getFocused(); + if (childFocused != null) + return this.handleAButton(screen, childFocused); } return false; } @@ -510,31 +503,31 @@ public class LambdaInput * @param screen The current screen. * @param right True if the right button is pressed, else false. */ - private boolean handle_left_right(@NotNull Screen screen, boolean right) + private boolean handleLeftRight(@NotNull Screen screen, boolean right) { Element focused = screen.getFocused(); if (focused != null) - if (this.handle_right_left_element(focused, right)) - return this.change_focus(screen, right); + if (this.handleRightLeftElement(focused, right)) + return this.changeFocus(screen, right); return true; } - private boolean handle_right_left_element(@NotNull Element element, boolean right) + private boolean handleRightLeftElement(@NotNull Element element, boolean right) { if (element instanceof SliderWidget) { SliderWidget slider = (SliderWidget) element; slider.keyPressed(right ? 262 : 263, 0, 0); - this.action_gui_cooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. + this.actionGuiCooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. return false; } else if (element instanceof AlwaysSelectedEntryListWidget) { - ((EntryListWidgetAccessor) element).lambdacontrols_move_selection(right ? 1 : -1); + ((EntryListWidgetAccessor) element).lambdacontrols_moveSelection(right ? 1 : -1); return false; } else if (element instanceof ParentElement) { - ParentElement entry_list = (ParentElement) element; - Element focused = entry_list.getFocused(); + ParentElement entryList = (ParentElement) element; + Element focused = entryList.getFocused(); if (focused == null) return true; - return this.handle_right_left_element(focused, right); + return this.handleRightLeftElement(focused, right); } return true; } @@ -547,103 +540,103 @@ public class LambdaInput * @param value The value of the look. * @param state The state. */ - public void handle_look(@NotNull MinecraftClient client, int axis, float value, int state) + public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) { // Handles the look direction. if (client.player != null) { - double pow_value = Math.pow(value, 4.0); + double powValue = Math.pow(value, 4.0); if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { if (state == 2) { - this.target_pitch = client.player.pitch - this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D; - this.target_pitch = MathHelper.clamp(this.target_pitch, -90.0D, 90.0D); + this.targetPitch = client.player.pitch - this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D; + this.targetPitch = MathHelper.clamp(this.targetPitch, -90.0D, 90.0D); } else if (state == 1) { - this.target_pitch = client.player.pitch + this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D; - this.target_pitch = MathHelper.clamp(this.target_pitch, -90.0D, 90.0D); + this.targetPitch = client.player.pitch + this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D; + this.targetPitch = MathHelper.clamp(this.targetPitch, -90.0D, 90.0D); } } if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) { if (state == 2) { - this.target_yaw = client.player.yaw - this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D; + this.targetYaw = client.player.yaw - this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D; } else if (state == 1) { - this.target_yaw = client.player.yaw + this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D; + this.targetYaw = client.player.yaw + this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D; } } } } - private boolean change_focus(@NotNull Screen screen, boolean down) + private boolean changeFocus(@NotNull Screen screen, boolean down) { if (!screen.changeFocus(down)) { if (screen.changeFocus(down)) { - this.action_gui_cooldown = 5; + this.actionGuiCooldown = 5; return false; } return true; } else { - this.action_gui_cooldown = 5; + this.actionGuiCooldown = 5; return false; } } - private static boolean is_screen_interactive(@NotNull Screen screen) + private static boolean isScreenInteractive(@NotNull Screen screen) { - return !(screen instanceof AdvancementsScreen || screen instanceof AbstractContainerScreen); + return !(screen instanceof AdvancementsScreen || screen instanceof ContainerScreen); } // Inspired from https://github.com/MrCrayfish/Controllable/blob/1.14.X/src/main/java/com/mrcrayfish/controllable/client/ControllerInput.java#L686. - private void move_mouse_to_closest_slot(@NotNull MinecraftClient client, @Nullable Screen screen) + private void moveMouseToClosestSlot(@NotNull MinecraftClient client, @Nullable Screen screen) { // Makes the mouse attracted to slots. This helps with selecting items when using a controller. - if (screen instanceof AbstractContainerScreen) { - AbstractContainerScreen inventory_screen = (AbstractContainerScreen) screen; - AbstractContainerScreenAccessor accessor = (AbstractContainerScreenAccessor) inventory_screen; - int gui_left = accessor.lambdacontrols_get_x(); - int gui_top = accessor.lambdacontrols_get_y(); - int mouse_x = (int) (target_mouse_x * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()); - int mouse_y = (int) (target_mouse_y * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()); + if (screen instanceof ContainerScreen) { + ContainerScreen inventoryScreen = (ContainerScreen) screen; + ContainerScreenAccessor accessor = (ContainerScreenAccessor) inventoryScreen; + int guiLeft = accessor.lambdacontrols_getX(); + int guiTop = accessor.lambdacontrols_getY(); + int mouseX = (int) (targetMouseX * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()); + int mouseY = (int) (targetMouseY * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()); // Finds the closest slot in the GUI within 14 pixels. - Optional> closest_slot = inventory_screen.getContainer().slotList.parallelStream() + Optional> closestSlot = inventoryScreen.getContainer().slots.parallelStream() .map(slot -> { - int pos_x = gui_left + slot.xPosition + 8; - int pos_y = gui_top + slot.yPosition + 8; + int x = guiLeft + slot.xPosition + 8; + int y = guiTop + slot.yPosition + 8; // Distance between the slot and the cursor. - double distance = Math.sqrt(Math.pow(pos_x - mouse_x, 2) + Math.pow(pos_y - mouse_y, 2)); + double distance = Math.sqrt(Math.pow(x - mouseX, 2) + Math.pow(y - mouseY, 2)); return Pair.of(slot, distance); - }).filter(entry -> entry.get_value() <= 14.0) - .min(Comparator.comparingDouble(Pair::get_value)); + }).filter(entry -> entry.value <= 14.0) + .min(Comparator.comparingDouble(p -> p.value)); - if (closest_slot.isPresent()) { - Slot slot = closest_slot.get().get_key(); + if (closestSlot.isPresent()) { + Slot slot = closestSlot.get().key; if (slot.hasStack() || !client.player.inventory.getMainHandStack().isEmpty()) { - int slot_center_x_scaled = gui_left + slot.xPosition + 8; - int slot_center_y_scaled = gui_top + slot.yPosition + 8; - int slot_center_x = (int) (slot_center_x_scaled / ((double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth())); - int slot_center_y = (int) (slot_center_y_scaled / ((double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight())); - double delta_x = slot_center_x - target_mouse_x; - double delta_y = slot_center_y - target_mouse_y; + int slotCenterXScaled = guiLeft + slot.xPosition + 8; + int slotCenterYScaled = guiTop + slot.yPosition + 8; + int slotCenterX = (int) (slotCenterXScaled / ((double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth())); + int slotCenterY = (int) (slotCenterYScaled / ((double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight())); + double deltaX = slotCenterX - targetMouseX; + double deltaY = slotCenterY - targetMouseY; - if (mouse_x != slot_center_x_scaled || mouse_y != slot_center_y_scaled) { - this.target_mouse_x += delta_x * 0.75; - this.target_mouse_y += delta_y * 0.75; + if (mouseX != slotCenterXScaled || mouseY != slotCenterYScaled) { + this.targetMouseX += deltaX * 0.75; + this.targetMouseY += deltaY * 0.75; } else { - this.mouse_speed_x *= 0.3F; - this.mouse_speed_y *= 0.3F; + this.mouseSpeedX *= 0.3F; + this.mouseSpeedY *= 0.3F; } - this.mouse_speed_x *= .75F; - this.mouse_speed_y *= .75F; + this.mouseSpeedX *= .75F; + this.mouseSpeedY *= .75F; } else { - this.mouse_speed_x *= .1F; - this.mouse_speed_y *= .1F; + this.mouseSpeedX *= .1F; + this.mouseSpeedY *= .1F; } } else { - this.mouse_speed_x *= .3F; - this.mouse_speed_y *= .3F; + this.mouseSpeedX *= .3F; + this.mouseSpeedY *= .3F; } } else { - this.mouse_speed_x = 0.F; - this.mouse_speed_y = 0.F; + this.mouseSpeedX = 0.F; + this.mouseSpeedY = 0.F; } } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java index ced6326..a9d644d 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java @@ -31,10 +31,10 @@ public class LambdaControlsCompat */ public static void init(@NotNull LambdaControlsClient mod) { - if (FabricLoader.getInstance().isModLoaded("okzoomer") && LambdaReflection.does_class_exist(OkZoomerCompat.OKZOOMER_CLASS_PATH)) { + if (FabricLoader.getInstance().isModLoaded("okzoomer") && LambdaReflection.doesClassExist(OkZoomerCompat.OKZOOMER_CLASS_PATH)) { mod.log("Adding okzoomer compatibility..."); new OkZoomerCompat().handle(mod); } - InputManager.load_button_bindings(mod.config); + InputManager.loadButtonBindings(mod.config); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/OkZoomerCompat.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/OkZoomerCompat.java index 6570fe9..552d203 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/OkZoomerCompat.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/OkZoomerCompat.java @@ -12,7 +12,6 @@ package me.lambdaurora.lambdacontrols.client.compat; import io.github.joaoh1.okzoomer.OkZoomer; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import me.lambdaurora.lambdacontrols.client.controller.InputManager; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; @@ -30,8 +29,12 @@ public class OkZoomerCompat implements CompatHandler @Override public void handle(@NotNull LambdaControlsClient mod) { - ButtonBinding binding = InputManager.register_binding(new ButtonBinding("zoom", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_X}, true)); - binding.set_key_binding(OkZoomer.zoomKeyBinding); - ButtonBinding.MISC_CATEGORY.register_binding(binding); + new ButtonBinding.Builder("zoom") + .buttons(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_X) + .onlyInGame() + .cooldown(true) + .category(ButtonBinding.MISC_CATEGORY) + .linkKeybind(OkZoomer.zoomKeyBinding) + .register(); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java index b73668a..72988e2 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java @@ -14,16 +14,18 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.options.GameOptions; import net.minecraft.client.options.KeyBinding; import net.minecraft.client.resource.language.I18n; +import org.aperlambda.lambdacommon.Identifier; import org.aperlambda.lambdacommon.utils.Nameable; +import org.aperlambda.lambdacommon.utils.function.PairPredicate; +import org.aperlambda.lambdacommon.utils.function.Predicates; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.lwjgl.glfw.GLFW; import java.util.*; import java.util.stream.Collectors; -import static me.lambdaurora.lambdacontrols.client.controller.InputManager.register_binding; -import static me.lambdaurora.lambdacontrols.client.controller.InputManager.register_default_category; +import static me.lambdaurora.lambdacontrols.client.controller.InputManager.registerDefaultCategory; +import static org.lwjgl.glfw.GLFW.*; /** * Represents a button binding. @@ -40,53 +42,66 @@ public class ButtonBinding implements Nameable public static final ButtonCategory MULTIPLAYER_CATEGORY; public static final ButtonCategory MISC_CATEGORY; - public static final ButtonBinding ATTACK = register_binding(new ButtonBinding("attack", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)}, false)); - public static final ButtonBinding BACK = register_binding(new ButtonBinding("back", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, false)}, false)); - public static final ButtonBinding CHAT = register_binding(new ButtonBinding("chat", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT}, true)); - public static final ButtonBinding DROP_ITEM = register_binding(new ButtonBinding("drop_item", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, true)); - public static final ButtonBinding FORWARD = register_binding(new ButtonBinding("forward", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, true)}, false)); - public static final ButtonBinding HOTBAR_LEFT = register_binding(new ButtonBinding("hotbar_left", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER}, - Collections.singletonList(InputHandlers.handle_hotbar(false)), true)); - public static final ButtonBinding HOTBAR_RIGHT = register_binding(new ButtonBinding("hotbar_right", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER}, - Collections.singletonList(InputHandlers.handle_hotbar(true)), true)); - public static final ButtonBinding INVENTORY = register_binding(new ButtonBinding("inventory", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, true)); - public static final ButtonBinding JUMP = register_binding(new ButtonBinding("jump", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, false)); - public static final ButtonBinding LEFT = register_binding(new ButtonBinding("left", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, false)}, false)); - public static final ButtonBinding PAUSE_GAME = register_binding(new ButtonBinding("pause_game", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_START}, - Collections.singletonList(InputHandlers::handle_pause_game), true)); - public static final ButtonBinding PICK_BLOCK = register_binding(new ButtonBinding("pick_block", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT}, true)); - public static final ButtonBinding PLAYER_LIST = register_binding(new ButtonBinding("player_list", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_BACK}, false)); - public static final ButtonBinding RIGHT = register_binding(new ButtonBinding("right", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, true)}, false)); - public static final ButtonBinding SCREENSHOT = register_binding(new ButtonBinding("screenshot", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_A}, - Collections.singletonList(InputHandlers::handle_screenshot), true)); - public static final ButtonBinding SMOOTH_CAMERA = register_binding(new ButtonBinding("toggle_smooth_camera", new int[]{-1}, true)); - public static final ButtonBinding SNEAK = register_binding(new ButtonBinding("sneak", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB}, - Arrays.asList(PressAction.DEFAULT_ACTION, InputHandlers::handle_toggle_sneak), true)); - public static final ButtonBinding SPRINT = register_binding(new ButtonBinding("sprint", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB}, false)); - public static final ButtonBinding SWAP_HANDS = register_binding(new ButtonBinding("swap_hands", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, true)); - public static final ButtonBinding TOGGLE_PERSPECTIVE = register_binding(new ButtonBinding("toggle_perspective", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_Y}, true)); - public static final ButtonBinding USE = register_binding(new ButtonBinding("use", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)}, false)); + public static final ButtonBinding ATTACK = new Builder("attack").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)).onlyInGame().register(); + public static final ButtonBinding BACK = new Builder("back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false)).onlyInGame().register(); + public static final ButtonBinding CHAT = new Builder("chat").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT).onlyInGame().cooldown(true).register(); + public static final ButtonBinding DROP_ITEM = new Builder("drop_item").buttons(GLFW_GAMEPAD_BUTTON_B).onlyInGame().cooldown(true).register(); + public static final ButtonBinding FORWARD = new Builder("forward").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true)).onlyInGame().register(); + public static final ButtonBinding HOTBAR_LEFT = new Builder("hotbar_left").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) + .action(InputHandlers.handleHotbar(false)).onlyInGame().cooldown(true).register(); + public static final ButtonBinding HOTBAR_RIGHT = new Builder("hotbar_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) + .action(InputHandlers.handleHotbar(true)).onlyInGame().cooldown(true).register(); + public static final ButtonBinding INVENTORY = new Builder("inventory").buttons(GLFW_GAMEPAD_BUTTON_Y).onlyInGame().cooldown(true).register(); + public static final ButtonBinding JUMP = new Builder("jump").buttons(GLFW_GAMEPAD_BUTTON_A).onlyInGame().register(); + public static final ButtonBinding LEFT = new Builder("left").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false)).onlyInGame().register(); + public static final ButtonBinding PAUSE_GAME = new Builder("pause_game").buttons(GLFW_GAMEPAD_BUTTON_START).action(InputHandlers::handlePauseGame).cooldown(true).register(); + public static final ButtonBinding PICK_BLOCK = new Builder("pick_block").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT).onlyInGame().cooldown(true).register(); + public static final ButtonBinding PLAYER_LIST = new Builder("player_list").buttons(GLFW_GAMEPAD_BUTTON_BACK).onlyInGame().register(); + public static final ButtonBinding RIGHT = new Builder("right").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true)).register(); + public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A) + .action(InputHandlers::handleScreenshot).cooldown(true).register(); + public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN) + .action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown(true).register(); + public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT) + .action(InputHandlers.handleInventorySlotPad(3)).onlyInInventory().cooldown(true).register(); + public static final ButtonBinding SLOT_RIGHT = new Builder("slot_right").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT) + .action(InputHandlers.handleInventorySlotPad(2)).onlyInInventory().cooldown(true).register(); + public static final ButtonBinding SLOT_UP = new Builder("slot_up").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP) + .action(InputHandlers.handleInventorySlotPad(0)).onlyInInventory().cooldown(true).register(); + public static final ButtonBinding SMOOTH_CAMERA = new Builder("toggle_smooth_camera").cooldown(true).register(); + public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB) + .actions(PressAction.DEFAULT_ACTION, InputHandlers::handleToggleSneak).onlyInGame().cooldown(true).register(); + public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).register(); + public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).cooldown(true).register(); + public static final ButtonBinding TAB_LEFT = new Builder("tab_left").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) + .action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown(true).register(); + public static final ButtonBinding TAB_RIGHT = new Builder("tab_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) + .action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown(true).register(); + public static final ButtonBinding TOGGLE_PERSPECTIVE = new Builder("toggle_perspective").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_Y).cooldown(true).register(); + public static final ButtonBinding USE = new Builder("use").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)).register(); - private int[] button; - private int[] default_button; - private String key; - private KeyBinding minecraft_key_binding = null; - private List actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION)); - private boolean has_cooldown; - private int cooldown = 0; + private int[] button; + private int[] defaultButton; + private String key; + private KeyBinding mcKeyBinding = null; + protected PairPredicate filter; + private List actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION)); + private boolean hasCooldown; + private int cooldown = 0; boolean pressed = false; - public ButtonBinding(@NotNull String key, int[] default_button, @NotNull List actions, boolean has_cooldown) + public ButtonBinding(@NotNull String key, int[] defaultButton, @NotNull List actions, PairPredicate filter, boolean hasCooldown) { - this.set_button(this.default_button = default_button); + this.setButton(this.defaultButton = defaultButton); this.key = key; + this.filter = filter; this.actions.addAll(actions); - this.has_cooldown = has_cooldown; + this.hasCooldown = hasCooldown; } - public ButtonBinding(@NotNull String key, int[] default_button, boolean has_cooldown) + public ButtonBinding(@NotNull String key, int[] defaultButton, boolean hasCooldown) { - this(key, default_button, Collections.emptyList(), has_cooldown); + this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown); } /** @@ -94,7 +109,7 @@ public class ButtonBinding implements Nameable * * @return The bound button. */ - public int[] get_button() + public int[] getButton() { return this.button; } @@ -104,12 +119,12 @@ public class ButtonBinding implements Nameable * * @param button The bound button. */ - public void set_button(int[] button) + public void setButton(int[] button) { this.button = button; - if (InputManager.has_binding(this)) - InputManager.sort_bindings(); + if (InputManager.hasBinding(this)) + InputManager.sortBindings(); } /** @@ -118,9 +133,9 @@ public class ButtonBinding implements Nameable * @param button The button to check. * @return True if the bound button is the specified button, else false. */ - public boolean is_button(int[] button) + public boolean isButton(int[] button) { - return InputManager.are_buttons_equivalent(button, this.button); + return InputManager.areButtonsEquivalent(button, this.button); } /** @@ -128,7 +143,7 @@ public class ButtonBinding implements Nameable * * @return True if the button is down, else false. */ - public boolean is_button_down() + public boolean isButtonDown() { return this.pressed; } @@ -138,7 +153,7 @@ public class ButtonBinding implements Nameable * * @return True if this button binding is bound, else false. */ - public boolean is_not_bound() + public boolean isNotBound() { return this.button.length == 0 || this.button[0] == -1; } @@ -148,9 +163,9 @@ public class ButtonBinding implements Nameable * * @return The default button. */ - public int[] get_default_button() + public int[] getDefaultButton() { - return this.default_button; + return this.defaultButton; } /** @@ -158,9 +173,9 @@ public class ButtonBinding implements Nameable * * @return True if the assigned button is the default button, else false. */ - public boolean is_default() + public boolean isDefault() { - return this.button.length == this.default_button.length && InputManager.are_buttons_equivalent(this.button, this.default_button); + return this.button.length == this.defaultButton.length && InputManager.areButtonsEquivalent(this.button, this.defaultButton); } /** @@ -168,7 +183,8 @@ public class ButtonBinding implements Nameable * * @return The button code. */ - public @NotNull String get_button_code() + public @NotNull + String getButtonCode() { return Arrays.stream(this.button) .mapToObj(btn -> Integer.valueOf(btn).toString()) @@ -178,11 +194,22 @@ public class ButtonBinding implements Nameable /** * Sets the key binding to emulate with this button binding. * - * @param key_binding The optional key binding. + * @param keyBinding The optional key binding. */ - public void set_key_binding(@Nullable KeyBinding key_binding) + public void setKeyBinding(@Nullable KeyBinding keyBinding) { - this.minecraft_key_binding = key_binding; + this.mcKeyBinding = keyBinding; + } + + /** + * Returns whether the button binding is available in the current context. + * + * @param client The client instance. + * @return True if the button binding is available, else false. + */ + public boolean isAvailable(@NotNull MinecraftClient client) + { + return this.filter.test(client, this); } /** @@ -190,7 +217,7 @@ public class ButtonBinding implements Nameable */ public void update() { - if (this.has_cooldown && this.cooldown > 0) + if (this.hasCooldown && this.cooldown > 0) this.cooldown--; } @@ -202,9 +229,9 @@ public class ButtonBinding implements Nameable */ public void handle(@NotNull MinecraftClient client, @NotNull ButtonState state) { - if (state == ButtonState.REPEAT && this.has_cooldown && this.cooldown != 0) + if (state == ButtonState.REPEAT && this.hasCooldown && this.cooldown != 0) return; - if (this.has_cooldown && state.is_pressed()) { + if (this.hasCooldown && state.isPressed()) { this.cooldown = 5; } @@ -215,7 +242,7 @@ public class ButtonBinding implements Nameable } @Override - public @NotNull String get_name() + public @NotNull String getName() { return this.key; } @@ -225,9 +252,10 @@ public class ButtonBinding implements Nameable * * @return The translation key. */ - public @NotNull String get_translation_key() + public @NotNull + String getTranslationKey() { - return "lambdacontrols.action." + this.get_name(); + return "lambdacontrols.action." + this.getName(); } /** @@ -235,9 +263,10 @@ public class ButtonBinding implements Nameable * * @return The key binding equivalent. */ - public @NotNull Optional as_key_binding() + public @NotNull + Optional asKeyBinding() { - return Optional.ofNullable(this.minecraft_key_binding); + return Optional.ofNullable(this.mcKeyBinding); } /** @@ -247,7 +276,7 @@ public class ButtonBinding implements Nameable * @param positive True if the axis part is positive, else false. * @return The axis as a button. */ - public static int axis_as_button(int axis, boolean positive) + public static int axisAsButton(int axis, boolean positive) { return positive ? 100 + axis : 200 + axis; } @@ -258,31 +287,31 @@ public class ButtonBinding implements Nameable * @param button The raw button code. * @return The second Joycon's button code. */ - public static int controller2_button(int button) + public static int controller2Button(int button) { return 500 + button; } public static void init(@NotNull GameOptions options) { - ATTACK.minecraft_key_binding = options.keyAttack; - BACK.minecraft_key_binding = options.keyBack; - CHAT.minecraft_key_binding = options.keyChat; - DROP_ITEM.minecraft_key_binding = options.keyDrop; - FORWARD.minecraft_key_binding = options.keyForward; - INVENTORY.minecraft_key_binding = options.keyInventory; - JUMP.minecraft_key_binding = options.keyJump; - LEFT.minecraft_key_binding = options.keyLeft; - PICK_BLOCK.minecraft_key_binding = options.keyPickItem; - PLAYER_LIST.minecraft_key_binding = options.keyPlayerList; - RIGHT.minecraft_key_binding = options.keyRight; - SCREENSHOT.minecraft_key_binding = options.keyScreenshot; - SMOOTH_CAMERA.minecraft_key_binding = options.keySmoothCamera; - SNEAK.minecraft_key_binding = options.keySneak; - SPRINT.minecraft_key_binding = options.keySprint; - SWAP_HANDS.minecraft_key_binding = options.keySwapHands; - TOGGLE_PERSPECTIVE.minecraft_key_binding = options.keyTogglePerspective; - USE.minecraft_key_binding = options.keyUse; + ATTACK.mcKeyBinding = options.keyAttack; + BACK.mcKeyBinding = options.keyBack; + CHAT.mcKeyBinding = options.keyChat; + DROP_ITEM.mcKeyBinding = options.keyDrop; + FORWARD.mcKeyBinding = options.keyForward; + INVENTORY.mcKeyBinding = options.keyInventory; + JUMP.mcKeyBinding = options.keyJump; + LEFT.mcKeyBinding = options.keyLeft; + PICK_BLOCK.mcKeyBinding = options.keyPickItem; + PLAYER_LIST.mcKeyBinding = options.keyPlayerList; + RIGHT.mcKeyBinding = options.keyRight; + SCREENSHOT.mcKeyBinding = options.keyScreenshot; + SMOOTH_CAMERA.mcKeyBinding = options.keySmoothCamera; + SNEAK.mcKeyBinding = options.keySneak; + SPRINT.mcKeyBinding = options.keySprint; + SWAP_HANDS.mcKeyBinding = options.keySwapHands; + TOGGLE_PERSPECTIVE.mcKeyBinding = options.keyTogglePerspective; + USE.mcKeyBinding = options.keyUse; } /** @@ -291,40 +320,41 @@ public class ButtonBinding implements Nameable * @param button The button. * @return The localized name of the button. */ - public static @NotNull String get_localized_button_name(int button) + public static @NotNull + String getLocalizedButtonName(int button) { switch (button % 500) { case -1: return I18n.translate("key.keyboard.unknown"); - case GLFW.GLFW_GAMEPAD_BUTTON_A: + case GLFW_GAMEPAD_BUTTON_A: return I18n.translate("lambdacontrols.button.a"); - case GLFW.GLFW_GAMEPAD_BUTTON_B: + case GLFW_GAMEPAD_BUTTON_B: return I18n.translate("lambdacontrols.button.b"); - case GLFW.GLFW_GAMEPAD_BUTTON_X: + case GLFW_GAMEPAD_BUTTON_X: return I18n.translate("lambdacontrols.button.x"); - case GLFW.GLFW_GAMEPAD_BUTTON_Y: + case GLFW_GAMEPAD_BUTTON_Y: return I18n.translate("lambdacontrols.button.y"); - case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: + case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: return I18n.translate("lambdacontrols.button.left_bumper"); - case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: + case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: return I18n.translate("lambdacontrols.button.right_bumper"); - case GLFW.GLFW_GAMEPAD_BUTTON_BACK: + case GLFW_GAMEPAD_BUTTON_BACK: return I18n.translate("lambdacontrols.button.back"); - case GLFW.GLFW_GAMEPAD_BUTTON_START: + case GLFW_GAMEPAD_BUTTON_START: return I18n.translate("lambdacontrols.button.start"); - case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE: + case GLFW_GAMEPAD_BUTTON_GUIDE: return I18n.translate("lambdacontrols.button.guide"); - case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB: + case GLFW_GAMEPAD_BUTTON_LEFT_THUMB: return I18n.translate("lambdacontrols.button.left_thumb"); - case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: + case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: return I18n.translate("lambdacontrols.button.right_thumb"); - case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP: + case GLFW_GAMEPAD_BUTTON_DPAD_UP: return I18n.translate("lambdacontrols.button.dpad_up"); - case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: + case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: return I18n.translate("lambdacontrols.button.dpad_right"); - case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN: + case GLFW_GAMEPAD_BUTTON_DPAD_DOWN: return I18n.translate("lambdacontrols.button.dpad_down"); - case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT: + case GLFW_GAMEPAD_BUTTON_DPAD_LEFT: return I18n.translate("lambdacontrols.button.dpad_left"); case 100: return I18n.translate("lambdacontrols.axis.left_x+"); @@ -352,7 +382,7 @@ public class ButtonBinding implements Nameable } static { - MOVEMENT_CATEGORY = register_default_category("key.categories.movement", category -> category.register_all_bindings( + MOVEMENT_CATEGORY = registerDefaultCategory("key.categories.movement", category -> category.registerAllBindings( ButtonBinding.FORWARD, ButtonBinding.BACK, ButtonBinding.LEFT, @@ -360,24 +390,207 @@ public class ButtonBinding implements Nameable ButtonBinding.JUMP, ButtonBinding.SNEAK, ButtonBinding.SPRINT)); - GAMEPLAY_CATEGORY = register_default_category("key.categories.gameplay", category -> category.register_all_bindings( + GAMEPLAY_CATEGORY = registerDefaultCategory("key.categories.gameplay", category -> category.registerAllBindings( ButtonBinding.ATTACK, ButtonBinding.PICK_BLOCK, ButtonBinding.USE )); - INVENTORY_CATEGORY = register_default_category("key.categories.inventory", category -> category.register_all_bindings( + INVENTORY_CATEGORY = registerDefaultCategory("key.categories.inventory", category -> category.registerAllBindings( ButtonBinding.DROP_ITEM, ButtonBinding.HOTBAR_LEFT, ButtonBinding.HOTBAR_RIGHT, ButtonBinding.INVENTORY, ButtonBinding.SWAP_HANDS )); - MULTIPLAYER_CATEGORY = register_default_category("key.categories.multiplayer", - category -> category.register_all_bindings(ButtonBinding.CHAT, ButtonBinding.PLAYER_LIST)); - MISC_CATEGORY = register_default_category("key.categories.misc", category -> category.register_all_bindings( + MULTIPLAYER_CATEGORY = registerDefaultCategory("key.categories.multiplayer", + category -> category.registerAllBindings(ButtonBinding.CHAT, ButtonBinding.PLAYER_LIST)); + MISC_CATEGORY = registerDefaultCategory("key.categories.misc", category -> category.registerAllBindings( ButtonBinding.SCREENSHOT, //SMOOTH_CAMERA, ButtonBinding.TOGGLE_PERSPECTIVE )); } + + /** + * Represents a quick {@link ButtonBinding} builder. + * + * @author LambdAurora + * @version 1.1.0 + * @since 1.1.0 + */ + public static class Builder + { + private final String key; + private int[] buttons = new int[0]; + private List actions = new ArrayList<>(); + private PairPredicate filter = Predicates.pairAlwaysTrue(); + private boolean cooldown = false; + private ButtonCategory category = null; + private KeyBinding mcBinding = null; + + /** + * This constructor shouldn't be used for other mods. + * + * @param key The key with format {@code "."}. + */ + public Builder(@NotNull String key) + { + this.key = key; + this.unbound(); + } + + public Builder(@NotNull Identifier identifier) + { + this(identifier.getNamespace() + "." + identifier.getName()); + } + + public Builder(@NotNull net.minecraft.util.Identifier identifier) + { + this(new Identifier(identifier.toString())); + } + + /** + * Defines the default buttons of the {@link ButtonBinding}. + * + * @param buttons The default buttons. + * @return The builder instance. + */ + public Builder buttons(int... buttons) + { + this.buttons = buttons; + return this; + } + + /** + * Sets the {@link ButtonBinding} to unbound. + * + * @return The builder instance. + */ + public Builder unbound() + { + return this.buttons(-1); + } + + /** + * Adds the actions to the {@link ButtonBinding}. + * + * @param actions The actions to add. + * @return The builder instance. + */ + public Builder actions(@NotNull PressAction... actions) + { + this.actions.addAll(Arrays.asList(actions)); + return this; + } + + /** + * Adds an action to the {@link ButtonBinding}. + * + * @param action The action to add. + * @return The builder instance. + */ + public Builder action(@NotNull PressAction action) + { + this.actions.add(action); + return this; + } + + /** + * Sets a filter for the {@link ButtonBinding}. + * + * @param filter The filter. + * @return The builder instance. + */ + public Builder filter(@NotNull PairPredicate filter) + { + this.filter = filter; + return this; + } + + /** + * Sets the filter of {@link ButtonBinding} to only in game. + * + * @return The builder instance. + * @see #filter(PairPredicate) + * @see InputHandlers#inGame(MinecraftClient, ButtonBinding) + */ + public Builder onlyInGame() + { + return this.filter(InputHandlers::inGame); + } + + /** + * Sets the filter of {@link ButtonBinding} to only in inventory. + * + * @return The builder instance. + * @see #filter(PairPredicate) + * @see InputHandlers#inInventory(MinecraftClient, ButtonBinding) + */ + public Builder onlyInInventory() + { + return this.filter(InputHandlers::inInventory); + } + + /** + * Sets whether the {@link ButtonBinding} has a cooldown or not. + * + * @param cooldown True if the {@link ButtonBinding} has a cooldown, else false. + * @return The builder instance. + */ + public Builder cooldown(boolean cooldown) + { + this.cooldown = cooldown; + return this; + } + + /** + * Sets the category of the {@link ButtonBinding}. + * + * @param category The category. + * @return The builder instance. + */ + public Builder category(@Nullable ButtonCategory category) + { + this.category = category; + return this; + } + + /** + * Sets the keybinding linked to the {@link ButtonBinding}. + * + * @param binding The keybinding to link. + * @return The builder instance. + */ + public Builder linkKeybind(@Nullable KeyBinding binding) + { + this.mcBinding = binding; + return this; + } + + /** + * Builds the {@link ButtonBinding}. + * + * @return The built {@link ButtonBinding}. + */ + public ButtonBinding build() + { + ButtonBinding binding = new ButtonBinding(this.key, this.buttons, this.actions, this.filter, this.cooldown); + if (this.category != null) + this.category.registerBinding(binding); + if (this.mcBinding != null) + binding.setKeyBinding(this.mcBinding); + return binding; + } + + /** + * Builds and registers the {@link ButtonBinding}. + * + * @return The built {@link ButtonBinding}. + * @see #build() + */ + public ButtonBinding register() + { + return InputManager.registerBinding(this.build()); + } + } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonCategory.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonCategory.java index 8782e1d..f9322d7 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonCategory.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonCategory.java @@ -43,21 +43,21 @@ public class ButtonCategory implements Identifiable this(id, 100); } - public void register_binding(@NotNull ButtonBinding binding) + public void registerBinding(@NotNull ButtonBinding binding) { if (this.bindings.contains(binding)) throw new IllegalStateException("Cannot register twice a button binding in the same category."); this.bindings.add(binding); } - public void register_all_bindings(@NotNull ButtonBinding... bindings) + public void registerAllBindings(@NotNull ButtonBinding... bindings) { - this.register_all_bindings(Arrays.asList(bindings)); + this.registerAllBindings(Arrays.asList(bindings)); } - public void register_all_bindings(@NotNull List bindings) + public void registerAllBindings(@NotNull List bindings) { - bindings.forEach(this::register_binding); + bindings.forEach(this::registerBinding); } /** @@ -65,7 +65,7 @@ public class ButtonCategory implements Identifiable * * @return The bindings assigned to this category. */ - public @NotNull List get_bindings() + public @NotNull List getBindings() { return Collections.unmodifiableList(this.bindings); } @@ -77,12 +77,12 @@ public class ButtonCategory implements Identifiable * * @return The translated name. */ - public @NotNull String get_translated_name() + public @NotNull String getTranslatedName() { - if (this.id.get_namespace().equals("minecraft")) - return I18n.translate(this.id.get_name()); + if (this.id.getNamespace().equals("minecraft")) + return I18n.translate(this.id.getName()); else - return I18n.translate(this.id.get_namespace() + "." + this.id.get_name()); + return I18n.translate(this.id.getNamespace() + "." + this.id.getName()); } /** @@ -91,13 +91,13 @@ public class ButtonCategory implements Identifiable * * @return The priority of this category. */ - public int get_priority() + public int getPriority() { return this.priority; } @Override - public @NotNull Identifier get_identifier() + public @NotNull Identifier getIdentifier() { return this.id; } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/Controller.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/Controller.java index ef86650..6908ea6 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/Controller.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/Controller.java @@ -52,7 +52,7 @@ public class Controller implements Nameable * * @return The identifier of this controller. */ - public int get_id() + public int getId() { return this.id; } @@ -62,7 +62,7 @@ public class Controller implements Nameable * * @return The controller's GUID. */ - public String get_guid() + public String getGuid() { String guid = GLFW.glfwGetJoystickGUID(this.id); return guid == null ? "" : guid; @@ -73,7 +73,7 @@ public class Controller implements Nameable * * @return True if this controller is connected, else false. */ - public boolean is_connected() + public boolean isConnected() { return GLFW.glfwJoystickPresent(this.id); } @@ -83,9 +83,9 @@ public class Controller implements Nameable * * @return True if this controller is a gamepad, else false. */ - public boolean is_gamepad() + public boolean isGamepad() { - return this.is_connected() && GLFW.glfwJoystickIsGamepad(this.id); + return this.isConnected() && GLFW.glfwJoystickIsGamepad(this.id); } /** @@ -94,10 +94,10 @@ public class Controller implements Nameable * @return The controller's name. */ @Override - public @NotNull String get_name() + public @NotNull String getName() { - String name = this.is_gamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id); - return name == null ? String.valueOf(this.get_id()) : name; + String name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id); + return name == null ? String.valueOf(this.getId()) : name; } /** @@ -105,15 +105,15 @@ public class Controller implements Nameable * * @return The state of the controller input. */ - public GLFWGamepadState get_state() + public GLFWGamepadState getState() { GLFWGamepadState state = GLFWGamepadState.create(); - if (this.is_gamepad()) + if (this.isGamepad()) GLFW.glfwGetGamepadState(this.id, state); return state; } - public static @NotNull Controller by_id(int id) + public static @NotNull Controller byId(int id) { if (id > GLFW.GLFW_JOYSTICK_LAST) { LambdaControlsClient.get().log("Controller '" + id + "' doesn't exist."); @@ -129,22 +129,22 @@ public class Controller implements Nameable } } - public static @NotNull Optional by_guid(@NotNull String guid) + public static @NotNull Optional byGuid(@NotNull String guid) { - return CONTROLLERS.values().stream().filter(Controller::is_connected) - .filter(controller -> controller.get_guid().equals(guid)) - .max(Comparator.comparingInt(Controller::get_id)); + return CONTROLLERS.values().stream().filter(Controller::isConnected) + .filter(controller -> controller.getGuid().equals(guid)) + .max(Comparator.comparingInt(Controller::getId)); } /** * Reads the specified resource and returns the raw data as a ByteBuffer. * - * @param resource The resource to read. - * @param buffer_size The initial buffer size. + * @param resource The resource to read. + * @param bufferSize The initial buffer size. * @return The resource data. * @throws IOException If an IO error occurs. */ - private static ByteBuffer io_resource_to_buffer(String resource, int buffer_size) throws IOException + private static ByteBuffer ioResourceToBuffer(String resource, int bufferSize) throws IOException { ByteBuffer buffer = null; @@ -164,14 +164,14 @@ public class Controller implements Nameable /** * Updates the controller mappings. */ - public static void update_mappings() + public static void updateMappings() { try { - File mappings_file = new File("config/gamecontrollerdb.txt"); - if (!mappings_file.exists()) + File mappingsFile = new File("config/gamecontrollerdb.txt"); + if (!mappingsFile.exists()) return; LambdaControlsClient.get().log("Updating controller mappings..."); - ByteBuffer buffer = io_resource_to_buffer(mappings_file.getPath(), 1024); + ByteBuffer buffer = ioResourceToBuffer(mappingsFile.getPath(), 1024); GLFW.glfwUpdateGamepadMappings(buffer); } catch (IOException e) { e.printStackTrace(); diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputHandlers.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputHandlers.java index 601b3ce..c73dd3f 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputHandlers.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputHandlers.java @@ -10,15 +10,27 @@ package me.lambdaurora.lambdacontrols.client.controller; import me.lambdaurora.lambdacontrols.client.ButtonState; +import me.lambdaurora.lambdacontrols.client.mixin.AdvancementsScreenAccessor; import me.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccessor; +import me.lambdaurora.lambdacontrols.client.util.ContainerScreenAccessor; import me.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen; +import net.minecraft.client.gui.screen.advancement.AdvancementTab; +import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; +import net.minecraft.client.gui.screen.ingame.ContainerScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.util.ScreenshotUtils; +import net.minecraft.container.Slot; import net.minecraft.item.ItemGroup; +import org.aperlambda.lambdacommon.utils.Pair; import org.jetbrains.annotations.NotNull; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; + /** * Represents some input handlers. * @@ -28,13 +40,11 @@ import org.jetbrains.annotations.NotNull; */ public class InputHandlers { - private static int hotbar_cooldown = 0; - private InputHandlers() { } - public static PressAction handle_hotbar(boolean right) + public static PressAction handleHotbar(boolean right) { return (client, button, action) -> { if (action == ButtonState.RELEASE) @@ -48,27 +58,42 @@ public class InputHandlers client.player.inventory.selectedSlot = client.player.inventory.selectedSlot == 0 ? 8 : client.player.inventory.selectedSlot - 1; return true; } else if (client.currentScreen instanceof CreativeInventoryScreen) { - CreativeInventoryScreenAccessor creative_inventory = (CreativeInventoryScreenAccessor) client.currentScreen; - int current_selected_tab = creative_inventory.lambdacontrols_get_selected_tab(); - int next_tab = current_selected_tab + (right ? 1 : -1); - if (next_tab < 0) - next_tab = ItemGroup.GROUPS.length - 1; - else if (next_tab >= ItemGroup.GROUPS.length) - next_tab = 0; - creative_inventory.lambdacontrols_set_selected_tab(ItemGroup.GROUPS[next_tab]); + CreativeInventoryScreenAccessor inventory = (CreativeInventoryScreenAccessor) client.currentScreen; + int currentSelectedTab = inventory.lambdacontrols_getSelectedTab(); + int nextTab = currentSelectedTab + (right ? 1 : -1); + if (nextTab < 0) + nextTab = ItemGroup.GROUPS.length - 1; + else if (nextTab >= ItemGroup.GROUPS.length) + nextTab = 0; + inventory.lambdacontrols_setSelectedTab(ItemGroup.GROUPS[nextTab]); return true; + } else if (client.currentScreen instanceof AdvancementsScreen) { + AdvancementsScreenAccessor screen = (AdvancementsScreenAccessor) client.currentScreen; + List tabs = screen.lambdacontrols_getTabs().values().stream().distinct().collect(Collectors.toList()); + AdvancementTab tab = screen.lambdacontrols_getSelectedTab(); + for (int i = 0; i < tabs.size(); i++) { + if (tabs.get(i).equals(tab)) { + int nextTab = i + (right ? 1 : -1); + if (nextTab < 0) + nextTab = tabs.size() - 1; + else if (nextTab >= tabs.size()) + nextTab = 0; + screen.lambdacontrols_getAdvancementManager().selectTab(tabs.get(nextTab).getRoot(), true); + break; + } + } } return false; }; } - public static boolean handle_pause_game(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, @NotNull ButtonState action) + public static boolean handlePauseGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, @NotNull ButtonState action) { if (action == ButtonState.PRESS) { // If in game, then pause the game. if (client.currentScreen == null) client.openPauseMenu(false); - else if (client.currentScreen instanceof AbstractContainerScreen && client.player != null) // If the current screen is a container then close it. + else if (client.currentScreen instanceof ContainerScreen && client.player != null) // If the current screen is a container then close it. client.player.closeContainer(); else // Else just close the current screen. client.currentScreen.onClose(); @@ -84,7 +109,7 @@ public class InputHandlers * @param action The action done on the binding. * @return True if handled, else false. */ - public static boolean handle_screenshot(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, @NotNull ButtonState action) + public static boolean handleScreenshot(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, @NotNull ButtonState action) { if (action == ButtonState.PRESS) ScreenshotUtils.saveScreenshot(client.runDirectory, client.getWindow().getFramebufferWidth(), client.getWindow().getFramebufferHeight(), client.getFramebuffer(), @@ -92,12 +117,129 @@ public class InputHandlers return true; } - public static boolean handle_toggle_sneak(@NotNull MinecraftClient client, @NotNull ButtonBinding button, @NotNull ButtonState action) + public static boolean handleToggleSneak(@NotNull MinecraftClient client, @NotNull ButtonBinding button, @NotNull ButtonState action) { if (client.player != null && !client.player.abilities.flying) { - button.as_key_binding().filter(binding -> action == ButtonState.PRESS).ifPresent(binding -> ((KeyBindingAccessor) binding).handle_press_state(!binding.isPressed())); + button.asKeyBinding().filter(binding -> action == ButtonState.PRESS).ifPresent(binding -> ((KeyBindingAccessor) binding).lambdacontrols_handlePressState(!binding.isPressed())); return true; } return false; } + + public static PressAction handleInventorySlotPad(int direction) + { + return (client, binding, action) -> { + if (!(client.currentScreen instanceof ContainerScreen && action != ButtonState.RELEASE)) + return false; + + ContainerScreen inventory = (ContainerScreen) client.currentScreen; + ContainerScreenAccessor accessor = (ContainerScreenAccessor) inventory; + int guiLeft = accessor.lambdacontrols_getX(); + int guiTop = accessor.lambdacontrols_getY(); + double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); + double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); + + // Finds the hovered slot. + Slot mouseSlot = accessor.lambdacontrols_getSlotAt(mouseX, mouseY); + + // Finds the closest slot in the GUI within 14 pixels. + Optional closestSlot = inventory.getContainer().slots.parallelStream() + .filter(Predicate.isEqual(mouseSlot).negate()) + .map(slot -> { + int posX = guiLeft + slot.xPosition + 8; + int posY = guiTop + slot.yPosition + 8; + + int otherPosX = (int) mouseX; + int otherPosY = (int) mouseY; + if (mouseSlot != null) { + otherPosX = guiLeft + mouseSlot.xPosition + 8; + otherPosY = guiTop + mouseSlot.yPosition + 8; + } + + // Distance between the slot and the cursor. + double distance = Math.sqrt(Math.pow(posX - otherPosX, 2) + Math.pow(posY - otherPosY, 2)); + return Pair.of(slot, distance); + }).filter(entry -> { + Slot slot = entry.key; + int posX = guiLeft + slot.xPosition + 8; + int posY = guiTop + slot.yPosition + 8; + int otherPosX = (int) mouseX; + int otherPosY = (int) mouseY; + if (mouseSlot != null) { + otherPosX = guiLeft + mouseSlot.xPosition + 8; + otherPosY = guiTop + mouseSlot.yPosition + 8; + } + if (direction == 0) + return posY < otherPosY; + else if (direction == 1) + return posY > otherPosY; + else if (direction == 2) + return posX > otherPosX; + else if (direction == 3) + return posX < otherPosX; + else + return false; + }) + .min(Comparator.comparingDouble(p -> p.value)) + .map(p -> p.key); + + if (closestSlot.isPresent()) { + Slot slot = closestSlot.get(); + int x = guiLeft + slot.xPosition + 8; + int y = guiTop + slot.yPosition + 8; + InputManager.queueMousePosition(x * (double) client.getWindow().getWidth() / (double) client.getWindow().getScaledWidth(), + y * (double) client.getWindow().getHeight() / (double) client.getWindow().getScaledHeight()); + return true; + } + return false; + }; + } + + /** + * Returns always true to the filter. + * + * @param client The client instance. + * @param binding The affected binding. + * @return True. + */ + public static boolean always(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) + { + return true; + } + + /** + * Returns whether the client is in game or not. + * + * @param client The client instance. + * @param binding The affected binding. + * @return True if the client is in game, else false. + */ + public static boolean inGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) + { + return client.currentScreen == null; + } + + /** + * Returns whether the client is in an inventory or not. + * + * @param client The client instance. + * @param binding The affected binding. + * @return True if the client is in an inventory, else false. + */ + public static boolean inInventory(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) + { + return client.currentScreen instanceof ContainerScreen; + } + + /** + * Returns whether the client is in the advancements screen or not. + * + * @param client The client instance. + * @param binding The affected binding. + * @return True if the client is in the advancements screen, else false. + */ + public static boolean inAdvancements(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) + { + return client.currentScreen instanceof AdvancementsScreen; + } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputManager.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputManager.java index 87709d5..5cd2f83 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputManager.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/InputManager.java @@ -9,11 +9,17 @@ package me.lambdaurora.lambdacontrols.client.controller; +import me.lambdaurora.lambdacontrols.ControlsMode; import me.lambdaurora.lambdacontrols.client.ButtonState; +import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; import me.lambdaurora.lambdacontrols.client.LambdaControlsConfig; +import me.lambdaurora.lambdacontrols.client.util.MouseAccessor; import net.minecraft.client.MinecraftClient; +import net.minecraft.util.math.MathHelper; import org.aperlambda.lambdacommon.Identifier; +import org.aperlambda.lambdacommon.utils.function.PairPredicate; import org.jetbrains.annotations.NotNull; +import org.lwjgl.glfw.GLFW; import java.util.*; import java.util.function.Consumer; @@ -29,9 +35,67 @@ import java.util.stream.Stream; */ public class InputManager { - private static final List BINDINGS = new ArrayList<>(); - private static final List CATEGORIES = new ArrayList<>(); - public static final Map STATES = new HashMap<>(); + public static final InputManager INPUT_MANAGER = new InputManager(); + private static final List BINDINGS = new ArrayList<>(); + private static final List CATEGORIES = new ArrayList<>(); + public static final Map STATES = new HashMap<>(); + private int prevTargetMouseX = 0; + private int prevTargetMouseY = 0; + private int targetMouseX = 0; + private int targetMouseY = 0; + + protected InputManager() + { + } + + public void tick(@NotNull MinecraftClient client) + { + if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) { + this.controllerTick(client); + } + } + + public void controllerTick(@NotNull MinecraftClient client) + { + this.prevTargetMouseX = this.targetMouseX; + this.prevTargetMouseY = this.targetMouseY; + } + + /** + * Updates the mouse position. Should only be called on pre render of a screen. + * + * @param client The client instance. + */ + public void updateMousePosition(@NotNull MinecraftClient client) + { + Objects.requireNonNull(client, "Client instance cannot be null."); + if (this.prevTargetMouseX != this.targetMouseX || this.prevTargetMouseY != this.targetMouseY) { + double mouseX = this.prevTargetMouseX + (this.targetMouseX - this.prevTargetMouseX) * client.getTickDelta() + 0.5; + double mouseY = this.prevTargetMouseY + (this.targetMouseY - this.prevTargetMouseY) * client.getTickDelta() + 0.5; + GLFW.glfwSetCursorPos(client.getWindow().getHandle(), mouseX, mouseY); + ((MouseAccessor) client.mouse).lambdacontrols_onCursorPos(client.getWindow().getHandle(), mouseX, mouseY); + } + } + + /** + * Resets the mouse position. + * + * @param windowWidth The window width. + * @param windowHeight The window height. + */ + public void resetMousePosition(int windowWidth, int windowHeight) + { + this.targetMouseX = this.prevTargetMouseX = (int) (windowWidth / 2.F); + this.targetMouseY = this.prevTargetMouseY = (int) (windowHeight / 2.F); + } + + public void resetMouseTarget(@NotNull MinecraftClient client) + { + double mouseX = client.mouse.getX(); + double mouseY = client.mouse.getY(); + this.prevTargetMouseX = this.targetMouseX = (int) mouseX; + this.prevTargetMouseY = this.targetMouseY = (int) mouseY; + } /** * Returns whether the specified binding is registered or not. @@ -39,7 +103,7 @@ public class InputManager * @param binding The binding to check. * @return True if the binding is registered, else false. */ - public static boolean has_binding(@NotNull ButtonBinding binding) + public static boolean hasBinding(@NotNull ButtonBinding binding) { return BINDINGS.contains(binding); } @@ -50,9 +114,9 @@ public class InputManager * @param name The name of the binding to check. * @return True if the binding is registered, else false. */ - public static boolean has_binding(@NotNull String name) + public static boolean hasBinding(@NotNull String name) { - return BINDINGS.parallelStream().map(ButtonBinding::get_name).anyMatch(binding -> binding.equalsIgnoreCase(name)); + return BINDINGS.parallelStream().map(ButtonBinding::getName).anyMatch(binding -> binding.equalsIgnoreCase(name)); } /** @@ -61,9 +125,9 @@ public class InputManager * @param identifier The identifier of the binding to check. * @return True if the binding is registered, else false. */ - public static boolean has_binding(@NotNull Identifier identifier) + public static boolean hasBinding(@NotNull Identifier identifier) { - return has_binding(identifier.get_namespace() + "." + identifier.get_name()); + return hasBinding(identifier.getNamespace() + "." + identifier.getName()); } /** @@ -72,44 +136,44 @@ public class InputManager * @param binding The binding to register. * @return The registered binding. */ - public static @NotNull ButtonBinding register_binding(@NotNull ButtonBinding binding) + public static @NotNull ButtonBinding registerBinding(@NotNull ButtonBinding binding) { - if (has_binding(binding)) + if (hasBinding(binding)) throw new IllegalStateException("Cannot register twice a button binding in the registry."); BINDINGS.add(binding); return binding; } - public static @NotNull ButtonBinding register_binding(@NotNull Identifier binding_id, int[] default_button, @NotNull List actions, boolean has_cooldown) + public static @NotNull ButtonBinding registerBinding(@NotNull Identifier id, int[] defaultButton, @NotNull List actions, @NotNull PairPredicate filter, boolean hasCooldown) { - return register_binding(new ButtonBinding(binding_id.get_namespace() + "." + binding_id.get_name(), default_button, actions, has_cooldown)); + return registerBinding(new ButtonBinding(id.getNamespace() + "." + id.getName(), defaultButton, actions, filter, hasCooldown)); } - public static @NotNull ButtonBinding register_binding(@NotNull Identifier binding_id, int[] default_button, boolean has_cooldown) + public static @NotNull ButtonBinding registerBinding(@NotNull Identifier id, int[] defaultButton, boolean hasCooldown) { - return register_binding(binding_id, default_button, Collections.emptyList(), has_cooldown); + return registerBinding(id, defaultButton, Collections.emptyList(), InputHandlers::always, hasCooldown); } - public static @NotNull ButtonBinding register_binding(@NotNull net.minecraft.util.Identifier binding_id, int[] default_button, @NotNull List actions, boolean has_cooldown) + public static @NotNull ButtonBinding registerBinding(@NotNull net.minecraft.util.Identifier id, int[] defaultButton, @NotNull List actions, @NotNull PairPredicate filter, boolean hasCooldown) { - return register_binding(new Identifier(binding_id.getNamespace(), binding_id.getPath()), default_button, actions, has_cooldown); + return registerBinding(new Identifier(id.getNamespace(), id.getPath()), defaultButton, actions, filter, hasCooldown); } - public static @NotNull ButtonBinding register_binding(@NotNull net.minecraft.util.Identifier binding_id, int[] default_button, boolean has_cooldown) + public static @NotNull ButtonBinding registerBinding(@NotNull net.minecraft.util.Identifier id, int[] defaultButton, boolean hasCooldown) { - return register_binding(binding_id, default_button, Collections.emptyList(), has_cooldown); + return registerBinding(id, defaultButton, Collections.emptyList(), InputHandlers::always, hasCooldown); } /** * Sorts bindings to get bindings with the higher button counts first. */ - public static void sort_bindings() + public static void sortBindings() { synchronized (BINDINGS) { - List sorted_bindings = BINDINGS.stream().sorted(Collections.reverseOrder(Comparator.comparingInt(binding -> binding.get_button().length))) + List sorted = BINDINGS.stream().sorted(Collections.reverseOrder(Comparator.comparingInt(binding -> binding.getButton().length))) .collect(Collectors.toList()); BINDINGS.clear(); - BINDINGS.addAll(sorted_bindings); + BINDINGS.addAll(sorted); } } @@ -119,26 +183,26 @@ public class InputManager * @param category The category to register. * @return The registered category. */ - public static ButtonCategory register_category(@NotNull ButtonCategory category) + public static ButtonCategory registerCategory(@NotNull ButtonCategory category) { CATEGORIES.add(category); return category; } - public static ButtonCategory register_category(@NotNull Identifier identifier, int priority) + public static ButtonCategory registerCategory(@NotNull Identifier identifier, int priority) { - return register_category(new ButtonCategory(identifier, priority)); + return registerCategory(new ButtonCategory(identifier, priority)); } - public static ButtonCategory register_category(@NotNull Identifier identifier) + public static ButtonCategory registerCategory(@NotNull Identifier identifier) { - return register_category(new ButtonCategory(identifier)); + return registerCategory(new ButtonCategory(identifier)); } - protected static ButtonCategory register_default_category(@NotNull String key, @NotNull Consumer key_adder) + protected static ButtonCategory registerDefaultCategory(@NotNull String key, @NotNull Consumer keyAdder) { - ButtonCategory category = register_category(new Identifier("minecraft", key), CATEGORIES.size()); - key_adder.accept(category); + ButtonCategory category = registerCategory(new Identifier("minecraft", key), CATEGORIES.size()); + keyAdder.accept(category); return category; } @@ -147,10 +211,10 @@ public class InputManager * * @param config The configuration instance. */ - public static void load_button_bindings(@NotNull LambdaControlsConfig config) + public static void loadButtonBindings(@NotNull LambdaControlsConfig config) { - List load_queue = new ArrayList<>(BINDINGS); - load_queue.forEach(config::load_button_binding); + List queue = new ArrayList<>(BINDINGS); + queue.forEach(config::loadButtonBinding); } /** @@ -159,17 +223,17 @@ public class InputManager * @param binding The binding. * @return The current state of the binding. */ - public static @NotNull ButtonState get_binding_state(@NotNull ButtonBinding binding) + public static @NotNull ButtonState getBindingState(@NotNull ButtonBinding binding) { ButtonState state = ButtonState.REPEAT; - for (int btn : binding.get_button()) { - ButtonState btn_state = InputManager.STATES.getOrDefault(btn, ButtonState.NONE); - if (btn_state == ButtonState.PRESS) + for (int btn : binding.getButton()) { + ButtonState btnState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE); + if (btnState == ButtonState.PRESS) state = ButtonState.PRESS; - else if (btn_state == ButtonState.RELEASE) { + else if (btnState == ButtonState.RELEASE) { state = ButtonState.RELEASE; break; - } else if (btn_state == ButtonState.NONE) { + } else if (btnState == ButtonState.NONE) { state = ButtonState.NONE; break; } @@ -183,9 +247,20 @@ public class InputManager * @param button The button to check. * @return True if the button has duplicated bindings, else false. */ - public static boolean has_duplicated_bindings(int[] button) + public static boolean hasDuplicatedBindings(int[] button) { - return BINDINGS.parallelStream().filter(binding -> are_buttons_equivalent(binding.get_button(), button)).count() > 1; + return BINDINGS.parallelStream().filter(binding -> areButtonsEquivalent(binding.getButton(), button)).count() > 1; + } + + /** + * Returns whether the button has duplicated bindings. + * + * @param binding The binding to check. + * @return True if the button has duplicated bindings, else false. + */ + public static boolean hasDuplicatedBindings(ButtonBinding binding) + { + return BINDINGS.parallelStream().filter(other -> areButtonsEquivalent(other.getButton(), binding.getButton()) && other.filter.equals(binding.filter)).count() > 1; } /** @@ -195,7 +270,7 @@ public class InputManager * @param buttons2 Second set of buttons. * @return True if the two sets of buttons are equivalent, else false. */ - public static boolean are_buttons_equivalent(int[] buttons1, int[] buttons2) + public static boolean areButtonsEquivalent(int[] buttons1, int[] buttons2) { if (buttons1.length != buttons2.length) return false; @@ -218,7 +293,7 @@ public class InputManager * @param button The button to check. * @return True if the button set contains the specified button, else false. */ - public static boolean contains_button(int[] buttons, int button) + public static boolean containsButton(int[] buttons, int button) { return Arrays.stream(buttons).anyMatch(btn -> btn == button); } @@ -226,7 +301,7 @@ public class InputManager /** * Updates the button states. */ - public static void update_states() + public static void updateStates() { STATES.forEach((btn, state) -> { if (state == ButtonState.PRESS) @@ -236,37 +311,49 @@ public class InputManager }); } - public static void update_bindings(@NotNull MinecraftClient client) + public static void updateBindings(@NotNull MinecraftClient client) { - List skip_buttons = new ArrayList<>(); + List skipButtons = new ArrayList<>(); Map states = new HashMap<>(); for (ButtonBinding binding : BINDINGS) { - ButtonState binding_state = get_binding_state(binding); - if (skip_buttons.stream().anyMatch(btn -> contains_button(binding.get_button(), btn))) { + ButtonState state = binding.isAvailable(client) ? getBindingState(binding) : ButtonState.NONE; + if (skipButtons.stream().anyMatch(btn -> containsButton(binding.getButton(), btn))) { if (binding.pressed) - binding_state = ButtonState.RELEASE; + state = ButtonState.RELEASE; else - binding_state = ButtonState.NONE; + state = ButtonState.NONE; } - binding.pressed = binding_state.is_pressed(); + binding.pressed = state.isPressed(); binding.update(); if (binding.pressed) - Arrays.stream(binding.get_button()).forEach(skip_buttons::add); - states.put(binding, binding_state); + Arrays.stream(binding.getButton()).forEach(skipButtons::add); + states.put(binding, state); } states.forEach((binding, state) -> { - if (state != ButtonState.NONE) + if (state != ButtonState.NONE) { binding.handle(client, state); + } }); } - public static @NotNull Stream stream_bindings() + public static void queueMousePosition(double x, double y) + { + INPUT_MANAGER.targetMouseX = (int) MathHelper.clamp(x, 0, MinecraftClient.getInstance().getWindow().getWidth()); + INPUT_MANAGER.targetMouseY = (int) MathHelper.clamp(y, 0, MinecraftClient.getInstance().getWindow().getHeight()); + } + + public static void queueMoveMousePosition(double x, double y) + { + queueMousePosition(INPUT_MANAGER.targetMouseX + x, INPUT_MANAGER.targetMouseY + y); + } + + public static @NotNull Stream streamBindings() { return BINDINGS.stream(); } - public static @NotNull Stream stream_categories() + public static @NotNull Stream streamCategories() { return CATEGORIES.stream(); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/PressAction.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/PressAction.java index 50fd10c..7651b1e 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/PressAction.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/PressAction.java @@ -27,7 +27,7 @@ public interface PressAction PressAction DEFAULT_ACTION = (client, button, action) -> { if (action == ButtonState.REPEAT || client.currentScreen != null) return false; - button.as_key_binding().ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(button.is_button_down())); + button.asKeyBinding().ifPresent(binding -> ((KeyBindingAccessor) binding).lambdacontrols_handlePressState(button.isButtonDown())); return true; }; diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerButtonWidget.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerButtonWidget.java index ac91152..8ffca82 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerButtonWidget.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerButtonWidget.java @@ -23,37 +23,37 @@ import org.jetbrains.annotations.NotNull; public class ControllerButtonWidget extends AbstractIconButtonWidget { private ButtonBinding binding; - private int icon_width; + private int iconWidth; - public ControllerButtonWidget(int x, int y, int width, @NotNull ButtonBinding button_binding, @NotNull PressAction on_press) + public ControllerButtonWidget(int x, int y, int width, @NotNull ButtonBinding binding, @NotNull PressAction action) { - super(x, y, width, 20, ButtonBinding.get_localized_button_name(button_binding.get_button()[0]), on_press); - this.binding = button_binding; + super(x, y, width, 20, ButtonBinding.getLocalizedButtonName(binding.getButton()[0]), action); + this.binding = binding; } public void update() { - int length = binding.get_button().length; - this.setMessage(this.binding.is_not_bound() ? I18n.translate("lambdacontrols.not_bound") : - (length > 0 ? ButtonBinding.get_localized_button_name(binding.get_button()[0]) : "<>")); + int length = binding.getButton().length; + this.setMessage(this.binding.isNotBound() ? I18n.translate("lambdacontrols.not_bound") : + (length > 0 ? ButtonBinding.getLocalizedButtonName(binding.getButton()[0]) : "<>")); } @Override public String getMessage() { - if (this.binding.get_button().length > 1) + if (this.binding.getButton().length > 1) return ""; return super.getMessage(); } @Override - protected int render_icon(int mouse_x, int mouse_y, float delta, int x, int y) + protected int renderIcon(int mouseX, int mouseY, float delta, int x, int y) { - if (this.binding.get_button().length > 1) { - x += (this.width / 2 - this.icon_width / 2) - 4; + if (this.binding.getButton().length > 1) { + x += (this.width / 2 - this.iconWidth / 2) - 4; } - Pair size = LambdaControlsClient.draw_button(x, y, this.binding, MinecraftClient.getInstance()); - this.icon_width = size.get_key(); - return size.get_value(); + Pair size = LambdaControlsClient.drawButton(x, y, this.binding, MinecraftClient.getInstance()); + this.iconWidth = size.key; + return size.value; } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsControlsScreen.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerControlsScreen.java similarity index 55% rename from fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsControlsScreen.java rename to fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerControlsScreen.java index ef7a771..b3a3d2d 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsControlsScreen.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerControlsScreen.java @@ -18,33 +18,32 @@ import net.minecraft.client.gui.screen.options.ControlsOptionsScreen; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.resource.language.I18n; import net.minecraft.text.TranslatableText; +import org.aperlambda.lambdacommon.utils.function.Predicates; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.Objects; -import java.util.function.Predicate; /** * Represents the controls screen. */ -public class LambdaControlsControlsScreen extends Screen +public class ControllerControlsScreen extends Screen { private final Screen parent; final LambdaControlsClient mod; - private final boolean hide_settings; - private ControlsListWidget bindings_list_widget; - private ButtonWidget reset_button; - public ButtonBinding focused_binding; - public boolean waiting = false; - public List current_buttons = new ArrayList<>(); + private final boolean hideSettings; + private ControlsListWidget bindingsListWidget; + private ButtonWidget resetButton; + public ButtonBinding focusedBinding; + public boolean waiting = false; + public List currentButtons = new ArrayList<>(); - public LambdaControlsControlsScreen(@NotNull Screen parent, boolean hide_settings) + public ControllerControlsScreen(@NotNull Screen parent, boolean hideSettings) { super(new TranslatableText("lambdacontrols.menu.title.controller_controls")); this.parent = parent; this.mod = LambdaControlsClient.get(); - this.hide_settings = hide_settings; + this.hideSettings = hideSettings; } @Override @@ -57,33 +56,26 @@ public class LambdaControlsControlsScreen extends Screen @Override protected void init() { - this.addButton(new SpruceButtonWidget(this.width / 2 - 155, 18, this.hide_settings ? 310 : 150, 20, I18n.translate("lambdacontrols.menu.keyboard_controls"), + this.addButton(new SpruceButtonWidget(this.width / 2 - 155, 18, this.hideSettings ? 310 : 150, 20, I18n.translate("lambdacontrols.menu.keyboard_controls"), btn -> this.minecraft.openScreen(new ControlsOptionsScreen(this, this.minecraft.options)))); - if (!this.hide_settings) + if (!this.hideSettings) this.addButton(new SpruceButtonWidget(this.width / 2 - 155 + 160, 18, 150, 20, I18n.translate("menu.options"), btn -> this.minecraft.openScreen(new LambdaControlsSettingsScreen(this, this.minecraft.options, true)))); - this.bindings_list_widget = new ControlsListWidget(this, this.minecraft); - this.children.add(this.bindings_list_widget); - this.reset_button = this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 150, 20, I18n.translate("controls.resetAll"), - btn -> InputManager.stream_bindings().forEach(binding -> this.mod.config.set_button_binding(binding, binding.get_default_button())))); + this.bindingsListWidget = new ControlsListWidget(this, this.minecraft); + this.children.add(this.bindingsListWidget); + this.resetButton = this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 150, 20, I18n.translate("controls.resetAll"), + btn -> InputManager.streamBindings().forEach(binding -> this.mod.config.setButtonBinding(binding, binding.getDefaultButton())))); this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, I18n.translate("gui.done"), btn -> this.minecraft.openScreen(this.parent))); } - // Replacement for Predicate#not as it is Java 11. - private Predicate not(Predicate target) - { - Objects.requireNonNull(target); - return target.negate(); - } - @Override - public void render(int mouse_x, int mouse_y, float delta) + public void render(int mouseX, int mouseY, float delta) { this.renderBackground(); - this.bindings_list_widget.render(mouse_x, mouse_y, delta); + this.bindingsListWidget.render(mouseX, mouseY, delta); this.drawCenteredString(this.font, this.title.asFormattedString(), this.width / 2, 8, 16777215); - this.reset_button.active = InputManager.stream_bindings().anyMatch(this.not(ButtonBinding::is_default)); - super.render(mouse_x, mouse_y, delta); + this.resetButton.active = InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault)); + super.render(mouseX, mouseY, delta); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java index a11f7e0..6cd8c33 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java @@ -33,22 +33,22 @@ import java.util.List; */ public class ControlsListWidget extends ElementListWidget { - private static final int[] UNBOUND = new int[0]; - private final LambdaControlsControlsScreen gui; - private int field_2733; + private static final int[] UNBOUND = new int[0]; + private final ControllerControlsScreen gui; + private int field_2733; - public ControlsListWidget(@NotNull LambdaControlsControlsScreen gui, @NotNull MinecraftClient client) + public ControlsListWidget(@NotNull ControllerControlsScreen gui, @NotNull MinecraftClient client) { super(client, gui.width + 45, gui.height, 43, gui.height - 32, 24); this.gui = gui; - InputManager.stream_categories() - .sorted(Comparator.comparingInt(ButtonCategory::get_priority)) + InputManager.streamCategories() + .sorted(Comparator.comparingInt(ButtonCategory::getPriority)) .forEach(category -> { this.addEntry(new CategoryEntry(category)); - category.get_bindings().forEach(binding -> { - int i = client.textRenderer.getStringWidth(I18n.translate(binding.get_translation_key())); + category.getBindings().forEach(binding -> { + int i = client.textRenderer.getStringWidth(I18n.translate(binding.getTranslationKey())); if (i > this.field_2733) { this.field_2733 = i; } @@ -73,43 +73,43 @@ public class ControlsListWidget extends ElementListWidget { - gui.focused_binding = binding; - gui.current_buttons.clear(); + this.bindingName = I18n.translate(this.binding.getTranslationKey()); + this.editButton = new ControllerButtonWidget(0, 0, 110, this.binding, btn -> { + gui.focusedBinding = binding; + gui.currentButtons.clear(); gui.waiting = true; }) { protected String getNarrationMessage() { - return binding.is_not_bound() ? I18n.translate("narrator.controls.unbound", binding_name) : I18n.translate("narrator.controls.bound", binding_name, super.getNarrationMessage()); + return binding.isNotBound() ? I18n.translate("narrator.controls.unbound", bindingName) : I18n.translate("narrator.controls.bound", bindingName, super.getNarrationMessage()); } }; - this.reset_button = new ButtonWidget(0, 0, 50, 20, I18n.translate("controls.reset"), - btn -> gui.mod.config.set_button_binding(binding, binding.get_default_button())) + this.resetButton = new ButtonWidget(0, 0, 50, 20, I18n.translate("controls.reset"), + btn -> gui.mod.config.setButtonBinding(binding, binding.getDefaultButton())) { protected String getNarrationMessage() { - return I18n.translate("narrator.controls.reset", binding_name); + return I18n.translate("narrator.controls.reset", bindingName); } }; - this.unbound_button = new ButtonWidget(0, 0, 50, 20, I18n.translate("lambdacontrols.menu.unbound"), + this.unboundButton = new ButtonWidget(0, 0, 50, 20, I18n.translate("lambdacontrols.menu.unbound"), btn -> { - gui.mod.config.set_button_binding(binding, UNBOUND); - gui.focused_binding = null; + gui.mod.config.setButtonBinding(binding, UNBOUND); + gui.focusedBinding = null; }) { protected String getNarrationMessage() { - return I18n.translate("lambdacontrols.narrator.unbound", binding_name); + return I18n.translate("lambdacontrols.narrator.unbound", bindingName); } }; } @@ -117,71 +117,71 @@ public class ControlsListWidget extends ElementListWidget children() { - return Collections.unmodifiableList(Arrays.asList(this.edit_button, this.reset_button)); + return Collections.unmodifiableList(Arrays.asList(this.editButton, this.resetButton)); } @Override - public void render(int index, int y, int x, int width, int height, int mouse_x, int mouse_y, boolean hovering, float delta) + public void render(int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovering, float delta) { - boolean focused = gui.focused_binding == this.binding; - TextRenderer text_renderer = ControlsListWidget.this.minecraft.textRenderer; - String binding_name = this.binding_name; + boolean focused = gui.focusedBinding == this.binding; + TextRenderer textRenderer = ControlsListWidget.this.minecraft.textRenderer; + String bindingName = this.bindingName; float var10002 = (float) (x + 70 - ControlsListWidget.this.field_2733); int var10003 = y + height / 2; - text_renderer.draw(binding_name, var10002, (float) (var10003 - 9 / 2), 16777215); - this.reset_button.x = this.unbound_button.x = x + 190; - this.reset_button.y = this.unbound_button.y = y; - this.reset_button.active = !this.binding.is_default(); + textRenderer.draw(bindingName, var10002, (float) (var10003 - 9 / 2), 16777215); + this.resetButton.x = this.unboundButton.x = x + 190; + this.resetButton.y = this.unboundButton.y = y; + this.resetButton.active = !this.binding.isDefault(); if (focused) - this.unbound_button.render(mouse_x, mouse_y, delta); + this.unboundButton.render(mouseX, mouseY, delta); else - this.reset_button.render(mouse_x, mouse_y, delta); - this.edit_button.x = x + 75; - this.edit_button.y = y; - this.edit_button.update(); + this.resetButton.render(mouseX, mouseY, delta); + this.editButton.x = x + 75; + this.editButton.y = y; + this.editButton.update(); if (focused) { - this.edit_button.setMessage(Formatting.WHITE + "> " + Formatting.YELLOW + this.edit_button.getMessage() + Formatting.WHITE + " <"); - } else if (!this.binding.is_not_bound() && InputManager.has_duplicated_bindings(this.binding.get_button())) { - this.edit_button.setMessage(Formatting.RED + this.edit_button.getMessage()); - } else if (this.binding.is_not_bound()) { - this.edit_button.setMessage(Formatting.GOLD + this.edit_button.getMessage()); + this.editButton.setMessage(Formatting.WHITE + "> " + Formatting.YELLOW + this.editButton.getMessage() + Formatting.WHITE + " <"); + } else if (!this.binding.isNotBound() && InputManager.hasDuplicatedBindings(this.binding)) { + this.editButton.setMessage(Formatting.RED + this.editButton.getMessage()); + } else if (this.binding.isNotBound()) { + this.editButton.setMessage(Formatting.GOLD + this.editButton.getMessage()); } - this.edit_button.render(mouse_x, mouse_y, delta); + this.editButton.render(mouseX, mouseY, delta); } - public boolean mouseClicked(double mouse_x, double mouse_y, int button) + public boolean mouseClicked(double mouseX, double mouseY, int button) { - boolean focused = gui.focused_binding == this.binding; - if (this.edit_button.mouseClicked(mouse_x, mouse_y, button)) + boolean focused = gui.focusedBinding == this.binding; + if (this.editButton.mouseClicked(mouseX, mouseY, button)) return true; else - return focused ? this.unbound_button.mouseClicked(mouse_x, mouse_y, button) : this.reset_button.mouseClicked(mouse_x, mouse_y, button); + return focused ? this.unboundButton.mouseClicked(mouseX, mouseY, button) : this.resetButton.mouseClicked(mouseX, mouseY, button); } - public boolean mouseReleased(double mouse_x, double mouse_y, int button) + public boolean mouseReleased(double mouseX, double mouseY, int button) { - return this.edit_button.mouseReleased(mouse_x, mouse_y, button) || this.reset_button.mouseReleased(mouse_x, mouse_y, button) - || this.unbound_button.mouseReleased(mouse_x, mouse_y, button); + return this.editButton.mouseReleased(mouseX, mouseY, button) || this.resetButton.mouseReleased(mouseX, mouseY, button) + || this.unboundButton.mouseReleased(mouseX, mouseY, button); } } public class CategoryEntry extends Entry { private final String name; - private final int name_width; + private final int nameWidth; public CategoryEntry(@NotNull ButtonCategory category) { - this.name = category.get_translated_name(); - this.name_width = ControlsListWidget.this.minecraft.textRenderer.getStringWidth(this.name); + this.name = category.getTranslatedName(); + this.nameWidth = ControlsListWidget.this.minecraft.textRenderer.getStringWidth(this.name); } @Override - public void render(int index, int y, int x, int width, int height, int mouse_x, int mouse_y, boolean hovering, float delta) + public void render(int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovering, float delta) { - ControlsListWidget.this.minecraft.textRenderer.draw(this.name, (float) (ControlsListWidget.this.minecraft.currentScreen.width / 2 - this.name_width / 2), + ControlsListWidget.this.minecraft.textRenderer.draw(this.name, (float) (ControlsListWidget.this.minecraft.currentScreen.width / 2 - this.nameWidth / 2), (float) ((y + height) - 9 - 1), 16777215); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java index ba18ec1..72313b5 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java @@ -10,11 +10,13 @@ package me.lambdaurora.lambdacontrols.client.gui; import me.lambdaurora.lambdacontrols.ControlsMode; +import me.lambdaurora.lambdacontrols.LambdaControlsConstants; import me.lambdaurora.lambdacontrols.client.HudSide; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding; +import me.lambdaurora.spruceui.hud.Hud; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.util.Identifier; import net.minecraft.util.hit.HitResult; import org.jetbrains.annotations.NotNull; @@ -25,32 +27,39 @@ import org.jetbrains.annotations.NotNull; * @version 1.1.0 * @since 1.0.0 */ -public class LambdaControlsHud extends DrawableHelper +public class LambdaControlsHud extends Hud { - private final MinecraftClient client; private final LambdaControlsClient mod; - private int width_bottom = 0; - private int width_top = 0; + private MinecraftClient client; + private int widthBottom = 0; + private int widthTop = 0; - public LambdaControlsHud(@NotNull MinecraftClient client, @NotNull LambdaControlsClient mod) + public LambdaControlsHud(@NotNull LambdaControlsClient mod) { - this.client = client; + super(new Identifier(LambdaControlsConstants.NAMESPACE, "hud/button_indicator")); this.mod = mod; } + @Override + public void init(@NotNull MinecraftClient client, int screenWidth, int screenHeight) + { + super.init(client, screenWidth, screenHeight); + this.client = client; + } + /** * Renders the LambdaControls' HUD. */ - public void render() + public void render(float tickDelta) { - if (this.mod.config.get_controls_mode() == ControlsMode.CONTROLLER && this.mod.config.is_hud_enabled() && this.client.currentScreen == null && !this.client.options.hudHidden) { - int x = this.mod.config.get_hud_side() == HudSide.LEFT ? 10 : client.getWindow().getScaledWidth() - 10 - this.width_bottom, y = bottom(10); - x += (this.width_bottom = this.draw_button_tip(x, y, ButtonBinding.INVENTORY, true) + 10); - this.width_bottom += this.draw_button_tip(x, y, ButtonBinding.SWAP_HANDS, true); - x = this.mod.config.get_hud_side() == HudSide.LEFT ? 10 : client.getWindow().getScaledWidth() - 10 - this.width_top; - x += (this.width_top = this.draw_button_tip(x, (y -= 20), ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty()) + 10); - this.width_top += this.draw_button_tip(x, y, ButtonBinding.ATTACK.get_button(), - this.client.crosshairTarget.getType() == HitResult.Type.BLOCK ? "lambdacontrols.action.hit" : ButtonBinding.ATTACK.get_translation_key(), + if (this.mod.config.getControlsMode() == ControlsMode.CONTROLLER && this.client.currentScreen == null) { + int x = this.mod.config.getHudSide() == HudSide.LEFT ? 10 : client.getWindow().getScaledWidth() - 10 - this.widthBottom, y = bottom(10); + x += (this.widthBottom = this.drawButtonTip(x, y, ButtonBinding.INVENTORY, true) + 10); + this.widthBottom += this.drawButtonTip(x, y, ButtonBinding.SWAP_HANDS, true); + x = this.mod.config.getHudSide() == HudSide.LEFT ? 10 : client.getWindow().getScaledWidth() - 10 - this.widthTop; + x += (this.widthTop = this.drawButtonTip(x, (y -= 20), ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty()) + 10); + this.widthTop += this.drawButtonTip(x, y, ButtonBinding.ATTACK.getButton(), + this.client.crosshairTarget.getType() == HitResult.Type.BLOCK ? "lambdacontrols.action.hit" : ButtonBinding.ATTACK.getTranslationKey(), this.client.crosshairTarget.getType() != HitResult.Type.MISS); } } @@ -60,13 +69,13 @@ public class LambdaControlsHud extends DrawableHelper return this.client.getWindow().getScaledHeight() - y - 15; } - private int draw_button_tip(int x, int y, @NotNull ButtonBinding button, boolean display) + private int drawButtonTip(int x, int y, @NotNull ButtonBinding button, boolean display) { - return LambdaControlsClient.draw_button_tip(x, y, button, display, this.client); + return LambdaControlsClient.drawButtonTip(x, y, button, display, this.client); } - private int draw_button_tip(int x, int y, int[] button, @NotNull String action, boolean display) + private int drawButtonTip(int x, int y, int[] button, @NotNull String action, boolean display) { - return LambdaControlsClient.draw_button_tip(x, y, button, action, display, this.client); + return LambdaControlsClient.drawButtonTip(x, y, button, action, display, this.client); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java index dd909f0..5c60d4a 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java @@ -10,18 +10,19 @@ package me.lambdaurora.lambdacontrols.client.gui; import me.lambdaurora.lambdacontrols.ControlsMode; +import me.lambdaurora.lambdacontrols.LambdaControls; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; import me.lambdaurora.lambdacontrols.client.controller.Controller; import me.lambdaurora.spruceui.SpruceButtonWidget; import me.lambdaurora.spruceui.SpruceLabelWidget; import me.lambdaurora.spruceui.Tooltip; import me.lambdaurora.spruceui.option.*; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.options.ControlsOptionsScreen; import net.minecraft.client.gui.widget.ButtonListWidget; import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.options.CyclingOption; import net.minecraft.client.options.GameOptions; import net.minecraft.client.options.Option; import net.minecraft.client.resource.language.I18n; @@ -36,132 +37,135 @@ import org.lwjgl.glfw.GLFW; */ public class LambdaControlsSettingsScreen extends Screen { - public static final String GAMEPAD_TOOL_URL = "http://generalarcade.com/gamepadtool/"; + public static final String GAMEPAD_TOOL_URL = "http://generalarcade.com/gamepadtool/"; final LambdaControlsClient mod; private final Screen parent; - private final boolean hide_controls; + private final boolean hideControls; // General options - private final Option auto_switch_mode_option; - private final Option rotation_speed_option; - private final Option mouse_speed_option; - private final Option reset_option; + private final Option autoSwitchModeOption; + private final Option rotationSpeedOption; + private final Option mouseSpeedOption; + private final Option resetOption; // Gameplay options - private final Option front_block_placing_option; - private final Option fly_drifting_option; + private final Option frontBlockPlacingOption; + private final Option flyDriftingOption; + private final Option flyVerticalDriftingOption; // Controller options - private final Option controller_option; - private final Option second_controller_option; - private final Option controller_type_option; - private final Option dead_zone_option; - private final Option inverts_right_x_axis; - private final Option inverts_right_y_axis; - private final Option unfocused_input_option; + private final Option controllerOption; + private final Option secondControllerOption; + private final Option controllerTypeOption; + private final Option deadZoneOption; + private final Option invertsRightXAxis; + private final Option invertsRightYAxis; + private final Option unfocusedInputOption; // Hud options - private final Option hud_enable_option; - private final Option hud_side_option; - private final String controller_mappings_url_text = I18n.translate("lambdacontrols.controller.mappings.2", Formatting.GOLD.toString(), GAMEPAD_TOOL_URL, Formatting.RESET.toString()); + private final Option hudEnableOption; + private final Option hudSideOption; + private final String controllerMappingsUrlText = I18n.translate("lambdacontrols.controller.mappings.2", Formatting.GOLD.toString(), GAMEPAD_TOOL_URL, Formatting.RESET.toString()); private ButtonListWidget list; - private SpruceLabelWidget gamepad_tool_url_label; + private SpruceLabelWidget gamepadToolUrlLabel; - public LambdaControlsSettingsScreen(Screen parent, @NotNull GameOptions options, boolean hide_controls) + public LambdaControlsSettingsScreen(Screen parent, @NotNull GameOptions options, boolean hideControls) { super(new TranslatableText("lambdacontrols.title.settings")); this.mod = LambdaControlsClient.get(); this.parent = parent; - this.hide_controls = hide_controls; + this.hideControls = hideControls; // General options - this.auto_switch_mode_option = new SpruceBooleanOption("lambdacontrols.menu.auto_switch_mode", game_options -> this.mod.config.has_auto_switch_mode(), - (game_options, new_value) -> this.mod.config.set_auto_switch_mode(new_value), new TranslatableText("lambdacontrols.tooltip.auto_switch_mode"), true); - this.rotation_speed_option = new SpruceDoubleOption("lambdacontrols.menu.rotation_speed", 0.0, 150.0, 0.5F, game_options -> this.mod.config.get_rotation_speed(), - (game_options, new_value) -> { + this.autoSwitchModeOption = new SpruceBooleanOption("lambdacontrols.menu.auto_switch_mode", this.mod.config::hasAutoSwitchMode, + this.mod.config::setAutoSwitchMode, new TranslatableText("lambdacontrols.tooltip.auto_switch_mode"), true); + this.rotationSpeedOption = new SpruceDoubleOption("lambdacontrols.menu.rotation_speed", 0.0, 150.0, 0.5F, this.mod.config::getRotationSpeed, + newValue -> { synchronized (this.mod.config) { - this.mod.config.set_rotation_speed(new_value); + this.mod.config.setRotationSpeed(newValue); } - }, (game_options, option) -> option.getDisplayPrefix() + option.get(options), + }, option -> option.getDisplayPrefix() + option.get(), new TranslatableText("lambdacontrols.tooltip.rotation_speed")); - this.mouse_speed_option = new SpruceDoubleOption("lambdacontrols.menu.mouse_speed", 0.0, 150.0, 0.5F, game_options -> this.mod.config.get_mouse_speed(), - (game_options, new_value) -> { + this.mouseSpeedOption = new SpruceDoubleOption("lambdacontrols.menu.mouse_speed", 0.0, 150.0, 0.5F, this.mod.config::getMouseSpeed, + newValue -> { synchronized (this.mod.config) { - this.mod.config.set_mouse_speed(new_value); + this.mod.config.setMouseSpeed(newValue); } - }, (game_options, option) -> option.getDisplayPrefix() + option.get(options), + }, option -> option.getDisplayPrefix() + option.get(), new TranslatableText("lambdacontrols.tooltip.mouse_speed")); - this.reset_option = new SpruceResetOption(btn -> { + this.resetOption = new SpruceResetOption(btn -> { this.mod.config.reset(); MinecraftClient client = MinecraftClient.getInstance(); this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); }); // Gameplay options - this.front_block_placing_option = new SpruceBooleanOption("lambdacontrols.menu.front_block_placing", game_options -> this.mod.config.has_front_block_placing(), - (game_options, new_value) -> this.mod.config.set_front_block_placing(new_value), new TranslatableText("lambdacontrols.tooltip.front_block_placing"), true); - this.fly_drifting_option = new SpruceBooleanOption("lambdacontrols.menu.fly_drifting", game_options -> this.mod.config.has_fly_drifting(), - (game_options, new_value) -> this.mod.config.set_fly_drifting(new_value), new TranslatableText("lambdacontrols.tooltip.fly_drifting"), true); + this.frontBlockPlacingOption = new SpruceBooleanOption("lambdacontrols.menu.front_block_placing", this.mod.config::hasFrontBlockPlacing, + this.mod.config::setFrontBlockPlacing, new TranslatableText("lambdacontrols.tooltip.front_block_placing"), true); + this.flyDriftingOption = new SpruceBooleanOption("lambdacontrols.menu.fly_drifting", this.mod.config::hasFlyDrifting, + this.mod.config::setFlyDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting"), true); + this.flyVerticalDriftingOption = new SpruceBooleanOption("lambdacontrols.menu.fly_drifting_vertical", this.mod.config::hasFlyVerticalDrifting, + this.mod.config::setFlyVerticalDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting_vertical"), true); // Controller options - this.controller_option = new CyclingOption("lambdacontrols.menu.controller", (game_options, amount) -> { - int current_id = this.mod.config.get_controller().get_id(); - current_id += amount; - if (current_id > GLFW.GLFW_JOYSTICK_LAST) - current_id = GLFW.GLFW_JOYSTICK_1; - this.mod.config.set_controller(Controller.by_id(current_id)); - }, (game_options, option) -> { - String controller_name = this.mod.config.get_controller().get_name(); - if (!this.mod.config.get_controller().is_connected()) - return option.getDisplayPrefix() + Formatting.RED + controller_name; - else if (!this.mod.config.get_controller().is_gamepad()) - return option.getDisplayPrefix() + Formatting.GOLD + controller_name; + this.controllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller", amount -> { + int id = this.mod.config.getController().getId(); + id += amount; + if (id > GLFW.GLFW_JOYSTICK_LAST) + id = GLFW.GLFW_JOYSTICK_1; + this.mod.config.setController(Controller.byId(id)); + }, option -> { + String controllerName = this.mod.config.getController().getName(); + if (!this.mod.config.getController().isConnected()) + return option.getDisplayPrefix() + Formatting.RED + controllerName; + else if (!this.mod.config.getController().isGamepad()) + return option.getDisplayPrefix() + Formatting.GOLD + controllerName; else - return option.getDisplayPrefix() + controller_name; - }); - this.second_controller_option = new SpruceCyclingOption("lambdacontrols.menu.controller2", - (game_options, amount) -> { - int current_id = this.mod.config.get_second_controller().map(Controller::get_id).orElse(-1); - current_id += amount; - if (current_id > GLFW.GLFW_JOYSTICK_LAST) - current_id = -1; - this.mod.config.set_second_controller(current_id == -1 ? null : Controller.by_id(current_id)); - }, (game_options, option) -> this.mod.config.get_second_controller().map(controller -> { - String controller_name = controller.get_name(); - if (!controller.is_connected()) - return option.getDisplayPrefix() + Formatting.RED + controller_name; - else if (!controller.is_gamepad()) - return option.getDisplayPrefix() + Formatting.GOLD + controller_name; + return option.getDisplayPrefix() + controllerName; + }, null); + this.secondControllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller2", + amount -> { + int id = this.mod.config.getSecondController().map(Controller::getId).orElse(-1); + id += amount; + if (id > GLFW.GLFW_JOYSTICK_LAST) + id = -1; + this.mod.config.setSecondController(id == -1 ? null : Controller.byId(id)); + }, option -> this.mod.config.getSecondController().map(controller -> { + String controllerName = controller.getName(); + if (!controller.isConnected()) + return option.getDisplayPrefix() + Formatting.RED + controllerName; + else if (!controller.isGamepad()) + return option.getDisplayPrefix() + Formatting.GOLD + controllerName; else - return option.getDisplayPrefix() + controller_name; + return option.getDisplayPrefix() + controllerName; }).orElse(option.getDisplayPrefix() + Formatting.RED + I18n.translate("options.off")), new TranslatableText("lambdacontrols.tooltip.controller2")); - this.controller_type_option = new SpruceCyclingOption("lambdacontrols.menu.controller_type", - (game_options, amount) -> this.mod.config.set_controller_type(this.mod.config.get_controller_type().next()), - (game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_controller_type().get_translated_name(), + this.controllerTypeOption = new SpruceCyclingOption("lambdacontrols.menu.controller_type", + amount -> this.mod.config.setControllerType(this.mod.config.getControllerType().next()), + option -> option.getDisplayPrefix() + this.mod.config.getControllerType().getTranslatedName(), new TranslatableText("lambdacontrols.tooltip.controller_type")); - this.dead_zone_option = new SpruceDoubleOption("lambdacontrols.menu.dead_zone", 0.05, 1.0, 0.05F, game_options -> this.mod.config.get_dead_zone(), - (game_options, new_value) -> { + this.deadZoneOption = new SpruceDoubleOption("lambdacontrols.menu.dead_zone", 0.05, 1.0, 0.05F, this.mod.config::getDeadZone, + newValue -> { synchronized (this.mod.config) { - this.mod.config.set_dead_zone(new_value); + this.mod.config.setDeadZone(newValue); } - }, (game_options, option) -> { - String value = String.valueOf(option.get(options)); + }, option -> { + String value = String.valueOf(option.get()); return option.getDisplayPrefix() + value.substring(0, Math.min(value.length(), 5)); }, new TranslatableText("lambdacontrols.tooltip.dead_zone")); - this.inverts_right_x_axis = new SpruceBooleanOption("lambdacontrols.menu.invert_right_x_axis", game_options -> this.mod.config.does_invert_right_x_axis(), - (game_options, new_value) -> { + this.invertsRightXAxis = new SpruceBooleanOption("lambdacontrols.menu.invert_right_x_axis", this.mod.config::doesInvertRightXAxis, + newValue -> { synchronized (this.mod.config) { - this.mod.config.set_invert_right_x_axis(new_value); + this.mod.config.setInvertRightXAxis(newValue); } }, null, true); - this.inverts_right_y_axis = new SpruceBooleanOption("lambdacontrols.menu.invert_right_y_axis", game_options -> this.mod.config.does_invert_right_y_axis(), - (game_options, new_value) -> { + this.invertsRightYAxis = new SpruceBooleanOption("lambdacontrols.menu.invert_right_y_axis", this.mod.config::doesInvertRightYAxis, + newValue -> { synchronized (this.mod.config) { - this.mod.config.set_invert_right_y_axis(new_value); + this.mod.config.setInvertRightYAxis(newValue); } }, null, true); - this.unfocused_input_option = new SpruceBooleanOption("lambdacontrols.menu.unfocused_input", (game_options) -> this.mod.config.has_unfocused_input(), - (game_options, new_value) -> this.mod.config.set_unfocused_input(new_value), new TranslatableText("lambdacontrols.tooltip.unfocused_input"), true); + this.unfocusedInputOption = new SpruceBooleanOption("lambdacontrols.menu.unfocused_input", this.mod.config::hasUnfocusedInput, + this.mod.config::setUnfocusedInput, new TranslatableText("lambdacontrols.tooltip.unfocused_input"), true); // HUD options - this.hud_enable_option = new SpruceBooleanOption("lambdacontrols.menu.hud_enable", (game_options) -> this.mod.config.is_hud_enabled(), - (game_options, new_value) -> this.mod.config.set_hud_enabled(new_value), new TranslatableText("lambdacontrols.tooltip.hud_enable"), true); - this.hud_side_option = new SpruceCyclingOption("lambdacontrols.menu.hud_side", - (game_options, amount) -> this.mod.config.set_hud_side(this.mod.config.get_hud_side().next()), - (game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_hud_side().get_translated_name(), + this.hudEnableOption = new SpruceBooleanOption("lambdacontrols.menu.hud_enable", this.mod.config::isHudEnabled, + this.mod::setHudEnabled, new TranslatableText("lambdacontrols.tooltip.hud_enable"), true); + this.hudSideOption = new SpruceCyclingOption("lambdacontrols.menu.hud_side", + amount -> this.mod.config.setHudSide(this.mod.config.getHudSide().next()), + option -> option.getDisplayPrefix() + this.mod.config.getHudSide().getTranslatedName(), new TranslatableText("lambdacontrols.tooltip.hud_side")); } @@ -179,7 +183,7 @@ public class LambdaControlsSettingsScreen extends Screen super.onClose(); } - private int get_text_height() + private int getTextHeight() { return (5 + this.font.fontHeight) * 3 + 5; } @@ -188,69 +192,74 @@ public class LambdaControlsSettingsScreen extends Screen protected void init() { super.init(); - int button_height = 20; - SpruceButtonWidget controls_mode_btn = new SpruceButtonWidget(this.width / 2 - 155, 18, this.hide_controls ? 310 : 150, button_height, - I18n.translate("lambdacontrols.menu.controls_mode") + ": " + I18n.translate(this.mod.config.get_controls_mode().get_translation_key()), + int buttonHeight = 20; + SpruceButtonWidget controlsModeBtn = new SpruceButtonWidget(this.width / 2 - 155, 18, this.hideControls ? 310 : 150, buttonHeight, + I18n.translate("lambdacontrols.menu.controls_mode") + ": " + I18n.translate(this.mod.config.getControlsMode().getTranslationKey()), btn -> { - ControlsMode next = this.mod.config.get_controls_mode().next(); - btn.setMessage(I18n.translate("lambdacontrols.menu.controls_mode") + ": " + I18n.translate(next.get_translation_key())); - this.mod.config.set_controls_mode(next); + ControlsMode next = this.mod.config.getControlsMode().next(); + btn.setMessage(I18n.translate("lambdacontrols.menu.controls_mode") + ": " + I18n.translate(next.getTranslationKey())); + this.mod.config.setControlsMode(next); this.mod.config.save(); + + if (this.minecraft.player != null) { + ClientSidePacketRegistry.INSTANCE.sendToServer(LambdaControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next)); + } }); - controls_mode_btn.set_tooltip(new TranslatableText("lambdacontrols.tooltip.controls_mode")); - this.addButton(controls_mode_btn); - if (!this.hide_controls) - this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, button_height, I18n.translate("options.controls"), + controlsModeBtn.setTooltip(new TranslatableText("lambdacontrols.tooltip.controls_mode")); + this.addButton(controlsModeBtn); + if (!this.hideControls) + this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, buttonHeight, I18n.translate("options.controls"), btn -> { - if (this.mod.config.get_controls_mode() == ControlsMode.CONTROLLER) - this.minecraft.openScreen(new LambdaControlsControlsScreen(this, true)); + if (this.mod.config.getControlsMode() == ControlsMode.CONTROLLER) + this.minecraft.openScreen(new ControllerControlsScreen(this, true)); else this.minecraft.openScreen(new ControlsOptionsScreen(this, this.minecraft.options)); })); - this.list = new ButtonListWidget(this.minecraft, this.width, this.height, 43, this.height - 29 - this.get_text_height(), 25); + this.list = new ButtonListWidget(this.minecraft, this.width, this.height, 43, this.height - 29 - this.getTextHeight(), 25); // General options this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.general", true, null)); - this.list.addOptionEntry(this.rotation_speed_option, this.mouse_speed_option); - this.list.addSingleOptionEntry(this.auto_switch_mode_option); + this.list.addOptionEntry(this.rotationSpeedOption, this.mouseSpeedOption); + this.list.addSingleOptionEntry(this.autoSwitchModeOption); // Gameplay options this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.gameplay", true, null)); - this.list.addSingleOptionEntry(this.front_block_placing_option); - this.list.addSingleOptionEntry(this.fly_drifting_option); + this.list.addSingleOptionEntry(this.frontBlockPlacingOption); + this.list.addSingleOptionEntry(this.flyDriftingOption); + this.list.addSingleOptionEntry(this.flyVerticalDriftingOption); // Controller options this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.controller", true, null)); - this.list.addSingleOptionEntry(this.controller_option); - this.list.addSingleOptionEntry(this.second_controller_option); - this.list.addOptionEntry(this.controller_type_option, this.dead_zone_option); - this.list.addOptionEntry(this.inverts_right_x_axis, this.inverts_right_y_axis); - this.list.addSingleOptionEntry(this.unfocused_input_option); + this.list.addSingleOptionEntry(this.controllerOption); + this.list.addSingleOptionEntry(this.secondControllerOption); + this.list.addOptionEntry(this.controllerTypeOption, this.deadZoneOption); + this.list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis); + this.list.addSingleOptionEntry(this.unfocusedInputOption); this.list.addSingleOptionEntry(new ReloadControllerMappingsOption()); // HUD options this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null)); - this.list.addOptionEntry(this.hud_enable_option, this.hud_side_option); + this.list.addOptionEntry(this.hudEnableOption, this.hudSideOption); this.children.add(this.list); - this.gamepad_tool_url_label = new SpruceLabelWidget(this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, this.controller_mappings_url_text, this.width, + this.gamepadToolUrlLabel = new SpruceLabelWidget(this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, this.controllerMappingsUrlText, this.width, label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true); - this.gamepad_tool_url_label.set_tooltip(new TranslatableText("chat.link.open")); - this.children.add(this.gamepad_tool_url_label); + this.gamepadToolUrlLabel.setTooltip(new TranslatableText("chat.link.open")); + this.children.add(this.gamepadToolUrlLabel); - this.addButton(this.reset_option.createButton(this.minecraft.options, this.width / 2 - 155, this.height - 29, 150)); - this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, button_height, I18n.translate("gui.done"), + this.addButton(this.resetOption.createButton(this.minecraft.options, this.width / 2 - 155, this.height - 29, 150)); + this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, buttonHeight, I18n.translate("gui.done"), (buttonWidget) -> this.minecraft.openScreen(this.parent))); } @Override - public void render(int mouse_x, int mouse_y, float delta) + public void render(int mouseX, int mouseY, float delta) { this.renderBackground(); - this.list.render(mouse_x, mouse_y, delta); - super.render(mouse_x, mouse_y, delta); + this.list.render(mouseX, mouseY, delta); + super.render(mouseX, mouseY, delta); this.drawCenteredString(this.font, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215); this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.1", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 3, 10526880); - this.gamepad_tool_url_label.render(mouse_x, mouse_y, delta); + this.gamepadToolUrlLabel.render(mouseX, mouseY, delta); this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight), 10526880); - Tooltip.render_all(); + Tooltip.renderAll(); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java index 125ec50..526b74f 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java @@ -36,19 +36,19 @@ public class ReloadControllerMappingsOption extends Option implements Nameable @Override public AbstractButtonWidget createButton(GameOptions options, int x, int y, int width) { - SpruceButtonWidget button = new SpruceButtonWidget(x, y, width, 20, this.get_name(), btn -> { + SpruceButtonWidget button = new SpruceButtonWidget(x, y, width, 20, this.getName(), btn -> { MinecraftClient client = MinecraftClient.getInstance(); - Controller.update_mappings(); + Controller.updateMappings(); if (client.currentScreen != null) client.currentScreen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.mappings.updated"), null)); }); - button.set_tooltip(new TranslatableText("lambdacontrols.tooltip.reload_controller_mappings")); + button.setTooltip(new TranslatableText("lambdacontrols.tooltip.reload_controller_mappings")); return button; } @Override - public @NotNull String get_name() + public @NotNull String getName() { return I18n.translate(KEY); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java index fbffd6d..41ac3c3 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java @@ -36,18 +36,18 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y; */ public class TouchscreenOverlay extends Screen { - public static final Identifier WIDGETS_LOCATION = new Identifier("lambdacontrols", "textures/gui/widgets.png"); + public static final Identifier WIDGETS_LOCATION = new Identifier("lambdacontrols", "textures/gui/widgets.png"); private LambdaControlsClient mod; - private SpruceTexturedButtonWidget jump_button; - private SpruceTexturedButtonWidget fly_button; - private SpruceTexturedButtonWidget fly_up_button; - private SpruceTexturedButtonWidget fly_down_button; - private int fly_button_enable_ticks = 0; - private int forward_button_tick = 0; - private SpruceTexturedButtonWidget forward_left_button; - private SpruceTexturedButtonWidget forward_right_button; - private SpruceTexturedButtonWidget start_sneak_button; - private SpruceTexturedButtonWidget end_sneak_button; + 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 TouchscreenOverlay(@NotNull LambdaControlsClient mod) { @@ -68,7 +68,7 @@ public class TouchscreenOverlay extends Screen return false; } - private void pause_game(boolean bl) + private void pauseGame(boolean bl) { if (this.minecraft == null) return; @@ -86,37 +86,37 @@ public class TouchscreenOverlay extends Screen * * @param state The button state. */ - private void update_forward_buttons_state(boolean state) + private void updateForwardButtonsState(boolean state) { if (state) - this.forward_button_tick = -1; + this.forwardButtonTick = -1; else - this.forward_button_tick = 20; + this.forwardButtonTick = 20; } /** * Updates the jump buttons. */ - private void update_jump_buttons() + private void updateJumpButtons() { if (this.minecraft == null) return; if (this.minecraft.player.abilities.allowFlying && this.minecraft.player.abilities.flying) { - boolean old_state_fly = this.fly_button.visible; - this.jump_button.visible = false; - this.fly_button.visible = true; - this.fly_up_button.visible = true; - this.fly_down_button.visible = true; - if (old_state_fly != this.fly_button.visible) { - this.fly_button_enable_ticks = 5; - this.handle_jump(null, false); - } else if (this.fly_button_enable_ticks > 0) - this.fly_button_enable_ticks--; + 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.jump_button.visible = true; - this.fly_button.visible = false; - this.fly_up_button.visible = false; - this.fly_down_button.visible = false; + this.jumpButton.visible = true; + this.flyButton.visible = false; + this.flyUpButton.visible = false; + this.flyDownButton.visible = false; } } @@ -126,44 +126,44 @@ public class TouchscreenOverlay extends Screen * @param btn The pressed button. * @param state The state of the jump button. */ - private void handle_jump(ButtonWidget btn, boolean state) + private void handleJump(ButtonWidget btn, boolean state) { - ((KeyBindingAccessor) this.minecraft.options.keyJump).handle_press_state(state); + ((KeyBindingAccessor) this.minecraft.options.keyJump).lambdacontrols_handlePressState(state); } @Override public void tick() { - if (this.forward_button_tick > 0) { - this.forward_button_tick--; - } else if (this.forward_button_tick == 0) { - if (this.forward_left_button.visible) - this.forward_left_button.visible = false; - if (this.forward_right_button.visible) - this.forward_right_button.visible = false; + 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.update_jump_buttons(); + this.updateJumpButtons(); } @Override protected void init() { super.init(); - int scaled_width = this.minecraft.getWindow().getScaledWidth(); - int scaled_height = this.minecraft.getWindow().getScaledHeight(); - this.addButton(new TexturedButtonWidget(scaled_width / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256, + int scaledWidth = this.minecraft.getWindow().getScaledWidth(); + int scaledHeight = this.minecraft.getWindow().getScaledHeight(); + this.addButton(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256, btn -> this.minecraft.openScreen(new ChatScreen("")), "")); - this.addButton(new TexturedButtonWidget(scaled_width / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, - btn -> this.pause_game(false))); + this.addButton(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, + btn -> this.pauseGame(false))); // Inventory buttons. - int inventory_button_x = scaled_width / 2; - int inventory_button_y = scaled_height - 16 - 5; + int inventoryButtonX = scaledWidth / 2; + int inventoryButtonY = scaledHeight - 16 - 5; if (this.minecraft.options.mainArm == Arm.LEFT) { - inventory_button_x = inventory_button_x - 91 - 24; + inventoryButtonX = inventoryButtonX - 91 - 24; } else { - inventory_button_x = inventory_button_x + 91 + 4; + inventoryButtonX = inventoryButtonX + 91 + 4; } - this.addButton(new TexturedButtonWidget(inventory_button_x, inventory_button_y, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, + this.addButton(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, btn -> { if (this.minecraft.interactionManager.hasRidingInventory()) { this.minecraft.player.openRidingInventory(); @@ -172,19 +172,19 @@ public class TouchscreenOverlay extends Screen this.minecraft.openScreen(new InventoryScreen(this.minecraft.player)); } })); - int jump_button_x, swap_hands_x, sneak_button_x; - int sneak_button_y = scaled_height - 10 - 40 - 5; - if (this.mod.config.get_hud_side() == HudSide.LEFT) { - jump_button_x = scaled_width - 20 - 20; - swap_hands_x = jump_button_x - 5 - 40; - sneak_button_x = 10 + 20 + 5; + int jumpButtonX, swapHandsX, sneakButtonX; + int sneakButtonY = scaledHeight - 10 - 40 - 5; + if (this.mod.config.getHudSide() == HudSide.LEFT) { + jumpButtonX = scaledWidth - 20 - 20; + swapHandsX = jumpButtonX - 5 - 40; + sneakButtonX = 10 + 20 + 5; } else { - jump_button_x = 20; - swap_hands_x = jump_button_x + 5 + 40; - sneak_button_x = scaled_width - 10 - 40 - 5; + jumpButtonX = 20; + swapHandsX = jumpButtonX + 5 + 40; + sneakButtonX = scaledWidth - 10 - 40 - 5; } // Swap items hand. - this.addButton(new SpruceTexturedButtonWidget(swap_hands_x, sneak_button_y, 20, 20, 0, 160, 20, WIDGETS_LOCATION, + this.addButton(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY, 20, 20, 0, 160, 20, WIDGETS_LOCATION, (btn, state) -> { if (state) { if (!this.minecraft.player.isSpectator()) { @@ -193,65 +193,65 @@ public class TouchscreenOverlay extends Screen } })); // Drop - this.addButton(new SpruceTexturedButtonWidget(swap_hands_x, sneak_button_y + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyDrop).handle_press_state(state))); + this.addButton(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION, + (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyDrop).lambdacontrols_handlePressState(state))); // Jump keys - this.addButton(this.jump_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y, 20, 20, 0, 40, 20, WIDGETS_LOCATION, - this::handle_jump)); - this.addButton(this.fly_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y, 20, 20, 20, 40, 20, WIDGETS_LOCATION, + this.addButton(this.jumpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 0, 40, 20, WIDGETS_LOCATION, + this::handleJump)); + this.addButton(this.flyButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 20, 40, 20, WIDGETS_LOCATION, (btn, state) -> { - if (this.fly_button_enable_ticks == 0) this.minecraft.player.abilities.flying = false; + if (this.flyButtonEnableTicks == 0) this.minecraft.player.abilities.flying = false; })); - this.addButton(this.fly_up_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION, - this::handle_jump)); - this.addButton(this.fly_down_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(state))); - this.update_jump_buttons(); + this.addButton(this.flyUpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION, + this::handleJump)); + this.addButton(this.flyDownButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION, + (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keySneak).lambdacontrols_handlePressState(state))); + this.updateJumpButtons(); // Movements keys - this.addButton((this.start_sneak_button = new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y, 20, 20, 0, 120, 20, WIDGETS_LOCATION, + this.addButton((this.startSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 0, 120, 20, WIDGETS_LOCATION, (btn, state) -> { if (state) { - ((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(true); - this.start_sneak_button.visible = false; - this.end_sneak_button.visible = true; + ((KeyBindingAccessor) this.minecraft.options.keySneak).lambdacontrols_handlePressState(true); + this.startSneakButton.visible = false; + this.endSneakButton.visible = true; } }))); - this.addButton((this.end_sneak_button = new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y, 20, 20, 20, 120, 20, WIDGETS_LOCATION, + this.addButton((this.endSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 20, 120, 20, WIDGETS_LOCATION, (btn, state) -> { if (state) { - ((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(false); - this.end_sneak_button.visible = false; - this.start_sneak_button.visible = true; + ((KeyBindingAccessor) this.minecraft.options.keySneak).lambdacontrols_handlePressState(false); + this.endSneakButton.visible = false; + this.startSneakButton.visible = true; } }))); - this.end_sneak_button.visible = false; - this.addButton(this.forward_left_button = new SpruceTexturedButtonWidget(sneak_button_x - 20 - 5, sneak_button_y - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION, + this.endSneakButton.visible = false; + this.addButton(this.forwardLeftButton = new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION, (btn, state) -> { - ((KeyBindingAccessor) this.minecraft.options.keyForward).handle_press_state(state); - ((KeyBindingAccessor) this.minecraft.options.keyLeft).handle_press_state(state); - this.update_forward_buttons_state(state); + ((KeyBindingAccessor) this.minecraft.options.keyForward).lambdacontrols_handlePressState(state); + ((KeyBindingAccessor) this.minecraft.options.keyLeft).lambdacontrols_handlePressState(state); + this.updateForwardButtonsState(state); })); - this.forward_left_button.visible = false; - this.addButton(new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION, + this.forwardLeftButton.visible = false; + this.addButton(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION, (btn, state) -> { - ((KeyBindingAccessor) this.minecraft.options.keyForward).handle_press_state(state); - this.update_forward_buttons_state(state); - this.forward_left_button.visible = true; - this.forward_right_button.visible = true; + ((KeyBindingAccessor) this.minecraft.options.keyForward).lambdacontrols_handlePressState(state); + this.updateForwardButtonsState(state); + this.forwardLeftButton.visible = true; + this.forwardRightButton.visible = true; })); - this.addButton(this.forward_right_button = new SpruceTexturedButtonWidget(sneak_button_x + 20 + 5, sneak_button_y - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION, + this.addButton(this.forwardRightButton = new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION, (btn, state) -> { - ((KeyBindingAccessor) this.minecraft.options.keyForward).handle_press_state(state); - ((KeyBindingAccessor) this.minecraft.options.keyRight).handle_press_state(state); - this.update_forward_buttons_state(state); + ((KeyBindingAccessor) this.minecraft.options.keyForward).lambdacontrols_handlePressState(state); + ((KeyBindingAccessor) this.minecraft.options.keyRight).lambdacontrols_handlePressState(state); + this.updateForwardButtonsState(state); })); - this.forward_right_button.visible = true; - this.addButton(new SpruceTexturedButtonWidget(sneak_button_x + 20 + 5, sneak_button_y, 20, 20, 20, 80, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyRight).handle_press_state(state))); - this.addButton(new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyBack).handle_press_state(state))); - this.addButton(new SpruceTexturedButtonWidget(sneak_button_x - 20 - 5, sneak_button_y, 20, 20, 60, 80, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyLeft).handle_press_state(state))); + this.forwardRightButton.visible = true; + this.addButton(new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY, 20, 20, 20, 80, 20, WIDGETS_LOCATION, + (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyRight).lambdacontrols_handlePressState(state))); + this.addButton(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION, + (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyBack).lambdacontrols_handlePressState(state))); + this.addButton(new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY, 20, 20, 60, 80, 20, WIDGETS_LOCATION, + (btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyLeft).lambdacontrols_handlePressState(state))); } @Override @@ -261,37 +261,37 @@ public class TouchscreenOverlay extends Screen } @Override - public boolean mouseClicked(double mouse_x, double mouse_y, int button) + public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (mouse_y >= (double) (this.height - 22) && this.minecraft != null && this.minecraft.player != null) { - int center_x = this.width / 2; - if (mouse_x >= (double) (center_x - 90) && mouse_x <= (double) (center_x + 90)) { + if (mouseY >= (double) (this.height - 22) && this.minecraft != null && this.minecraft.player != null) { + int centerX = this.width / 2; + if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { for (int slot = 0; slot < 9; ++slot) { - int slot_x = center_x - 90 + slot * 20 + 2; - if (mouse_x >= (double) slot_x && mouse_x <= (double) (slot_x + 20)) { + int slotX = centerX - 90 + slot * 20 + 2; + if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { this.minecraft.player.inventory.selectedSlot = slot; return true; } } } } - return super.mouseClicked(mouse_x, mouse_y, button); + return super.mouseClicked(mouseX, mouseY, button); } @Override - public boolean mouseDragged(double mouse_x, double mouse_y, int button, double delta_x, double delta_y) + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.minecraft != null) { - if (delta_y > 0.01) - this.mod.input.handle_look(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(delta_y / 5.0), 2); - else if (delta_y < 0.01) - this.mod.input.handle_look(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(delta_y / 5.0), 1); + if (deltaY > 0.01) + this.mod.input.handleLook(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2); + else if (deltaY < 0.01) + this.mod.input.handleLook(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1); - if (delta_x > 0.01) - this.mod.input.handle_look(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(delta_x / 5.0), 2); - else if (delta_x < 0.01) - this.mod.input.handle_look(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(delta_x / 5.0), 1); + if (deltaX > 0.01) + this.mod.input.handleLook(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2); + else if (deltaX < 0.01) + this.mod.input.handleLook(this.minecraft, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1); } - return super.mouseDragged(mouse_x, mouse_y, button, delta_x, delta_y); + return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AbstractButtonWidgetAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AbstractButtonWidgetAccessor.java index 49b77c8..5ef0f42 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AbstractButtonWidgetAccessor.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AbstractButtonWidgetAccessor.java @@ -17,5 +17,5 @@ import org.spongepowered.asm.mixin.gen.Accessor; public interface AbstractButtonWidgetAccessor { @Accessor("height") - int lambdacontrols_get_height(); + int lambdacontrols_getHeight(); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AdvancementsScreenAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AdvancementsScreenAccessor.java new file mode 100644 index 0000000..2902d29 --- /dev/null +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AdvancementsScreenAccessor.java @@ -0,0 +1,35 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols.client.mixin; + +import net.minecraft.advancement.Advancement; +import net.minecraft.client.gui.screen.advancement.AdvancementTab; +import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; +import net.minecraft.client.network.ClientAdvancementManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +/** + * Represents an accessor of {@link AdvancementsScreen}. + */ +@Mixin(AdvancementsScreen.class) +public interface AdvancementsScreenAccessor +{ + @Accessor("advancementHandler") + ClientAdvancementManager lambdacontrols_getAdvancementManager(); + + @Accessor("tabs") + Map lambdacontrols_getTabs(); + + @Accessor("selectedTab") + AdvancementTab lambdacontrols_getSelectedTab(); +} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayNetworkHandlerMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayNetworkHandlerMixin.java new file mode 100644 index 0000000..795562a --- /dev/null +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayNetworkHandlerMixin.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols.client.mixin; + +import me.lambdaurora.lambdacontrols.LambdaControls; +import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.client.network.packet.GameJoinS2CPacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientPlayNetworkHandler.class) +public class ClientPlayNetworkHandlerMixin +{ + @Inject(method = "onGameJoin", at = @At(value = "TAIL")) + private void lambdacontrols_onConnect(GameJoinS2CPacket packet, CallbackInfo ci) + { + ClientSidePacketRegistry.INSTANCE.sendToServer(LambdaControls.HELLO_CHANNEL, LambdaControls.get().makeHello(LambdaControlsClient.get().config.getControlsMode())); + ClientSidePacketRegistry.INSTANCE.sendToServer(LambdaControls.CONTROLS_MODE_CHANNEL, + LambdaControls.get().makeControlsModeBuffer(LambdaControlsClient.get().config.getControlsMode())); + } +} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayerEntityMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayerEntityMixin.java index 713d009..7794b7d 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayerEntityMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ClientPlayerEntityMixin.java @@ -11,11 +11,14 @@ package me.lambdaurora.lambdacontrols.client.mixin; import com.mojang.authlib.GameProfile; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.input.Input; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.MovementType; import net.minecraft.util.math.Vec3d; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -28,11 +31,21 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ClientPlayerEntity.class) public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity { - private boolean lambdacontrols_drifting_prevented = false; + private boolean lambdacontrols_driftingPrevented = false; @Shadow protected abstract boolean hasMovementInput(); + @Shadow + @Final + protected MinecraftClient client; + + @Shadow + public Input input; + + @Shadow + protected abstract boolean isCamera(); + public ClientPlayerEntityMixin(ClientWorld world, GameProfile profile) { super(world, profile); @@ -43,14 +56,36 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity { LambdaControlsClient mod = LambdaControlsClient.get(); if (type == MovementType.SELF) { - if (this.abilities.flying && !mod.config.has_fly_drifting()) { + if (this.abilities.flying && (!mod.config.hasFlyDrifting() || !mod.config.hasFlyVerticalDrifting())) { if (!this.hasMovementInput()) { - if (!this.lambdacontrols_drifting_prevented) { - this.setVelocity(this.getVelocity().multiply(0, 1.0, 0)); + if (!this.lambdacontrols_driftingPrevented) { + if (!mod.config.hasFlyDrifting()) + this.setVelocity(this.getVelocity().multiply(0, 1.0, 0)); } - this.lambdacontrols_drifting_prevented = true; + this.lambdacontrols_driftingPrevented = true; } else - this.lambdacontrols_drifting_prevented = false; + this.lambdacontrols_driftingPrevented = false; + } + } + } + + @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z")) + public void lambdacontrols_tickMovement(CallbackInfo ci) + { + if (this.abilities.flying && this.isCamera()) { + if (LambdaControlsClient.get().config.hasFlyVerticalDrifting()) + return; + int moving = 0; + if (this.input.sneaking) { + --moving; + } + + if (this.input.jumping) { + ++moving; + } + + if (moving == 0) { + this.setVelocity(this.getVelocity().multiply(1.0, 0.0, 1.0)); } } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AbstractContainerScreenMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ContainerScreenMixin.java similarity index 51% rename from fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AbstractContainerScreenMixin.java rename to fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ContainerScreenMixin.java index d183796..0cad2e7 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/AbstractContainerScreenMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ContainerScreenMixin.java @@ -11,9 +11,9 @@ package me.lambdaurora.lambdacontrols.client.mixin; import me.lambdaurora.lambdacontrols.ControlsMode; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import me.lambdaurora.lambdacontrols.client.util.AbstractContainerScreenAccessor; +import me.lambdaurora.lambdacontrols.client.util.ContainerScreenAccessor; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen; +import net.minecraft.client.gui.screen.ingame.ContainerScreen; import net.minecraft.container.Slot; import org.lwjgl.glfw.GLFW; import org.spongepowered.asm.mixin.Mixin; @@ -23,40 +23,40 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** - * Represents the mixin for the class AbstractContainerScreen. + * Represents the mixin for the class ContainerScreen. */ -@Mixin(AbstractContainerScreen.class) -public abstract class AbstractContainerScreenMixin implements AbstractContainerScreenAccessor +@Mixin(ContainerScreen.class) +public abstract class ContainerScreenMixin implements ContainerScreenAccessor { protected int x; protected int y; @Override - public int lambdacontrols_get_x() + public int lambdacontrols_getX() { return this.x; } @Override - public int lambdacontrols_get_y() + public int lambdacontrols_getY() { return this.y; } @Invoker("getSlotAt") - public abstract Slot lambdacontrols_get_slot_at(double pos_x, double pos_y); + public abstract Slot lambdacontrols_getSlotAt(double posX, double posY); @Inject(method = "render", at = @At("RETURN")) public void render(int mouseX, int mouseY, float delta, CallbackInfo ci) { - if (LambdaControlsClient.get().config.get_controls_mode() == ControlsMode.CONTROLLER) { + if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) { MinecraftClient client = MinecraftClient.getInstance(); int x = 10, y = client.getWindow().getScaledHeight() - 10 - 15; - x += LambdaControlsClient.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 10; - x += LambdaControlsClient.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "lambdacontrols.action.exit", true, client) + 10; - x += LambdaControlsClient.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "lambdacontrols.action.pickup", true, client) + 10; - LambdaControlsClient.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, "lambdacontrols.action.quick_move", true, client); + x += LambdaControlsClient.drawButtonTip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 10; + x += LambdaControlsClient.drawButtonTip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "lambdacontrols.action.exit", true, client) + 10; + x += LambdaControlsClient.drawButtonTip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "lambdacontrols.action.pickup", true, client) + 10; + LambdaControlsClient.drawButtonTip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, "lambdacontrols.action.quick_move", true, client); } } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java index a6ba4d1..1a84810 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java @@ -9,7 +9,7 @@ package me.lambdaurora.lambdacontrols.client.mixin; -import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsControlsScreen; +import me.lambdaurora.lambdacontrols.client.gui.ControllerControlsScreen; import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.options.ControlsOptionsScreen; @@ -29,18 +29,18 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(ControlsOptionsScreen.class) public class ControlsOptionsScreenMixin extends GameOptionsScreen { - public ControlsOptionsScreenMixin(Screen parent, GameOptions game_options, Text text) + public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) { - super(parent, game_options, text); + super(parent, gameOptions, text); } @Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/options/ControlsOptionsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 1)) private AbstractButtonWidget on_init(ControlsOptionsScreen screen, AbstractButtonWidget btn) { - if (this.parent instanceof LambdaControlsControlsScreen) + if (this.parent instanceof ControllerControlsScreen) return this.addButton(btn); else - return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).lambdacontrols_get_height(), I18n.translate("menu.options"), + return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).lambdacontrols_getHeight(), I18n.translate("menu.options"), b -> this.minecraft.openScreen(new LambdaControlsSettingsScreen(this, this.gameOptions, true)))); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/CreativeInventoryScreenAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/CreativeInventoryScreenAccessor.java index b4c2c07..0b2e08e 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/CreativeInventoryScreenAccessor.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/CreativeInventoryScreenAccessor.java @@ -10,8 +10,10 @@ package me.lambdaurora.lambdacontrols.client.mixin; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; +import net.minecraft.container.Slot; import net.minecraft.item.ItemGroup; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Invoker; @@ -28,7 +30,7 @@ public interface CreativeInventoryScreenAccessor * @return The selected tab index. */ @Accessor("selectedTab") - int lambdacontrols_get_selected_tab(); + int lambdacontrols_getSelectedTab(); /** * Sets the selected tab. @@ -36,5 +38,14 @@ public interface CreativeInventoryScreenAccessor * @param group The tab's item group. */ @Invoker("setSelectedTab") - void lambdacontrols_set_selected_tab(@NotNull ItemGroup group); + void lambdacontrols_setSelectedTab(@NotNull ItemGroup group); + + /** + * Returns whether the slot belongs to the creative inventory or not. + * + * @param slot The slot to check. + * @return True if the slot is from the creative inventory, else false. + */ + @Invoker("isCreativeInventorySlot") + boolean lambdacontrols_isCreativeInventorySlot(@Nullable Slot slot); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/EntryListWidgetAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/EntryListWidgetAccessor.java index fc94e70..592353e 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/EntryListWidgetAccessor.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/EntryListWidgetAccessor.java @@ -17,5 +17,5 @@ import org.spongepowered.asm.mixin.gen.Invoker; public interface EntryListWidgetAccessor { @Invoker("moveSelection") - void lambdacontrols_move_selection(int amount); + void lambdacontrols_moveSelection(int amount); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/GameRendererMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/GameRendererMixin.java index 2e3f224..27f1f05 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/GameRendererMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/GameRendererMixin.java @@ -28,9 +28,9 @@ public class GameRendererMixin private MinecraftClient client; @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Mouse;getX()D")) - private void on_render(float tick_delta, long start_time, boolean full_render, CallbackInfo ci) + private void onRender(float tickDelta, long startTime, boolean fullRender, CallbackInfo ci) { - if (this.client.currentScreen != null && LambdaControlsClient.get().config.get_controls_mode() == ControlsMode.CONTROLLER) - LambdaControlsClient.get().input.on_pre_render_screen(this.client, this.client.currentScreen); + if (this.client.currentScreen != null && LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) + LambdaControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/KeyBindingMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/KeyBindingMixin.java index 72af876..1815e13 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/KeyBindingMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/KeyBindingMixin.java @@ -12,7 +12,6 @@ package me.lambdaurora.lambdacontrols.client.mixin; import me.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; import net.minecraft.client.options.KeyBinding; import net.minecraft.client.util.InputUtil; -import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -28,20 +27,14 @@ public class KeyBindingMixin implements KeyBindingAccessor @Shadow private boolean pressed; - @Override - public @NotNull InputUtil.KeyCode get_key_code() - { - return this.keyCode; - } - @Override public boolean lambdacontrols_press() { - boolean old_pressed = this.pressed; + boolean oldPressed = this.pressed; if (!this.pressed) this.pressed = true; ++this.timesPressed; - return old_pressed != this.pressed; + return oldPressed != this.pressed; } @Override diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java index 05ce2a2..f7f5ac6 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java @@ -9,9 +9,8 @@ package me.lambdaurora.lambdacontrols.client.mixin; -import me.lambdaurora.lambdacontrols.ControlsMode; +import me.lambdaurora.lambdacontrols.LambdaControlsFeature; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import me.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay; import net.minecraft.block.BlockState; import net.minecraft.block.FluidBlock; import net.minecraft.client.MinecraftClient; @@ -19,7 +18,6 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.client.render.GameRenderer; -import net.minecraft.client.util.Window; import net.minecraft.client.world.ClientWorld; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; @@ -42,16 +40,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(MinecraftClient.class) public abstract class MinecraftClientMixin { - @Final - @Shadow - private Window window; - - @Shadow - public boolean skipGameRender; - - @Shadow - public Screen currentScreen; - @Shadow @Nullable public HitResult crosshairTarget; @@ -73,64 +61,49 @@ public abstract class MinecraftClientMixin public GameRenderer gameRenderer; @Inject(method = "", at = @At("RETURN")) - private void lambdacontrols_on_init(CallbackInfo ci) + private void lambdacontrols_onInit(CallbackInfo ci) { - LambdaControlsClient.get().on_mc_init((MinecraftClient) (Object) this); + LambdaControlsClient.get().onMcInit((MinecraftClient) (Object) this); } @Inject(method = "render", at = @At("HEAD")) - private void lambdacontrols_on_render(boolean full_render, CallbackInfo ci) + private void lambdacontrols_onRender(boolean fullRender, CallbackInfo ci) { - LambdaControlsClient.get().on_render((MinecraftClient) (Object) (this)); + LambdaControlsClient.get().onRender((MinecraftClient) (Object) (this)); } - @Inject(method = "tick", at = @At("HEAD")) - private void lambdacontrols_on_handle_input_events(CallbackInfo ci) + @Inject(method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At("RETURN")) + private void lambdacontrols_onLeave(@Nullable Screen screen, CallbackInfo ci) { - LambdaControlsClient.get().on_tick((MinecraftClient) (Object) this); - } - - @Inject(method = "openScreen", at = @At("RETURN")) - private void lambdacontrols_on_open_screen(@Nullable Screen screen, CallbackInfo ci) - { - LambdaControlsClient mod = LambdaControlsClient.get(); - if (screen == null && mod.config.get_controls_mode() == ControlsMode.TOUCHSCREEN) { - screen = new TouchscreenOverlay(mod); - screen.init(((MinecraftClient) (Object) this), this.window.getScaledWidth(), this.window.getScaledHeight()); - this.skipGameRender = false; - this.currentScreen = screen; - } else if (screen != null) { - mod.input.on_screen_open(((MinecraftClient) (Object) this), this.window.getWidth(), this.window.getHeight()); - } + LambdaControlsClient.get().onLeave(); } @Inject(method = "doItemUse()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"), locals = LocalCapture.CAPTURE_FAILEXCEPTION, cancellable = true) - private void lambdacontrols_on_item_use(CallbackInfo ci, Hand[] hands, int hand_count, int hand_index, Hand hand, ItemStack stack_in_hand) + private void lambdacontrols_onItemUse(CallbackInfo ci, Hand[] hands, int handCount, int handIndex, Hand hand, ItemStack stackInHand) { - LambdaControlsClient mod = LambdaControlsClient.get(); - if (!stack_in_hand.isEmpty() && this.player.pitch > 35.0F && mod.config.has_front_block_placing()) { + if (!stackInHand.isEmpty() && this.player.pitch > 35.0F && LambdaControlsFeature.FRONT_BLOCK_PLACING.isAvailable()) { if (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.MISS && this.player.onGround) { - if (!stack_in_hand.isEmpty() && stack_in_hand.getItem() instanceof BlockItem) { - BlockPos player_pos = this.player.getBlockPos().down(); - BlockPos target_pos = new BlockPos(this.crosshairTarget.getPos()).subtract(player_pos); - BlockPos vector = new BlockPos(MathHelper.clamp(target_pos.getX(), -1, 1), 0, MathHelper.clamp(target_pos.getZ(), -1, 1)); - BlockPos block_pos = player_pos.add(vector); + if (!stackInHand.isEmpty() && stackInHand.getItem() instanceof BlockItem) { + BlockPos playerPos = this.player.getBlockPos().down(); + BlockPos targetPos = new BlockPos(this.crosshairTarget.getPos()).subtract(playerPos); + BlockPos vector = new BlockPos(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1)); + BlockPos blockPos = playerPos.add(vector); Direction direction = player.getHorizontalFacing(); - BlockState adjacent_block_state = this.world.getBlockState(block_pos.offset(direction.getOpposite())); - if (adjacent_block_state.isAir() || adjacent_block_state.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) { + BlockState adjacentBlockState = this.world.getBlockState(blockPos.offset(direction.getOpposite())); + if (adjacentBlockState.isAir() || adjacentBlockState.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) { return; } - BlockHitResult hit_result = new BlockHitResult(this.crosshairTarget.getPos(), direction.getOpposite(), block_pos, false); + BlockHitResult hitResult = new BlockHitResult(this.crosshairTarget.getPos(), direction.getOpposite(), blockPos, false); - int previous_stack_count = stack_in_hand.getCount(); - ActionResult result = this.interactionManager.interactBlock(this.player, this.world, hand, hit_result); + int previousStackCount = stackInHand.getCount(); + ActionResult result = this.interactionManager.interactBlock(this.player, this.world, hand, hitResult); if (result.isAccepted()) { if (result.shouldSwingHand()) { this.player.swingHand(hand); - if (!stack_in_hand.isEmpty() && (stack_in_hand.getCount() != previous_stack_count || this.interactionManager.hasCreativeInventory())) { + if (!stackInHand.isEmpty() && (stackInHand.getCount() != previousStackCount || this.interactionManager.hasCreativeInventory())) { this.gameRenderer.firstPersonRenderer.resetEquipProgress(hand); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MouseMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MouseMixin.java index 43f58d7..3d0abfd 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MouseMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MouseMixin.java @@ -32,14 +32,14 @@ public abstract class MouseMixin implements MouseAccessor protected abstract void onMouseButton(long window, int button, int action, int mods); @Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true) - private void on_mouse_locked(CallbackInfo ci) + private void lambdacontrols_onMouseLocked(CallbackInfo ci) { - if (LambdaControlsClient.get().config.get_controls_mode() == ControlsMode.TOUCHSCREEN) + if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.TOUCHSCREEN) ci.cancel(); } @Override - public void lambdacontrols_on_cursor_pos(long window, double x, double y) + public void lambdacontrols_onCursorPos(long window, double x, double y) { this.onCursorPos(window, x, y); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/SettingsScreenMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/SettingsScreenMixin.java index a05df75..a1927a0 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/SettingsScreenMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/SettingsScreenMixin.java @@ -11,7 +11,7 @@ package me.lambdaurora.lambdacontrols.client.mixin; import me.lambdaurora.lambdacontrols.ControlsMode; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsControlsScreen; +import me.lambdaurora.lambdacontrols.client.gui.ControllerControlsScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.SettingsScreen; import net.minecraft.client.gui.widget.AbstractButtonWidget; @@ -33,11 +33,11 @@ public class SettingsScreenMixin extends Screen } @Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SettingsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 7)) - private AbstractButtonWidget on_init(SettingsScreen screen, AbstractButtonWidget btn) + private AbstractButtonWidget lambdacontrols_onInit(SettingsScreen screen, AbstractButtonWidget btn) { - if (LambdaControlsClient.get().config.get_controls_mode() == ControlsMode.CONTROLLER) { - return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).lambdacontrols_get_height(), btn.getMessage(), - b -> this.minecraft.openScreen(new LambdaControlsControlsScreen(this, false)))); + if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) { + return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).lambdacontrols_getHeight(), btn.getMessage(), + b -> this.minecraft.openScreen(new ControllerControlsScreen(this, false)))); } else { return this.addButton(btn); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/AbstractContainerScreenAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/ContainerScreenAccessor.java similarity index 81% rename from fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/AbstractContainerScreenAccessor.java rename to fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/ContainerScreenAccessor.java index b3d3dd0..355a3cb 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/AbstractContainerScreenAccessor.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/ContainerScreenAccessor.java @@ -14,21 +14,21 @@ import net.minecraft.container.Slot; /** * Represents an accessor to AbstractContainerScreen. */ -public interface AbstractContainerScreenAccessor +public interface ContainerScreenAccessor { /** * Gets the left coordinate of the GUI. * * @return The left coordinate of the GUI. */ - int lambdacontrols_get_x(); + int lambdacontrols_getX(); /** * Gets the top coordinate of the GUI. * * @return The top coordinate of the GUI. */ - int lambdacontrols_get_y(); + int lambdacontrols_getY(); /** * Gets the slot at position. @@ -37,5 +37,5 @@ public interface AbstractContainerScreenAccessor * @param pos_y The Y position to check. * @return The slot at the specified position. */ - Slot lambdacontrols_get_slot_at(double pos_x, double pos_y); + Slot lambdacontrols_getSlotAt(double pos_x, double pos_y); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java index 25ebf41..4ceb58f 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java @@ -9,21 +9,16 @@ package me.lambdaurora.lambdacontrols.client.util; -import net.minecraft.client.util.InputUtil; -import org.jetbrains.annotations.NotNull; - /** * Represents a Minecraft keybinding with extra access. */ public interface KeyBindingAccessor { - @NotNull InputUtil.KeyCode get_key_code(); - boolean lambdacontrols_press(); boolean lambdacontrols_unpress(); - default boolean handle_press_state(boolean pressed) + default boolean lambdacontrols_handlePressState(boolean pressed) { if (pressed) return this.lambdacontrols_press(); diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/MouseAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/MouseAccessor.java index ca91fee..38414f8 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/MouseAccessor.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/util/MouseAccessor.java @@ -14,5 +14,5 @@ package me.lambdaurora.lambdacontrols.client.util; */ public interface MouseAccessor { - void lambdacontrols_on_cursor_pos(long window, double x, double y); + void lambdacontrols_onCursorPos(long window, double x, double y); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeCallback.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeCallback.java index 31e4306..02cb75e 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeCallback.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeCallback.java @@ -25,11 +25,11 @@ import org.jetbrains.annotations.NotNull; @FunctionalInterface public interface PlayerChangeControlsModeCallback { - Event EVENT = EventFactory.createArrayBacked(PlayerChangeControlsModeCallback.class, listeners -> (player, controls_mode) -> { + Event EVENT = EventFactory.createArrayBacked(PlayerChangeControlsModeCallback.class, listeners -> (player, controlsMode) -> { for (PlayerChangeControlsModeCallback event : listeners) { - event.apply(player, controls_mode); + event.apply(player, controlsMode); } }); - void apply(@NotNull PlayerEntity player, @NotNull ControlsMode controls_mode); + void apply(@NotNull PlayerEntity player, @NotNull ControlsMode controlsMode); } diff --git a/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json b/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json index 05cea50..aef6a71 100644 --- a/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json +++ b/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json @@ -80,6 +80,7 @@ "lambdacontrols.menu.controls_mode": "Mode", "lambdacontrols.menu.dead_zone": "Dead Zone", "lambdacontrols.menu.fly_drifting": "Fly Drifting", + "lambdacontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting", "lambdacontrols.menu.front_block_placing": "Front Block Placing", "lambdacontrols.menu.hud_enable": "Enable HUD", "lambdacontrols.menu.hud_side": "HUD Side", @@ -105,6 +106,7 @@ "lambdacontrols.tooltip.controls_mode": "The controls mode.", "lambdacontrols.tooltip.dead_zone": "The dead zone for the controller's analogue sticks.", "lambdacontrols.tooltip.fly_drifting": "While flying, enables drifting/inertia.", + "lambdacontrols.tooltip.fly_drifting_vertical": "While flying, enables vertical drifting/intertia.", "lambdacontrols.tooltip.front_block_placing": "Enables front block placing, §cmight be considered cheating on some servers§r.", "lambdacontrols.tooltip.hud_enable": "Toggles the on-screen controller button indicator.", "lambdacontrols.tooltip.hud_side": "The position of the HUD.", diff --git a/fabric/src/main/resources/assets/lambdacontrols/lang/fr_ca.json b/fabric/src/main/resources/assets/lambdacontrols/lang/fr_ca.json index f21e0b2..6aa04c4 100644 --- a/fabric/src/main/resources/assets/lambdacontrols/lang/fr_ca.json +++ b/fabric/src/main/resources/assets/lambdacontrols/lang/fr_ca.json @@ -80,6 +80,7 @@ "lambdacontrols.menu.controls_mode": "Mode", "lambdacontrols.menu.dead_zone": "Zone morte", "lambdacontrols.menu.fly_drifting": "Inertie de vol", + "lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol", "lambdacontrols.menu.front_block_placing": "Placement avant de bloc", "lambdacontrols.menu.hud_enable": "Activer le HUD", "lambdacontrols.menu.hud_side": "Côté du HUD", @@ -105,6 +106,7 @@ "lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.", "lambdacontrols.tooltip.dead_zone": "Zone morte des axes de la manette.", "lambdacontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement.", + "lambdacontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical.", "lambdacontrols.tooltip.front_block_placing": "Active le placement avant de blocs, §cpeut être considérer comme de la trice sur certains serveurs§r.", "lambdacontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.", "lambdacontrols.tooltip.hud_side": "Change la position du HUD.", diff --git a/fabric/src/main/resources/assets/lambdacontrols/lang/fr_fr.json b/fabric/src/main/resources/assets/lambdacontrols/lang/fr_fr.json index f21e0b2..6aa04c4 100644 --- a/fabric/src/main/resources/assets/lambdacontrols/lang/fr_fr.json +++ b/fabric/src/main/resources/assets/lambdacontrols/lang/fr_fr.json @@ -80,6 +80,7 @@ "lambdacontrols.menu.controls_mode": "Mode", "lambdacontrols.menu.dead_zone": "Zone morte", "lambdacontrols.menu.fly_drifting": "Inertie de vol", + "lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol", "lambdacontrols.menu.front_block_placing": "Placement avant de bloc", "lambdacontrols.menu.hud_enable": "Activer le HUD", "lambdacontrols.menu.hud_side": "Côté du HUD", @@ -105,6 +106,7 @@ "lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.", "lambdacontrols.tooltip.dead_zone": "Zone morte des axes de la manette.", "lambdacontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement.", + "lambdacontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical.", "lambdacontrols.tooltip.front_block_placing": "Active le placement avant de blocs, §cpeut être considérer comme de la trice sur certains serveurs§r.", "lambdacontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.", "lambdacontrols.tooltip.hud_side": "Change la position du HUD.", diff --git a/fabric/src/main/resources/config.toml b/fabric/src/main/resources/config.toml index 686ab3b..7e68c75 100644 --- a/fabric/src/main/resources/config.toml +++ b/fabric/src/main/resources/config.toml @@ -15,8 +15,12 @@ auto_switch_mode = false [gameplay] # Enables front block placing like in Bedrock Edition. front_block_placing = false - # Enables fly drifting. - fly_drifting = false + # Fly behaviors + [gameplay.fly] + # Enables fly drifting. + drifting = false + # Enables vertical fly drifting. + vertical_drifting = true # Controller settings [controller] @@ -58,20 +62,36 @@ auto_switch_mode = false inventory = "3" # Jump control. jump = "0" + # Left movement control. + left = "200" # Pause game control. pause_game = "7" # Pick block control. pick_block = "14" # Show player list control. player_list = "6" + # Right movement control. + right = "100" # Take screenshot control. screenshot = "11+0" + # Down slot control. + slot_down = "13" + # Left slot control. + slot_left = "14" + # Right slot control. + slot_right = "12" + # Up slot control. + slot_up = "11" # Sneak control. sneak = "10" # Sprint control. sprint = "9" # Swap hands control. swap_hands = "2" + # Switch to left tab control. + tab_left = "4" + # Switch to right tab control. + tab_right = "5" # Toggle perspective control. toggle_perspective = "11+3" # Toggle smooth camera control. diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 4bee1c5..4a5d8ea 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "fabricloader": ">=0.4.0", "fabric": "*", "minecraft": "1.15.x", - "spruceui": ">=1.1.0" + "spruceui": ">=1.3.4" }, "recommends": { "modmenu": ">=1.8.0+build.16", diff --git a/fabric/src/main/resources/lambdacontrols.mixins.json b/fabric/src/main/resources/lambdacontrols.mixins.json index 737ff01..d2eb164 100644 --- a/fabric/src/main/resources/lambdacontrols.mixins.json +++ b/fabric/src/main/resources/lambdacontrols.mixins.json @@ -4,8 +4,10 @@ "compatibilityLevel": "JAVA_8", "client": [ "AbstractButtonWidgetAccessor", - "AbstractContainerScreenMixin", + "AdvancementsScreenAccessor", + "ContainerScreenMixin", "ClientPlayerEntityMixin", + "ClientPlayNetworkHandlerMixin", "ControlsOptionsScreenMixin", "CreativeInventoryScreenAccessor", "EntryListWidgetAccessor", diff --git a/gradle.properties b/gradle.properties index ecb0ef7..af1f1d8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use - minecraft_version=1.15.1 - yarn_mappings=1.15.1+build.37:v2 - loader_version=0.7.3+build.176 + minecraft_version=1.15.2 + yarn_mappings=1.15.2+build.9:v2 + loader_version=0.7.6+build.180 # Mod Properties - mod_version = 1.1.0-test9 + mod_version = 1.1.0 maven_group = me.lambdaurora archives_base_name = lambdacontrols # 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.4.27+build.286-1.15 - spruceui_version=1.1.0 + fabric_version=0.4.29+build.290-1.15 + spruceui_version=1.3.4 diff --git a/settings.gradle b/settings.gradle index fb1505d..136fc93 100644 --- a/settings.gradle +++ b/settings.gradle @@ -10,4 +10,4 @@ pluginManagement { } rootProject.name = 'lambdacontrols' -include 'core', 'fabric', 'elytra' +include 'core', 'fabric', 'spigot' diff --git a/spigot/build.gradle b/spigot/build.gradle new file mode 100644 index 0000000..ea9a61e --- /dev/null +++ b/spigot/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'java-library' +} + +archivesBaseName = project.archives_base_name + "-spigot" + +repositories { + maven { url = 'https://hub.spigotmc.org/nexus/content/groups/public/' } + maven { url = 'https://libraries.minecraft.net/' } +} + +configurations { + include +} + +dependencies { + api project(":core") + include(project(":core")) { + exclude group: 'com.google.code.gson' + exclude group: 'com.google.guava' + } + api 'org.spigotmc:spigot-api:1.15.1-R0.1-SNAPSHOT' + api 'io.netty:netty-all:4.1.28.Final' +} + +processResources { + inputs.property "version", project.version + + from(sourceSets.main.resources.srcDirs) { + include "plugin.yml" + + expand 'version': project.version.toString().replace("#", "") + } +} + +jar { + from '../LICENSE' + + dependsOn configurations.include + from { + (configurations.include).collect { + it.isDirectory() ? it : zipTree(it) + } + } +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} diff --git a/spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java b/spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java new file mode 100644 index 0000000..128b482 --- /dev/null +++ b/spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols; + +import com.electronwill.nightconfig.core.file.FileConfig; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +/** + * Represents the LambdaControls Spigot configuration. + */ +public class LambdaControlsConfig +{ + private static final boolean DEFAULT_FRONT_BLOCK_PLACING = true; + + protected final FileConfig config = FileConfig.builder("config/lambdacontrols.toml").concurrent().defaultResource("/server_config.toml").build(); + private final LambdaControlsSpigot plugin; + + public LambdaControlsConfig(@NotNull LambdaControlsSpigot plugin) + { + this.plugin = plugin; + } + + public void load() + { + File configDir = new File("config/"); + if (!configDir.exists()) + configDir.mkdirs(); + this.config.load(); + this.plugin.log("Configuration loaded."); + LambdaControlsFeature.FRONT_BLOCK_PLACING.setAllowed(this.config.getOrElse("gameplay.front_block_placing", DEFAULT_FRONT_BLOCK_PLACING)); + } +} diff --git a/spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsSpigot.java b/spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsSpigot.java new file mode 100644 index 0000000..39712b1 --- /dev/null +++ b/spigot/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsSpigot.java @@ -0,0 +1,148 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols; + +import io.netty.buffer.Unpooled; +import me.lambdaurora.lambdacontrols.event.PlayerChangeControlsModeEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import static me.lambdaurora.lambdacontrols.LambdaControlsConstants.*; + +/** + * Represents the LambdaControls spigot plugin which provides extra features for servers. + * + * @author LambdAurora + * @version 1.1.0 + * @since 1.1.0 + */ +public class LambdaControlsSpigot extends JavaPlugin implements PluginMessageListener, Listener +{ + private static final Map PLAYERS_CONTROLS_MODE = new HashMap<>(); + public final LambdaControlsConfig config = new LambdaControlsConfig(this); + + @Override + public void onEnable() + { + super.onEnable(); + + this.config.load(); + + // Note that Spigot has a bullshit channel size restriction as Minecraft SUPPORTS UP TO 32767 AS CHANNEL SIZE. + // Please stop using that bad server software, move over Sponge or idk other things. REALLY. + this.getServer().getMessenger().registerIncomingPluginChannel(this, CONTROLS_MODE_CHANNEL.toString(), this); + this.getServer().getMessenger().registerOutgoingPluginChannel(this, CONTROLS_MODE_CHANNEL.toString()); + this.getServer().getMessenger().registerOutgoingPluginChannel(this, FEATURE_CHANNEL.toString()); + this.getServer().getMessenger().registerIncomingPluginChannel(this, HELLO_CHANNEL.toString(), this); + this.getServer().getPluginManager().registerEvents(this, this); + + this.getServer().getOnlinePlayers().forEach(player -> { + PLAYERS_CONTROLS_MODE.put(player, ControlsMode.DEFAULT); + + this.requestPlayerControlsMode(player); + this.updatePlayerFeature(player, LambdaControlsFeature.FRONT_BLOCK_PLACING); + }); + } + + @Override + public void onDisable() + { + super.onDisable(); + + this.getServer().getMessenger().unregisterIncomingPluginChannel(this, CONTROLS_MODE_CHANNEL.toString()); + this.getServer().getMessenger().unregisterOutgoingPluginChannel(this, CONTROLS_MODE_CHANNEL.toString()); + this.getServer().getMessenger().unregisterOutgoingPluginChannel(this, FEATURE_CHANNEL.toString()); + this.getServer().getMessenger().unregisterIncomingPluginChannel(this, HELLO_CHANNEL.toString()); + + PLAYERS_CONTROLS_MODE.clear(); + } + + public void requestPlayerControlsMode(@NotNull Player player) + { + player.sendPluginMessage(this, CONTROLS_MODE_CHANNEL.toString(), new byte[0]); + } + + public void updatePlayerFeature(@NotNull Player player, @NotNull LambdaControlsFeature feature) + { + Objects.requireNonNull(player); + Objects.requireNonNull(feature); + + player.sendPluginMessage(this, FEATURE_CHANNEL.toString(), this.makeFeatureMessage(feature)); + } + + /** + * Prints a message to the terminal. + * + * @param info The message to print. + */ + public void log(String info) + { + this.getLogger().info(info); + } + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) + { + if (channel.equals(HELLO_CHANNEL.toString())) { + NettyPacketBuffer buffer = new NettyPacketBuffer(Unpooled.copiedBuffer(message)); + String version = buffer.readString(16); + ControlsMode.byId(buffer.readString(32)).ifPresent(controlsMode -> { + PLAYERS_CONTROLS_MODE.put(player, controlsMode); + PlayerChangeControlsModeEvent event = new PlayerChangeControlsModeEvent(player, controlsMode); + this.getServer().getPluginManager().callEvent(event); + }); + this.updatePlayerFeature(player, LambdaControlsFeature.FRONT_BLOCK_PLACING); + } else if (channel.equals(CONTROLS_MODE_CHANNEL.toString())) { + NettyPacketBuffer buffer = new NettyPacketBuffer(Unpooled.copiedBuffer(message)); + ControlsMode.byId(buffer.readString(32)).ifPresent(controlsMode -> { + PLAYERS_CONTROLS_MODE.put(player, controlsMode); + PlayerChangeControlsModeEvent event = new PlayerChangeControlsModeEvent(player, controlsMode); + this.getServer().getPluginManager().callEvent(event); + }); + } + } + + /** + * Returns a packet byte buffer made for the lambdacontrols:feature plugin message. + * + * @param feature The feature data to send. + * @return The packet byte buffer. + */ + public byte[] makeFeatureMessage(@NotNull LambdaControlsFeature feature) + { + Objects.requireNonNull(feature, "Feature cannot be null."); + NettyPacketBuffer buffer = new NettyPacketBuffer(Unpooled.buffer()); + buffer.writeString(feature.getName()); + buffer.writeBoolean(feature.isAllowed()); + return buffer.array(); + } + + @EventHandler + public void onPlayerJoin(@NotNull PlayerJoinEvent event) + { + PLAYERS_CONTROLS_MODE.put(event.getPlayer(), ControlsMode.DEFAULT); + } + + @EventHandler + public void onPlayerLeave(@NotNull PlayerQuitEvent event) + { + PLAYERS_CONTROLS_MODE.remove(event.getPlayer()); + } +} diff --git a/spigot/src/main/java/me/lambdaurora/lambdacontrols/NettyPacketBuffer.java b/spigot/src/main/java/me/lambdaurora/lambdacontrols/NettyPacketBuffer.java new file mode 100644 index 0000000..412d09c --- /dev/null +++ b/spigot/src/main/java/me/lambdaurora/lambdacontrols/NettyPacketBuffer.java @@ -0,0 +1,102 @@ +package me.lambdaurora.lambdacontrols; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.DecoderException; +import io.netty.handler.codec.EncoderException; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +public class NettyPacketBuffer extends PacketBuffer +{ + public NettyPacketBuffer(ByteBuf byteBuf) + { + super(byteBuf); + } + + @Override + public int readVarint() + { + int var1 = 0; + int var2 = 0; + byte var3; + + do { + var3 = this.readByte(); + var1 |= (var3 & 127) << var2++ * 7; + + if (var2 > 5) + throw new RuntimeException("VarInt too big"); + } while ((var3 & 128) == 128); + + return var1; + } + + @Override + public void writeVarint(int input) + { + while ((input & -128) != 0) { + this.writeByte(input & 127 | 128); + input >>>= 7; + } + + this.writeByte(input); + } + + @Override + public String readString(int maxLength) + { + int var2 = this.readVarint(); + + if (var2 > maxLength * 4) + throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + var2 + " > " + maxLength * 4 + ")"); + else if (var2 < 0) + throw new DecoderException("The received encoded string buffer length is less than zero! Weird string!"); + else { + String var3 = this.readCharSequence(var2, StandardCharsets.UTF_8).toString(); + + if (var3.length() > maxLength) + throw new DecoderException("The received string length is longer than maximum allowed (" + var2 + " > " + maxLength + ")"); + else + return var3; + } + } + + @Override + public void writeString(String string) + { + byte[] var2 = string.getBytes(Charset.forName("UTF-8")); + + if (var2.length > 32767) { + throw new EncoderException("String too big (was " + string.length() + " data encoded, max " + 32767 + ")"); + } else { + this.writeVarint(var2.length); + this.writeCharSequence(string, StandardCharsets.UTF_8); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + NettyPacketBuffer buffer = (NettyPacketBuffer) o; + + return byteBuf.equals(buffer.byteBuf); + } + + @Override + public int compareTo(ByteBuf buffer) + { + return this.byteBuf.compareTo(buffer); + } + + @Override + public String toString() + { + return this.byteBuf.toString(); + } +} diff --git a/spigot/src/main/java/me/lambdaurora/lambdacontrols/PacketBuffer.java b/spigot/src/main/java/me/lambdaurora/lambdacontrols/PacketBuffer.java new file mode 100644 index 0000000..66fd110 --- /dev/null +++ b/spigot/src/main/java/me/lambdaurora/lambdacontrols/PacketBuffer.java @@ -0,0 +1,1153 @@ +/* + * Copyright © 2019 LambdAurora + * + * This file is part of mcelytra. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.util.ByteProcessor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; +import java.util.UUID; + +/** + * Represents a packet buffer. + */ +public abstract class PacketBuffer extends ByteBuf +{ + protected ByteBuf byteBuf; + + public PacketBuffer(ByteBuf byteBuf) + { + this.byteBuf = byteBuf; + } + + public abstract int readVarint(); + + public abstract void writeVarint(int value); + + public abstract String readString(int maxLength); + + public abstract void writeString(String value); + + @Override + public int refCnt() + { + return this.byteBuf.refCnt(); + } + + @Override + public boolean release() + { + return this.byteBuf.release(); + } + + @Override + public boolean release(int decrement) + { + return this.byteBuf.release(decrement); + } + + @Override + public int capacity() + { + return this.byteBuf.capacity(); + } + + @Override + public ByteBuf capacity(int newCapacity) + { + return this.byteBuf.capacity(newCapacity); + } + + @Override + public int maxCapacity() + { + return this.byteBuf.maxCapacity(); + } + + @Override + public ByteBufAllocator alloc() + { + return this.byteBuf.alloc(); + } + + @Override + public ByteOrder order() + { + return this.byteBuf.order(); + } + + @Override + public ByteBuf order(ByteOrder endianness) + { + return this.byteBuf.order(endianness); + } + + @Override + public ByteBuf unwrap() + { + return this.byteBuf.unwrap(); + } + + @Override + public boolean isDirect() + { + return this.byteBuf.isDirect(); + } + + @Override + public boolean isReadOnly() + { + return this.byteBuf.isReadOnly(); + } + + @Override + public ByteBuf asReadOnly() + { + return this.byteBuf.asReadOnly(); + } + + @Override + public int readerIndex() + { + return this.byteBuf.readerIndex(); + } + + @Override + public ByteBuf readerIndex(int readerIndex) + { + return this.byteBuf.readerIndex(readerIndex); + } + + @Override + public int writerIndex() + { + return this.byteBuf.writerIndex(); + } + + @Override + public ByteBuf writerIndex(int writerIndex) + { + return this.byteBuf.writerIndex(writerIndex); + } + + @Override + public ByteBuf setIndex(int readerIndex, int writerIndex) + { + return this.byteBuf.setIndex(readerIndex, writerIndex); + } + + @Override + public int readableBytes() + { + return this.byteBuf.readableBytes(); + } + + @Override + public int writableBytes() + { + return this.byteBuf.writableBytes(); + } + + @Override + public int maxWritableBytes() + { + return this.byteBuf.maxWritableBytes(); + } + + @Override + public boolean isReadable() + { + return this.byteBuf.isReadable(); + } + + @Override + public boolean isReadable(int size) + { + return this.byteBuf.isReadable(size); + } + + @Override + public boolean isWritable() + { + return this.byteBuf.isWritable(); + } + + @Override + public boolean isWritable(int size) + { + return this.byteBuf.isWritable(size); + } + + @Override + public ByteBuf clear() + { + return this.byteBuf.clear(); + } + + @Override + public ByteBuf markReaderIndex() + { + return this.byteBuf.markReaderIndex(); + } + + @Override + public ByteBuf resetReaderIndex() + { + return this.byteBuf.resetReaderIndex(); + } + + @Override + public ByteBuf markWriterIndex() + { + return this.byteBuf.markWriterIndex(); + } + + @Override + public ByteBuf resetWriterIndex() + { + return this.byteBuf.resetWriterIndex(); + } + + @Override + public ByteBuf discardReadBytes() + { + return this.byteBuf.discardReadBytes(); + } + + @Override + public ByteBuf discardSomeReadBytes() + { + return this.byteBuf.discardSomeReadBytes(); + } + + @Override + public ByteBuf ensureWritable(int minWritableBytes) + { + return this.byteBuf.ensureWritable(minWritableBytes); + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) + { + return this.byteBuf.ensureWritable(minWritableBytes, force); + } + + @Override + public boolean getBoolean(int index) + { + return this.byteBuf.getBoolean(index); + } + + @Override + public byte getByte(int index) + { + return this.byteBuf.getByte(index); + } + + @Override + public short getUnsignedByte(int index) + { + return this.byteBuf.getUnsignedByte(index); + } + + @Override + public short getShort(int index) + { + return this.byteBuf.getShort(index); + } + + @Override + public short getShortLE(int index) + { + return this.byteBuf.getShortLE(index); + } + + @Override + public int getUnsignedShort(int index) + { + return this.byteBuf.getUnsignedShort(index); + } + + @Override + public int getUnsignedShortLE(int index) + { + return this.byteBuf.getUnsignedShortLE(index); + } + + @Override + public int getMedium(int index) + { + return this.byteBuf.getMedium(index); + } + + @Override + public int getMediumLE(int index) + { + return this.byteBuf.getMediumLE(index); + } + + @Override + public int getUnsignedMedium(int index) + { + return this.byteBuf.getUnsignedMedium(index); + } + + @Override + public int getUnsignedMediumLE(int index) + { + return this.byteBuf.getUnsignedMediumLE(index); + } + + @Override + public int getInt(int index) + { + return this.byteBuf.getInt(index); + } + + @Override + public int getIntLE(int index) + { + return this.byteBuf.getIntLE(index); + } + + @Override + public long getUnsignedInt(int index) + { + return this.byteBuf.getUnsignedInt(index); + } + + @Override + public long getUnsignedIntLE(int index) + { + return this.byteBuf.getUnsignedIntLE(index); + } + + @Override + public long getLong(int index) + { + return this.byteBuf.getLong(index); + } + + @Override + public long getLongLE(int index) + { + return this.byteBuf.getLongLE(index); + } + + @Override + public char getChar(int index) + { + return this.byteBuf.getChar(index); + } + + @Override + public float getFloat(int index) + { + return this.byteBuf.getFloat(index); + } + + @Override + public double getDouble(int index) + { + return this.byteBuf.getDouble(index); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst) + { + return this.byteBuf.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int length) + { + return this.byteBuf.getBytes(index, dst, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) + { + return this.byteBuf.getBytes(index, dst, dstIndex, length); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst) + { + return this.byteBuf.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) + { + return this.byteBuf.getBytes(index, dst, dstIndex, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) + { + return this.byteBuf.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException + { + return this.byteBuf.getBytes(index, out, length); + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException + { + return this.byteBuf.getBytes(index, out, length); + } + + @Override + public int getBytes(int index, FileChannel out, long position, int length) throws IOException + { + return this.byteBuf.getBytes(index, out, position, length); + } + + @Override + public CharSequence getCharSequence(int index, int length, Charset charset) + { + return this.byteBuf.getCharSequence(index, length, charset); + } + + @Override + public ByteBuf setBoolean(int index, boolean value) + { + return this.byteBuf.setBoolean(index, value); + } + + @Override + public ByteBuf setByte(int index, int value) + { + return this.byteBuf.setByte(index, value); + } + + @Override + public ByteBuf setShort(int index, int value) + { + return this.byteBuf.setShort(index, value); + } + + @Override + public ByteBuf setShortLE(int index, int value) + { + return this.byteBuf.setShortLE(index, value); + } + + @Override + public ByteBuf setMedium(int index, int value) + { + return this.byteBuf.setMedium(index, value); + } + + @Override + public ByteBuf setMediumLE(int index, int value) + { + return this.byteBuf.setMediumLE(index, value); + } + + @Override + public ByteBuf setInt(int index, int value) + { + return this.byteBuf.setInt(index, value); + } + + @Override + public ByteBuf setIntLE(int index, int value) + { + return this.byteBuf.setIntLE(index, value); + } + + @Override + public ByteBuf setLong(int index, long value) + { + return this.byteBuf.setLong(index, value); + } + + @Override + public ByteBuf setLongLE(int index, long value) + { + return this.byteBuf.setLongLE(index, value); + } + + @Override + public ByteBuf setChar(int index, int value) + { + return this.byteBuf.setChar(index, value); + } + + @Override + public ByteBuf setFloat(int index, float value) + { + return this.byteBuf.setFloat(index, value); + } + + @Override + public ByteBuf setDouble(int index, double value) + { + return this.byteBuf.setDouble(index, value); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src) + { + return this.byteBuf.setBytes(index, src); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int length) + { + return this.byteBuf.setBytes(index, src, length); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) + { + return this.byteBuf.setBytes(index, src, srcIndex, length); + } + + @Override + public ByteBuf setBytes(int index, byte[] src) + { + return this.byteBuf.setBytes(index, src); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) + { + return this.byteBuf.setBytes(index, src, srcIndex, length); + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) + { + return this.byteBuf.setBytes(index, src); + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException + { + return this.byteBuf.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException + { + return this.byteBuf.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, FileChannel in, long position, int length) throws IOException + { + return this.byteBuf.setBytes(index, in, position, length); + } + + @Override + public ByteBuf setZero(int index, int length) + { + return this.byteBuf.setZero(index, length); + } + + @Override + public int setCharSequence(int index, CharSequence sequence, Charset charset) + { + return this.byteBuf.setCharSequence(index, sequence, charset); + } + + @Override + public boolean readBoolean() + { + return this.byteBuf.readBoolean(); + } + + @Override + public byte readByte() + { + return this.byteBuf.readByte(); + } + + @Override + public short readUnsignedByte() + { + return this.byteBuf.readUnsignedByte(); + } + + @Override + public short readShort() + { + return this.byteBuf.readShort(); + } + + @Override + public short readShortLE() + { + return this.byteBuf.readShortLE(); + } + + @Override + public int readUnsignedShort() + { + return this.byteBuf.readUnsignedShort(); + } + + @Override + public int readUnsignedShortLE() + { + return this.byteBuf.readUnsignedShortLE(); + } + + @Override + public int readMedium() + { + return this.byteBuf.readMedium(); + } + + @Override + public int readMediumLE() + { + return this.byteBuf.readMediumLE(); + } + + @Override + public int readUnsignedMedium() + { + return this.byteBuf.readUnsignedMedium(); + } + + @Override + public int readUnsignedMediumLE() + { + return this.byteBuf.readUnsignedMediumLE(); + } + + @Override + public int readInt() + { + return this.byteBuf.readInt(); + } + + @Override + public int readIntLE() + { + return this.byteBuf.readIntLE(); + } + + @Override + public long readUnsignedInt() + { + return this.byteBuf.readUnsignedInt(); + } + + @Override + public long readUnsignedIntLE() + { + return this.byteBuf.readUnsignedIntLE(); + } + + @Override + public long readLong() + { + return this.byteBuf.readLong(); + } + + @Override + public long readLongLE() + { + return this.byteBuf.readLongLE(); + } + + @Override + public char readChar() + { + return this.byteBuf.readChar(); + } + + @Override + public float readFloat() + { + return this.byteBuf.readFloat(); + } + + @Override + public double readDouble() + { + return this.byteBuf.readDouble(); + } + + @Override + public ByteBuf readBytes(int length) + { + return this.byteBuf.readBytes(length); + } + + @Override + public ByteBuf readSlice(int length) + { + return this.byteBuf.readSlice(length); + } + + @Override + public ByteBuf readRetainedSlice(int length) + { + return this.byteBuf.readRetainedSlice(length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst) + { + return this.byteBuf.readBytes(dst); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int length) + { + return this.byteBuf.readBytes(dst, length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) + { + return this.byteBuf.readBytes(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(byte[] dst) + { + return this.byteBuf.readBytes(dst); + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) + { + return this.byteBuf.readBytes(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) + { + return this.byteBuf.readBytes(dst); + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException + { + return this.byteBuf.readBytes(out, length); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException + { + return this.byteBuf.readBytes(out, length); + } + + @Override + public CharSequence readCharSequence(int length, Charset charset) + { + return this.byteBuf.readCharSequence(length, charset); + } + + @Override + public int readBytes(FileChannel out, long position, int length) throws IOException + { + return this.byteBuf.readBytes(out, position, length); + } + + @Override + public ByteBuf skipBytes(int length) + { + return this.byteBuf.skipBytes(length); + } + + @Override + public ByteBuf writeBoolean(boolean value) + { + return this.byteBuf.writeBoolean(value); + } + + @Override + public ByteBuf writeByte(int value) + { + return this.byteBuf.writeByte(value); + } + + @Override + public ByteBuf writeShort(int value) + { + return this.byteBuf.writeShort(value); + } + + @Override + public ByteBuf writeShortLE(int value) + { + return this.byteBuf.writeShortLE(value); + } + + @Override + public ByteBuf writeMedium(int value) + { + return this.byteBuf.writeMedium(value); + } + + @Override + public ByteBuf writeMediumLE(int value) + { + return this.byteBuf.writeMediumLE(value); + } + + @Override + public ByteBuf writeInt(int value) + { + return this.byteBuf.writeInt(value); + } + + @Override + public ByteBuf writeIntLE(int value) + { + return this.byteBuf.writeIntLE(value); + } + + @Override + public ByteBuf writeLong(long value) + { + return this.byteBuf.writeLong(value); + } + + @Override + public ByteBuf writeLongLE(long value) + { + return this.byteBuf.writeLongLE(value); + } + + @Override + public ByteBuf writeChar(int value) + { + return this.byteBuf.writeChar(value); + } + + @Override + public ByteBuf writeFloat(float value) + { + return this.byteBuf.writeFloat(value); + } + + @Override + public ByteBuf writeDouble(double value) + { + return this.byteBuf.writeDouble(value); + } + + @Override + public ByteBuf writeBytes(ByteBuf src) + { + return this.byteBuf.writeBytes(src); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int length) + { + return this.byteBuf.writeBytes(src, length); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) + { + return this.byteBuf.writeBytes(src, srcIndex, length); + } + + @Override + public ByteBuf writeBytes(byte[] src) + { + return this.byteBuf.writeBytes(src); + } + + @Override + public ByteBuf writeBytes(byte[] src, int srcIndex, int length) + { + return this.byteBuf.writeBytes(src, srcIndex, length); + } + + @Override + public ByteBuf writeBytes(ByteBuffer src) + { + return this.byteBuf.writeBytes(src); + } + + @Override + public int writeBytes(InputStream in, int length) throws IOException + { + return this.byteBuf.writeBytes(in, length); + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException + { + return this.byteBuf.writeBytes(in, length); + } + + @Override + public int writeBytes(FileChannel in, long position, int length) throws IOException + { + return this.byteBuf.writeBytes(in, position, length); + } + + @Override + public ByteBuf writeZero(int length) + { + return this.byteBuf.writeZero(length); + } + + @Override + public int writeCharSequence(CharSequence sequence, Charset charset) + { + return this.byteBuf.writeCharSequence(sequence, charset); + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) + { + return this.byteBuf.indexOf(fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) + { + return this.byteBuf.bytesBefore(value); + } + + @Override + public int bytesBefore(int length, byte value) + { + return this.byteBuf.bytesBefore(length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) + { + return this.byteBuf.bytesBefore(index, length, value); + } + + @Override + public int forEachByte(ByteProcessor processor) + { + return this.byteBuf.forEachByte(processor); + } + + @Override + public int forEachByte(int index, int length, ByteProcessor processor) + { + return this.byteBuf.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(ByteProcessor processor) + { + return this.byteBuf.forEachByteDesc(processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteProcessor processor) + { + return this.byteBuf.forEachByteDesc(index, length, processor); + } + + @Override + public ByteBuf copy() + { + return this.byteBuf.copy(); + } + + @Override + public ByteBuf copy(int index, int length) + { + return this.byteBuf.copy(index, length); + } + + @Override + public ByteBuf slice() + { + return this.byteBuf.slice(); + } + + @Override + public ByteBuf retainedSlice() + { + return this.byteBuf.retainedSlice(); + } + + @Override + public ByteBuf slice(int index, int length) + { + return this.byteBuf.slice(index, length); + } + + @Override + public ByteBuf retainedSlice(int index, int length) + { + return this.byteBuf.retainedSlice(); + } + + @Override + public ByteBuf duplicate() + { + return this.byteBuf.duplicate(); + } + + @Override + public ByteBuf retainedDuplicate() + { + return this.byteBuf.retainedDuplicate(); + } + + @Override + public int nioBufferCount() + { + return this.byteBuf.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer() + { + return this.byteBuf.nioBuffer(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) + { + return this.byteBuf.nioBuffer(index, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) + { + return this.byteBuf.internalNioBuffer(index, length); + } + + @Override + public ByteBuffer[] nioBuffers() + { + return this.byteBuf.nioBuffers(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) + { + return this.byteBuf.nioBuffers(index, length); + } + + @Override + public boolean hasArray() + { + return this.byteBuf.hasArray(); + } + + @Override + public byte[] array() + { + return this.byteBuf.array(); + } + + @Override + public int arrayOffset() + { + return this.byteBuf.arrayOffset(); + } + + @Override + public boolean hasMemoryAddress() + { + return this.byteBuf.hasMemoryAddress(); + } + + @Override + public long memoryAddress() + { + return this.byteBuf.memoryAddress(); + } + + @Override + public String toString(Charset charset) + { + return this.byteBuf.toString(charset); + } + + @Override + public String toString(int index, int length, Charset charset) + { + return this.byteBuf.toString(index, length, charset); + } + + @Override + public int hashCode() + { + return this.byteBuf.hashCode(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + PacketBuffer buffer = (PacketBuffer) o; + + return byteBuf.equals(buffer.byteBuf); + } + + @Override + public int compareTo(ByteBuf buffer) + { + return this.byteBuf.compareTo(buffer); + } + + @Override + public String toString() + { + return this.byteBuf.toString(); + } + + @Override + public ByteBuf retain(int increment) + { + return this.byteBuf.retain(increment); + } + + @Override + public ByteBuf retain() + { + return this.byteBuf.retain(); + } + + @Override + public ByteBuf touch() + { + return this.byteBuf.touch(); + } + + @Override + public ByteBuf touch(Object hint) + { + return this.byteBuf.touch(hint); + } +} diff --git a/spigot/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeEvent.java b/spigot/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeEvent.java new file mode 100644 index 0000000..a17fb44 --- /dev/null +++ b/spigot/src/main/java/me/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeEvent.java @@ -0,0 +1,65 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols.event; + +import me.lambdaurora.lambdacontrols.ControlsMode; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +/** + * Represents an event which is fired when a player change their controls mode. + * + * @author LambdAurora + * @version 1.1.0 + * @since 1.1.0 + */ +public class PlayerChangeControlsModeEvent extends PlayerEvent +{ + private static final HandlerList HANDLERS = new HandlerList(); + private final ControlsMode controlsMode; + + public PlayerChangeControlsModeEvent(@NotNull Player who, @NotNull ControlsMode controlsMode) + { + super(who); + this.controlsMode = controlsMode; + } + + /** + * Returns the controls mode of the player. + * + * @return The player's controls mode. + */ + public ControlsMode getControlsMode() + { + return this.controlsMode; + } + + @Override + public String toString() + { + return "PlayerChangeControlsModeEvent{" + + "player=" + this.player + + ", controls_mode=" + this.controlsMode + + '}'; + } + + @Override + public @NotNull HandlerList getHandlers() + { + return HANDLERS; + } + + public static @NotNull HandlerList getHandlerList() + { + return HANDLERS; + } +} diff --git a/spigot/src/main/resources/plugin.yml b/spigot/src/main/resources/plugin.yml new file mode 100644 index 0000000..92327cb --- /dev/null +++ b/spigot/src/main/resources/plugin.yml @@ -0,0 +1,6 @@ +name: LambdaControls +version: ${version} +description: A quick Spigot plugin for LambdaControls which allow server admins to disable some features. + +main: me.lambdaurora.lambdacontrols.LambdaControlsSpigot +api-version: 1.13 diff --git a/spigot/src/main/resources/server_config.toml b/spigot/src/main/resources/server_config.toml new file mode 100644 index 0000000..a5e6e93 --- /dev/null +++ b/spigot/src/main/resources/server_config.toml @@ -0,0 +1,6 @@ +# LambdaControls server configuration. + +# Gameplay settings +[gameplay] + # Allows front block placing like in Bedrock Edition. + front_block_placing = true