From 5fcf4c2b1bf91c4cfc406e1deb8603ae94c990ea Mon Sep 17 00:00:00 2001 From: Motschen Date: Sat, 12 Mar 2022 22:33:19 +0100 Subject: [PATCH] MidnightControls 0.1.0 (Beta) Changes from LambdaControls: - Support for Steam Deck and Dualsense - Support for L4, L5, R4, R5 buttons - Updated Libraries - New Logo and Name - Lots of Bugfixes - MidnightConfig backend --- .github/workflows/gradlepublish.yml | 2 +- CHANGELOG.md | 42 +- CONTRIBUTING.md | 18 +- HEADER | 2 +- README.md | 8 +- build.gradle | 65 +- controller.svg | 303 +++++++ gradle.properties | 19 +- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 269 +++--- icon.png | Bin 7987 -> 67940 bytes settings.gradle | 2 +- .../client/LambdaControlsConfig.java | 836 ------------------ .../client/gui/TouchscreenOverlay.java | 282 ------ .../mixin/ControlsOptionsScreenMixin.java | 58 -- .../client/mixin/HandledScreenMixin.java | 67 -- .../client/mixin/OptionsScreenMixin.java | 53 -- .../client/util/KeyBindingAccessor.java | 26 - .../midnightcontrols}/ControlsMode.java | 8 +- .../midnightcontrols/MidnightControls.java} | 44 +- .../MidnightControlsConstants.java} | 13 +- .../MidnightControlsFeature.java} | 27 +- .../midnightcontrols}/client/ButtonState.java | 4 +- .../client/ControllerType.java | 22 +- .../midnightcontrols}/client/HudSide.java | 6 +- .../client/MidnightControlsClient.java} | 120 +-- .../client/MidnightControlsConfig.java | 259 ++++++ .../client/MidnightControlsModMenu.java} | 12 +- .../client/MidnightInput.java} | 158 ++-- .../client/MidnightReacharound.java} | 16 +- .../client/VirtualMouseSkin.java | 6 +- .../client/compat/CompatHandler.java | 8 +- .../client/compat/EmotecraftCompat.java | 51 ++ .../client/compat/HQMCompat.java | 8 +- .../compat/MidnightControlsCompat.java} | 18 +- .../compat/MidnightControlsMixinPlugin.java} | 18 +- .../client/compat/OkZoomerCompat.java | 10 +- .../client/compat/ReiCompat.java | 24 +- .../compat/mixin/EntryListWidgetAccessor.java | 4 +- .../compat/mixin/EntryWidgetAccessor.java | 6 +- .../mixin/RecipeViewingScreenAccessor.java | 4 +- .../VillagerRecipeViewingScreenAccessor.java | 6 +- .../client/controller/ButtonBinding.java | 89 +- .../client/controller/ButtonCategory.java | 4 +- .../client/controller/Controller.java | 23 +- .../client/controller/InputHandlers.java | 27 +- .../client/controller/InputManager.java | 30 +- .../client/controller/MovementHandler.java | 11 +- .../client/controller/PressAction.java | 10 +- .../client/gui/MappingsStringInputWidget.java | 18 +- .../client/gui/MidnightControlsHud.java} | 93 +- .../client/gui/MidnightControlsRenderer.java} | 46 +- .../gui/MidnightControlsSettingsScreen.java} | 232 +++-- .../gui/ReloadControllerMappingsOption.java | 14 +- .../client/gui/RingScreen.java | 18 +- .../client/gui/TouchscreenOverlay.java | 301 +++++++ .../gui/widget/ControllerButtonWidget.java | 10 +- .../gui/widget/ControllerControlsWidget.java | 25 +- .../client/gui/widget/ControlsListWidget.java | 23 +- .../mixin/AdvancementsScreenAccessor.java | 4 +- .../client/mixin/ClickableWidgetAccessor.java | 4 +- .../client/mixin/ClientPlayerEntityMixin.java | 25 +- .../mixin/ControlsOptionsScreenMixin.java | 42 + .../CreativeInventoryScreenAccessor.java | 10 +- .../client/mixin/EntryListWidgetAccessor.java | 6 +- .../client/mixin/GameOptionsMixin.java | 4 +- .../client/mixin/GameRendererMixin.java | 13 +- .../client/mixin/HandledScreenMixin.java | 70 ++ .../client/mixin/KeyBindingMixin.java | 10 +- .../client/mixin/MinecraftClientMixin.java | 48 +- .../client/mixin/MouseMixin.java | 30 +- .../mixin/RecipeBookWidgetAccessor.java | 6 +- .../client/mixin/WorldRendererMixin.java | 15 +- .../client/ring/DummyRingAction.java | 4 +- .../client/ring/KeyBindingRingAction.java | 10 +- .../client/ring/MidnightRing.java} | 37 +- .../client/ring/RingAction.java | 6 +- .../client/ring/RingButtonMode.java | 6 +- .../client/ring/RingPage.java | 8 +- .../client/util/HandledScreenAccessor.java | 10 +- .../client/util/KeyBindingAccessor.java | 26 + .../client/util/MouseAccessor.java | 6 +- .../PlayerChangeControlsModeCallback.java | 6 +- .../resources/assets/lambdacontrols/icon.png | Bin 1082 -> 0 bytes .../assets/lambdacontrols/icon_x400.png | Bin 4917 -> 0 bytes .../assets/lambdacontrols/lang/en_us.json | 150 ---- .../assets/lambdacontrols/lang/es_mx.json | 150 ---- .../assets/lambdacontrols/lang/fr_ca.json | 150 ---- .../assets/lambdacontrols/lang/fr_fr.json | 150 ---- .../assets/lambdacontrols/lang/tr_tr.json | 135 --- .../assets/lambdacontrols/lang/zh_cn.json | 150 ---- .../textures/gui/controller_axis.png | Bin 1688 -> 0 bytes .../textures/gui/controller_buttons.png | Bin 3508 -> 0 bytes .../lambdacontrols/textures/gui/widgets.png | Bin 4345 -> 0 bytes .../assets/midnightcontrols/icon.png | Bin 0 -> 4811 bytes .../assets/midnightcontrols/lang/en_us.json | 157 ++++ .../assets/midnightcontrols/lang/es_mx.json | 150 ++++ .../assets/midnightcontrols/lang/fr_ca.json | 150 ++++ .../assets/midnightcontrols/lang/fr_fr.json | 150 ++++ .../assets/midnightcontrols/lang/tr_tr.json | 135 +++ .../assets/midnightcontrols/lang/zh_cn.json | 150 ++++ .../textures/gui/controller_axis.png | Bin 0 -> 14130 bytes .../textures/gui/controller_buttons.png | Bin 0 -> 25958 bytes .../textures/gui/controller_expanded.png | Bin 0 -> 13171 bytes .../textures/gui/cursor.png | Bin .../midnightcontrols/textures/gui/widgets.png | Bin 0 -> 12410 bytes src/main/resources/config.toml | 119 --- src/main/resources/fabric.mod.json | 34 +- .../lambdacontrols_compat.mixins.json | 11 - ...widener => midnightcontrols.accesswidener} | 0 ...xins.json => midnightcontrols.mixins.json} | 3 +- .../midnightcontrols_compat.mixins.json | 11 + 113 files changed, 2934 insertions(+), 3307 deletions(-) create mode 100644 controller.svg delete mode 100644 src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java delete mode 100644 src/main/java/dev/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java delete mode 100644 src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java delete mode 100644 src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/HandledScreenMixin.java delete mode 100644 src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java delete mode 100644 src/main/java/dev/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/ControlsMode.java (87%) rename src/main/java/{dev/lambdaurora/lambdacontrols/LambdaControls.java => eu/midnightdust/midnightcontrols/MidnightControls.java} (73%) rename src/main/java/{dev/lambdaurora/lambdacontrols/LambdaControlsConstants.java => eu/midnightdust/midnightcontrols/MidnightControlsConstants.java} (64%) rename src/main/java/{dev/lambdaurora/lambdacontrols/LambdaControlsFeature.java => eu/midnightdust/midnightcontrols/MidnightControlsFeature.java} (70%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/ButtonState.java (90%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/ControllerType.java (76%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/HudSide.java (92%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/LambdaControlsClient.java => eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java} (56%) create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java rename src/main/java/{dev/lambdaurora/lambdacontrols/client/LambdaControlsModMenu.java => eu/midnightdust/midnightcontrols/client/MidnightControlsModMenu.java} (52%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/LambdaInput.java => eu/midnightdust/midnightcontrols/client/MidnightInput.java} (81%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/LambdaReacharound.java => eu/midnightdust/midnightcontrols/client/MidnightReacharound.java} (92%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/VirtualMouseSkin.java (92%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/CompatHandler.java (93%) create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/HQMCompat.java (80%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java => eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java} (89%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsMixinPlugin.java => eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java} (73%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/OkZoomerCompat.java (86%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/ReiCompat.java (94%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/mixin/EntryListWidgetAccessor.java (81%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/mixin/EntryWidgetAccessor.java (71%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/mixin/RecipeViewingScreenAccessor.java (85%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/compat/mixin/VillagerRecipeViewingScreenAccessor.java (89%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/controller/ButtonBinding.java (90%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/controller/ButtonCategory.java (96%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/controller/Controller.java (85%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/controller/InputHandlers.java (92%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/controller/InputManager.java (92%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/controller/MovementHandler.java (89%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/controller/PressAction.java (76%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/gui/MappingsStringInputWidget.java (82%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java => eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java} (63%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsRenderer.java => eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java} (82%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java => eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java} (57%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/gui/ReloadControllerMappingsOption.java (69%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/gui/RingScreen.java (66%) create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/gui/widget/ControllerButtonWidget.java (82%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/gui/widget/ControllerControlsWidget.java (71%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/gui/widget/ControlsListWidget.java (92%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/AdvancementsScreenAccessor.java (90%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/ClickableWidgetAccessor.java (81%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/ClientPlayerEntityMixin.java (75%) create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/CreativeInventoryScreenAccessor.java (82%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/EntryListWidgetAccessor.java (69%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/GameOptionsMixin.java (89%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/GameRendererMixin.java (63%) create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/mixin/HandledScreenMixin.java rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/KeyBindingMixin.java (75%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/MinecraftClientMixin.java (72%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/MouseMixin.java (54%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/RecipeBookWidgetAccessor.java (83%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/mixin/WorldRendererMixin.java (86%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/ring/DummyRingAction.java (90%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/ring/KeyBindingRingAction.java (84%) rename src/main/java/{dev/lambdaurora/lambdacontrols/client/ring/LambdaRing.java => eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java} (65%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/ring/RingAction.java (90%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/ring/RingButtonMode.java (90%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/ring/RingPage.java (90%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/util/HandledScreenAccessor.java (73%) create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/util/KeyBindingAccessor.java rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/client/util/MouseAccessor.java (58%) rename src/main/java/{dev/lambdaurora/lambdacontrols => eu/midnightdust/midnightcontrols}/event/PlayerChangeControlsModeCallback.java (86%) delete mode 100644 src/main/resources/assets/lambdacontrols/icon.png delete mode 100644 src/main/resources/assets/lambdacontrols/icon_x400.png delete mode 100644 src/main/resources/assets/lambdacontrols/lang/en_us.json delete mode 100644 src/main/resources/assets/lambdacontrols/lang/es_mx.json delete mode 100644 src/main/resources/assets/lambdacontrols/lang/fr_ca.json delete mode 100644 src/main/resources/assets/lambdacontrols/lang/fr_fr.json delete mode 100644 src/main/resources/assets/lambdacontrols/lang/tr_tr.json delete mode 100644 src/main/resources/assets/lambdacontrols/lang/zh_cn.json delete mode 100644 src/main/resources/assets/lambdacontrols/textures/gui/controller_axis.png delete mode 100644 src/main/resources/assets/lambdacontrols/textures/gui/controller_buttons.png delete mode 100644 src/main/resources/assets/lambdacontrols/textures/gui/widgets.png create mode 100644 src/main/resources/assets/midnightcontrols/icon.png create mode 100644 src/main/resources/assets/midnightcontrols/lang/en_us.json create mode 100644 src/main/resources/assets/midnightcontrols/lang/es_mx.json create mode 100644 src/main/resources/assets/midnightcontrols/lang/fr_ca.json create mode 100644 src/main/resources/assets/midnightcontrols/lang/fr_fr.json create mode 100644 src/main/resources/assets/midnightcontrols/lang/tr_tr.json create mode 100644 src/main/resources/assets/midnightcontrols/lang/zh_cn.json create mode 100644 src/main/resources/assets/midnightcontrols/textures/gui/controller_axis.png create mode 100644 src/main/resources/assets/midnightcontrols/textures/gui/controller_buttons.png create mode 100644 src/main/resources/assets/midnightcontrols/textures/gui/controller_expanded.png rename src/main/resources/assets/{lambdacontrols => midnightcontrols}/textures/gui/cursor.png (100%) create mode 100644 src/main/resources/assets/midnightcontrols/textures/gui/widgets.png delete mode 100644 src/main/resources/config.toml delete mode 100644 src/main/resources/lambdacontrols_compat.mixins.json rename src/main/resources/{lambdacontrols.accesswidener => midnightcontrols.accesswidener} (100%) rename src/main/resources/{lambdacontrols.mixins.json => midnightcontrols.mixins.json} (85%) create mode 100644 src/main/resources/midnightcontrols_compat.mixins.json diff --git a/.github/workflows/gradlepublish.yml b/.github/workflows/gradlepublish.yml index 43c04ee..f8c8fbf 100755 --- a/.github/workflows/gradlepublish.yml +++ b/.github/workflows/gradlepublish.yml @@ -35,6 +35,6 @@ jobs: REPO_NAME: ${{ github.repository }} USERNAME: ${{ github.actor }} TOKEN: ${{ secrets.GITHUB_TOKEN }} - LAMBDACONTROLS_MAVEN: ${{ secrets.MAVEN_URL }} + midnightcontrols_MAVEN: ${{ secrets.MAVEN_URL }} MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 34ad803..f8e53b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,11 +14,11 @@ ### 1.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)) +- Fixed tutorial toast to look around not affected by camera movement done with a controller. ([#2](https://github.com/LambdAurora/midnightcontrols/issues/2)) ### 1.0.2 (Unofficial) -This update was never pushed but was aiming to fix [#4](https://github.com/LambdAurora/LambdaControls/issues/4). +This update was never pushed but was aiming to fix [#4](https://github.com/LambdAurora/midnightcontrols/issues/4). - Fixed the toggle sneak button binding. - Fixed broken chat arrow keys. @@ -26,17 +26,17 @@ This update was never pushed but was aiming to fix [#4](https://github.com/Lambd ## 1.1.0 - Chording update -This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAurora/LambdaControls/issues/9)). +This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAurora/midnightcontrols/issues/9)). - Rewrote everything (almost). -- Added [networking](https://github.com/LambdAurora/LambdaControls/wiki/LambdaControls-Networking) for some features. +- Added [networking](https://github.com/LambdAurora/midnightcontrols/wiki/midnightcontrols-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 hover messages ([#5](https://github.com/LambdAurora/midnightcontrols/issues/5)). +- Added hotbar button bindings ([#7](https://github.com/LambdAurora/midnightcontrols/issues/7)). +- Added front block placing feature ([#8](https://github.com/LambdAurora/midnightcontrols/issues/8)). +- Added no creative fly drifting ([#8](https://github.com/LambdAurora/midnightcontrols/issues/8)). - Added option to enable controller focus. - Added [OkZoomer](https://github.com/joaoh1/OkZoomer) compatibility. - Added D-pad movements in inventories. @@ -50,10 +50,10 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur ## 1.2.0-1.3.0 -- Improved rotation algorithm ([#11](https://github.com/LambdAurora/LambdaControls/issues/11)). +- Improved rotation algorithm ([#11](https://github.com/LambdAurora/midnightcontrols/issues/11)). - Added virtual mouse. - Added outline on front block placing. -- Added fast block placement ([#8](https://github.com/LambdAurora/LambdaControls/issues/8)). +- Added fast block placement ([#8](https://github.com/LambdAurora/midnightcontrols/issues/8)). - Added [REI](https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items) compatibility. - Improved HUD. - Added recipe book control. @@ -62,7 +62,7 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur ### 1.3.1 -- Fixed broken inventory interactions ([#13](https://github.com/LambdAurora/LambdaControls/issues/13)) +- Fixed broken inventory interactions ([#13](https://github.com/LambdAurora/midnightcontrols/issues/13)) - Fixed virtual mouse preventing continuous attack (thus making breaking blocks impossible). - Added support for [ModUpdater](https://gitea.thebrokenrail.com/TheBrokenRail/ModUpdater) hopefully. - Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to 1.5.2. @@ -76,7 +76,7 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur ## 1.4.0 - - Added analog movements ([#10](https://github.com/LambdAurora/LambdaControls/issues/10)). + - Added analog movements ([#10](https://github.com/LambdAurora/midnightcontrols/issues/10)). - Improved Ok Zoomer compability. - Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to 1.5.8 to ensure 1.16.2 compability. - Internal changes: @@ -84,7 +84,7 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur - Replace lot of strings with Texts. - Improved block outline rendering injection. - Shadow library jars instead of Jar-in-Jar. - - Fixed crash in inventory ([#16](https://github.com/LambdAurora/LambdaControls/issues/16)) + - Fixed crash in inventory ([#16](https://github.com/LambdAurora/midnightcontrols/issues/16)) - WIP: - Started to work on action ring. - Will allow for better compability with other mods. @@ -97,8 +97,8 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur ## 1.5.0 - Added mappings string editor screen. - - Added Simplified Chinese translations ([#18](https://github.com/LambdAurora/LambdaControls/pull/18)). - - Added Mexican Spanish translations ([#22](https://github.com/LambdAurora/LambdaControls/pull/22)). + - Added Simplified Chinese translations ([#18](https://github.com/LambdAurora/midnightcontrols/pull/18)). + - Added Mexican Spanish translations ([#22](https://github.com/LambdAurora/midnightcontrols/pull/22)). - Added Xbox 360 button skin and overhauled Xbox button skin. - Added debug option. - Respect toggle setting in Accessibility screen. @@ -114,17 +114,17 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur ## 1.6.0 - Reworked entirely the settings screen. -- Added independent stick dead zones. ([#32](https://github.com/LambdAurora/LambdaControls/issues/32)) -- Added max values range. ([#41](https://github.com/LambdAurora/LambdaControls/issues/41)) -- Updated [SpruceUI] and fix related crashes due to incompatible versions ([#40](https://github.com/LambdAurora/LambdaControls/issues/40), [#48](https://github.com/LambdAurora/LambdaControls/issues/48)). -- Fix boat control issues ([#37](https://github.com/LambdAurora/LambdaControls/issues/37)). -- Fix incompatibilities with mods using night-config. Now shadowing properly night-config. ([#33](https://github.com/LambdAurora/LambdaControls/issues/33), [#39](https://github.com/LambdAurora/LambdaControls/issues/39)) +- Added independent stick dead zones. ([#32](https://github.com/LambdAurora/midnightcontrols/issues/32)) +- Added max values range. ([#41](https://github.com/LambdAurora/midnightcontrols/issues/41)) +- Updated [SpruceUI] and fix related crashes due to incompatible versions ([#40](https://github.com/LambdAurora/midnightcontrols/issues/40), [#48](https://github.com/LambdAurora/midnightcontrols/issues/48)). +- Fix boat control issues ([#37](https://github.com/LambdAurora/midnightcontrols/issues/37)). +- Fix incompatibilities with mods using night-config. Now shadowing properly night-config. ([#33](https://github.com/LambdAurora/midnightcontrols/issues/33), [#39](https://github.com/LambdAurora/midnightcontrols/issues/39)) ## 1.7.0 - Updated to 1.17. - Small improvements to the codebase thanks to Java 16. -- Fix controller bindings not being saved ([#31](https://github.com/LambdAurora/LambdaControls/issues/31), [#55](https://github.com/LambdAurora/LambdaControls/issues/55)). +- Fix controller bindings not being saved ([#31](https://github.com/LambdAurora/midnightcontrols/issues/31), [#55](https://github.com/LambdAurora/midnightcontrols/issues/55)). - Dropped entirely Touchscreen Input Mode. - Dropped Roughly Enough Items compatibility. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e8d124..e756e0e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,8 @@ -# Contributing to LambdaControls +# Contributing to midnightcontrols :tada: First of all, thanks for taking time to contribute! :tada: -The following is a set of guidelines for contributing to LambdaControls. +The following is a set of guidelines for contributing to midnightcontrols. Feel free to propose changes to this document in a pull request. **Table of Contents** @@ -17,7 +17,7 @@ Feel free to propose changes to this document in a pull request. ## Code of Conduct -This project and everyone participating in it is governed by the [Code of Conduct](https://github.com/LambdAurora/LambdaControls/blob/master/CODE_OF_CONDUCT.md). +This project and everyone participating in it is governed by the [Code of Conduct](https://github.com/LambdAurora/midnightcontrols/blob/master/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior at [aurora42lambda@gmail.com](mailto:aurora42lambda@gmail.com). ## What should I know before I get started? @@ -28,7 +28,7 @@ By participating, you are expected to uphold this code. Please report unacceptab ### Java 16 -Java is the main language used to make LambdaControls alive. +Java is the main language used to make midnightcontrols alive. Knowing how to code in Java is necessary if you contribute to the code. ### Minecraft @@ -45,7 +45,7 @@ As it is a Minecraft mod you should know a bit how Minecraft works and how moddi ### Git -Git is the control version software we use for LambdaControls, please know how to use it if you consider contributing to the code. +Git is the control version software we use for midnightcontrols, please know how to use it if you consider contributing to the code. Git commits should be signed. @@ -60,16 +60,16 @@ Git commits should be signed. #### How do I submit a bug report? -Go in the issues tab in GitHub and read the [bug report guide](https://github.com/LambdAurora/LambdaControls/blob/1.17/.github/ISSUE_TEMPLATE/bug_report.md) +Go in the issues tab in GitHub and read the [bug report guide](https://github.com/LambdAurora/midnightcontrols/blob/1.17/.github/ISSUE_TEMPLATE/bug_report.md) ### Suggesting enhancements -Enhancement suggestions are tracked as [GitHub issues](https://github.com/LambdAurora/LambdaControls/issues). -Check out the [feature request](https://github.com/LambdAurora/LambdaControls/blob/1.17/.github/ISSUE_TEMPLATE/feature_request.md) guide. +Enhancement suggestions are tracked as [GitHub issues](https://github.com/LambdAurora/midnightcontrols/issues). +Check out the [feature request](https://github.com/LambdAurora/midnightcontrols/blob/1.17/.github/ISSUE_TEMPLATE/feature_request.md) guide. ### Do pull requests -You can help LambdaControls by writing code and submit it with pull requests. +You can help midnightcontrols by writing code and submit it with pull requests. Pull requests will be accepted if they follow the [styleguide](#styleguides), if they are useful, etc... We can refuse a pull request if the commits are not signed, so don't forget to [sign them](https://help.github.com/en/articles/signing-commits)! diff --git a/HEADER b/HEADER index c53862a..bc9a89b 100644 --- a/HEADER +++ b/HEADER @@ -1,6 +1,6 @@ Copyright © 2021 LambdAurora -This file is part of LambdaControls. +This file is part of midnightcontrols. Licensed under the MIT license. For more information, see the LICENSE file. \ No newline at end of file diff --git a/README.md b/README.md index a0713fe..4a358be 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# LambdaControls +# midnightcontrols ![Java 16](https://img.shields.io/badge/language-Java%2016-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) +[![GitHub license](https://img.shields.io/github/license/LambdAurora/midnightcontrols?style=flat-square)](https://raw.githubusercontent.com/LambdAurora/midnightcontrols/master/LICENSE) ![Environment: Client](https://img.shields.io/badge/environment-client-1976d2?style=flat-square) [![Mod loader: Fabric]][fabric] -![Version](https://img.shields.io/github/v/tag/LambdAurora/LambdaControls?label=version&style=flat-square) -[![CurseForge](http://cf.way2muchnoise.eu/title/354231.svg)](https://www.curseforge.com/minecraft/mc-mods/lambdacontrols) +![Version](https://img.shields.io/github/v/tag/LambdAurora/midnightcontrols?label=version&style=flat-square) +[![CurseForge](http://cf.way2muchnoise.eu/title/354231.svg)](https://www.curseforge.com/minecraft/mc-mods/midnightcontrols) A Fabric Minecraft mod which adds better controls, reach-around and controller support. diff --git a/build.gradle b/build.gradle index ffad70e..a00dd9f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.9.+' + id 'fabric-loom' version '0.11-SNAPSHOT' id 'java-library' id 'maven-publish' id 'com.github.johnrengelman.shadow' version '7.0.0' @@ -26,7 +26,7 @@ version = "${project.mod_version}+${getMCVersionString()}" archivesBaseName = project.archives_base_name // This field defines the Java version your mod target. -def targetJavaVersion = 16 +def targetJavaVersion = 17 boolean isMCVersionNonRelease() { return project.minecraft_version.matches('^\\d\\dw\\d\\d[a-z]$') @@ -65,13 +65,10 @@ String parseReadme() { def readme = (String) file('README.md').text readme = readme.replaceAll(excludeRegex, '') - readme = readme.replaceAll(linkRegex, '![$1](https://raw.githubusercontent.com/LambdAurora/LambdaControls/1.17/$2)') + readme = readme.replaceAll(linkRegex, '![$1](https://raw.githubusercontent.com/LambdAurora/midnightcontrols/1.17/$2)') return readme } -minecraft { - accessWidener file('src/main/resources/lambdacontrols.accesswidener') -} repositories { mavenLocal() @@ -93,8 +90,10 @@ repositories { includeGroup 'com.terraformersmc' } } + maven { url 'https://maven.kosmx.dev' } maven { url 'https://maven.shedaniel.me/' } maven { url 'https://jitpack.io' } + maven { url "https://api.modrinth.com/maven" } } configurations { @@ -113,6 +112,11 @@ dependencies { modImplementation "dev.lambdaurora:spruceui:${project.spruceui_version}" include "dev.lambdaurora:spruceui:${project.spruceui_version}" + api('org.aperlambda:lambdajcommon:1.8.1') { + exclude group: 'com.google.code.gson' + exclude group: 'com.google.guava' + } + include 'org.aperlambda:lambdajcommon:1.8.1' modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}" @@ -121,10 +125,18 @@ dependencies { exclude group: 'com.terraformersmc' exclude group: 'dev.lambdaurora' } + modImplementation "maven.modrinth:emotecraft:${project.emotecraft_version}" + modImplementation "io.github.kosmx:bendy-lib:${project.bendylib_version}" + + modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}" + include "maven.modrinth:midnightlib:${project.midnightlib_version}" shadow 'com.electronwill.night-config:core:3.6.3' shadow 'com.electronwill.night-config:toml:3.6.3' } +loom { + accessWidenerPath = file("src/main/resources/midnightcontrols.accesswidener") +} java { sourceCompatibility = JavaVersion.toVersion(targetJavaVersion) @@ -158,29 +170,6 @@ license { include '**/*.java' } -shadowJar { - dependsOn jar - configurations = [project.configurations.shadow] - archiveClassifier.set('dev') - - exclude 'META-INF/maven/**' - exclude 'com/google/**' - exclude 'javax/**' - exclude 'org/**' - relocate 'com.electronwill.nightconfig', 'dev.lambdaurora.lambdacontrols.shadow.nightconfig' -} -remapJar.dependsOn(shadowJar) - -task shadowRemapJar(type: RemapJarTask) { - dependsOn shadowJar - - input.set(file("${project.buildDir}/libs/$archivesBaseName-$version-dev.jar")) - archiveFileName = "${archivesBaseName}-${version}.jar" - addNestedDependencies.set(true) - remapAccessWidener.set(true) -} -build.dependsOn(shadowRemapJar) - task publishModrinth(type: TaskModrinthUpload) { dependsOn(build) onlyIf { @@ -190,8 +179,7 @@ task publishModrinth(type: TaskModrinthUpload) { token = System.getenv('MODRINTH_TOKEN') projectId = project.modrinth_id versionNumber = version - versionName = "LambdaControls ${project.mod_version} (${getMCVersionString()})" - uploadFile = shadowRemapJar + versionName = "midnightcontrols ${project.mod_version} (${getMCVersionString()})" addGameVersion((String) project.minecraft_version) addLoader('fabric') versionType = isMCVersionNonRelease() ? VersionType.BETA : VersionType.RELEASE @@ -246,15 +234,12 @@ task publishModrinth(type: TaskModrinthUpload) { publishing { publications { mavenJava(MavenPublication) { - artifact(shadowRemapJar) { - builtBy shadowRemapJar - } artifact(sourcesJar) { builtBy remapSourcesJar } pom { - name = 'LambdaControls' + name = 'midnightcontrols' description = 'Adds better controls, and controller support.' } @@ -277,17 +262,17 @@ publishing { mavenLocal() maven { name 'GithubPackages' - url uri('https://maven.pkg.github.com/LambdAurora/LambdaControls') + url uri('https://maven.pkg.github.com/LambdAurora/midnightcontrols') credentials { username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") password = project.findProperty("gpr.key") ?: System.getenv("TOKEN") } } - def lambdacontrolsMaven = System.getenv('LAMBDACONTROLS_MAVEN') - if (lambdacontrolsMaven) { + def midnightcontrolsMaven = System.getenv('midnightcontrols_MAVEN') + if (midnightcontrolsMaven) { maven { - name 'LambdaControlsMaven' - url uri(lambdacontrolsMaven) + name 'midnightcontrolsMaven' + url uri(midnightcontrolsMaven) credentials { username = project.findProperty('gpr.user') ?: System.getenv('MAVEN_USERNAME') password = project.findProperty('gpr.key') ?: System.getenv('MAVEN_PASSWORD') diff --git a/controller.svg b/controller.svg new file mode 100644 index 0000000..65573a0 --- /dev/null +++ b/controller.svg @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle.properties b/gradle.properties index f4ee81d..b1e9276 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,18 +3,21 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use -minecraft_version=1.17 -yarn_mappings=1.17+build.13 -loader_version=0.11.6 +minecraft_version=1.18.1 +yarn_mappings=1.18.1+build.22 +loader_version=0.13.3 # Mod Properties -mod_version = 1.7.1 -maven_group = dev.lambdaurora -archives_base_name = lambdacontrols +mod_version = 0.1.0 +maven_group = eu.midnightdust +archives_base_name = midnightcontrols modrinth_id=W1D3UXEc # 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.36.0+1.17 -spruceui_version=3.2.0+1.17 +fabric_version=0.46.6+1.18 +spruceui_version=3.3.2+1.17 +midnightlib_version=0.4.0 modmenu_version=2.0.2 +emotecraft_version=2.1-MC1.18.1-fabric +bendylib_version=2.0.+ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 20926 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 i_W%EDg1>@4`_NK(#)z|gdCiK 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 69a9715..00e33ed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0..1b6c787 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/icon.png b/icon.png index 20da8ee3e124f59de9dfed745ee600f8b9bc475e..c3239502e0b48483bc0bce71eff0be704fefb237 100644 GIT binary patch literal 67940 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 L`9<>Q-< literal 7987 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 diff --git a/settings.gradle b/settings.gradle index 9a90a75..2602762 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,4 +8,4 @@ pluginManagement { } } -rootProject.name = 'lambdacontrols' +rootProject.name = 'midnightcontrols' diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java b/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java deleted file mode 100644 index cdd3786..0000000 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright © 2021 LambdAurora - * - * This file is part of LambdaControls. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package dev.lambdaurora.lambdacontrols.client; - -import com.electronwill.nightconfig.core.file.FileConfig; -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.LambdaControlsFeature; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.controller.Controller; -import dev.lambdaurora.lambdacontrols.client.controller.InputManager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.lwjgl.glfw.GLFW; - -import java.util.Arrays; -import java.util.Optional; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_X; -import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y; - -/** - * Represents LambdaControls configuration. - */ -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 boolean DEFAULT_DEBUG = false; - // HUD - private static final boolean DEFAULT_HUD_ENABLE = true; - private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT; - // Gameplay - private static final boolean DEFAULT_ANALOG_MOVEMENT = true; - private static final boolean DEFAULT_FAST_BLOCK_INTERACTION = true; - private static final boolean DEFAULT_FLY_DRIFTING = false; - private static final boolean DEFAULT_FLY_VERTICAL_DRIFTING = true; - private static final boolean DEFAULT_HORIZONTAL_REACHAROUND = false; - private static final boolean DEFAULT_VERTICAL_REACHAROUND = false; - private static final boolean DEFAULT_REACHAROUND_OUTLINE = true; - private static final int[] DEFAULT_REACHAROUND_OUTLINE_COLOR = new int[]{255, 255, 255, 102}; - // Controller - private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT; - private static final double DEFAULT_DEAD_ZONE = 0.25; - private static final double DEFAULT_MAX_VALUE = 1; - 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 boolean DEFAULT_VIRTUAL_MOUSE = false; - private static final VirtualMouseSkin DEFAULT_VIRTUAL_MOUSE_SKIN = VirtualMouseSkin.DEFAULT_LIGHT; - - 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 controlsMode; - private ControllerType controllerType; - // Gameplay. - private boolean analogMovement; - private boolean shouldRenderReacharoundOutline; - private int[] reacharoundOutlineColor; - // Controller settings - private double rightDeadZone; - private double leftDeadZone; - private double[] maxAnalogValues = new double[]{DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE}; - private double rotationSpeed; - private double mouseSpeed; - private boolean unfocusedInput; - private boolean virtualMouse; - private VirtualMouseSkin virtualMouseSkin; - // HUD settings. - private boolean hudEnable; - private HudSide hudSide; - - public LambdaControlsConfig(@NotNull LambdaControlsClient mod) { - this.mod = mod; - } - - /** - * Loads the configuration - */ - public void load() { - this.config.load(); - this.checkAndFix(); - this.mod.log("Configuration loaded."); - this.controlsMode = ControlsMode.byId(this.config.getOrElse("controls", DEFAULT_CONTROLS_MODE.getName())).orElse(DEFAULT_CONTROLS_MODE); - // HUD settings. - 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 - this.analogMovement = this.config.getOrElse("gameplay.analog_movement", DEFAULT_ANALOG_MOVEMENT); - LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(this.config.getOrElse("gameplay.fast_block_placing", DEFAULT_FAST_BLOCK_INTERACTION)); - LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(this.config.getOrElse("gameplay.reacharound.horizontal", DEFAULT_HORIZONTAL_REACHAROUND)); - LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(this.config.getOrElse("gameplay.reacharound.vertical", DEFAULT_VERTICAL_REACHAROUND)); - this.shouldRenderReacharoundOutline = this.config.getOrElse("gameplay.reacharound.outline", DEFAULT_REACHAROUND_OUTLINE); - this.reacharoundOutlineColor = this.config.getOptional("gameplay.reacharound.outline_color") - .map(hex -> parseColor((String) hex)) - .orElse(DEFAULT_REACHAROUND_OUTLINE_COLOR); - // Controller settings. - this.controllerType = ControllerType.byId(this.config.getOrElse("controller.type", DEFAULT_CONTROLLER_TYPE.getName())).orElse(DEFAULT_CONTROLLER_TYPE); - this.rightDeadZone = this.config.getOrElse("controller.right_dead_zone", DEFAULT_DEAD_ZONE); - this.leftDeadZone = this.config.getOrElse("controller.left_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); - this.virtualMouse = this.config.getOrElse("controller.virtual_mouse", DEFAULT_VIRTUAL_MOUSE); - this.virtualMouseSkin = VirtualMouseSkin.byId(this.config.getOrElse("controller.virtual_mouse_skin", DEFAULT_VIRTUAL_MOUSE_SKIN.getName())).orElse(DEFAULT_VIRTUAL_MOUSE_SKIN); - - for (int i = 0; i < this.maxAnalogValues.length; i++) { - this.maxAnalogValues[i] = this.config.getOrElse("controller.max_value_" + i, DEFAULT_MAX_VALUE); - } - // Controller controls. - InputManager.loadButtonBindings(this); - - this.mod.ring.load(this.config); - } - - /** - * Saves the configuration. - */ - public void save() { - this.config.set("controller.right_dead_zone", this.rightDeadZone); - this.config.set("controller.left_dead_zone", this.leftDeadZone); - 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.set("controller.virtual_mouse", this.virtualMouse); - - for (int i = 0; i < this.maxAnalogValues.length; i++) { - this.config.set("controller.max_value_" + i, this.maxAnalogValues[i]); - } - this.config.save(); - this.mod.log("Configuration saved."); - } - - public void checkAndFix() { - InputManager.streamBindings().forEach(binding -> { - var path = "controller.controls." + binding.getName(); - var raw = this.config.getRaw(path); - if (raw instanceof Number) { - this.mod.warn("Invalid data at \"" + path + "\", fixing..."); - this.config.set(path, String.valueOf(raw)); - } - }); - - if (this.config.contains("gameplay.front_block_placing.enabled")) { - this.setFrontBlockPlacing(this.config.getOrElse("gameplay.front_block_placing.enabled", DEFAULT_HORIZONTAL_REACHAROUND)); - this.config.remove("gameplay.front_block_placing.enabled"); - } - - if (this.config.contains("gameplay.front_block_placing.outline")) { - this.setRenderReacharoundOutline(this.config.getOrElse("gameplay.front_block_placing.outline", DEFAULT_REACHAROUND_OUTLINE)); - this.config.remove("gameplay.front_block_placing.outline"); - } - - if (this.config.contains("gameplay.front_block_placing.outline_color")) { - this.config.getOptional("gameplay.front_block_placing.outline_color").ifPresent(color -> this.config.set("gameplay.reacharound.outline_color", color)); - this.config.remove("gameplay.front_block_placing.outline_color"); - } - - this.renamed("controller.dead_zone", "controller.right_dead_zone"); - this.renamed("controller.controls.tab_left", "controller.controls.tab_back"); - this.renamed("controller.controls.tab_right", "controller.controls.tab_next"); - } - - private void renamed(String oldPath, String newPath) { - if (!this.config.contains(oldPath)) - return; - var raw = this.config.getRaw(oldPath); - this.config.remove(oldPath); - this.config.set(newPath, raw); - } - - /** - * Resets the configuration to default values. - */ - public void reset() { - // General - this.setControlsMode(DEFAULT_CONTROLS_MODE); - this.setAutoSwitchMode(DEFAULT_AUTO_SWITCH_MODE); - this.setDebug(DEFAULT_DEBUG); - // Gameplay - this.setAnalogMovement(DEFAULT_ANALOG_MOVEMENT); - this.setFastBlockPlacing(DEFAULT_FAST_BLOCK_INTERACTION); - this.setFlyDrifting(DEFAULT_FLY_DRIFTING); - this.setFlyVerticalDrifting(DEFAULT_FLY_VERTICAL_DRIFTING); - this.setFrontBlockPlacing(DEFAULT_HORIZONTAL_REACHAROUND); - this.setVerticalReacharound(DEFAULT_VERTICAL_REACHAROUND); - this.setRenderReacharoundOutline(DEFAULT_REACHAROUND_OUTLINE); - // Controller - this.setControllerType(DEFAULT_CONTROLLER_TYPE); - this.setRightDeadZone(DEFAULT_DEAD_ZONE); - this.setLeftDeadZone(DEFAULT_DEAD_ZONE); - this.setRotationSpeed(DEFAULT_ROTATION_SPEED); - this.setMouseSpeed(DEFAULT_MOUSE_SPEED); - this.setUnfocusedInput(DEFAULT_UNFOCUSED_INPUT); - this.setVirtualMouse(DEFAULT_VIRTUAL_MOUSE); - this.setVirtualMouseSkin(DEFAULT_VIRTUAL_MOUSE_SKIN); - - Arrays.fill(this.maxAnalogValues, DEFAULT_MAX_VALUE); - // HUD - this.setHudEnabled(DEFAULT_HUD_ENABLE); - this.setHudSide(DEFAULT_HUD_SIDE); - - // Collect prevents concurrent modification. - InputManager.streamBindings().collect(Collectors.toList()).forEach(binding -> this.setButtonBinding(binding, binding.getDefaultButton())); - } - - /** - * Gets the controls mode from the configuration. - * - * @return the controls mode - */ - public @NotNull ControlsMode getControlsMode() { - return this.controlsMode; - } - - /** - * Sets the controls mode in the configuration. - * - * @param controlsMode the controls mode - */ - public void setControlsMode(@NotNull ControlsMode controlsMode) { - this.controlsMode = controlsMode; - this.config.set("controls", controlsMode.getName()); - } - - /** - * Returns whether the auto switch mode is enabled or not. - * - * @return true if the auto switch mode is enabled, else false - */ - public boolean hasAutoSwitchMode() { - return this.config.getOrElse("auto_switch_mode", DEFAULT_AUTO_SWITCH_MODE); - } - - /** - * Sets whether the auto switch mode is enabled or not. - * - * @param autoSwitchMode true if the auto switch mode is enabled, else false - */ - public void setAutoSwitchMode(boolean autoSwitchMode) { - this.config.set("auto_switch_mode", autoSwitchMode); - } - - /** - * Returns whether the mod has debug enabled or not. - * - * @return true if debug is enabled, else false - */ - public boolean hasDebug() { - return this.config.getOrElse("debug", DEFAULT_DEBUG); - } - - /** - * Sets whether the mod has debug enabled or not. - * - * @param debug true if debug is enabled, else false - */ - protected void setDebug(boolean debug) { - this.config.set("debug", debug); - } - - /* - HUD settings - */ - - /** - * Returns whether the HUD is enabled. - * - * @return true if the HUD is enabled, else false - */ - public boolean isHudEnabled() { - return this.hudEnable; - } - - /** - * Sets whether the HUD is enabled. - * - * @param enable true if the HUD is enabled, else false - */ - public void setHudEnabled(boolean enable) { - this.hudEnable = enable; - this.config.set("hud.enable", this.hudEnable); - } - - /** - * Gets the HUD side from the configuration. - * - * @return the HUD side - */ - public @NotNull HudSide getHudSide() { - return this.hudSide; - } - - /** - * Sets the HUD side in the configuration. - * - * @param hudSide the HUD side - */ - public void setHudSide(@NotNull HudSide hudSide) { - this.hudSide = hudSide; - this.config.set("hud.side", hudSide.getName()); - } - - /* - Gameplay settings - */ - - /** - * Gets whether analog movement is enabled. - * - * @return {@code true} if analog movement is enabled, else {@code false} - */ - public boolean hasAnalogMovement() { - return this.analogMovement; - } - - /** - * Sets whether analog movement is enabled. - * - * @param analogMovement {@code true} if analog movement is enabled, else {@code false} - */ - public void setAnalogMovement(boolean analogMovement) { - this.config.set("gameplay.analog_movement", this.analogMovement = analogMovement); - } - - /** - * Gets whether fast block placing is enabled or not. - * - * @return true if fast block placing is enabled, else false - */ - public boolean hasFastBlockPlacing() { - return LambdaControlsFeature.FAST_BLOCK_PLACING.isEnabled(); - } - - /** - * Sets whether fast block placing is enabled or not. - * - * @param enable true if fast block placing is enabled, else false - */ - public void setFastBlockPlacing(boolean enable) { - LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(enable); - this.config.set("gameplay.fast_block_placing", enable); - } - - /** - * Returns whether fly drifting is enabled or not. - * - * @return true if fly drifting is enabled, else false - */ - public boolean hasFlyDrifting() { - return this.config.getOrElse("gameplay.fly.drifting", DEFAULT_FLY_DRIFTING); - } - - /** - * Sets whether fly drifting is enabled or not. - * - * @param flyDrifting true if fly drifting is enabled, else false - */ - public void setFlyDrifting(boolean flyDrifting) { - 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); - } - - /** - * Returns whether front block placing is enabled or not. - * - * @return true if front block placing is enabled, else false - */ - public boolean hasFrontBlockPlacing() { - return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isEnabled(); - } - - /** - * Sets whether front block placing is enabled or not. - * - * @param enable true if front block placing is enabled, else false - */ - public void setFrontBlockPlacing(boolean enable) { - LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(enable); - this.config.set("gameplay.reacharound.horizontal", enable); - } - - /** - * Returns whether vertical reacharound is enabled or not. - * - * @return true if vertical reacharound is enabled, else false - */ - public boolean hasVerticalReacharound() { - return LambdaControlsFeature.VERTICAL_REACHAROUND.isEnabled(); - } - - /** - * Sets whether vertical reacharound is enabled or not. - * - * @param enable true if vertical reacharound is enabled, else false - */ - public void setVerticalReacharound(boolean enable) { - LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(enable); - this.config.set("gameplay.reacharound.vertical", enable); - } - - /** - * Returns whether front block placing outline is enabled or not. - * - * @return true if front block placing outline is enabled, else false - */ - public boolean shouldRenderReacharoundOutline() { - return this.shouldRenderReacharoundOutline; - } - - /** - * Sets whether front block placing outline is enabled or not. - * - * @param render true if front block placing outline is enabled, else false - */ - public void setRenderReacharoundOutline(boolean render) { - this.config.set("gameplay.reacharound.outline", this.shouldRenderReacharoundOutline = render); - } - - /** - * Returns the front block placing outline color as an integer array. - *

- * The integer array has 4 elements: red, green, blue and alpha. - * - * @return the color as a RGBA integer array - */ - public int[] getReacharoundOutlineColor() { - return this.reacharoundOutlineColor; - } - - /* - Controller settings - */ - - /** - * Gets the used controller. - * - * @return the controller - */ - public Controller getController() { - var raw = this.config.getRaw("controller.id"); - if (raw instanceof Number) { - return Controller.byId((Integer) raw); - } else if (raw instanceof String) { - return Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1)); - } - return Controller.byId(GLFW.GLFW_JOYSTICK_1); - } - - /** - * Sets the used controller. - * - * @param controller the controller - */ - public void setController(Controller controller) { - this.config.set("controller.id", controller.id()); - } - - /** - * Gets the second controller (for Joy-Con supports). - * - * @return the second controller - */ - public Optional getSecondController() { - var raw = this.config.getRaw("controller.id2"); - if (raw instanceof Number) { - if ((int) raw == -1) - return Optional.empty(); - return Optional.of(Controller.byId((Integer) raw)); - } else if (raw instanceof String) { - return Optional.of(Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1))); - } - return Optional.empty(); - } - - /** - * Sets the second controller. - * - * @param controller the second controller - */ - public void setSecondController(@Nullable Controller controller) { - this.config.set("controller.id2", controller == null ? -1 : controller.id()); - } - - /** - * Gets the controller's type. - * - * @return the controller's type - */ - public @NotNull ControllerType getControllerType() { - return this.controllerType; - } - - /** - * Sets the controller's type. - * - * @param controllerType the controller's type - */ - public void setControllerType(@NotNull ControllerType controllerType) { - this.controllerType = controllerType; - this.config.set("controller.type", controllerType.getName()); - } - - /** - * Gets the controller's right dead zone from the configuration. - * - * @return the controller's right dead zone value - */ - public double getRightDeadZone() { - return this.rightDeadZone; - } - - /** - * Sets the controller's right dead zone in the configuration. - * - * @param deadZone the controller's right dead zone value - */ - public void setRightDeadZone(double deadZone) { - this.rightDeadZone = deadZone; - } - - /** - * Gets the controller's left dead zone from the configuration. - * - * @return the controller's left dead zone value - */ - public double getLeftDeadZone() { - return this.leftDeadZone; - } - - /** - * Sets the controller's left dead zone in the configuration. - * - * @param deadZone the controller's left dead zone value - */ - public void setLeftDeadZone(double deadZone) { - this.leftDeadZone = deadZone; - } - - /** - * Gets the controller's rotation speed. - * - * @return the rotation speed - */ - public double getRotationSpeed() { - return this.rotationSpeed; - } - - /** - * Sets the controller's rotation speed. - * - * @param rotationSpeed the rotation speed - */ - public void setRotationSpeed(double rotationSpeed) { - this.rotationSpeed = rotationSpeed; - } - - /** - * Gets the controller's mouse speed. - * - * @return the mouse speed - */ - public double getMouseSpeed() { - return this.mouseSpeed; - } - - /** - * Sets the controller's mouse speed. - * - * @param mouseSpeed the mouse speed - */ - public void setMouseSpeed(double mouseSpeed) { - this.mouseSpeed = mouseSpeed; - } - - /** - * Returns whether the right X axis is inverted or not. - * - * @return true if the right X axis is inverted, else false - */ - public boolean doesInvertRightXAxis() { - return this.config.getOrElse("controller.invert_right_x_axis", false); - } - - /** - * Sets whether the right X axis is inverted or not. - * - * @param invert true if the right X axis is inverted, else false - */ - public void setInvertRightXAxis(boolean invert) { - this.config.set("controller.invert_right_x_axis", invert); - } - - /** - * Returns whether the right Y axis is inverted or not. - * - * @return true if the right Y axis is inverted, else false - */ - public boolean doesInvertRightYAxis() { - return this.config.getOrElse("controller.invert_right_y_axis", false); - } - - /** - * Sets whether the right Y axis is inverted or not. - * - * @param invert true if the right Y axis is inverted, else false - */ - public void setInvertRightYAxis(boolean invert) { - this.config.set("controller.invert_right_y_axis", invert); - } - - /** - * Returns whether unfocused controller input is allowed or not. - * - * @return true if unfocused controller input is allowed, else false - */ - public boolean hasUnfocusedInput() { - return this.unfocusedInput; - } - - /** - * Sets whether unfocused controller input is allowed or not. - * - * @param unfocusedInput true if unfocused controller input is allowed, else false - */ - public void setUnfocusedInput(boolean unfocusedInput) { - this.unfocusedInput = unfocusedInput; - } - - /** - * Returns whether the mouse is virtual or not. - * - * @return true if the mouse is virtual, else false - */ - public boolean hasVirtualMouse() { - return this.virtualMouse; - } - - /** - * Sets whether the mouse is virtual or not. - * - * @param virtualMouse true if the mouse is virtual, else false - */ - public void setVirtualMouse(boolean virtualMouse) { - this.virtualMouse = virtualMouse; - } - - /** - * Gets the virtual mouse skin. - * - * @return the virtual mouse skin - */ - public VirtualMouseSkin getVirtualMouseSkin() { - return this.virtualMouseSkin; - } - - /** - * Sets the virtual mouse skin. - * - * @param skin the virtual mouse skin - */ - public void setVirtualMouseSkin(VirtualMouseSkin skin) { - this.virtualMouseSkin = skin; - this.config.set("controller.virtual_mouse_skin", skin.getName()); - } - - /** - * Gets the right X axis sign. - * - * @return the right X axis sign - */ - public double getRightXAxisSign() { - return this.doesInvertRightXAxis() ? -1.0 : 1.0; - } - - /** - * Gets the right Y axis sign. - * - * @return the right Y axis sign - */ - public double getRightYAxisSign() { - return this.doesInvertRightYAxis() ? -1.0 : 1.0; - } - - public double getAxisMaxValue(int axis) { - if (axis >= this.maxAnalogValues.length) - return DEFAULT_MAX_VALUE; - return this.maxAnalogValues[axis]; - } - - public void setAxisMaxValue(int axis, double value) { - if (axis < this.maxAnalogValues.length) - this.maxAnalogValues[axis] = value; - } - - /** - * Loads the button binding from configuration. - * - * @param button the button binding - */ - public void loadButtonBinding(@NotNull ButtonBinding button) { - button.setButton(button.getDefaultButton()); - var code = this.config.getOrElse("controller.controls." + button.getName(), button.getButtonCode()); - - var matcher = BUTTON_BINDING_PATTERN.matcher(code); - - try { - var buttons = new int[1]; - int count = 0; - while (matcher.find()) { - count++; - if (count > buttons.length) - buttons = Arrays.copyOf(buttons, count); - String current; - 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 \"" + code + "\" for binding \"" + button.getName() + "\"."); - this.setButtonBinding(button, new int[]{-1}); - } - - button.setButton(buttons); - } catch (Exception e) { - this.mod.warn("Malformed config value \"" + code + "\" for binding \"" + button.getName() + "\"."); - this.config.set("controller.controls." + button.getName(), button.getButtonCode()); - } - } - - private boolean checkValidity(@NotNull ButtonBinding binding, @NotNull String input, String group) { - if (group == null) { - this.mod.warn("Malformed config value \"" + input + "\" for binding \"" + binding.getName() + "\"."); - this.config.set("controller.controls." + binding.getName(), binding.getButtonCode()); - return false; - } - return true; - } - - /** - * Sets the button binding in configuration. - * - * @param binding the button binding - * @param button the button - */ - public void setButtonBinding(@NotNull ButtonBinding binding, int[] button) { - binding.setButton(button); - this.config.set("controller.controls." + binding.getName(), binding.getButtonCode()); - } - - public boolean isBackButton(int btn, boolean isBtn, int state) { - if (!isBtn && state == 0) - return false; - return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false) == ButtonBinding.axisAsButton(btn, state == 1); - } - - public boolean isForwardButton(int btn, boolean isBtn, int state) { - if (!isBtn && state == 0) - return false; - return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true) == ButtonBinding.axisAsButton(btn, state == 1); - } - - public boolean isLeftButton(int btn, boolean isBtn, int state) { - if (!isBtn && state == 0) - return false; - return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false) == ButtonBinding.axisAsButton(btn, state == 1); - } - - public boolean isRightButton(int btn, boolean isBtn, int state) { - if (!isBtn && state == 0) - return false; - return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true) == ButtonBinding.axisAsButton(btn, state == 1); - } - - /** - * Returns whether the specified axis is an axis used for movements. - * - * @param axis the axis index - * @return true if the axis is used for movements, else false - */ - public boolean isMovementAxis(int axis) { - return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X; - } - - /** - * Parses a color from a hexadecimal color string. - * - * @param hex the hexadecimal color - * @return the color instance, null if invalid - */ - private static int[] parseColor(String hex) { - hex = hex.replace("#", ""); - return switch (hex.length()) { - case 6 -> new int[]{ - Integer.valueOf(hex.substring(0, 2), 16), - Integer.valueOf(hex.substring(2, 4), 16), - Integer.valueOf(hex.substring(4, 6), 16), - 255 - }; - case 8 -> new int[]{ - Integer.valueOf(hex.substring(0, 2), 16), - Integer.valueOf(hex.substring(2, 4), 16), - Integer.valueOf(hex.substring(4, 6), 16), - Integer.valueOf(hex.substring(6, 8), 16) - }; - default -> null; - }; - } -} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java b/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java deleted file mode 100644 index 520b078..0000000 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright © 2021 LambdAurora - * - * This file is part of LambdaControls. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package dev.lambdaurora.lambdacontrols.client.gui; - -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.text.LiteralText; -import org.jetbrains.annotations.NotNull; - -/** - * Represents the touchscreen overlay - */ -public class TouchscreenOverlay extends Screen { - public TouchscreenOverlay(@NotNull LambdaControlsClient mod) { - super(new LiteralText("Touchscreen overlay")); - } - /*public static final Identifier WIDGETS_LOCATION = new Identifier("lambdacontrols", "textures/gui/widgets.png"); - private LambdaControlsClient mod; - private SpruceTexturedButtonWidget jumpButton; - private SpruceTexturedButtonWidget flyButton; - private SpruceTexturedButtonWidget flyUpButton; - private SpruceTexturedButtonWidget flyDownButton; - private int flyButtonEnableTicks = 0; - private int forwardButtonTick = 0; - private SpruceTexturedButtonWidget forwardLeftButton; - private SpruceTexturedButtonWidget forwardRightButton; - private SpruceTexturedButtonWidget startSneakButton; - private SpruceTexturedButtonWidget endSneakButton; - - public TouchscreenOverlay(@NotNull LambdaControlsClient mod) - { - super(new LiteralText("Touchscreen overlay")); - this.mod = mod; - this.passEvents = true; - } - - @Override - public boolean isPauseScreen() - { - return false; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) - { - return false; - } - - private void pauseGame(boolean bl) - { - if (this.client == null) - return; - boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote(); - if (bl2) { - this.client.openScreen(new GameMenuScreen(!bl)); - this.client.getSoundManager().pauseAll(); - } else { - this.client.openScreen(new GameMenuScreen(true)); - } - } - - /** - * Updates the forward button ticks cooldown. - * - * @param state The button state. - * - private void updateForwardButtonsState(boolean state) - { - if (state) - this.forwardButtonTick = -1; - else - this.forwardButtonTick = 20; - } - - /** - * Updates the jump buttons. - * - private void updateJumpButtons() - { - if (this.client == null) - return; - if (this.client.player.abilities.allowFlying && this.client.player.abilities.flying) { - boolean oldStateFly = this.flyButton.visible; - this.jumpButton.visible = false; - this.flyButton.visible = true; - this.flyUpButton.visible = true; - this.flyDownButton.visible = true; - if (oldStateFly != this.flyButton.visible) { - this.flyButtonEnableTicks = 5; - this.handleJump(null, false); - } else if (this.flyButtonEnableTicks > 0) - this.flyButtonEnableTicks--; - } else { - this.jumpButton.visible = true; - this.flyButton.visible = false; - this.flyUpButton.visible = false; - this.flyDownButton.visible = false; - } - } - - /** - * Handles the jump button. - * - * @param btn The pressed button. - * @param state The state of the jump button. - * - private void handleJump(ButtonWidget btn, boolean state) - { - ((KeyBindingAccessor) this.client.options.keyJump).lambdacontrols_handlePressState(state); - } - - @Override - public void tick() - { - if (this.forwardButtonTick > 0) { - this.forwardButtonTick--; - } else if (this.forwardButtonTick == 0) { - if (this.forwardLeftButton.visible) - this.forwardLeftButton.visible = false; - if (this.forwardRightButton.visible) - this.forwardRightButton.visible = false; - } - this.updateJumpButtons(); - } - - @Override - protected void init() - { - super.init(); - int scaledWidth = this.client.getWindow().getScaledWidth(); - int scaledHeight = this.client.getWindow().getScaledHeight(); - this.addButton(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256, - btn -> this.client.openScreen(new ChatScreen("")), LiteralText.EMPTY)); - this.addButton(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, - btn -> this.pauseGame(false))); - // Inventory buttons. - int inventoryButtonX = scaledWidth / 2; - int inventoryButtonY = scaledHeight - 16 - 5; - if (this.client.options.mainArm == Arm.LEFT) { - inventoryButtonX = inventoryButtonX - 91 - 24; - } else { - inventoryButtonX = inventoryButtonX + 91 + 4; - } - this.addButton(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, - btn -> { - if (this.client.interactionManager.hasRidingInventory()) { - this.client.player.openRidingInventory(); - } else { - this.client.getTutorialManager().onInventoryOpened(); - this.client.openScreen(new InventoryScreen(this.client.player)); - } - })); - int jumpButtonX, swapHandsX, sneakButtonX; - int sneakButtonY = scaledHeight - 10 - 40 - 5; - if (this.mod.config.getHudSide() == HudSide.LEFT) { - jumpButtonX = scaledWidth - 20 - 20; - swapHandsX = jumpButtonX - 5 - 40; - sneakButtonX = 10 + 20 + 5; - } else { - jumpButtonX = 20; - swapHandsX = jumpButtonX + 5 + 40; - sneakButtonX = scaledWidth - 10 - 40 - 5; - } - // Swap items hand. - this.addButton(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY, 20, 20, 0, 160, 20, WIDGETS_LOCATION, - (btn, state) -> { - if (state) { - if (!this.client.player.isSpectator()) { - this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN)); - } - } - })); - // Drop - this.addButton(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.client.options.keyDrop).lambdacontrols_handlePressState(state))); - // Jump keys - 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.flyButtonEnableTicks == 0) this.client.player.abilities.flying = false; - })); - 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.client.options.keySneak).lambdacontrols_handlePressState(state))); - this.updateJumpButtons(); - // Movements keys - this.addButton((this.startSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 0, 120, 20, WIDGETS_LOCATION, - (btn, state) -> { - if (state) { - ((KeyBindingAccessor) this.client.options.keySneak).lambdacontrols_handlePressState(true); - this.startSneakButton.visible = false; - this.endSneakButton.visible = true; - } - }))); - this.addButton((this.endSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 20, 120, 20, WIDGETS_LOCATION, - (btn, state) -> { - if (state) { - ((KeyBindingAccessor) this.client.options.keySneak).lambdacontrols_handlePressState(false); - this.endSneakButton.visible = false; - this.startSneakButton.visible = true; - } - }))); - 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.client.options.keyForward).lambdacontrols_handlePressState(state); - ((KeyBindingAccessor) this.client.options.keyLeft).lambdacontrols_handlePressState(state); - this.updateForwardButtonsState(state); - })); - this.forwardLeftButton.visible = false; - this.addButton(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION, - (btn, state) -> { - ((KeyBindingAccessor) this.client.options.keyForward).lambdacontrols_handlePressState(state); - this.updateForwardButtonsState(state); - this.forwardLeftButton.visible = true; - this.forwardRightButton.visible = true; - })); - this.addButton(this.forwardRightButton = new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION, - (btn, state) -> { - ((KeyBindingAccessor) this.client.options.keyForward).lambdacontrols_handlePressState(state); - ((KeyBindingAccessor) this.client.options.keyRight).lambdacontrols_handlePressState(state); - this.updateForwardButtonsState(state); - })); - this.forwardRightButton.visible = true; - this.addButton(new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY, 20, 20, 20, 80, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.client.options.keyRight).lambdacontrols_handlePressState(state))); - this.addButton(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.client.options.keyBack).lambdacontrols_handlePressState(state))); - this.addButton(new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY, 20, 20, 60, 80, 20, WIDGETS_LOCATION, - (btn, state) -> ((KeyBindingAccessor) this.client.options.keyLeft).lambdacontrols_handlePressState(state))); - - this.buttons.forEach(button -> { - if (button instanceof SpruceTexturedButtonWidget) { - ((SpruceTexturedButtonWidget) button).setSilent(true); - } - }); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) - { - if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) { - int centerX = this.width / 2; - if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { - for (int slot = 0; slot < 9; ++slot) { - int slotX = centerX - 90 + slot * 20 + 2; - if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { - this.client.player.inventory.selectedSlot = slot; - return true; - } - } - } - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) - { - if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) { - if (deltaY > 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2); - else if (deltaY < 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1); - - if (deltaX > 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2); - else if (deltaX < 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1); - } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - }*/ -} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java b/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java deleted file mode 100644 index a7c2771..0000000 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright © 2021 LambdAurora - * - * This file is part of LambdaControls. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package dev.lambdaurora.lambdacontrols.client.mixin; - -import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen; -import net.minecraft.client.gui.Drawable; -import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.Selectable; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; -import net.minecraft.client.gui.screen.option.GameOptionsScreen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.CyclingButtonWidget; -import net.minecraft.client.option.GameOptions; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableText; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -/** - * Injects the new controls settings button. - */ -@Mixin(ControlsOptionsScreen.class) -public class ControlsOptionsScreenMixin extends GameOptionsScreen { - public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) { - super(parent, gameOptions, text); - } - - @SuppressWarnings("unchecked") - @Redirect( - method = "init", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/screen/option/ControlsOptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;", - ordinal = 1 - ) - ) - private R onInit(ControlsOptionsScreen screen, T element) { - /*if (this.parent instanceof ControllerControlsWidget) - return this.addButton(btn); - else*/ - if (element instanceof CyclingButtonWidget btn) { - return (R) this.addDrawableChild(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((ClickableWidgetAccessor) btn).getHeight(), - new TranslatableText("menu.options"), - b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, true)))); - } else { - return (R) this.addDrawableChild(element); - } - } -} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/HandledScreenMixin.java b/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/HandledScreenMixin.java deleted file mode 100644 index faf0435..0000000 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/HandledScreenMixin.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2021 LambdAurora - * - * This file is part of LambdaControls. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package dev.lambdaurora.lambdacontrols.client.mixin; - -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; -import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer; -import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.screen.slot.Slot; -import net.minecraft.screen.slot.SlotActionType; -import org.jetbrains.annotations.Nullable; -import org.lwjgl.glfw.GLFW; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import org.spongepowered.asm.mixin.gen.Invoker; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -/** - * Represents the mixin for the class ContainerScreen. - */ -@Mixin(HandledScreen.class) -public abstract class HandledScreenMixin implements HandledScreenAccessor { - @Accessor("x") - public abstract int getX(); - - @Accessor("y") - public abstract int getY(); - - @Invoker("getSlotAt") - public abstract Slot lambdacontrols$getSlotAt(double posX, double posY); - - @Invoker("isClickOutsideBounds") - public abstract boolean lambdacontrols$isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button); - - @Invoker("onMouseClick") - public abstract void lambdacontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType); - - @Inject(method = "render", at = @At("RETURN")) - public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { - if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) { - var client = MinecraftClient.getInstance(); - int x = 2, y = client.getWindow().getScaledHeight() - 2 - LambdaControlsRenderer.ICON_SIZE; - - x = LambdaControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 2; - x = LambdaControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "lambdacontrols.action.exit", true, client) + 2; - if (LambdaControlsCompat.isReiPresent()) { - x = 2; - y -= 24; - } - x = LambdaControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "lambdacontrols.action.pickup", true, client) + 2; - LambdaControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, "lambdacontrols.action.quick_move", true, client); - } - } -} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java b/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java deleted file mode 100644 index 335a5e6..0000000 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright © 2021 LambdAurora - * - * This file is part of LambdaControls. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package dev.lambdaurora.lambdacontrols.client.mixin; - -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen; -import net.minecraft.client.gui.Drawable; -import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.Selectable; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -/** - * Injects the new controls settings button. - */ -@Mixin(OptionsScreen.class) -public class OptionsScreenMixin extends Screen { - protected OptionsScreenMixin(Text title) { - super(title); - } - - @SuppressWarnings("unchecked") - @Redirect( - method = "init", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/screen/option/OptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;", - ordinal = 7 - ) - ) - private T lambdacontrols$onInit(OptionsScreen screen, T element) { - if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER && element instanceof ButtonWidget btn) { - return (T) this.addDrawableChild(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((ClickableWidgetAccessor) btn).getHeight(), - btn.getMessage(), - b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, false)))); - } else { - return this.addDrawableChild(element); - } - } -} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java b/src/main/java/dev/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java deleted file mode 100644 index bab76cf..0000000 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/util/KeyBindingAccessor.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright © 2021 LambdAurora - * - * This file is part of LambdaControls. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package dev.lambdaurora.lambdacontrols.client.util; - -/** - * Represents a Minecraft keybinding with extra access. - */ -public interface KeyBindingAccessor { - boolean lambdacontrols$press(); - - boolean lambdacontrols$unpress(); - - default boolean lambdacontrols$handlePressState(boolean pressed) { - if (pressed) - return this.lambdacontrols$press(); - else - return this.lambdacontrols$unpress(); - } -} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/ControlsMode.java b/src/main/java/eu/midnightdust/midnightcontrols/ControlsMode.java similarity index 87% rename from src/main/java/dev/lambdaurora/lambdacontrols/ControlsMode.java rename to src/main/java/eu/midnightdust/midnightcontrols/ControlsMode.java index c1bb15b..cb45f8b 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/ControlsMode.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/ControlsMode.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols; +package eu.midnightdust.midnightcontrols; -import org.aperlambda.lambdacommon.utils.Nameable; +import dev.lambdaurora.spruceui.util.Nameable; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -45,7 +45,7 @@ public enum ControlsMode implements Nameable { * @since 1.1.0 */ public String getTranslationKey() { - return "lambdacontrols.controls_mode." + this.getName(); + return "midnightcontrols.controls_mode." + this.getName(); } @Override diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/LambdaControls.java b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControls.java similarity index 73% rename from src/main/java/dev/lambdaurora/lambdacontrols/LambdaControls.java rename to src/main/java/eu/midnightdust/midnightcontrols/MidnightControls.java index ce23717..8a714ed 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/LambdaControls.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControls.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols; +package eu.midnightdust.midnightcontrols; -import dev.lambdaurora.lambdacontrols.event.PlayerChangeControlsModeCallback; +import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback; import io.netty.buffer.Unpooled; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; @@ -26,26 +26,26 @@ import java.util.Objects; import java.util.Optional; /** - * Represents the LambdaControls mod. + * Represents the midnightcontrols mod. * * @author LambdAurora * @version 1.7.0 * @since 1.0.0 */ -public class LambdaControls implements ModInitializer { - private static LambdaControls INSTANCE; - 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 class MidnightControls implements ModInitializer { + private static MidnightControls INSTANCE; + public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString()); + public static final Identifier FEATURE_CHANNEL = new Identifier(MidnightControlsConstants.FEATURE_CHANNEL.toString()); + public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString()); - public static final TranslatableText NOT_BOUND_TEXT = new TranslatableText("lambdacontrols.not_bound"); + public static final TranslatableText NOT_BOUND_TEXT = new TranslatableText("midnightcontrols.not_bound"); - public final Logger logger = LogManager.getLogger("LambdaControls"); + public final Logger logger = LogManager.getLogger("midnightcontrols"); @Override public void onInitialize() { INSTANCE = this; - this.log("Initializing LambdaControls..."); + this.log("Initializing midnightcontrols..."); ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> { String version = buf.readString(32); @@ -53,7 +53,7 @@ public class LambdaControls implements ModInitializer { .ifPresent(controlsMode -> server .execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode))); server.execute(() -> { - ServerPlayNetworking.send(player, FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.HORIZONTAL_REACHAROUND)); + ServerPlayNetworking.send(player, FEATURE_CHANNEL, this.makeFeatureBuffer(MidnightControlsFeature.HORIZONTAL_REACHAROUND)); }); }); ServerPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, @@ -68,7 +68,7 @@ public class LambdaControls implements ModInitializer { * @param info the message to print */ public void log(String info) { - this.logger.info("[LambdaControls] " + info); + this.logger.info("[midnightcontrols] " + info); } /** @@ -77,11 +77,11 @@ public class LambdaControls implements ModInitializer { * @param warning the warning to print */ public void warn(String warning) { - this.logger.info("[LambdaControls] " + warning); + this.logger.info("[midnightcontrols] " + warning); } /** - * Returns a packet byte buffer made for the lambdacontrols:controls_mode plugin message. + * Returns a packet byte buffer made for the midnightcontrols:controls_mode plugin message. * * @param controlsMode the controls mode to send * @return the packet byte buffer @@ -92,12 +92,12 @@ public class LambdaControls implements ModInitializer { } /** - * Returns a packet byte buffer made for the lambdacontrols:feature plugin message. + * Returns a packet byte buffer made for the midnightcontrols:feature plugin message. * * @param features the features data to send * @return the packet byte buffer */ - public PacketByteBuf makeFeatureBuffer(LambdaControlsFeature... features) { + public PacketByteBuf makeFeatureBuffer(MidnightControlsFeature... features) { if (features.length == 0) throw new IllegalArgumentException("At least one feature must be provided."); var buffer = new PacketByteBuf(Unpooled.buffer()); @@ -112,18 +112,18 @@ public class LambdaControls implements ModInitializer { public PacketByteBuf makeHello(@NotNull ControlsMode controlsMode) { var version = ""; Optional container; - if ((container = FabricLoader.getInstance().getModContainer(LambdaControlsConstants.NAMESPACE)).isPresent()) { + if ((container = FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE)).isPresent()) { version = container.get().getMetadata().getVersion().getFriendlyString(); } return new PacketByteBuf(Unpooled.buffer()).writeString(version, 32).writeString(controlsMode.getName(), 32); } /** - * Gets the LambdaControls instance. + * Gets the midnightcontrols instance. * - * @return the LambdaControls instance + * @return the midnightcontrols instance */ - public static LambdaControls get() { + public static MidnightControls get() { return INSTANCE; } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/LambdaControlsConstants.java b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsConstants.java similarity index 64% rename from src/main/java/dev/lambdaurora/lambdacontrols/LambdaControlsConstants.java rename to src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsConstants.java index 1a04890..9d70186 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/LambdaControlsConstants.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsConstants.java @@ -1,25 +1,26 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols; +package eu.midnightdust.midnightcontrols; -import org.aperlambda.lambdacommon.Identifier; + +import net.minecraft.util.Identifier; /** - * Represents the constants used by LambdaControls. + * Represents the constants used by midnightcontrols. * * @author LambdAurora * @version 1.1.0 * @since 1.1.0 */ -public class LambdaControlsConstants { - public static final String NAMESPACE = "lambdacontrols"; +public class MidnightControlsConstants { + public static final String NAMESPACE = "midnightcontrols"; 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/src/main/java/dev/lambdaurora/lambdacontrols/LambdaControlsFeature.java b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsFeature.java similarity index 70% rename from src/main/java/dev/lambdaurora/lambdacontrols/LambdaControlsFeature.java rename to src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsFeature.java index a6a0323..bfc1f76 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/LambdaControlsFeature.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/MidnightControlsFeature.java @@ -1,15 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols; +package eu.midnightdust.midnightcontrols; -import org.aperlambda.lambdacommon.utils.Nameable; +import dev.lambdaurora.spruceui.util.Nameable; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -24,11 +25,11 @@ import java.util.Optional; * @version 1.5.0 * @since 1.1.0 */ -public class LambdaControlsFeature implements Nameable { - private static final List FEATURES = new ArrayList<>(); - public static final LambdaControlsFeature FAST_BLOCK_PLACING = new LambdaControlsFeature("fast_block_placing", true, true); - public static final LambdaControlsFeature HORIZONTAL_REACHAROUND = new LambdaControlsFeature("horizontal_reacharound", true, false); - public static final LambdaControlsFeature VERTICAL_REACHAROUND = new LambdaControlsFeature("vertical_reacharound", true, false); +public class MidnightControlsFeature implements Nameable { + private static final List FEATURES = new ArrayList<>(); + public static final MidnightControlsFeature FAST_BLOCK_PLACING = new MidnightControlsFeature("fast_block_placing", true, MidnightControlsConfig.fastBlockPlacing); + public static final MidnightControlsFeature HORIZONTAL_REACHAROUND = new MidnightControlsFeature("horizontal_reacharound", true, MidnightControlsConfig.horizontalReacharound); + public static final MidnightControlsFeature VERTICAL_REACHAROUND = new MidnightControlsFeature("vertical_reacharound", true, MidnightControlsConfig.verticalReacharound); private final String key; private final boolean defaultAllowed; @@ -36,14 +37,14 @@ public class LambdaControlsFeature implements Nameable { private final boolean defaultEnabled; private boolean enabled; - public LambdaControlsFeature(@NotNull String key, boolean allowed, boolean enabled) { + public MidnightControlsFeature(@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) { + public MidnightControlsFeature(@NotNull String key) { this(key, false, false); } @@ -121,7 +122,7 @@ public class LambdaControlsFeature implements Nameable { return this.key; } - public static @NotNull Optional fromName(@NotNull String 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(); } @@ -130,14 +131,14 @@ public class LambdaControlsFeature implements Nameable { * Resets all features to their default values. */ public static void resetAll() { - FEATURES.parallelStream().forEach(LambdaControlsFeature::reset); + FEATURES.parallelStream().forEach(MidnightControlsFeature::reset); } /** * Resets all features to allow state. */ public static void resetAllAllowed() { - FEATURES.parallelStream().forEach(LambdaControlsFeature::resetAllowed); + FEATURES.parallelStream().forEach(MidnightControlsFeature::resetAllowed); } static { diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ButtonState.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ButtonState.java similarity index 90% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ButtonState.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ButtonState.java index 1663dad..8baa630 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ButtonState.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ButtonState.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; /** * Represents a button state. diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ControllerType.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ControllerType.java similarity index 76% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ControllerType.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ControllerType.java index fd39660..49ba222 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ControllerType.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ControllerType.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; @@ -26,20 +26,22 @@ import java.util.Optional; * @since 1.0.0 */ public enum ControllerType implements Nameable { - DEFAULT(0), - DUALSHOCK(1), - SWITCH(2), - XBOX_360(3, new LiteralText("Xbox 360")), - XBOX(4), - STEAM(5), - OUYA(6); + DEFAULT(0, new LiteralText("Default")), + DUALSHOCK(1, new LiteralText("Dualshock")), + DUALSENSE(2, new LiteralText("Dualsense")), + SWITCH(3, new LiteralText("Switch")), + XBOX_360(4, new LiteralText("Xbox 360")), + XBOX(5, new LiteralText("Xbox")), + STEAM_DECK(6, new LiteralText("Steam Deck")), + STEAM_CONTROLLER(7, new LiteralText("Steam Controller")), + OUYA(8, new LiteralText("Ouya")); private final int id; private final Text text; ControllerType(int id) { this.id = id; - this.text = new TranslatableText("lambdacontrols.controller_type." + this.getName()); + this.text = new TranslatableText("midnightcontrols.controller_type." + this.getName()); } ControllerType(int id, @NotNull Text text) { diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/HudSide.java b/src/main/java/eu/midnightdust/midnightcontrols/client/HudSide.java similarity index 92% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/HudSide.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/HudSide.java index fe104f8..8ce117b 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/HudSide.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/HudSide.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; @@ -52,7 +52,7 @@ public enum HudSide implements Nameable { * @return the translation key of this hude side */ public @NotNull String getTranslationKey() { - return "lambdacontrols.hud_side." + this.getName(); + return "midnightcontrols.hud_side." + this.getName(); } /** diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsClient.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java similarity index 56% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsClient.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java index 074a769..6ea4926 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsClient.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java @@ -1,25 +1,27 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.LambdaControls; -import dev.lambdaurora.lambdacontrols.LambdaControlsConstants; -import dev.lambdaurora.lambdacontrols.LambdaControlsFeature; -import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.controller.Controller; -import dev.lambdaurora.lambdacontrols.client.controller.InputManager; -import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsHud; -import dev.lambdaurora.lambdacontrols.client.ring.KeyBindingRingAction; -import dev.lambdaurora.lambdacontrols.client.ring.LambdaRing; +import dev.lambdaurora.spruceui.event.OpenScreenCallback; +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.MidnightControls; +import eu.midnightdust.midnightcontrols.MidnightControlsConstants; +import eu.midnightdust.midnightcontrols.MidnightControlsFeature; +import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.Controller; +import eu.midnightdust.midnightcontrols.client.controller.InputManager; +import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsHud; +import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; +import eu.midnightdust.midnightcontrols.client.ring.KeyBindingRingAction; +import eu.midnightdust.midnightcontrols.client.ring.MidnightRing; import dev.lambdaurora.spruceui.hud.HudManager; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; @@ -40,33 +42,33 @@ import org.lwjgl.glfw.GLFW; import java.io.File; /** - * Represents the LambdaControls client mod. + * Represents the midnightcontrols client mod. * * @author LambdAurora * @version 1.7.0 * @since 1.1.0 */ -public class LambdaControlsClient extends LambdaControls implements ClientModInitializer { - private static LambdaControlsClient INSTANCE; - public static final KeyBinding BINDING_LOOK_UP = InputManager.makeKeyBinding(new Identifier(LambdaControlsConstants.NAMESPACE, "look_up"), +public class MidnightControlsClient extends MidnightControls implements ClientModInitializer { + private static MidnightControlsClient INSTANCE; + public static final KeyBinding BINDING_LOOK_UP = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_up"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_8, "key.categories.movement"); - public static final KeyBinding BINDING_LOOK_RIGHT = InputManager.makeKeyBinding(new Identifier(LambdaControlsConstants.NAMESPACE, "look_right"), + public static final KeyBinding BINDING_LOOK_RIGHT = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_right"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_6, "key.categories.movement"); - public static final KeyBinding BINDING_LOOK_DOWN = InputManager.makeKeyBinding(new Identifier(LambdaControlsConstants.NAMESPACE, "look_down"), + public static final KeyBinding BINDING_LOOK_DOWN = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_down"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement"); - public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(new Identifier(LambdaControlsConstants.NAMESPACE, "look_left"), + public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_left"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement"); - /*public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(LambdaControlsConstants.NAMESPACE, "ring"), + /*public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(midnightcontrolsConstants.NAMESPACE, "ring"), InputUtil.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_5, "key.categories.misc");*/ - public static final Identifier CONTROLLER_BUTTONS = new Identifier(LambdaControlsConstants.NAMESPACE, "textures/gui/controller_buttons.png"); - public static final Identifier CONTROLLER_AXIS = new Identifier(LambdaControlsConstants.NAMESPACE, "textures/gui/controller_axis.png"); - public static final Identifier CURSOR_TEXTURE = new Identifier(LambdaControlsConstants.NAMESPACE, "textures/gui/cursor.png"); + public static final Identifier CONTROLLER_BUTTONS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_buttons.png"); + public static final Identifier CONTROLLER_EXPANDED = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_expanded.png"); + public static final Identifier CONTROLLER_AXIS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_axis.png"); + public static final Identifier CURSOR_TEXTURE = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/cursor.png"); public final static File MAPPINGS_FILE = new File("config/gamecontrollerdb.txt"); - public final LambdaControlsConfig config = new LambdaControlsConfig(this); - public final LambdaInput input = new LambdaInput(this); - public final LambdaRing ring = new LambdaRing(this); - public final LambdaReacharound reacharound = new LambdaReacharound(); - private LambdaControlsHud hud; + public final MidnightInput input = new MidnightInput(); + public final MidnightRing ring = new MidnightRing(this); + public final MidnightReacharound reacharound = new MidnightReacharound(); + private MidnightControlsHud hud; private ControlsMode previousControlsMode; @Override @@ -81,37 +83,37 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni this.ring.registerAction("keybinding", KeyBindingRingAction.FACTORY); ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) -> { - responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(this.config.getControlsMode())); + responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)); }); ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> { int features = buf.readVarInt(); for (int i = 0; i < features; i++) { var name = buf.readString(64); boolean allowed = buf.readBoolean(); - LambdaControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed))); + MidnightControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed))); } }); ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> { - sender.sendPacket(HELLO_CHANNEL, this.makeHello(this.config.getControlsMode())); - sender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(this.config.getControlsMode())); + sender.sendPacket(HELLO_CHANNEL, this.makeHello(MidnightControlsConfig.controlsMode)); + sender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)); }); ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave); ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick); ClientTickEvents.END_CLIENT_TICK.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) { + OpenScreenCallback.EVENT.register((client, screen) -> { +// if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) { +// screen = new TouchscreenOverlay(this); +// screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); +// client.skipGameRender = false; +// client.currentScreen = screen; +// } else if (screen != null) { this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight()); - } - });*/ + //} + }); - HudManager.register(this.hud = new LambdaControlsHud(this)); + HudManager.register(this.hud = new MidnightControlsHud(this)); } /** @@ -119,23 +121,23 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni */ public void onMcInit(@NotNull MinecraftClient client) { ButtonBinding.init(client.options); - this.config.load(); - this.hud.setVisible(this.config.isHudEnabled()); + MidnightControlsConfig.load(); + this.hud.setVisible(MidnightControlsConfig.hudEnable); Controller.updateMappings(); GLFW.glfwSetJoystickCallback((jid, event) -> { if (event == GLFW.GLFW_CONNECTED) { var controller = Controller.byId(jid); - client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.connected", jid), + client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("midnightcontrols.controller.connected", jid), 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), + client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("midnightcontrols.controller.disconnected", jid), null)); } this.switchControlsMode(); }); - LambdaControlsCompat.init(this); + MidnightControlsCompat.init(this); } /** @@ -145,7 +147,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni */ public void onTick(@NotNull MinecraftClient client) { this.input.tick(client); - if (this.config.getControlsMode() == ControlsMode.CONTROLLER && (client.isWindowFocused() || this.config.hasUnfocusedInput())) + if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput)) this.input.tickController(client); /*if (BINDING_RING.wasPressed()) { @@ -161,23 +163,23 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni * Called when leaving a server. */ public void onLeave(ClientPlayNetworkHandler handler, MinecraftClient client) { - LambdaControlsFeature.resetAllAllowed(); + MidnightControlsFeature.resetAllAllowed(); } /** * Switches the controls mode if the auto switch is enabled. */ public void switchControlsMode() { - if (this.config.hasAutoSwitchMode()) { - if (this.config.getController().isGamepad()) { - this.previousControlsMode = this.config.getControlsMode(); - this.config.setControlsMode(ControlsMode.CONTROLLER); + if (MidnightControlsConfig.autoSwitchMode) { + if (MidnightControlsConfig.getController().isGamepad()) { + this.previousControlsMode = MidnightControlsConfig.controlsMode; + MidnightControlsConfig.controlsMode = ControlsMode.CONTROLLER; } else { if (this.previousControlsMode == null) { this.previousControlsMode = ControlsMode.DEFAULT; } - this.config.setControlsMode(this.previousControlsMode); + MidnightControlsConfig.controlsMode = this.previousControlsMode; } } } @@ -188,16 +190,16 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni * @param enabled true if the HUD is enabled, else false */ public void setHudEnabled(boolean enabled) { - this.config.setHudEnabled(enabled); + MidnightControlsConfig.hudEnable = enabled; this.hud.setVisible(enabled); } /** - * Gets the LambdaControls client instance. + * Gets the midnightcontrols client instance. * - * @return the LambdaControls client instance + * @return the midnightcontrols client instance */ - public static LambdaControlsClient get() { + public static MidnightControlsClient get() { return INSTANCE; } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java new file mode 100644 index 0000000..cb295c1 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java @@ -0,0 +1,259 @@ +/* + * Copyright © 2021 LambdAurora + * + * This file is part of midnightcontrols. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package eu.midnightdust.midnightcontrols.client; + +import eu.midnightdust.lib.config.MidnightConfig; +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.Controller; +import eu.midnightdust.midnightcontrols.client.controller.InputManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.glfw.GLFW; + +import java.util.*; +import java.util.regex.Pattern; + +import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_X; +import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y; + +/** + * Represents MidnightControls configuration. + */ +public class MidnightControlsConfig extends MidnightConfig { + // General + @Entry public static ControlsMode controlsMode = ControlsMode.DEFAULT; + @Entry public static boolean autoSwitchMode = false; + @Entry public static boolean debug = false; + // HUD + @Entry public static boolean hudEnable = true; + @Entry public static HudSide hudSide = HudSide.LEFT; + // Gameplay + @Entry public static boolean analogMovement = true; + @Entry public static boolean fastBlockPlacing = true; + @Entry public static boolean flyDrifting = false; + @Entry public static boolean verticalFlyDrifting = true; + @Entry public static boolean horizontalReacharound = false; + @Entry public static boolean verticalReacharound = false; + @Entry public static boolean shouldRenderReacharoundOutline = true; + @Entry public static int[] reacharoundOutlineColor = new int[]{255, 255, 255, 102}; + // Controller + @Entry public static ControllerType controllerType = ControllerType.DEFAULT; + //private static final double DEFAULT_DEAD_ZONE = 0.25; + @Entry public static double rightDeadZone = 0.25; + @Entry public static double leftDeadZone = 0.25; + @Entry public static boolean invertRightYAxis = false; + @Entry public static boolean invertRightXAxis = false; + @Entry public static double DEFAULT_MAX_VALUE = 1; + @Entry public static double rotationSpeed = 40.0; + @Entry public static double mouseSpeed = 25.0; + @Entry public static boolean unfocusedInput = false; + @Entry public static boolean virtualMouse = false; + @Entry public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT; +// @Entry public static List ringPages = new ArrayList(); +// @Entry public static double maxAnalog1 = 1; +// @Entry public static double maxAnalog2 = 1; +// @Entry public static double maxAnalog3 = 1; +// @Entry public static double maxAnalog4 = 1; + @Entry public static Object controllerID = 0; + @Entry public static Object secondControllerID = -1; + @Entry public static Map BINDINGS = Map.of(); + + private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?"); + // Gameplay. + // Controller settings + @Entry public static double[] maxAnalogValues = new double[]{DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE}; + + /** + * Loads the configuration + */ + public static void load() { + MidnightControlsConfig.init("midnightcontrols", MidnightControlsConfig.class); + MidnightControlsClient.get().log("Configuration loaded."); + // Controller controls. + InputManager.loadButtonBindings(); + //this.mod.ring.load(this.config); + } + + /** + * Saves the configuration. + */ + public static void save() { + MidnightControlsConfig.write("midnightcontrols"); + MidnightControlsClient.get().log("Configuration saved."); + } + /** + * Gets the used controller. + * + * @return the controller + */ + public static Controller getController() { + var raw = MidnightControlsConfig.controllerID; + if (raw instanceof Number) { + return Controller.byId(((Number) raw).intValue()); + } else if (raw instanceof String) { + return Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1)); + } + return Controller.byId(GLFW.GLFW_JOYSTICK_1); + } + + /** + * Sets the used controller. + * + * @param controller the controller + */ + public static void setController(Controller controller) { + MidnightControlsConfig.controllerID = controller.id(); + MidnightControlsConfig.write("midnightcontrols"); + } + + /** + * Gets the second controller (for Joy-Con supports). + * + * @return the second controller + */ + public static Optional getSecondController() { + var raw = MidnightControlsConfig.secondControllerID; + if (raw instanceof Number) { + if (((Number) raw).intValue() == -1) + return Optional.empty(); + return Optional.of(Controller.byId((Integer) raw)); + } else if (raw instanceof String) { + return Optional.of(Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1))); + } + return Optional.empty(); + } + + /** + * Sets the second controller. + * + * @param controller the second controller + */ + public static void setSecondController(@Nullable Controller controller) { + MidnightControlsConfig.secondControllerID = controller == null ? -1 : controller.id(); + } + /** + * Gets the right X axis sign. + * + * @return the right X axis sign + */ + public static double getRightXAxisSign() { + return MidnightControlsConfig.invertRightXAxis ? -1.0 : 1.0; + } + + /** + * Gets the right Y axis sign. + * + * @return the right Y axis sign + */ + public static double getRightYAxisSign() { + return MidnightControlsConfig.invertRightYAxis ? -1.0 : 1.0; + } + + public static double getAxisMaxValue(int axis) { + if (axis >= MidnightControlsConfig.maxAnalogValues.length) + return DEFAULT_MAX_VALUE; + return MidnightControlsConfig.maxAnalogValues[axis]; + } + + public static void setAxisMaxValue(int axis, double value) { + if (axis < MidnightControlsConfig.maxAnalogValues.length) + MidnightControlsConfig.maxAnalogValues[axis] = value; + } + + /** + * Loads the button binding from configuration. + * + * @param button the button binding + */ + public static void loadButtonBinding(@NotNull ButtonBinding button) { + button.setButton(button.getDefaultButton()); + var code = MidnightControlsConfig.BINDINGS.getOrDefault("controller.controls." + button.getName(), button.getButtonCode()); + + var matcher = BUTTON_BINDING_PATTERN.matcher(code); + + try { + var buttons = new int[1]; + int count = 0; + while (matcher.find()) { + count++; + if (count > buttons.length) + buttons = Arrays.copyOf(buttons, count); + String current; + if (!MidnightControlsConfig.checkValidity(button, code, current = matcher.group(1))) + return; + buttons[count - 1] = Integer.parseInt(current); + } + if (count == 0) { + MidnightControlsClient.get().warn("Malformed config value \"" + code + "\" for binding \"" + button.getName() + "\"."); + MidnightControlsConfig.setButtonBinding(button, new int[]{-1}); + } + + button.setButton(buttons); + } catch (Exception e) { + MidnightControlsClient.get().warn("Malformed config value \"" + code + "\" for binding \"" + button.getName() + "\"."); + MidnightControlsConfig.BINDINGS.put("controller.controls." + button.getName(), button.getButtonCode()); + } + } + + private static boolean checkValidity(@NotNull ButtonBinding binding, @NotNull String input, String group) { + if (group == null) { + MidnightControlsClient.get().warn("Malformed config value \"" + input + "\" for binding \"" + binding.getName() + "\"."); + MidnightControlsConfig.BINDINGS.put("controller.controls." + binding.getName(), binding.getButtonCode()); + return false; + } + return true; + } + + /** + * Sets the button binding in configuration. + * + * @param binding the button binding + * @param button the button + */ + public static void setButtonBinding(@NotNull ButtonBinding binding, int[] button) { + binding.setButton(button); + MidnightControlsConfig.BINDINGS.put("controller.controls." + binding.getName(), binding.getButtonCode()); + } + + public static boolean isBackButton(int btn, boolean isBtn, int state) { + if (!isBtn && state == 0) + return false; + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false) == ButtonBinding.axisAsButton(btn, state == 1); + } + + public static boolean isForwardButton(int btn, boolean isBtn, int state) { + if (!isBtn && state == 0) + return false; + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true) == ButtonBinding.axisAsButton(btn, state == 1); + } + + public static boolean isLeftButton(int btn, boolean isBtn, int state) { + if (!isBtn && state == 0) + return false; + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false) == ButtonBinding.axisAsButton(btn, state == 1); + } + + public static boolean isRightButton(int btn, boolean isBtn, int state) { + if (!isBtn && state == 0) + return false; + return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true) == ButtonBinding.axisAsButton(btn, state == 1); + } + + /** + * Returns whether the specified axis is an axis used for movements. + * + * @param axis the axis index + * @return true if the axis is used for movements, else false + */ + public static boolean isMovementAxis(int axis) { + return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X; + } +} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsModMenu.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsModMenu.java similarity index 52% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsModMenu.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsModMenu.java index d20210f..010234d 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaControlsModMenu.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsModMenu.java @@ -1,28 +1,28 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; -import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen; +import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen; /** - * Represents the API implementation of ModMenu for LambdaControls. + * Represents the API implementation of ModMenu for midnightcontrols. * * @author LambdAurora * @version 1.7.0 * @since 1.1.0 */ -public class LambdaControlsModMenu implements ModMenuApi { +public class MidnightControlsModMenu implements ModMenuApi { @Override public ConfigScreenFactory getModConfigScreenFactory() { - return parent -> new LambdaControlsSettingsScreen(parent, false); + return parent -> new MidnightControlsSettingsScreen(parent, false); } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaInput.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java similarity index 81% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaInput.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java index 0e2e31e..70d2ab4 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaInput.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java @@ -1,26 +1,26 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; import com.google.common.collect.ImmutableSet; -import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.controller.Controller; -import dev.lambdaurora.lambdacontrols.client.controller.InputManager; -import dev.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay; -import dev.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget; -import dev.lambdaurora.lambdacontrols.client.mixin.AdvancementsScreenAccessor; -import dev.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccessor; -import dev.lambdaurora.lambdacontrols.client.mixin.EntryListWidgetAccessor; -import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor; -import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor; +import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.Controller; +import eu.midnightdust.midnightcontrols.client.controller.InputManager; +import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; +import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget; +import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor; +import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor; +import eu.midnightdust.midnightcontrols.client.mixin.EntryListWidgetAccessor; +import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; +import eu.midnightdust.midnightcontrols.client.util.MouseAccessor; import dev.lambdaurora.spruceui.navigation.NavigationDirection; import dev.lambdaurora.spruceui.screen.SpruceScreen; import dev.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget; @@ -58,20 +58,17 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -import static dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding.axisAsButton; -import static dev.lambdaurora.lambdacontrols.client.controller.InputManager.INPUT_MANAGER; import static org.lwjgl.glfw.GLFW.*; /** - * Represents the LambdaControls' input handler. + * Represents the midnightcontrols' input handler. * * @author LambdAurora * @version 1.7.0 * @since 1.0.0 */ -public class LambdaInput { +public class MidnightInput { private static final Map BUTTON_COOLDOWNS = new HashMap<>(); - private final LambdaControlsConfig config; // Cooldowns private int actionGuiCooldown = 0; private boolean ignoreNextARelease = false; @@ -87,9 +84,7 @@ public class LambdaInput { private ControllerControlsWidget controlsInput = null; - public LambdaInput(@NotNull LambdaControlsClient mod) { - this.config = mod.config; - } + public MidnightInput() {} /** * This method is called every Minecraft tick. @@ -101,18 +96,18 @@ public class LambdaInput { this.targetPitch = 0.F; // Handles the key bindings. - if (LambdaControlsClient.BINDING_LOOK_UP.isPressed()) { + if (MidnightControlsClient.BINDING_LOOK_UP.isPressed()) { this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_Y, 0.8F, 2); - } else if (LambdaControlsClient.BINDING_LOOK_DOWN.isPressed()) { + } else if (MidnightControlsClient.BINDING_LOOK_DOWN.isPressed()) { this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_Y, 0.8F, 1); } - if (LambdaControlsClient.BINDING_LOOK_LEFT.isPressed()) { + if (MidnightControlsClient.BINDING_LOOK_LEFT.isPressed()) { this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_X, 0.8F, 2); - } else if (LambdaControlsClient.BINDING_LOOK_RIGHT.isPressed()) { + } else if (MidnightControlsClient.BINDING_LOOK_RIGHT.isPressed()) { this.handleLook(client, GLFW_GAMEPAD_AXIS_RIGHT_X, 0.8F, 1); } - INPUT_MANAGER.tick(client); + InputManager.INPUT_MANAGER.tick(client); } /** @@ -129,13 +124,13 @@ public class LambdaInput { InputManager.updateStates(); - var controller = this.config.getController(); + var controller = MidnightControlsConfig.getController(); if (controller.isConnected()) { var state = controller.getState(); this.fetchButtonInput(client, state, false); this.fetchAxeInput(client, state, false); } - this.config.getSecondController().filter(Controller::isConnected) + MidnightControlsConfig.getSecondController().filter(Controller::isConnected) .ifPresent(joycon -> { GLFWGamepadState state = joycon.getState(); this.fetchButtonInput(client, state, true); @@ -173,7 +168,7 @@ public class LambdaInput { */ public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen) { if (!isScreenInteractive(screen)) { - INPUT_MANAGER.updateMousePosition(client); + InputManager.INPUT_MANAGER.updateMousePosition(client); } } @@ -212,10 +207,10 @@ public class LambdaInput { public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight) { if (client.currentScreen == null) { this.mouseSpeedX = this.mouseSpeedY = 0.0F; - INPUT_MANAGER.resetMousePosition(windowWidth, windowHeight); - } else if (isScreenInteractive(client.currentScreen) && this.config.hasVirtualMouse()) { - ((MouseAccessor) client.mouse).lambdacontrols$onCursorPos(client.getWindow().getHandle(), 0, 0); - INPUT_MANAGER.resetMouseTarget(client); + InputManager.INPUT_MANAGER.resetMousePosition(windowWidth, windowHeight); + } else if (isScreenInteractive(client.currentScreen) && MidnightControlsConfig.virtualMouse) { + ((MouseAccessor) client.mouse).midnightcontrols$onCursorPos(client.getWindow().getHandle(), 0, 0); + InputManager.INPUT_MANAGER.resetMouseTarget(client); } this.inventoryInteractionCooldown = 5; } @@ -263,7 +258,7 @@ public class LambdaInput { if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y) value *= -1.0F; - int state = value > this.config.getRightDeadZone() ? 1 : (value < -this.config.getRightDeadZone() ? 2 : 0); + int state = value > MidnightControlsConfig.rightDeadZone ? 1 : (value < -MidnightControlsConfig.rightDeadZone ? 2 : 0); this.handleAxe(client, axis, value, absValue, state); } } @@ -318,7 +313,7 @@ public class LambdaInput { if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) { if (client.currentScreen != null) { - if (!LambdaControlsCompat.handleMenuBack(client, client.currentScreen)) + if (!MidnightControlsCompat.handleMenuBack(client, client.currentScreen)) if (!this.tryGoBack(client.currentScreen)) client.currentScreen.onClose(); return; @@ -344,7 +339,6 @@ public class LambdaInput { } } } - /** * Handles inventory interaction. * @@ -372,13 +366,13 @@ public class LambdaInput { var screen = (HandledScreen) client.currentScreen; var accessor = (HandledScreenAccessor) screen; - Slot slot = ((HandledScreenAccessor) client.currentScreen).lambdacontrols$getSlotAt(x, y); + Slot slot = ((HandledScreenAccessor) client.currentScreen).midnightcontrols$getSlotAt(x, y); int slotId; if (slot == null) { if (client.player.currentScreenHandler.getCursorStack().isEmpty()) return false; - slotId = accessor.lambdacontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1; + slotId = accessor.midnightcontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1; } else { slotId = slot.id; } @@ -388,9 +382,9 @@ public class LambdaInput { switch (button) { case GLFW_GAMEPAD_BUTTON_A: if (screen instanceof CreativeInventoryScreen) - if (((CreativeInventoryScreenAccessor) screen).lambdacontrols$isCreativeInventorySlot(slot)) + if (((CreativeInventoryScreenAccessor) screen).midnightcontrols$isCreativeInventorySlot(slot)) actionType = SlotActionType.CLONE; - if (slot != null && LambdaControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot))) + if (slot != null && MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot))) actionType = SlotActionType.CLONE; break; case GLFW.GLFW_GAMEPAD_BUTTON_X: @@ -403,7 +397,7 @@ public class LambdaInput { return false; } - accessor.lambdacontrols$onMouseClick(slot, slotId, clickData, actionType); + accessor.midnightcontrols$onMouseClick(slot, slotId, clickData, actionType); return true; } @@ -428,8 +422,8 @@ public class LambdaInput { } private double getDeadZoneValue(int axis) { - return (axis == GLFW_GAMEPAD_AXIS_LEFT_X || axis == GLFW_GAMEPAD_AXIS_LEFT_Y) ? this.config.getLeftDeadZone() - : this.config.getRightDeadZone(); + return (axis == GLFW_GAMEPAD_AXIS_LEFT_X || axis == GLFW_GAMEPAD_AXIS_LEFT_Y) ? MidnightControlsConfig.leftDeadZone + : MidnightControlsConfig.rightDeadZone; } private void handleAxe(@NotNull MinecraftClient client, int axis, float value, float absValue, int state) { @@ -444,28 +438,28 @@ public class LambdaInput { { boolean currentPlusState = asButtonState == 1; boolean currentMinusState = asButtonState == 2; - var previousPlusState = InputManager.STATES.getOrDefault(axisAsButton(axis, true), ButtonState.NONE); - var previousMinusState = InputManager.STATES.getOrDefault(axisAsButton(axis, false), ButtonState.NONE); + var previousPlusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, true), ButtonState.NONE); + var previousMinusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, false), ButtonState.NONE); if (currentPlusState != previousPlusState.isPressed()) { - InputManager.STATES.put(axisAsButton(axis, true), currentPlusState ? ButtonState.PRESS : ButtonState.RELEASE); + InputManager.STATES.put(ButtonBinding.axisAsButton(axis, true), currentPlusState ? ButtonState.PRESS : ButtonState.RELEASE); if (currentPlusState) - BUTTON_COOLDOWNS.put(axisAsButton(axis, true), 5); + BUTTON_COOLDOWNS.put(ButtonBinding.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); + InputManager.STATES.put(ButtonBinding.axisAsButton(axis, true), ButtonState.REPEAT); + if (BUTTON_COOLDOWNS.getOrDefault(ButtonBinding.axisAsButton(axis, true), 0) == 0) { + BUTTON_COOLDOWNS.put(ButtonBinding.axisAsButton(axis, true), 5); } } if (currentMinusState != previousMinusState.isPressed()) { - InputManager.STATES.put(axisAsButton(axis, false), currentMinusState ? ButtonState.PRESS : ButtonState.RELEASE); + InputManager.STATES.put(ButtonBinding.axisAsButton(axis, false), currentMinusState ? ButtonState.PRESS : ButtonState.RELEASE); if (currentMinusState) - BUTTON_COOLDOWNS.put(axisAsButton(axis, false), 5); + BUTTON_COOLDOWNS.put(ButtonBinding.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); + InputManager.STATES.put(ButtonBinding.axisAsButton(axis, false), ButtonState.REPEAT); + if (BUTTON_COOLDOWNS.getOrDefault(ButtonBinding.axisAsButton(axis, false), 0) == 0) { + BUTTON_COOLDOWNS.put(ButtonBinding.axisAsButton(axis, false), 5); } } @@ -473,23 +467,23 @@ public class LambdaInput { float axisValue = absValue < deadZone ? 0.f : (float) (absValue - deadZone); axisValue /= (1.0 - deadZone); - axisValue = (float) Math.min(axisValue / this.config.getAxisMaxValue(axis), 1); + axisValue = (float) Math.min(axisValue / MidnightControlsConfig.getAxisMaxValue(axis), 1); if (currentPlusState) - InputManager.BUTTON_VALUES.put(axisAsButton(axis, true), axisValue); + InputManager.BUTTON_VALUES.put(ButtonBinding.axisAsButton(axis, true), axisValue); else - InputManager.BUTTON_VALUES.put(axisAsButton(axis, true), 0.f); + InputManager.BUTTON_VALUES.put(ButtonBinding.axisAsButton(axis, true), 0.f); if (currentMinusState) - InputManager.BUTTON_VALUES.put(axisAsButton(axis, false), axisValue); + InputManager.BUTTON_VALUES.put(ButtonBinding.axisAsButton(axis, false), axisValue); else - InputManager.BUTTON_VALUES.put(axisAsButton(axis, false), 0.f); + InputManager.BUTTON_VALUES.put(ButtonBinding.axisAsButton(axis, false), 0.f); } double deadZone = this.getDeadZoneValue(axis); if (this.controlsInput != null && this.controlsInput.focusedBinding != null) { - if (asButtonState != 0 && !this.controlsInput.currentButtons.contains(axisAsButton(axis, asButtonState == 1))) { + if (asButtonState != 0 && !this.controlsInput.currentButtons.contains(ButtonBinding.axisAsButton(axis, asButtonState == 1))) { - this.controlsInput.currentButtons.add(axisAsButton(axis, asButtonState == 1)); + this.controlsInput.currentButtons.add(ButtonBinding.axisAsButton(axis, asButtonState == 1)); int[] buttons = new int[this.controlsInput.currentButtons.size()]; for (int i = 0; i < this.controlsInput.currentButtons.size(); i++) @@ -503,7 +497,7 @@ public class LambdaInput { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen; // @TODO allow rebinding to left stick - if (accessor.lambdacontrols$hasScrollbar() && absValue >= deadZone) { + if (accessor.midnightcontrols$hasScrollbar() && absValue >= deadZone) { creativeInventoryScreen.mouseScrolled(0.0, 0.0, -value); } return; @@ -521,21 +515,21 @@ public class LambdaInput { absValue -= deadZone; absValue /= (1.0 - deadZone); - absValue = (float) MathHelper.clamp(absValue / this.config.getAxisMaxValue(axis), 0.f, 1.f); + absValue = (float) MathHelper.clamp(absValue / MidnightControlsConfig.getAxisMaxValue(axis), 0.f, 1.f); if (client.currentScreen == null) { // Handles the look direction. this.handleLook(client, axis, absValue, state); } else { boolean allowMouseControl = true; - if (this.actionGuiCooldown == 0 && this.config.isMovementAxis(axis) && isScreenInteractive(client.currentScreen)) { - if (this.config.isForwardButton(axis, false, asButtonState)) { + if (this.actionGuiCooldown == 0 && MidnightControlsConfig.isMovementAxis(axis) && isScreenInteractive(client.currentScreen)) { + if (MidnightControlsConfig.isForwardButton(axis, false, asButtonState)) { allowMouseControl = this.changeFocus(client.currentScreen, NavigationDirection.UP); - } else if (this.config.isBackButton(axis, false, asButtonState)) { + } else if (MidnightControlsConfig.isBackButton(axis, false, asButtonState)) { allowMouseControl = this.changeFocus(client.currentScreen, NavigationDirection.DOWN); - } else if (this.config.isLeftButton(axis, false, asButtonState)) { + } else if (MidnightControlsConfig.isLeftButton(axis, false, asButtonState)) { allowMouseControl = this.handleLeftRight(client.currentScreen, false); - } else if (this.config.isRightButton(axis, false, asButtonState)) { + } else if (MidnightControlsConfig.isRightButton(axis, false, asButtonState)) { allowMouseControl = this.handleLeftRight(client.currentScreen, true); } } @@ -543,13 +537,13 @@ public class LambdaInput { float movementX = 0.f; float movementY = 0.f; - if (this.config.isBackButton(axis, false, (value > 0 ? 1 : 2))) { + if (MidnightControlsConfig.isBackButton(axis, false, (value > 0 ? 1 : 2))) { movementY = absValue; - } else if (this.config.isForwardButton(axis, false, (value > 0 ? 1 : 2))) { + } else if (MidnightControlsConfig.isForwardButton(axis, false, (value > 0 ? 1 : 2))) { movementY = -absValue; - } else if (this.config.isLeftButton(axis, false, (value > 0 ? 1 : 2))) { + } else if (MidnightControlsConfig.isLeftButton(axis, false, (value > 0 ? 1 : 2))) { movementX = -absValue; - } else if (this.config.isRightButton(axis, false, (value > 0 ? 1 : 2))) { + } else if (MidnightControlsConfig.isRightButton(axis, false, (value > 0 ? 1 : 2))) { movementX = absValue; } @@ -561,7 +555,7 @@ public class LambdaInput { It prevents the cursor to jump to the old target mouse position if the user moves the cursor with the mouse. */ if (Math.abs(prevXAxis) < deadZone && Math.abs(prevYAxis) < deadZone) { - INPUT_MANAGER.resetMouseTarget(client); + InputManager.INPUT_MANAGER.resetMouseTarget(client); } this.mouseSpeedX = movementX; @@ -573,8 +567,8 @@ public class LambdaInput { if (Math.abs(this.mouseSpeedX) >= .05f || Math.abs(this.mouseSpeedY) >= .05f) { InputManager.queueMoveMousePosition( - this.mouseSpeedX * this.config.getMouseSpeed(), - this.mouseSpeedY * this.config.getMouseSpeed() + this.mouseSpeedX * MidnightControlsConfig.mouseSpeed, + this.mouseSpeedY * MidnightControlsConfig.mouseSpeed ); } @@ -649,7 +643,7 @@ public class LambdaInput { 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$moveSelection(right ? EntryListWidget.MoveDirection.UP : EntryListWidget.MoveDirection.DOWN); + ((EntryListWidgetAccessor) element).midnightcontrols$moveSelection(right ? EntryListWidget.MoveDirection.UP : EntryListWidget.MoveDirection.DOWN); return false; } else if (element instanceof ParentElement entryList) { var focused = entryList.getFocused(); @@ -674,16 +668,16 @@ public class LambdaInput { double powValue = Math.pow(value, 2.0); if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { if (state == 2) { - this.targetPitch = -this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D; + this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D; } else if (state == 1) { - this.targetPitch = this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D; + this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D; } } if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) { if (state == 2) { - this.targetYaw = -this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D; + this.targetYaw = -MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D; } else if (state == 1) { - this.targetYaw = this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D; + this.targetYaw = MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D; } } } @@ -711,7 +705,7 @@ public class LambdaInput { public static boolean isScreenInteractive(@NotNull Screen screen) { return !(screen instanceof AdvancementsScreen || screen instanceof HandledScreen || screen instanceof PackScreen || (screen instanceof SpruceScreen && ((SpruceScreen) screen).requiresCursor()) - || LambdaControlsCompat.requireMouseOnScreen(screen)); + || MidnightControlsCompat.requireMouseOnScreen(screen)); } // Inspired from https://github.com/MrCrayfish/Controllable/blob/1.14.X/src/main/java/com/mrcrayfish/controllable/client/ControllerInput.java#L686. diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaReacharound.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java similarity index 92% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaReacharound.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java index 8ce531a..1a0b10b 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/LambdaReacharound.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; -import dev.lambdaurora.lambdacontrols.LambdaControlsFeature; +import eu.midnightdust.midnightcontrols.MidnightControlsFeature; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.FluidBlock; @@ -28,12 +28,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Represents the reach-around API of LambdaControls. + * Represents the reach-around API of midnightcontrols. * * @version 1.7.0 * @since 1.3.2 */ -public class LambdaReacharound { +public class MidnightReacharound { private BlockHitResult lastReacharoundResult = null; private boolean lastReacharoundVertical = false; private boolean onSlab = false; @@ -70,7 +70,7 @@ public class LambdaReacharound { * @return {@code true} if reacharound is available, else {@code false} */ public boolean isReacharoundAvailable() { - return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable(); + return MidnightControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || MidnightControlsFeature.VERTICAL_REACHAROUND.isAvailable(); } private float getPlayerRange(@NotNull MinecraftClient client) { @@ -84,7 +84,7 @@ public class LambdaReacharound { * @return a block hit result if vertical reach-around is possible, else {@code null} */ public @Nullable BlockHitResult tryVerticalReachAround(@NotNull MinecraftClient client) { - if (!LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable()) + if (!MidnightControlsFeature.VERTICAL_REACHAROUND.isAvailable()) return null; if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.MISS || !client.player.isOnGround() || client.player.getPitch(0.f) < 80.0F @@ -116,7 +116,7 @@ public class LambdaReacharound { * @return a block hit result if horizontal reach-around is possible */ public @Nullable BlockHitResult tryHorizontalReachAround(@NotNull MinecraftClient client) { - if (!LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable()) + if (!MidnightControlsFeature.HORIZONTAL_REACHAROUND.isAvailable()) return null; if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/VirtualMouseSkin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/VirtualMouseSkin.java similarity index 92% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/VirtualMouseSkin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/VirtualMouseSkin.java index 6737569..f2871ce 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/VirtualMouseSkin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/VirtualMouseSkin.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client; +package eu.midnightdust.midnightcontrols.client; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; @@ -55,7 +55,7 @@ public enum VirtualMouseSkin implements Nameable { * @return the virtual mouse skin's translation key */ public @NotNull String getTranslationKey() { - return "lambdacontrols.virtual_mouse.skin." + this.getName(); + return "midnightcontrols.virtual_mouse.skin." + this.getName(); } /** diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/CompatHandler.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/CompatHandler.java similarity index 93% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/CompatHandler.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/CompatHandler.java index cb4d6ad..04beb0e 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/CompatHandler.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/CompatHandler.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat; +package eu.midnightdust.midnightcontrols.client.compat; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; @@ -31,7 +31,7 @@ public interface CompatHandler { * * @param mod this mod instance */ - void handle(@NotNull LambdaControlsClient mod); + void handle(@NotNull MidnightControlsClient mod); /** * Returns whether the mouse is required on the specified screen. diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java new file mode 100644 index 0000000..23abf68 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/EmotecraftCompat.java @@ -0,0 +1,51 @@ +/* + * Copyright © 2021 LambdAurora + * + * This file is part of midnightcontrols. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package eu.midnightdust.midnightcontrols.client.compat; + +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import io.github.kosmx.emotes.arch.gui.screen.ingame.FastChosseScreen; +import io.github.kosmx.emotes.main.network.ClientEmotePlay; +import net.minecraft.client.gui.screen.Screen; +import org.jetbrains.annotations.NotNull; +import org.lwjgl.glfw.GLFW; + +/** + * Represents a compatibility handler for Emotecraft. + * + * @author Motschen + * @version 1.4.3 + * @since 1.0.0 + */ +public class EmotecraftCompat implements CompatHandler { + @Override + public void handle(@NotNull MidnightControlsClient mod) { + new ButtonBinding.Builder("key.emotecraft.fastchoose") + .buttons(16) + .onlyInGame() + .cooldown(true) + .category(ButtonBinding.MISC_CATEGORY) + .action((client, button, value, action) -> { + client.setScreen(new FastChosseScreen(null)); + return true; + }) + .register(); + new ButtonBinding.Builder("key.emotecraft.stop") + .buttons(17) + .onlyInGame() + .cooldown(true) + .category(ButtonBinding.MISC_CATEGORY) + .action((client, button, value, action) -> { + ClientEmotePlay.clientStopLocalEmote(); + return true; + }) + .register(); + } +} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/HQMCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/HQMCompat.java similarity index 80% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/HQMCompat.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/HQMCompat.java index 49fdbdf..ea48cfe 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/HQMCompat.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/HQMCompat.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat; +package eu.midnightdust.midnightcontrols.client.compat; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import net.minecraft.client.gui.screen.Screen; import org.aperlambda.lambdacommon.utils.LambdaReflection; import org.jetbrains.annotations.NotNull; @@ -30,7 +30,7 @@ public class HQMCompat implements CompatHandler { private Optional> guiBaseClass; @Override - public void handle(@NotNull LambdaControlsClient mod) { + public void handle(@NotNull MidnightControlsClient mod) { this.guiBaseClass = LambdaReflection.getClass(GUI_BASE_CLASS_PATH); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java similarity index 89% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java index 6c95ee9..cfc067e 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsCompat.java @@ -1,16 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat; +package eu.midnightdust.midnightcontrols.client.compat; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.controller.InputManager; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.controller.InputManager; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; @@ -30,7 +30,7 @@ import java.util.stream.Stream; * @version 1.5.0 * @since 1.1.0 */ -public class LambdaControlsCompat { +public class MidnightControlsCompat { private static final List HANDLERS = new ArrayList<>(); /** @@ -38,7 +38,7 @@ public class LambdaControlsCompat { * * @param mod the mod instance */ - public static void init(@NotNull LambdaControlsClient mod) { + public static void init(@NotNull MidnightControlsClient mod) { if (FabricLoader.getInstance().isModLoaded("okzoomer")) { mod.log("Adding okzoomer compatibility..."); HANDLERS.add(new OkZoomerCompat()); @@ -51,8 +51,12 @@ public class LambdaControlsCompat { mod.log("Adding HQM compatibility..."); HANDLERS.add(new HQMCompat()); } + if (FabricLoader.getInstance().isModLoaded("emotecraft")) { + mod.log("Adding Emotecraft compatibility..."); + HANDLERS.add(new EmotecraftCompat()); + } HANDLERS.forEach(handler -> handler.handle(mod)); - InputManager.loadButtonBindings(mod.config); + InputManager.loadButtonBindings(); } /** diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsMixinPlugin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java similarity index 73% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsMixinPlugin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java index 4f745a7..7a1d915 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/LambdaControlsMixinPlugin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/MidnightControlsMixinPlugin.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat; +package eu.midnightdust.midnightcontrols.client.compat; import org.jetbrains.annotations.NotNull; import org.objectweb.asm.tree.ClassNode; @@ -25,18 +25,18 @@ import java.util.Set; * @version 1.5.0 * @since 1.2.0 */ -public class LambdaControlsMixinPlugin implements IMixinConfigPlugin { +public class MidnightControlsMixinPlugin implements IMixinConfigPlugin { private final HashMap conditionalMixins = new HashMap<>(); - public LambdaControlsMixinPlugin() { - this.putConditionalMixin("EntryListWidgetAccessor", LambdaControlsCompat.isReiPresent()); - this.putConditionalMixin("EntryWidgetAccessor", LambdaControlsCompat.isReiPresent()); - this.putConditionalMixin("RecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent()); - this.putConditionalMixin("VillagerRecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent()); + public MidnightControlsMixinPlugin() { + this.putConditionalMixin("EntryListWidgetAccessor", MidnightControlsCompat.isReiPresent()); + this.putConditionalMixin("EntryWidgetAccessor", MidnightControlsCompat.isReiPresent()); + this.putConditionalMixin("RecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent()); + this.putConditionalMixin("VillagerRecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent()); } private void putConditionalMixin(@NotNull String path, boolean condition) { - this.conditionalMixins.put("me.lambdaurora.lambdacontrols.client.compat.mixin." + path, condition); + this.conditionalMixins.put("me.lambdaurora.midnightcontrols.client.compat.mixin." + path, condition); } @Override diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/OkZoomerCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/OkZoomerCompat.java similarity index 86% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/OkZoomerCompat.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/OkZoomerCompat.java index b24856a..adfc80c 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/OkZoomerCompat.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/OkZoomerCompat.java @@ -1,16 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat; +package eu.midnightdust.midnightcontrols.client.compat; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import io.github.ennuil.okzoomer.keybinds.ZoomKeybinds; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; @@ -24,7 +24,7 @@ import org.lwjgl.glfw.GLFW; */ public class OkZoomerCompat implements CompatHandler { @Override - public void handle(@NotNull LambdaControlsClient mod) { + public void handle(@NotNull MidnightControlsClient mod) { new ButtonBinding.Builder("zoom") .buttons(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_X) .onlyInGame() diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/ReiCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/ReiCompat.java similarity index 94% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/ReiCompat.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/ReiCompat.java index 72b5acb..31f7c74 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/ReiCompat.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/ReiCompat.java @@ -1,19 +1,19 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat; +package eu.midnightdust.midnightcontrols.client.compat; -import dev.lambdaurora.lambdacontrols.client.ButtonState; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.controller.InputHandlers; -import dev.lambdaurora.lambdacontrols.client.controller.PressAction; +import eu.midnightdust.midnightcontrols.client.ButtonState; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.InputHandlers; +import eu.midnightdust.midnightcontrols.client.controller.PressAction; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.Identifier; @@ -33,7 +33,7 @@ public class ReiCompat implements CompatHandler { //private static EntryListWidget ENTRY_LIST_WIDGET; @Override - public void handle(@NotNull LambdaControlsClient mod) { + public void handle(@NotNull MidnightControlsClient mod) { ButtonBinding.builder(new Identifier("rei", "category_back")) .buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) .filter((client, binding) -> isViewingScreen(client.currentScreen)) @@ -188,12 +188,12 @@ public class ReiCompat implements CompatHandler { private static @Nullable EntryStack getCurrentStack(@NotNull Element element, double mouseX, double mouseY) { if (element instanceof EntryWidget entry) { if (entry.containsMouse(mouseX, mouseY)) - return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry(); + return ((EntryWidgetAccessor) entry).midnightcontrols_getCurrentEntry(); } else if (element instanceof EntryListWidget) { var entries = ((EntryListWidgetAccessor) element).getEntries(); for (EntryListEntryWidget entry : entries) { if (entry.containsMouse(mouseX, mouseY)) { - return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry(); + return ((EntryWidgetAccessor) entry).midnightcontrols_getCurrentEntry(); } } } else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds widgetWithBounds) { @@ -276,7 +276,7 @@ public class ReiCompat implements CompatHandler { int currentTab = screen.getSelectedCategoryIndex(); screen.setSelectedCategoryIndex(getNextIndex(currentTab, categories.size(), next)); screen.setSelectedRecipeIndex(0); - screen.lambdacontrols_init(); + screen.midnightcontrols_init(); return true; }*/ return false; @@ -315,7 +315,7 @@ public class ReiCompat implements CompatHandler { } screen.setSelectedRecipeIndex(nextRecipe); - screen.lambdacontrols_init(); + screen.midnightcontrols_init(); return true; }*/ diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/EntryListWidgetAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/EntryListWidgetAccessor.java similarity index 81% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/EntryListWidgetAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/EntryListWidgetAccessor.java index 4e07249..4ebf374 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/EntryListWidgetAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/EntryListWidgetAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat.mixin; +package eu.midnightdust.midnightcontrols.client.compat.mixin; /** * Represents an accessor to REI's EntryListWidget. diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/EntryWidgetAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/EntryWidgetAccessor.java similarity index 71% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/EntryWidgetAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/EntryWidgetAccessor.java index a057fdd..1f91774 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/EntryWidgetAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/EntryWidgetAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat.mixin; +package eu.midnightdust.midnightcontrols.client.compat.mixin; /** * Represents an accessor to REI's EntryWidget. @@ -19,5 +19,5 @@ package dev.lambdaurora.lambdacontrols.client.compat.mixin; //@Mixin(value = EntryWidget.class, remap = false) public interface EntryWidgetAccessor { /*@Invoker("getCurrentEntry") - EntryStack lambdacontrols_getCurrentEntry();*/ + EntryStack midnightcontrols_getCurrentEntry();*/ } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/RecipeViewingScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/RecipeViewingScreenAccessor.java similarity index 85% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/RecipeViewingScreenAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/RecipeViewingScreenAccessor.java index 5d187b6..c5ca69a 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/RecipeViewingScreenAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/RecipeViewingScreenAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat.mixin; +package eu.midnightdust.midnightcontrols.client.compat.mixin; /** * Represents an accessor to REI's RecipeViewingScreen. diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/VillagerRecipeViewingScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/VillagerRecipeViewingScreenAccessor.java similarity index 89% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/VillagerRecipeViewingScreenAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/VillagerRecipeViewingScreenAccessor.java index 0881734..eade134 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/compat/mixin/VillagerRecipeViewingScreenAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/mixin/VillagerRecipeViewingScreenAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.compat.mixin; +package eu.midnightdust.midnightcontrols.client.compat.mixin; /** * Represents an accessor to REI's VillagerRecipeViewingScreen. @@ -40,5 +40,5 @@ public interface VillagerRecipeViewingScreenAccessor { ScrollingContainer getScrolling(); @Invoker("init") - void lambdacontrols_init();*/ + void midnightcontrols_init();*/ } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java similarity index 90% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java index 9ed8101..154d532 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java @@ -1,22 +1,21 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.controller; +package eu.midnightdust.midnightcontrols.client.controller; -import dev.lambdaurora.lambdacontrols.client.ButtonState; +import eu.midnightdust.midnightcontrols.client.ButtonState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.KeyBinding; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; -import org.aperlambda.lambdacommon.Identifier; -import org.aperlambda.lambdacommon.utils.Nameable; +import net.minecraft.util.Identifier; import org.aperlambda.lambdacommon.utils.function.PairPredicate; import org.aperlambda.lambdacommon.utils.function.Predicates; import org.jetbrains.annotations.NotNull; @@ -34,7 +33,7 @@ import static org.lwjgl.glfw.GLFW.*; * @version 1.7.0 * @since 1.0.0 */ -public class ButtonBinding implements Nameable { +public class ButtonBinding { public static final ButtonCategory MOVEMENT_CATEGORY; public static final ButtonCategory GAMEPLAY_CATEGORY; public static final ButtonCategory INVENTORY_CATEGORY; @@ -230,7 +229,6 @@ public class ButtonBinding implements Nameable { } } - @Override public @NotNull String getName() { return this.key; } @@ -241,7 +239,7 @@ public class ButtonBinding implements Nameable { * @return the translation key */ public @NotNull String getTranslationKey() { - return "lambdacontrols.action." + this.getName(); + return "midnightcontrols.action." + this.getName(); } public @NotNull Text getText() { @@ -326,32 +324,36 @@ public class ButtonBinding implements Nameable { public static @NotNull Text getLocalizedButtonName(int button) { return switch (button % 500) { case -1 -> new TranslatableText("key.keyboard.unknown"); - case GLFW_GAMEPAD_BUTTON_A -> new TranslatableText("lambdacontrols.button.a"); - case GLFW_GAMEPAD_BUTTON_B -> new TranslatableText("lambdacontrols.button.b"); - case GLFW_GAMEPAD_BUTTON_X -> new TranslatableText("lambdacontrols.button.x"); - case GLFW_GAMEPAD_BUTTON_Y -> new TranslatableText("lambdacontrols.button.y"); - case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> new TranslatableText("lambdacontrols.button.left_bumper"); - case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> new TranslatableText("lambdacontrols.button.right_bumper"); - case GLFW_GAMEPAD_BUTTON_BACK -> new TranslatableText("lambdacontrols.button.back"); - case GLFW_GAMEPAD_BUTTON_START -> new TranslatableText("lambdacontrols.button.start"); - case GLFW_GAMEPAD_BUTTON_GUIDE -> new TranslatableText("lambdacontrols.button.guide"); - case GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> new TranslatableText("lambdacontrols.button.left_thumb"); - case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> new TranslatableText("lambdacontrols.button.right_thumb"); - case GLFW_GAMEPAD_BUTTON_DPAD_UP -> new TranslatableText("lambdacontrols.button.dpad_up"); - case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> new TranslatableText("lambdacontrols.button.dpad_right"); - case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> new TranslatableText("lambdacontrols.button.dpad_down"); - case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> new TranslatableText("lambdacontrols.button.dpad_left"); - case 100 -> new TranslatableText("lambdacontrols.axis.left_x+"); - case 101 -> new TranslatableText("lambdacontrols.axis.left_y+"); - case 102 -> new TranslatableText("lambdacontrols.axis.right_x+"); - case 103 -> new TranslatableText("lambdacontrols.axis.right_y+"); - case 104 -> new TranslatableText("lambdacontrols.axis.left_trigger"); - case 105 -> new TranslatableText("lambdacontrols.axis.right_trigger"); - case 200 -> new TranslatableText("lambdacontrols.axis.left_x-"); - case 201 -> new TranslatableText("lambdacontrols.axis.left_y-"); - case 202 -> new TranslatableText("lambdacontrols.axis.right_x-"); - case 203 -> new TranslatableText("lambdacontrols.axis.right_y-"); - default -> new TranslatableText("lambdacontrols.button.unknown", button); + case GLFW_GAMEPAD_BUTTON_A -> new TranslatableText("midnightcontrols.button.a"); + case GLFW_GAMEPAD_BUTTON_B -> new TranslatableText("midnightcontrols.button.b"); + case GLFW_GAMEPAD_BUTTON_X -> new TranslatableText("midnightcontrols.button.x"); + case GLFW_GAMEPAD_BUTTON_Y -> new TranslatableText("midnightcontrols.button.y"); + case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> new TranslatableText("midnightcontrols.button.left_bumper"); + case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> new TranslatableText("midnightcontrols.button.right_bumper"); + case GLFW_GAMEPAD_BUTTON_BACK -> new TranslatableText("midnightcontrols.button.back"); + case GLFW_GAMEPAD_BUTTON_START -> new TranslatableText("midnightcontrols.button.start"); + case GLFW_GAMEPAD_BUTTON_GUIDE -> new TranslatableText("midnightcontrols.button.guide"); + case GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> new TranslatableText("midnightcontrols.button.left_thumb"); + case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> new TranslatableText("midnightcontrols.button.right_thumb"); + case GLFW_GAMEPAD_BUTTON_DPAD_UP -> new TranslatableText("midnightcontrols.button.dpad_up"); + case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> new TranslatableText("midnightcontrols.button.dpad_right"); + case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> new TranslatableText("midnightcontrols.button.dpad_down"); + case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> new TranslatableText("midnightcontrols.button.dpad_left"); + case 100 -> new TranslatableText("midnightcontrols.axis.left_x+"); + case 101 -> new TranslatableText("midnightcontrols.axis.left_y+"); + case 102 -> new TranslatableText("midnightcontrols.axis.right_x+"); + case 103 -> new TranslatableText("midnightcontrols.axis.right_y+"); + case 104 -> new TranslatableText("midnightcontrols.axis.left_trigger"); + case 105 -> new TranslatableText("midnightcontrols.axis.right_trigger"); + case 200 -> new TranslatableText("midnightcontrols.axis.left_x-"); + case 201 -> new TranslatableText("midnightcontrols.axis.left_y-"); + case 202 -> new TranslatableText("midnightcontrols.axis.right_x-"); + case 203 -> new TranslatableText("midnightcontrols.axis.right_y-"); + case 15 -> new TranslatableText("midnightcontrols.button.l4"); + case 16 -> new TranslatableText("midnightcontrols.button.l5"); + case 17 -> new TranslatableText("midnightcontrols.button.r4"); + case 18 -> new TranslatableText("midnightcontrols.button.r5"); + default -> new TranslatableText("midnightcontrols.button.unknown", button); }; } @@ -385,17 +387,6 @@ public class ButtonBinding implements Nameable { )); } - /** - * Returns a builder instance. - * - * @param identifier the identifier of the button binding - * @return the builder instanc - * @since 1.5.0 - */ - public static Builder builder(@NotNull Identifier identifier) { - return new Builder(identifier); - } - /** * Returns a builder instance. * @@ -403,7 +394,7 @@ public class ButtonBinding implements Nameable { * @return the builder instance * @since 1.5.0 */ - public static Builder builder(@NotNull net.minecraft.util.Identifier identifier) { + public static Builder builder(@NotNull Identifier identifier) { return new Builder(identifier); } @@ -435,11 +426,7 @@ public class ButtonBinding implements Nameable { } public Builder(@NotNull Identifier identifier) { - this(identifier.getNamespace() + "." + identifier.getName()); - } - - public Builder(@NotNull net.minecraft.util.Identifier identifier) { - this(new Identifier(identifier.toString())); + this(identifier.getNamespace() + "." + identifier.getNamespace()); } /** diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/ButtonCategory.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonCategory.java similarity index 96% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/controller/ButtonCategory.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonCategory.java index 4f731ce..930ee28 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/ButtonCategory.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonCategory.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.controller; +package eu.midnightdust.midnightcontrols.client.controller; import net.minecraft.client.resource.language.I18n; import org.aperlambda.lambdacommon.Identifier; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/Controller.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/Controller.java similarity index 85% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/controller/Controller.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/controller/Controller.java index 5fc2723..e854dfe 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/Controller.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/Controller.java @@ -1,16 +1,17 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.controller; +package eu.midnightdust.midnightcontrols.client.controller; -import dev.lambdaurora.lambdacontrols.LambdaControls; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import eu.midnightdust.midnightcontrols.MidnightControls; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import net.minecraft.client.MinecraftClient; import net.minecraft.client.toast.SystemToast; import net.minecraft.text.LiteralText; @@ -96,7 +97,7 @@ public record Controller(int id) implements Nameable { public static Controller byId(int id) { if (id > GLFW.GLFW_JOYSTICK_LAST) { - LambdaControlsClient.get().log("Controller '" + id + "' doesn't exist."); + MidnightControlsClient.get().log("Controller '" + id + "' doesn't exist."); id = GLFW.GLFW_JOYSTICK_LAST; } Controller controller; @@ -144,10 +145,10 @@ public record Controller(int id) implements Nameable { */ public static void updateMappings() { try { - if (!LambdaControlsClient.MAPPINGS_FILE.exists()) + if (!MidnightControlsClient.MAPPINGS_FILE.exists()) return; - LambdaControlsClient.get().log("Updating controller mappings..."); - var buffer = ioResourceToBuffer(LambdaControlsClient.MAPPINGS_FILE.getPath(), 1024); + MidnightControlsClient.get().log("Updating controller mappings..."); + var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024); GLFW.glfwUpdateGamepadMappings(buffer); } catch (IOException e) { e.printStackTrace(); @@ -162,21 +163,21 @@ public record Controller(int id) implements Nameable { var client = MinecraftClient.getInstance(); if (client != null) { client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT, - new TranslatableText("lambdacontrols.controller.mappings.error"), new LiteralText(string))); + new TranslatableText("midnightcontrols.controller.mappings.error"), new LiteralText(string))); } } } catch (Throwable e) { /* Ignored :concern: */ } - if (LambdaControlsClient.get().config.hasDebug()) { + if (MidnightControlsConfig.debug) { for (int i = GLFW.GLFW_JOYSTICK_1; i <= GLFW.GLFW_JOYSTICK_16; i++) { var controller = byId(i); if (!controller.isConnected()) continue; - LambdaControls.get().log(String.format("Controller #%d name: \"%s\"\n GUID: %s\n Gamepad: %s", + MidnightControls.get().log(String.format("Controller #%d name: \"%s\"\n GUID: %s\n Gamepad: %s", controller.id, controller.getName(), controller.getGuid(), diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/InputHandlers.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java similarity index 92% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/controller/InputHandlers.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java index d496157..970334a 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/InputHandlers.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java @@ -1,21 +1,22 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.controller; +package eu.midnightdust.midnightcontrols.client.controller; -import dev.lambdaurora.lambdacontrols.client.ButtonState; -import dev.lambdaurora.lambdacontrols.client.LambdaInput; -import dev.lambdaurora.lambdacontrols.client.mixin.AdvancementsScreenAccessor; -import dev.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccessor; -import dev.lambdaurora.lambdacontrols.client.mixin.RecipeBookWidgetAccessor; -import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor; +import eu.midnightdust.midnightcontrols.client.ButtonState; +import eu.midnightdust.midnightcontrols.client.MidnightInput; +import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor; +import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor; +import eu.midnightdust.midnightcontrols.client.mixin.RecipeBookWidgetAccessor; +import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.Framebuffer; import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; @@ -60,7 +61,7 @@ public class InputHandlers { nextTab = ItemGroup.GROUPS.length - 1; else if (nextTab >= ItemGroup.GROUPS.length) nextTab = 0; - inventory.lambdacontrols$setSelectedTab(ItemGroup.GROUPS[nextTab]); + inventory.midnightcontrols$setSelectedTab(ItemGroup.GROUPS[nextTab]); return true; } else if (client.currentScreen instanceof InventoryScreen inventoryScreen) { var recipeBook = (RecipeBookWidgetAccessor) inventoryScreen.getRecipeBookWidget(); @@ -76,7 +77,7 @@ public class InputHandlers { currentTab.setToggled(false); recipeBook.setCurrentTab(currentTab = tabs.get(nextTab)); currentTab.setToggled(true); - recipeBook.lambdacontrols$refreshResults(true); + recipeBook.midnightcontrols$refreshResults(true); return true; } else if (client.currentScreen instanceof AdvancementsScreenAccessor screen) { var tabs = screen.getTabs().values().stream().distinct().collect(Collectors.toList()); @@ -123,7 +124,7 @@ public class InputHandlers { */ public static boolean handleScreenshot(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, float value, @NotNull ButtonState action) { if (action == ButtonState.RELEASE) - ScreenshotRecorder.saveScreenshot(client.runDirectory, client.getWindow().getFramebufferWidth(), client.getWindow().getFramebufferHeight(), client.getFramebuffer(), + ScreenshotRecorder.saveScreenshot(client.runDirectory, client.getFramebuffer(), text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text))); return true; } @@ -152,7 +153,7 @@ public class InputHandlers { double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); // Finds the hovered slot. - var mouseSlot = accessor.lambdacontrols$getSlotAt(mouseX, mouseY); + var mouseSlot = accessor.midnightcontrols$getSlotAt(mouseX, mouseY); // Finds the closest slot in the GUI within 14 pixels. Optional closestSlot = inventory.getScreenHandler().slots.parallelStream() @@ -239,7 +240,7 @@ public class InputHandlers { public static boolean inNonInteractiveScreens(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { if (client.currentScreen == null) return false; - return !LambdaInput.isScreenInteractive(client.currentScreen); + return !MidnightInput.isScreenInteractive(client.currentScreen); } /** diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/InputManager.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputManager.java similarity index 92% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/controller/InputManager.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputManager.java index ca5ec84..5ed4253 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/InputManager.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputManager.java @@ -1,19 +1,18 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.controller; +package eu.midnightdust.midnightcontrols.client.controller; -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.client.ButtonState; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig; -import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor; +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.client.ButtonState; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.util.MouseAccessor; import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.MinecraftClient; @@ -52,7 +51,7 @@ public class InputManager { } public void tick(@NotNull MinecraftClient client) { - if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) { + if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) { this.controllerTick(client); } } @@ -72,9 +71,9 @@ public class InputManager { 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; - if (!LambdaControlsClient.get().config.hasVirtualMouse()) + if (!MidnightControlsConfig.virtualMouse) GLFW.glfwSetCursorPos(client.getWindow().getHandle(), mouseX, mouseY); - ((MouseAccessor) client.mouse).lambdacontrols$onCursorPos(client.getWindow().getHandle(), mouseX, mouseY); + ((MouseAccessor) client.mouse).midnightcontrols$onCursorPos(client.getWindow().getHandle(), mouseX, mouseY); } } @@ -161,8 +160,7 @@ public class InputManager { public static void sortBindings() { synchronized (BINDINGS) { var sorted = BINDINGS.stream() - .sorted(Collections.reverseOrder(Comparator.comparingInt(binding -> binding.getButton().length))) - .collect(Collectors.toList()); + .sorted(Collections.reverseOrder(Comparator.comparingInt(binding -> binding.getButton().length))).toList(); BINDINGS.clear(); BINDINGS.addAll(sorted); } @@ -195,12 +193,10 @@ public class InputManager { /** * Loads the button bindings from configuration. - * - * @param config the configuration instance */ - public static void loadButtonBindings(@NotNull LambdaControlsConfig config) { + public static void loadButtonBindings() { var queue = new ArrayList<>(BINDINGS); - queue.forEach(config::loadButtonBinding); + queue.forEach(MidnightControlsConfig::loadButtonBinding); } /** @@ -314,7 +310,7 @@ public class InputManager { var states = new Object2ObjectOpenHashMap(); for (var binding : BINDINGS) { var state = binding.isAvailable(client) ? getBindingState(binding) : ButtonState.NONE; - if (skipButtons.stream().anyMatch(btn -> containsButton(binding.getButton(), btn))) { + if (skipButtons.intStream().anyMatch(btn -> containsButton(binding.getButton(), btn))) { if (binding.pressed) state = ButtonState.RELEASE; else diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/MovementHandler.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/MovementHandler.java similarity index 89% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/controller/MovementHandler.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/controller/MovementHandler.java index 680ae36..04d653e 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/MovementHandler.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/MovementHandler.java @@ -1,16 +1,17 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.controller; +package eu.midnightdust.midnightcontrols.client.controller; -import dev.lambdaurora.lambdacontrols.client.ButtonState; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import eu.midnightdust.midnightcontrols.client.ButtonState; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import org.jetbrains.annotations.NotNull; @@ -68,7 +69,7 @@ public final class MovementHandler implements PressAction { this.shouldOverrideMovement = direction != 0; - if (LambdaControlsClient.get().config.hasAnalogMovement()) { + if (MidnightControlsConfig.analogMovement) { value = (float) Math.pow(value, 2); } else value = 1.f; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/PressAction.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/PressAction.java similarity index 76% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/controller/PressAction.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/controller/PressAction.java index 6476d79..f8ce0e2 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/controller/PressAction.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/PressAction.java @@ -1,16 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.controller; +package eu.midnightdust.midnightcontrols.client.controller; -import dev.lambdaurora.lambdacontrols.client.ButtonState; -import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; +import eu.midnightdust.midnightcontrols.client.ButtonState; +import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.StickyKeyBinding; import org.jetbrains.annotations.NotNull; @@ -31,7 +31,7 @@ public interface PressAction { if (binding instanceof StickyKeyBinding) binding.setPressed(button.pressed); else - ((KeyBindingAccessor) binding).lambdacontrols$handlePressState(button.isButtonDown()); + ((KeyBindingAccessor) binding).midnightcontrols$handlePressState(button.isButtonDown()); }); return true; }; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/MappingsStringInputWidget.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MappingsStringInputWidget.java similarity index 82% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/MappingsStringInputWidget.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/MappingsStringInputWidget.java index 5984ad6..9b56c1d 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/MappingsStringInputWidget.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MappingsStringInputWidget.java @@ -1,16 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui; +package eu.midnightdust.midnightcontrols.client.gui; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.controller.Controller; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.controller.Controller; import dev.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.option.SpruceOption; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget; @@ -37,7 +37,7 @@ public class MappingsStringInputWidget extends SpruceContainerWidget { protected MappingsStringInputWidget(Position position, int width, int height) { super(position, width, height); - //super(new TranslatableText("lambdacontrols.menu.title.mappings.string")); + //super(new TranslatableText("midnightcontrols.menu.title.mappings.string")); this.reloadMappingsOption = ReloadControllerMappingsOption.newOption(btn -> { this.writeMappings(); @@ -59,13 +59,13 @@ public class MappingsStringInputWidget extends SpruceContainerWidget { if (this.textArea != null) { this.mappings = this.textArea.getText(); try { - var fw = new FileWriter(LambdaControlsClient.MAPPINGS_FILE, false); + var fw = new FileWriter(MidnightControlsClient.MAPPINGS_FILE, false); fw.write(this.mappings); fw.close(); } catch (IOException e) { if (this.client != null) this.client.getToastManager().add(SystemToast.create(this.client, SystemToast.Type.TUTORIAL_HINT, - new TranslatableText("lambdacontrols.controller.mappings.error.write"), LiteralText.EMPTY)); + new TranslatableText("midnightcontrols.controller.mappings.error.write"), LiteralText.EMPTY)); e.printStackTrace(); } } @@ -80,9 +80,9 @@ public class MappingsStringInputWidget extends SpruceContainerWidget { if (this.mappings != null) mappings = this.mappings; - else if (LambdaControlsClient.MAPPINGS_FILE.exists()) { + else if (MidnightControlsClient.MAPPINGS_FILE.exists()) { try { - mappings = String.join("\n", Files.readAllLines(LambdaControlsClient.MAPPINGS_FILE.toPath())); + mappings = String.join("\n", Files.readAllLines(MidnightControlsClient.MAPPINGS_FILE.toPath())); this.mappings = mappings; } catch (IOException e) { /* Ignored */ diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java similarity index 63% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java index c71fa4c..544176e 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsHud.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsHud.java @@ -1,20 +1,21 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui; +package eu.midnightdust.midnightcontrols.client.gui; -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.LambdaControlsConstants; -import dev.lambdaurora.lambdacontrols.client.HudSide; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.MidnightControlsConstants; +import eu.midnightdust.midnightcontrols.client.HudSide; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import dev.lambdaurora.spruceui.hud.Hud; import net.minecraft.client.MinecraftClient; import net.minecraft.client.resource.language.I18n; @@ -28,14 +29,14 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Represents the LambdaControls HUD. + * Represents the midnightcontrols HUD. * * @author LambdAurora * @version 1.7.0 * @since 1.0.0 */ -public class LambdaControlsHud extends Hud { - private final LambdaControlsClient mod; +public class MidnightControlsHud extends Hud { + private final MidnightControlsClient mod; private MinecraftClient client; private int attackWidth = 0; private int attackButtonWidth = 0; @@ -52,8 +53,8 @@ public class LambdaControlsHud extends Hud { private String placeAction = ""; private int ticksDisplayedCrosshair = 0; - public LambdaControlsHud(@NotNull LambdaControlsClient mod) { - super(new Identifier(LambdaControlsConstants.NAMESPACE, "hud/button_indicator")); + public MidnightControlsHud(@NotNull MidnightControlsClient mod) { + super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator")); this.mod = mod; } @@ -62,26 +63,26 @@ public class LambdaControlsHud extends Hud { super.init(client, screenWidth, screenHeight); this.client = client; this.inventoryWidth = this.width(ButtonBinding.INVENTORY); - this.inventoryButtonWidth = LambdaControlsRenderer.getBindingIconWidth(ButtonBinding.INVENTORY); + this.inventoryButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.INVENTORY); this.swapHandsWidth = this.width(ButtonBinding.SWAP_HANDS); - this.swapHandsButtonWidth = LambdaControlsRenderer.getBindingIconWidth(ButtonBinding.SWAP_HANDS); + this.swapHandsButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.SWAP_HANDS); this.dropItemWidth = this.width(ButtonBinding.DROP_ITEM); - this.dropItemButtonWidth = LambdaControlsRenderer.getBindingIconWidth(ButtonBinding.DROP_ITEM); - this.attackButtonWidth = LambdaControlsRenderer.getBindingIconWidth(ButtonBinding.ATTACK); - this.useButtonWidth = LambdaControlsRenderer.getBindingIconWidth(ButtonBinding.USE); + this.dropItemButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.DROP_ITEM); + this.attackButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.ATTACK); + this.useButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.USE); } /** - * Renders the LambdaControls' HUD. + * Renders the midnightcontrols' HUD. */ @Override public void render(MatrixStack matrices, float tickDelta) { - if (this.mod.config.getControlsMode() == ControlsMode.CONTROLLER && this.client.currentScreen == null) { + if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && this.client.currentScreen == null) { int y = bottom(2); - this.renderFirstIcons(matrices, this.mod.config.getHudSide() == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); - this.renderSecondIcons(matrices, this.mod.config.getHudSide() == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); - this.renderFirstSection(matrices, this.mod.config.getHudSide() == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); - this.renderSecondSection(matrices, this.mod.config.getHudSide() == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); + this.renderFirstIcons(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); + this.renderSecondIcons(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); + this.renderFirstSection(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); + this.renderSecondSection(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); } if (this.mod.reacharound.isLastReacharoundVertical()) { @@ -100,14 +101,14 @@ public class LambdaControlsHud extends Hud { public void renderFirstIcons(MatrixStack matrices, int x, int y) { int offset = 2 + this.inventoryWidth + this.inventoryButtonWidth + 4; - int currentX = this.mod.config.getHudSide() == HudSide.LEFT ? x : x - this.inventoryButtonWidth; + int currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.inventoryButtonWidth; this.drawButton(matrices, currentX, y, ButtonBinding.INVENTORY, true); - this.drawButton(matrices, currentX += (this.mod.config.getHudSide() == HudSide.LEFT ? offset : -offset), y, ButtonBinding.SWAP_HANDS, true); + this.drawButton(matrices, currentX += (MidnightControlsConfig.hudSide == HudSide.LEFT ? offset : -offset), y, ButtonBinding.SWAP_HANDS, true); offset = 2 + this.swapHandsWidth + this.dropItemButtonWidth + 4; - if (this.client.options.showSubtitles && this.mod.config.getHudSide() == HudSide.RIGHT) { + if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.RIGHT) { currentX += -offset; } else { - currentX = this.mod.config.getHudSide() == HudSide.LEFT ? x : x - this.dropItemButtonWidth; + currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.dropItemButtonWidth; y -= 24; } this.drawButton(matrices, currentX, y, ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty()); @@ -117,11 +118,11 @@ public class LambdaControlsHud extends Hud { int offset; int currentX = x; if (!this.placeAction.isEmpty()) { - if (this.mod.config.getHudSide() == HudSide.LEFT) + if (MidnightControlsConfig.hudSide == HudSide.LEFT) currentX -= this.useButtonWidth; this.drawButton(matrices, currentX, y, ButtonBinding.USE, true); offset = 2 + this.useWidth + 4; - if (this.client.options.showSubtitles && this.mod.config.getHudSide() == HudSide.LEFT) { + if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.LEFT) { currentX -= offset; } else { currentX = x; @@ -129,23 +130,23 @@ public class LambdaControlsHud extends Hud { } } - if (this.mod.config.getHudSide() == HudSide.LEFT) + if (MidnightControlsConfig.hudSide == HudSide.LEFT) currentX -= this.attackButtonWidth; this.drawButton(matrices, currentX, y, ButtonBinding.ATTACK, this.attackWidth != 0); } public void renderFirstSection(MatrixStack matrices, int x, int y) { - int currentX = this.mod.config.getHudSide() == HudSide.LEFT ? x + this.inventoryButtonWidth + 2 : x - this.inventoryButtonWidth - 2 - this.inventoryWidth; + int currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x + this.inventoryButtonWidth + 2 : x - this.inventoryButtonWidth - 2 - this.inventoryWidth; this.drawTip(matrices, currentX, y, ButtonBinding.INVENTORY, true); - currentX += this.mod.config.getHudSide() == HudSide.LEFT ? this.inventoryWidth + 4 + this.swapHandsButtonWidth + 2 + currentX += MidnightControlsConfig.hudSide == HudSide.LEFT ? this.inventoryWidth + 4 + this.swapHandsButtonWidth + 2 : -this.swapHandsWidth - 2 - this.swapHandsButtonWidth - 4; this.drawTip(matrices, currentX, y, ButtonBinding.SWAP_HANDS, true); - if (this.client.options.showSubtitles && this.mod.config.getHudSide() == HudSide.RIGHT) { + if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.RIGHT) { currentX += -this.dropItemWidth - 2 - this.dropItemButtonWidth - 4; } else { y -= 24; - currentX = this.mod.config.getHudSide() == HudSide.LEFT ? x + this.dropItemButtonWidth + 2 : x - this.dropItemButtonWidth - 2 - this.dropItemWidth; + currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x + this.dropItemButtonWidth + 2 : x - this.dropItemButtonWidth - 2 - this.dropItemWidth; } this.drawTip(matrices, currentX, y, ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty()); } @@ -154,11 +155,11 @@ public class LambdaControlsHud extends Hud { int currentX = x; if (!this.placeAction.isEmpty()) { - currentX += this.mod.config.getHudSide() == HudSide.RIGHT ? this.useButtonWidth + 2 : -this.useButtonWidth - 2 - this.useWidth; + currentX += MidnightControlsConfig.hudSide == HudSide.RIGHT ? this.useButtonWidth + 2 : -this.useButtonWidth - 2 - this.useWidth; this.drawTip(matrices, currentX, y, this.placeAction, true); - if (this.client.options.showSubtitles && this.mod.config.getHudSide() == HudSide.LEFT) { + if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.LEFT) { currentX -= 4; } else { currentX = x; @@ -166,7 +167,7 @@ public class LambdaControlsHud extends Hud { } } - currentX += this.mod.config.getHudSide() == HudSide.RIGHT ? this.attackButtonWidth + 2 : -this.attackButtonWidth - 2 - this.attackWidth; + currentX += MidnightControlsConfig.hudSide == HudSide.RIGHT ? this.attackButtonWidth + 2 : -this.attackButtonWidth - 2 - this.attackWidth; this.drawTip(matrices, currentX, y, this.attackAction, this.attackWidth != 0); } @@ -174,7 +175,7 @@ public class LambdaControlsHud extends Hud { @Override public void tick() { super.tick(); - if (this.mod.config.getControlsMode() == ControlsMode.CONTROLLER) { + if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) { if (this.client.crosshairTarget == null) return; @@ -191,7 +192,7 @@ public class LambdaControlsHud extends Hud { else this.placeHitResult = null; - this.attackAction = this.client.crosshairTarget.getType() == HitResult.Type.BLOCK ? "lambdacontrols.action.hit" : ButtonBinding.ATTACK.getTranslationKey(); + this.attackAction = this.client.crosshairTarget.getType() == HitResult.Type.BLOCK ? "midnightcontrols.action.hit" : ButtonBinding.ATTACK.getTranslationKey(); this.attackWidth = this.width(attackAction); } @@ -202,7 +203,7 @@ public class LambdaControlsHud extends Hud { this.ticksDisplayedCrosshair = 0; } - var customAttackAction = LambdaControlsCompat.getAttackActionAt(this.client, this.placeHitResult); + var customAttackAction = MidnightControlsCompat.getAttackActionAt(this.client, this.placeHitResult); if (customAttackAction != null) { this.attackAction = customAttackAction; this.attackWidth = this.width(customAttackAction); @@ -218,13 +219,13 @@ public class LambdaControlsHud extends Hud { placeAction = ""; } else { if (this.placeHitResult != null && stack.getItem() instanceof BlockItem) { - placeAction = "lambdacontrols.action.place"; + placeAction = "midnightcontrols.action.place"; } else { placeAction = ButtonBinding.USE.getTranslationKey(); } } - var customUseAction = LambdaControlsCompat.getUseActionAt(this.client, this.placeHitResult); + var customUseAction = MidnightControlsCompat.getUseActionAt(this.client, this.placeHitResult); if (customUseAction != null) placeAction = customUseAction; @@ -244,7 +245,7 @@ public class LambdaControlsHud extends Hud { } private int bottom(int y) { - return this.client.getWindow().getScaledHeight() - y - LambdaControlsRenderer.ICON_SIZE; + return this.client.getWindow().getScaledHeight() - y - MidnightControlsRenderer.ICON_SIZE; } private int width(@NotNull ButtonBinding binding) { @@ -259,7 +260,7 @@ public class LambdaControlsHud extends Hud { private void drawButton(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display) { if (display) - LambdaControlsRenderer.drawButton(matrices, x, y, button, this.client); + MidnightControlsRenderer.drawButton(matrices, x, y, button, this.client); } private void drawTip(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display) { @@ -270,7 +271,7 @@ public class LambdaControlsHud extends Hud { if (!display) return; var translatedAction = I18n.translate(action); - int textY = (LambdaControlsRenderer.ICON_SIZE / 2 - this.client.textRenderer.fontHeight / 2) + 1; + int textY = (MidnightControlsRenderer.ICON_SIZE / 2 - this.client.textRenderer.fontHeight / 2) + 1; this.client.textRenderer.draw(matrices, translatedAction, (float) x, (float) (y + textY), 14737632); } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsRenderer.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java similarity index 82% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsRenderer.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java index 3c43325..9cdc41f 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsRenderer.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java @@ -1,20 +1,21 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui; +package eu.midnightdust.midnightcontrols.client.gui; import com.mojang.blaze3d.systems.RenderSystem; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.LambdaInput; -import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.MidnightInput; +import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawableHelper; @@ -25,13 +26,13 @@ import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; /** - * Represents the LambdaControls renderer. + * Represents the midnightcontrols renderer. * * @author LambdAurora * @version 1.7.0 * @since 1.2.0 */ -public class LambdaControlsRenderer { +public class MidnightControlsRenderer { public static final int ICON_SIZE = 20; private static final int BUTTON_SIZE = 15; private static final int AXIS_SIZE = 18; @@ -96,7 +97,6 @@ public class LambdaControlsRenderer { return new ButtonSize(length, height); } - @SuppressWarnings("deprecated") public static int drawButton(MatrixStack matrices, int x, int y, int button, @NotNull MinecraftClient client) { boolean second = false; if (button == -1) @@ -106,10 +106,14 @@ public class LambdaControlsRenderer { second = true; } - int controllerType = LambdaControlsClient.get().config.getControllerType().getId(); + int controllerType = MidnightControlsConfig.controllerType.getId(); boolean axis = false; int buttonOffset = button * 15; switch (button) { + case 15 -> buttonOffset = 0; + case 16 -> buttonOffset = 18; + case 17 -> buttonOffset = 36; + case 18 -> buttonOffset = 54; case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> buttonOffset = 7 * 15; case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> buttonOffset = 8 * 15; case GLFW.GLFW_GAMEPAD_BUTTON_BACK -> buttonOffset = 4 * 15; @@ -153,14 +157,14 @@ public class LambdaControlsRenderer { case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200 -> buttonOffset = 10 * 15; } - RenderSystem.setShaderTexture(0, axis ? LambdaControlsClient.CONTROLLER_AXIS : LambdaControlsClient.CONTROLLER_BUTTONS); + RenderSystem.setShaderTexture(0, axis ? MidnightControlsClient.CONTROLLER_AXIS : button >= 15 && button <= 19 ? MidnightControlsClient.CONTROLLER_EXPANDED :MidnightControlsClient.CONTROLLER_BUTTONS); RenderSystem.disableDepthTest(); - int assetSize = axis ? AXIS_SIZE : BUTTON_SIZE; + int assetSize = axis || (button >= 15 && button <= 18) ? AXIS_SIZE : BUTTON_SIZE; RenderSystem.setShaderColor(1.f, second ? 0.f : 1.f, 1.f, 1.f); DrawableHelper.drawTexture(matrices, x + (ICON_SIZE / 2 - assetSize / 2), y + (ICON_SIZE / 2 - assetSize / 2), - (float) buttonOffset, (float) (controllerType * (axis ? AXIS_SIZE : BUTTON_SIZE)), + (float) buttonOffset, (float) (controllerType * assetSize), assetSize, assetSize, 256, 256); RenderSystem.enableDepthTest(); @@ -177,7 +181,7 @@ public class LambdaControlsRenderer { int buttonWidth = drawButton(matrices, x, y, button, client).length(); var translatedAction = I18n.translate(action); - int textY = (LambdaControlsRenderer.ICON_SIZE / 2 - client.textRenderer.fontHeight / 2) + 1; + int textY = (MidnightControlsRenderer.ICON_SIZE / 2 - client.textRenderer.fontHeight / 2) + 1; return client.textRenderer.drawWithShadow(matrices, translatedAction, (float) (x + buttonWidth + 2), (float) (y + textY), 14737632); } @@ -190,8 +194,8 @@ public class LambdaControlsRenderer { } public static void renderVirtualCursor(@NotNull MatrixStack matrices, @NotNull MinecraftClient client) { - if (!LambdaControlsClient.get().config.hasVirtualMouse() || (client.currentScreen == null - || LambdaInput.isScreenInteractive(client.currentScreen))) + if (!MidnightControlsConfig.virtualMouse || (client.currentScreen == null + || MidnightInput.isScreenInteractive(client.currentScreen))) return; int mouseX = (int) (client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()); @@ -203,7 +207,7 @@ public class LambdaControlsRenderer { int guiLeft = inventoryScreen.getX(); int guiTop = inventoryScreen.getY(); - Slot slot = inventoryScreen.lambdacontrols$getSlotAt(mouseX, mouseY); + Slot slot = inventoryScreen.midnightcontrols$getSlotAt(mouseX, mouseY); if (slot != null) { mouseX = guiLeft + slot.x; @@ -213,7 +217,7 @@ public class LambdaControlsRenderer { } if (!hoverSlot) { - var slot = LambdaControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY); + var slot = MidnightControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY); if (slot != null) { mouseX = slot.x(); @@ -243,9 +247,9 @@ public class LambdaControlsRenderer { RenderSystem.disableDepthTest(); RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f); - RenderSystem.setShaderTexture(0, LambdaControlsClient.CURSOR_TEXTURE); + RenderSystem.setShaderTexture(0, MidnightControlsClient.CURSOR_TEXTURE); DrawableHelper.drawTexture(matrices, x, y, - hoverSlot ? 16.f : 0.f, LambdaControlsClient.get().config.getVirtualMouseSkin().ordinal() * 16.f, + hoverSlot ? 16.f : 0.f, MidnightControlsConfig.virtualMouseSkin.ordinal() * 16.f, 16, 16, 32, 64); RenderSystem.enableDepthTest(); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java similarity index 57% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java index cc22865..c545e43 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsSettingsScreen.java @@ -1,19 +1,19 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui; +package eu.midnightdust.midnightcontrols.client.gui; -import dev.lambdaurora.lambdacontrols.LambdaControls; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig; -import dev.lambdaurora.lambdacontrols.client.controller.Controller; -import dev.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget; +import eu.midnightdust.midnightcontrols.MidnightControls; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.controller.Controller; +import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget; import dev.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.option.*; @@ -38,13 +38,12 @@ import net.minecraft.util.Util; import org.lwjgl.glfw.GLFW; /** - * Represents the LambdaControls settings screen. + * Represents the midnightcontrols settings screen. */ -public class LambdaControlsSettingsScreen extends SpruceScreen { +public class MidnightControlsSettingsScreen extends SpruceScreen { private static final Text SDL2_GAMEPAD_TOOL = new LiteralText("SDL2 Gamepad Tool").formatted(Formatting.GREEN); public static final String GAMEPAD_TOOL_URL = "https://generalarcade.com/gamepadtool/"; - final LambdaControlsClient mod = LambdaControlsClient.get(); - private final LambdaControlsConfig config = this.mod.config; + final MidnightControlsClient mod = MidnightControlsClient.get(); private final Screen parent; // General options private final SpruceOption inputModeOption; @@ -68,17 +67,17 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { private final SpruceOption hudSideOption; // Controller options private final SpruceOption controllerOption = - new SpruceCyclingOption("lambdacontrols.menu.controller", + new SpruceCyclingOption("midnightcontrols.menu.controller", amount -> { - int id = this.config.getController().id(); + int id = MidnightControlsConfig.getController().id(); id += amount; if (id > GLFW.GLFW_JOYSTICK_LAST) id = GLFW.GLFW_JOYSTICK_1; id = searchNextAvailableController(id, false); - this.config.setController(Controller.byId(id)); + MidnightControlsConfig.setController(Controller.byId(id)); }, option -> { - var controller = this.config.getController(); + var controller = MidnightControlsConfig.getController(); var controllerName = controller.getName(); if (!controller.isConnected()) return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED)); @@ -87,16 +86,16 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { else return option.getDisplayText(new LiteralText(controllerName)); }, null); - private final SpruceOption secondControllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller2", + private final SpruceOption secondControllerOption = new SpruceCyclingOption("midnightcontrols.menu.controller2", amount -> { - int id = this.config.getSecondController().map(Controller::id).orElse(-1); + int id = MidnightControlsConfig.getSecondController().map(Controller::id).orElse(-1); id += amount; if (id > GLFW.GLFW_JOYSTICK_LAST) id = -1; id = searchNextAvailableController(id, true); - this.config.setSecondController(id == -1 ? null : Controller.byId(id)); + MidnightControlsConfig.setSecondController(id == -1 ? null : Controller.byId(id)); }, - option -> this.config.getSecondController().map(controller -> { + option -> MidnightControlsConfig.getSecondController().map(controller -> { var controllerName = controller.getName(); if (!controller.isConnected()) return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED)); @@ -105,23 +104,23 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { else return option.getDisplayText(new LiteralText(controllerName)); }).orElse(option.getDisplayText(SpruceTexts.OPTIONS_OFF.shallowCopy().formatted(Formatting.RED))), - new TranslatableText("lambdacontrols.tooltip.controller2")); + new TranslatableText("midnightcontrols.tooltip.controller2")); private final SpruceOption unfocusedInputOption; private final SpruceOption invertsRightXAxis; private final SpruceOption invertsRightYAxis; private final SpruceOption rightDeadZoneOption; private final SpruceOption leftDeadZoneOption; private final SpruceOption[] maxAnalogValueOptions = new SpruceOption[]{ - maxAnalogValueOption(this.config, "lambdacontrols.menu.max_left_x_value", GLFW.GLFW_GAMEPAD_AXIS_LEFT_X), - maxAnalogValueOption(this.config, "lambdacontrols.menu.max_left_y_value", GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y), - maxAnalogValueOption(this.config, "lambdacontrols.menu.max_right_x_value", GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X), - maxAnalogValueOption(this.config, "lambdacontrols.menu.max_right_y_value", GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y) + maxAnalogValueOption("midnightcontrols.menu.max_left_x_value", GLFW.GLFW_GAMEPAD_AXIS_LEFT_X), + maxAnalogValueOption("midnightcontrols.menu.max_left_y_value", GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y), + maxAnalogValueOption("midnightcontrols.menu.max_right_x_value", GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X), + maxAnalogValueOption("midnightcontrols.menu.max_right_y_value", GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y) }; - private static SpruceOption maxAnalogValueOption(LambdaControlsConfig config, String key, int axis) { + private static SpruceOption maxAnalogValueOption(String key, int axis) { return new SpruceDoubleOption(key, .25f, 1.f, 0.05f, - () -> config.getAxisMaxValue(axis), - newValue -> config.setAxisMaxValue(axis, newValue), + () -> MidnightControlsConfig.getAxisMaxValue(axis), + newValue -> MidnightControlsConfig.setAxisMaxValue(axis, newValue), option -> option.getDisplayText(new LiteralText(String.format("%.2f", option.get()))), new TranslatableText(key.replace("menu", "tooltip")) ); @@ -145,125 +144,102 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { return connected ? newId : searchNextAvailableController(newId, allowNone); } - public LambdaControlsSettingsScreen(Screen parent, boolean hideControls) { - super(new TranslatableText("lambdacontrols.title.settings")); + public MidnightControlsSettingsScreen(Screen parent, boolean hideControls) { + super(new TranslatableText("midnightcontrols.title.settings")); this.parent = parent; // General options - this.inputModeOption = new SpruceCyclingOption("lambdacontrols.menu.controls_mode", + this.inputModeOption = new SpruceCyclingOption("midnightcontrols.menu.controls_mode", amount -> { - var next = this.config.getControlsMode().next(); - this.config.setControlsMode(next); - this.config.save(); + var next = MidnightControlsConfig.controlsMode.next(); + MidnightControlsConfig.controlsMode = next; + MidnightControlsConfig.save(); if (this.client.player != null) { - ClientPlayNetworking.getSender().sendPacket(LambdaControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next)); + ClientPlayNetworking.getSender().sendPacket(MidnightControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next)); } - }, option -> option.getDisplayText(new TranslatableText(this.config.getControlsMode().getTranslationKey())), - new TranslatableText("lambdacontrols.tooltip.controls_mode")); - this.autoSwitchModeOption = new SpruceToggleBooleanOption("lambdacontrols.menu.auto_switch_mode", this.config::hasAutoSwitchMode, - this.config::setAutoSwitchMode, new TranslatableText("lambdacontrols.tooltip.auto_switch_mode")); - this.rotationSpeedOption = new SpruceDoubleOption("lambdacontrols.menu.rotation_speed", 0.0, 100.0, .5f, - this.config::getRotationSpeed, - newValue -> { - synchronized (this.config) { - this.config.setRotationSpeed(newValue); - } - }, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))), - new TranslatableText("lambdacontrols.tooltip.rotation_speed")); - this.mouseSpeedOption = new SpruceDoubleOption("lambdacontrols.menu.mouse_speed", 0.0, 150.0, .5f, - this.config::getMouseSpeed, - newValue -> { - synchronized (this.config) { - this.config.setMouseSpeed(newValue); - } - }, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))), - new TranslatableText("lambdacontrols.tooltip.mouse_speed")); + }, option -> option.getDisplayText(new TranslatableText(MidnightControlsConfig.controlsMode.getTranslationKey())), + new TranslatableText("midnightcontrols.tooltip.controls_mode")); + this.autoSwitchModeOption = new SpruceToggleBooleanOption("midnightcontrols.menu.auto_switch_mode", () -> MidnightControlsConfig.autoSwitchMode, + value -> MidnightControlsConfig.autoSwitchMode = value, new TranslatableText("midnightcontrols.tooltip.auto_switch_mode")); + this.rotationSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.rotation_speed", 0.0, 100.0, .5f, + () -> MidnightControlsConfig.rotationSpeed, + value -> MidnightControlsConfig.rotationSpeed = value, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))), + new TranslatableText("midnightcontrols.tooltip.rotation_speed")); + this.mouseSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.mouse_speed", 0.0, 150.0, .5f, + () -> MidnightControlsConfig.mouseSpeed, + value -> MidnightControlsConfig.mouseSpeed = value, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))), + new TranslatableText("midnightcontrols.tooltip.mouse_speed")); this.resetOption = SpruceSimpleActionOption.reset(btn -> { - this.config.reset(); + // TODO + MidnightControlsConfig.init("midnightcontrols", MidnightControlsConfig.class); var client = MinecraftClient.getInstance(); this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); }); // Gameplay options - this.analogMovementOption = new SpruceToggleBooleanOption("lambdacontrols.menu.analog_movement", - this.config::hasAnalogMovement, this.config::setAnalogMovement, - new TranslatableText("lambdacontrols.tooltip.analog_movement")); + this.analogMovementOption = new SpruceToggleBooleanOption("midnightcontrols.menu.analog_movement", + () -> MidnightControlsConfig.analogMovement, value -> MidnightControlsConfig.analogMovement = value, + new TranslatableText("midnightcontrols.tooltip.analog_movement")); this.autoJumpOption = new SpruceToggleBooleanOption("options.autoJump", () -> this.client.options.autoJump, newValue -> this.client.options.autoJump = newValue, null); - this.fastBlockPlacingOption = new SpruceToggleBooleanOption("lambdacontrols.menu.fast_block_placing", this.config::hasFastBlockPlacing, - this.config::setFastBlockPlacing, new TranslatableText("lambdacontrols.tooltip.fast_block_placing")); - this.frontBlockPlacingOption = new SpruceToggleBooleanOption("lambdacontrols.menu.reacharound.horizontal", this.config::hasFrontBlockPlacing, - this.config::setFrontBlockPlacing, new TranslatableText("lambdacontrols.tooltip.reacharound.horizontal")); - this.verticalReacharoundOption = new SpruceToggleBooleanOption("lambdacontrols.menu.reacharound.vertical", this.config::hasVerticalReacharound, - this.config::setVerticalReacharound, new TranslatableText("lambdacontrols.tooltip.reacharound.vertical")); - this.flyDriftingOption = new SpruceToggleBooleanOption("lambdacontrols.menu.fly_drifting", this.config::hasFlyDrifting, - this.config::setFlyDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting")); - this.flyVerticalDriftingOption = new SpruceToggleBooleanOption("lambdacontrols.menu.fly_drifting_vertical", this.config::hasFlyVerticalDrifting, - this.config::setFlyVerticalDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting_vertical")); + this.fastBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fast_block_placing", () -> MidnightControlsConfig.fastBlockPlacing, + value -> MidnightControlsConfig.fastBlockPlacing = value, new TranslatableText("midnightcontrols.tooltip.fast_block_placing")); + this.frontBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.horizontal", () -> MidnightControlsConfig.horizontalReacharound, + value -> MidnightControlsConfig.horizontalReacharound = value, new TranslatableText("midnightcontrols.tooltip.reacharound.horizontal")); + this.verticalReacharoundOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.vertical", () -> MidnightControlsConfig.verticalReacharound, + value -> MidnightControlsConfig.verticalReacharound = value, new TranslatableText("midnightcontrols.tooltip.reacharound.vertical")); + this.flyDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting", () -> MidnightControlsConfig.flyDrifting, + value -> MidnightControlsConfig.flyDrifting = value, new TranslatableText("midnightcontrols.tooltip.fly_drifting")); + this.flyVerticalDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting_vertical", () -> MidnightControlsConfig.verticalFlyDrifting, + value -> MidnightControlsConfig.verticalFlyDrifting = value, new TranslatableText("midnightcontrols.tooltip.fly_drifting_vertical")); // Appearance options - this.controllerTypeOption = new SpruceCyclingOption("lambdacontrols.menu.controller_type", - amount -> this.config.setControllerType(this.config.getControllerType().next()), - option -> option.getDisplayText(this.config.getControllerType().getTranslatedText()), - new TranslatableText("lambdacontrols.tooltip.controller_type")); - this.virtualMouseSkinOption = new SpruceCyclingOption("lambdacontrols.menu.virtual_mouse.skin", - amount -> this.config.setVirtualMouseSkin(this.config.getVirtualMouseSkin().next()), - option -> option.getDisplayText(this.config.getVirtualMouseSkin().getTranslatedText()), + this.controllerTypeOption = new SpruceCyclingOption("midnightcontrols.menu.controller_type", + amount -> MidnightControlsConfig.controllerType = MidnightControlsConfig.controllerType.next(), + option -> option.getDisplayText(MidnightControlsConfig.controllerType.getTranslatedText()), + new TranslatableText("midnightcontrols.tooltip.controller_type")); + this.virtualMouseSkinOption = new SpruceCyclingOption("midnightcontrols.menu.virtual_mouse.skin", + amount -> MidnightControlsConfig.virtualMouseSkin = MidnightControlsConfig.virtualMouseSkin.next(), + option -> option.getDisplayText(MidnightControlsConfig.virtualMouseSkin.getTranslatedText()), null); - this.hudEnableOption = new SpruceToggleBooleanOption("lambdacontrols.menu.hud_enable", this.config::isHudEnabled, - this.mod::setHudEnabled, new TranslatableText("lambdacontrols.tooltip.hud_enable")); - this.hudSideOption = new SpruceCyclingOption("lambdacontrols.menu.hud_side", - amount -> this.config.setHudSide(this.config.getHudSide().next()), - option -> option.getDisplayText(this.config.getHudSide().getTranslatedText()), - new TranslatableText("lambdacontrols.tooltip.hud_side")); + this.hudEnableOption = new SpruceToggleBooleanOption("midnightcontrols.menu.hud_enable", () -> MidnightControlsConfig.hudEnable, + this.mod::setHudEnabled, new TranslatableText("midnightcontrols.tooltip.hud_enable")); + this.hudSideOption = new SpruceCyclingOption("midnightcontrols.menu.hud_side", + amount -> MidnightControlsConfig.hudSide = MidnightControlsConfig.hudSide.next(), + option -> option.getDisplayText(MidnightControlsConfig.hudSide.getTranslatedText()), + new TranslatableText("midnightcontrols.tooltip.hud_side")); // Controller options - this.rightDeadZoneOption = new SpruceDoubleOption("lambdacontrols.menu.right_dead_zone", 0.05, 1.0, .05f, - this.config::getRightDeadZone, - newValue -> { - synchronized (this.config) { - this.config.setRightDeadZone(newValue); - } - }, option -> { + this.rightDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.right_dead_zone", 0.05, 1.0, .05f, + () -> MidnightControlsConfig.rightDeadZone, + value -> MidnightControlsConfig.rightDeadZone = value, option -> { var value = String.valueOf(option.get()); return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5)))); - }, new TranslatableText("lambdacontrols.tooltip.right_dead_zone")); - this.leftDeadZoneOption = new SpruceDoubleOption("lambdacontrols.menu.left_dead_zone", 0.05, 1.0, .05f, - this.config::getLeftDeadZone, - newValue -> { - synchronized (this.config) { - this.config.setLeftDeadZone(newValue); - } - }, option -> { + }, new TranslatableText("midnightcontrols.tooltip.right_dead_zone")); + this.leftDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.left_dead_zone", 0.05, 1.0, .05f, + () -> MidnightControlsConfig.leftDeadZone, + value -> MidnightControlsConfig.leftDeadZone = value, option -> { var value = String.valueOf(option.get()); return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5)))); - }, new TranslatableText("lambdacontrols.tooltip.left_dead_zone")); - this.invertsRightXAxis = new SpruceToggleBooleanOption("lambdacontrols.menu.invert_right_x_axis", this.config::doesInvertRightXAxis, - newValue -> { - synchronized (this.config) { - this.config.setInvertRightXAxis(newValue); - } - }, null); - this.invertsRightYAxis = new SpruceToggleBooleanOption("lambdacontrols.menu.invert_right_y_axis", this.config::doesInvertRightYAxis, - newValue -> { - synchronized (this.config) { - this.config.setInvertRightYAxis(newValue); - } - }, null); - this.unfocusedInputOption = new SpruceToggleBooleanOption("lambdacontrols.menu.unfocused_input", this.config::hasUnfocusedInput, - this.config::setUnfocusedInput, new TranslatableText("lambdacontrols.tooltip.unfocused_input")); - this.virtualMouseOption = new SpruceToggleBooleanOption("lambdacontrols.menu.virtual_mouse", this.config::hasVirtualMouse, - this.config::setVirtualMouse, new TranslatableText("lambdacontrols.tooltip.virtual_mouse")); + }, new TranslatableText("midnightcontrols.tooltip.left_dead_zone")); + this.invertsRightXAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_x_axis", () -> MidnightControlsConfig.invertRightXAxis, + value -> MidnightControlsConfig.invertRightXAxis = value, null); + this.invertsRightYAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_y_axis", () -> MidnightControlsConfig.invertRightYAxis, + value -> MidnightControlsConfig.invertRightYAxis = value, null); + this.unfocusedInputOption = new SpruceToggleBooleanOption("midnightcontrols.menu.unfocused_input", () -> MidnightControlsConfig.unfocusedInput, + value -> MidnightControlsConfig.unfocusedInput = value, new TranslatableText("midnightcontrols.tooltip.unfocused_input")); + this.virtualMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.virtual_mouse", () -> MidnightControlsConfig.virtualMouse, + value -> MidnightControlsConfig.virtualMouse = value, new TranslatableText("midnightcontrols.tooltip.virtual_mouse")); } @Override public void removed() { - this.config.save(); + MidnightControlsConfig.save(); super.removed(); } @Override public void onClose() { - this.config.save(); + MidnightControlsConfig.save(); super.onClose(); } @@ -279,7 +255,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { this.addDrawableChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150)); this.addDrawableChild(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE, - btn -> this.client.openScreen(this.parent))); + btn -> this.client.setScreen(this.parent))); } public void buildTabs() { @@ -288,22 +264,22 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { Math.max(116, this.width / 8), 0); this.addDrawableChild(tabs); - tabs.addSeparatorEntry(new TranslatableText("lambdacontrols.menu.separator.general")); - tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.general"), null, + tabs.addSeparatorEntry(new TranslatableText("midnightcontrols.menu.separator.general")); + tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.general"), null, this::buildGeneralTab); - tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.gameplay"), null, + tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.gameplay"), null, this::buildGameplayTab); - tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.visual"), null, + tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.visual"), null, this::buildVisualTab); tabs.addSeparatorEntry(new TranslatableText("options.controls")); - tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.controller_controls"), null, + tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.controller_controls"), null, this::buildControllerControlsTab); - tabs.addSeparatorEntry(new TranslatableText("lambdacontrols.menu.separator.controller")); - tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.controller"), null, + tabs.addSeparatorEntry(new TranslatableText("midnightcontrols.menu.separator.controller")); + tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.controller"), null, this::buildControllerTab); - tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.mappings.string"), null, + tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.mappings.string"), null, this::buildMappingsStringEditorTab); } @@ -333,7 +309,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { var list = new SpruceOptionListWidget(Position.origin(), width, height); list.addSingleOptionEntry(this.controllerTypeOption); list.addSingleOptionEntry(this.virtualMouseSkinOption); - list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null)); + list.addSingleOptionEntry(new SpruceSeparatorOption("midnightcontrols.menu.title.hud", true, null)); list.addSingleOptionEntry(this.hudEnableOption); list.addSingleOptionEntry(this.hudSideOption); return list; @@ -347,7 +323,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { var root = new SpruceContainerWidget(Position.origin(), width, height); var aboutMappings1 = new SpruceLabelWidget(Position.of(0, 2), - new TranslatableText("lambdacontrols.controller.mappings.1", SDL2_GAMEPAD_TOOL), + new TranslatableText("midnightcontrols.controller.mappings.1", SDL2_GAMEPAD_TOOL), width, true); var gamepadToolUrlLabel = new SpruceLabelWidget(Position.of(0, aboutMappings1.getHeight() + 4), @@ -357,7 +333,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { var aboutMappings3 = new SpruceLabelWidget(Position.of(0, aboutMappings1.getHeight() + gamepadToolUrlLabel.getHeight() + 6), - new TranslatableText("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), + new TranslatableText("midnightcontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), width, true); int listHeight = height - 8 - aboutMappings1.getHeight() - aboutMappings3.getHeight() - gamepadToolUrlLabel.getHeight(); @@ -390,6 +366,6 @@ public class LambdaControlsSettingsScreen extends SpruceScreen { @Override public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) { - drawCenteredText(matrices, this.textRenderer, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215); + drawCenteredText(matrices, this.textRenderer, I18n.translate("midnightcontrols.menu.title"), this.width / 2, 8, 16777215); } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/ReloadControllerMappingsOption.java similarity index 69% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/ReloadControllerMappingsOption.java index 657a8df..bd3f1db 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/ReloadControllerMappingsOption.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui; +package eu.midnightdust.midnightcontrols.client.gui; -import dev.lambdaurora.lambdacontrols.client.controller.Controller; +import eu.midnightdust.midnightcontrols.client.controller.Controller; import dev.lambdaurora.spruceui.option.SpruceSimpleActionOption; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget; import net.minecraft.client.MinecraftClient; @@ -24,7 +24,7 @@ import java.util.function.Consumer; * Represents the option to reload the controller mappings. */ public class ReloadControllerMappingsOption { - private static final String KEY = "lambdacontrols.menu.reload_controller_mappings"; + private static final String KEY = "midnightcontrols.menu.reload_controller_mappings"; public static SpruceSimpleActionOption newOption(@Nullable Consumer before) { return SpruceSimpleActionOption.of(KEY, btn -> { @@ -32,10 +32,10 @@ public class ReloadControllerMappingsOption { if (before != null) before.accept(btn); Controller.updateMappings(); - if (client.currentScreen instanceof LambdaControlsSettingsScreen) + if (client.currentScreen instanceof MidnightControlsSettingsScreen) client.currentScreen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT, - new TranslatableText("lambdacontrols.controller.mappings.updated"), LiteralText.EMPTY)); - }, new TranslatableText("lambdacontrols.tooltip.reload_controller_mappings")); + new TranslatableText("midnightcontrols.controller.mappings.updated"), LiteralText.EMPTY)); + }, new TranslatableText("midnightcontrols.tooltip.reload_controller_mappings")); } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/RingScreen.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/RingScreen.java similarity index 66% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/RingScreen.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/RingScreen.java index 7ed9bb8..4a2c9a6 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/RingScreen.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/RingScreen.java @@ -1,16 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui; +package eu.midnightdust.midnightcontrols.client.gui; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.ring.RingPage; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.ring.RingPage; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.TranslatableText; @@ -23,15 +23,15 @@ import net.minecraft.text.TranslatableText; * @since 1.4.3 */ public class RingScreen extends Screen { - protected final LambdaControlsClient mod; + protected final MidnightControlsClient mod; public RingScreen() { - super(new TranslatableText("lambdacontrols.menu.title.ring")); - this.mod = LambdaControlsClient.get(); + super(new TranslatableText("midnightcontrols.menu.title.ring")); + this.mod = MidnightControlsClient.get(); } @Override - public boolean isPauseScreen() { + public boolean shouldPause() { return false; } @@ -46,7 +46,7 @@ public class RingScreen extends Screen { @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { - /*if (LambdaControlsClient.BINDING_RING.matchesMouse(button)) { + /*if (midnightcontrolsClient.BINDING_RING.matchesMouse(button)) { this.onClose(); return true; }*/ diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java new file mode 100644 index 0000000..55809f3 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java @@ -0,0 +1,301 @@ +/* + * Copyright © 2021 LambdAurora + * + * This file is part of midnightcontrols. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package eu.midnightdust.midnightcontrols.client.gui; + +import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget; +import eu.midnightdust.midnightcontrols.client.HudSide; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; +import net.minecraft.client.gui.screen.ChatScreen; +import net.minecraft.client.gui.screen.GameMenuScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.InventoryScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TexturedButtonWidget; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; +import net.minecraft.text.LiteralText; +import net.minecraft.util.Arm; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import org.jetbrains.annotations.NotNull; +import org.lwjgl.glfw.GLFW; + +import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X; +import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y; + +/** + * Represents the touchscreen overlay + */ +public class TouchscreenOverlay extends Screen { + public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png"); + private MidnightControlsClient mod; + private SpruceTexturedButtonWidget jumpButton; + private SpruceTexturedButtonWidget flyButton; + private SpruceTexturedButtonWidget flyUpButton; + private SpruceTexturedButtonWidget flyDownButton; + private int flyButtonEnableTicks = 0; + private int forwardButtonTick = 0; + private SpruceTexturedButtonWidget forwardLeftButton; + private SpruceTexturedButtonWidget forwardRightButton; + private SpruceTexturedButtonWidget startSneakButton; + private SpruceTexturedButtonWidget endSneakButton; + + public TouchscreenOverlay(@NotNull MidnightControlsClient mod) + { + super(new LiteralText("Touchscreen overlay")); + this.mod = mod; + this.passEvents = true; + } + +// @Override +// public boolean shouldPause() +// { +// return false; +// } +// +// @Override +// public boolean keyPressed(int keyCode, int scanCode, int modifiers) +// { +// super.keyPressed(keyCode,scanCode,modifiers); +// //return false; +// return true; +// } +// +// private void pauseGame(boolean bl) +// { +// if (this.client == null) +// return; +// boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote(); +// if (bl2) { +// this.client.setScreen(new GameMenuScreen(!bl)); +// this.client.getSoundManager().pauseAll(); +// } else { +// this.client.setScreen(new GameMenuScreen(true)); +// } +// } +// +// /** +// * Updates the forward button ticks cooldown. +// * +// * @param state The button state. +// * +// */ +// private void updateForwardButtonsState(boolean state) +// { +// if (state) +// this.forwardButtonTick = -1; +// else +// this.forwardButtonTick = 20; +// } +// +// /** +// * Updates the jump buttons. +// */ +// private void updateJumpButtons() +// { +// if (this.client == null) +// return; +// if (!this.client.interactionManager.isFlyingLocked()) { +// boolean oldStateFly = this.flyButton.visible; +// this.jumpButton.visible = false; +// this.flyButton.visible = true; +// this.flyUpButton.visible = true; +// this.flyDownButton.visible = true; +// if (oldStateFly != this.flyButton.visible) { +// this.flyButtonEnableTicks = 5; +// this.handleJump(null, false); +// } else if (this.flyButtonEnableTicks > 0) +// this.flyButtonEnableTicks--; +// } else { +// this.jumpButton.visible = true; +// this.flyButton.visible = false; +// this.flyUpButton.visible = false; +// this.flyDownButton.visible = false; +// } +// } +// +// /** +// * Handles the jump button. +// * +// * @param btn The pressed button. +// * @param state The state of the jump button. +// */ +// private void handleJump(ButtonWidget btn, boolean state) +// { +// ((KeyBindingAccessor) this.client.options.keyJump).midnightcontrols$handlePressState(state); +// } +// +// @Override +// public void tick() +// { +// if (this.forwardButtonTick > 0) { +// this.forwardButtonTick--; +// } else if (this.forwardButtonTick == 0) { +// if (this.forwardLeftButton.visible) +// this.forwardLeftButton.visible = false; +// if (this.forwardRightButton.visible) +// this.forwardRightButton.visible = false; +// } +// this.updateJumpButtons(); +// } +// +// @Override +// protected void init() +// { +// super.init(); +// int scaledWidth = this.client.getWindow().getScaledWidth(); +// int scaledHeight = this.client.getWindow().getScaledHeight(); +// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256, +// btn -> this.client.setScreen(new ChatScreen("")), LiteralText.EMPTY)); +// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, +// btn -> this.pauseGame(false))); +// // Inventory buttons. +// int inventoryButtonX = scaledWidth / 2; +// int inventoryButtonY = scaledHeight - 16 - 5; +// if (this.client.options.mainArm == Arm.LEFT) { +// inventoryButtonX = inventoryButtonX - 91 - 24; +// } else { +// inventoryButtonX = inventoryButtonX + 91 + 4; +// } +// this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, +// btn -> { +// if (this.client.interactionManager.hasRidingInventory()) { +// this.client.player.openRidingInventory(); +// } else { +// this.client.getTutorialManager().onInventoryOpened(); +// this.client.openScreen(new InventoryScreen(this.client.player)); +// } +// })); +// int jumpButtonX, swapHandsX, sneakButtonX; +// int sneakButtonY = scaledHeight - 10 - 40 - 5; +// if (MidnightControlsConfig.hudSide == HudSide.LEFT) { +// jumpButtonX = scaledWidth - 20 - 20; +// swapHandsX = jumpButtonX - 5 - 40; +// sneakButtonX = 10 + 20 + 5; +// } else { +// jumpButtonX = 20; +// swapHandsX = jumpButtonX + 5 + 40; +// sneakButtonX = scaledWidth - 10 - 40 - 5; +// } +// // Swap items hand. +// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY, 20, 20, 0, 160, 20, WIDGETS_LOCATION, +// (btn, state) -> { +// if (state) { +// if (!this.client.player.isSpectator()) { +// this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN)); +// } +// } +// })); +// // Drop +// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION, +// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyDrop).midnightcontrols$handlePressState(state))); +// // Jump keys +// this.addDrawableChild(this.jumpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 0, 40, 20, WIDGETS_LOCATION, +// this::handleJump)); +// this.addDrawableChild(this.flyButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 20, 40, 20, WIDGETS_LOCATION, +// (btn, state) -> { +// if (this.flyButtonEnableTicks == 0) this.client..abilities.flying = false; +// })); +// this.addDrawableChild(this.flyUpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION, +// this::handleJump)); +// this.addDrawableChild(this.flyDownButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION, +// (btn, state) -> ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(state))); +// this.updateJumpButtons(); +// // Movements keys +// this.addDrawableChild((this.startSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 0, 120, 20, WIDGETS_LOCATION, +// (btn, state) -> { +// if (state) { +// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(true); +// this.startSneakButton.setVisible(false); +// this.endSneakButton.setVisible(true); +// } +// }))); +// this.addDrawableChild((this.endSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 20, 120, 20, WIDGETS_LOCATION, +// (btn, state) -> { +// if (state) { +// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(false); +// this.endSneakButton.setVisible(false); +// this.startSneakButton.setVisible(true); +// } +// }))); +// this.endSneakButton.setVisible(false); +// this.addDrawableChild(this.forwardLeftButton = new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION, +// (btn, state) -> { +// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); +// ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state); +// this.updateForwardButtonsState(state); +// })); +// this.forwardLeftButton.setVisible(false); +// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION, +// (btn, state) -> { +// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); +// this.updateForwardButtonsState(state); +// this.forwardLeftButton.setVisible(true); +// this.forwardRightButton.setVisible(true); +// })); +// this.addDrawableChild(this.forwardRightButton = new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION, +// (btn, state) -> { +// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); +// ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state); +// this.updateForwardButtonsState(state); +// })); +// this.forwardRightButton.setVisible(true); +// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY, 20, 20, 20, 80, 20, WIDGETS_LOCATION, +// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state))); +// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION, +// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyBack).midnightcontrols$handlePressState(state))); +// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY, 20, 20, 60, 80, 20, WIDGETS_LOCATION, +// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state))); +// +// this.children().forEach(button -> { +// if (button instanceof SpruceTexturedButtonWidget) { +// ((SpruceTexturedButtonWidget) button).setSilent(true); +// } +// }); +// } +// +// @Override +// public boolean mouseClicked(double mouseX, double mouseY, int button) +// { +// if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) { +// int centerX = this.width / 2; +// if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { +// for (int slot = 0; slot < 9; ++slot) { +// int slotX = centerX - 90 + slot * 20 + 2; +// if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { +// this.client.player.getInventory().selectedSlot = slot; +// return true; +// } +// } +// } +// } +// return super.mouseClicked(mouseX, mouseY, button); +// } +// +// @Override +// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) +// { +// if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) { +// if (deltaY > 0.01) +// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2); +// else if (deltaY < 0.01) +// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1); +// +// if (deltaX > 0.01) +// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2); +// else if (deltaX < 0.01) +// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1); +// } +// return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); +// } +} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControllerButtonWidget.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerButtonWidget.java similarity index 82% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControllerButtonWidget.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerButtonWidget.java index d427d73..7aac73a 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControllerButtonWidget.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerButtonWidget.java @@ -1,16 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui.widget; +package eu.midnightdust.midnightcontrols.client.gui.widget; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer; import dev.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget; @@ -51,7 +51,7 @@ public class ControllerButtonWidget extends AbstractSpruceIconButtonWidget { if (this.binding.getButton().length > 1) { x += (this.width / 2 - this.iconWidth / 2) - 4; } - var size = LambdaControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance()); + var size = MidnightControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance()); this.iconWidth = size.length(); return size.height(); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControllerControlsWidget.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerControlsWidget.java similarity index 71% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControllerControlsWidget.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerControlsWidget.java index 38bf20c..f8f2c67 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControllerControlsWidget.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControllerControlsWidget.java @@ -1,17 +1,18 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui.widget; +package eu.midnightdust.midnightcontrols.client.gui.widget; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.controller.InputManager; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.InputManager; import dev.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget; @@ -29,7 +30,7 @@ import java.util.stream.Collectors; * Represents the controls screen. */ public class ControllerControlsWidget extends SpruceContainerWidget { - final LambdaControlsClient mod; + final MidnightControlsClient mod; private ControlsListWidget bindingsListWidget; private SpruceButtonWidget resetButton; public ButtonBinding focusedBinding; @@ -38,25 +39,25 @@ public class ControllerControlsWidget extends SpruceContainerWidget { public ControllerControlsWidget(Position position, int width, int height) { super(position, width, height); - this.mod = LambdaControlsClient.get(); + this.mod = MidnightControlsClient.get(); this.init(); } protected void init() { this.addChild(new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, 18), 310, 20, - new TranslatableText("lambdacontrols.menu.keyboard_controls"), - btn -> this.client.openScreen(new ControlsOptionsScreen(null, this.client.options)))); + new TranslatableText("midnightcontrols.menu.keyboard_controls"), + btn -> this.client.setScreen(new ControlsOptionsScreen(null, this.client.options)))); this.bindingsListWidget = new ControlsListWidget(Position.of(this, 0, 43), this.width, this.height - 43 - 35, this); this.addChild(this.bindingsListWidget); this.addChild(this.resetButton = new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150, 20, SpruceTexts.CONTROLS_RESET_ALL, - btn -> InputManager.streamBindings().collect(Collectors.toSet()).forEach(binding -> this.mod.config.setButtonBinding(binding, binding.getDefaultButton())))); + btn -> InputManager.streamBindings().collect(Collectors.toSet()).forEach(binding -> MidnightControlsConfig.setButtonBinding(binding, binding.getDefaultButton())))); } @Override public void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) { - drawCenteredText(matrices, this.client.textRenderer, new TranslatableText("lambdacontrols.menu.title.controller_controls"), + drawCenteredText(matrices, this.client.textRenderer, new TranslatableText("midnightcontrols.menu.title.controller_controls"), this.getX() + this.width / 2, this.getY() + 4, 16777215); this.resetButton.setActive(InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault))); super.renderWidget(matrices, mouseX, mouseY, delta); @@ -64,7 +65,7 @@ public class ControllerControlsWidget extends SpruceContainerWidget { public void finishBindingEdit(int... buttons) { if (this.focusedBinding == null) return; - this.mod.config.setButtonBinding(this.focusedBinding, buttons); + MidnightControlsConfig.setButtonBinding(this.focusedBinding, buttons); this.focusedBinding = null; } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControlsListWidget.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControlsListWidget.java similarity index 92% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControlsListWidget.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControlsListWidget.java index f9a3401..8e91d33 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/gui/widget/ControlsListWidget.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/widget/ControlsListWidget.java @@ -1,18 +1,19 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.gui.widget; +package eu.midnightdust.midnightcontrols.client.gui.widget; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; -import dev.lambdaurora.lambdacontrols.client.controller.ButtonCategory; -import dev.lambdaurora.lambdacontrols.client.controller.InputManager; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory; +import eu.midnightdust.midnightcontrols.client.controller.InputManager; import dev.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.navigation.NavigationDirection; @@ -89,7 +90,7 @@ public class ControlsListWidget extends SpruceEntryListWidget { gui.focusedBinding = binding; - LambdaControlsClient.get().input.beginControlsInput(gui); + MidnightControlsClient.get().input.beginControlsInput(gui); }) { protected Text getNarrationMessage() { return binding.isNotBound() ? new TranslatableText("narrator.controls.unbound", bindingName) @@ -100,7 +101,7 @@ public class ControlsListWidget extends SpruceEntryListWidget LambdaControlsClient.get().config.setButtonBinding(binding, binding.getDefaultButton())) { + btn -> MidnightControlsConfig.setButtonBinding(binding, binding.getDefaultButton())) { protected Text getNarrationMessage() { return new TranslatableText("narrator.controls.reset", bindingName); } @@ -110,12 +111,12 @@ public class ControlsListWidget extends SpruceEntryListWidget { - LambdaControlsClient.get().config.setButtonBinding(binding, UNBOUND); + MidnightControlsConfig.setButtonBinding(binding, UNBOUND); gui.focusedBinding = null; - LambdaControlsClient.get().input.beginControlsInput(null); + MidnightControlsClient.get().input.beginControlsInput(null); }) { protected Text getNarrationMessage() { - return new TranslatableText("lambdacontrols.narrator.unbound", bindingName); + return new TranslatableText("midnightcontrols.narrator.unbound", bindingName); } }; this.children.add(this.unbindButton); diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/AdvancementsScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/AdvancementsScreenAccessor.java similarity index 90% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/AdvancementsScreenAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/AdvancementsScreenAccessor.java index ca13f33..35d7cb0 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/AdvancementsScreenAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/AdvancementsScreenAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; import net.minecraft.advancement.Advancement; import net.minecraft.client.gui.screen.advancement.AdvancementTab; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ClickableWidgetAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClickableWidgetAccessor.java similarity index 81% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ClickableWidgetAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClickableWidgetAccessor.java index 2fe75a5..f94af4c 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ClickableWidgetAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClickableWidgetAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; import net.minecraft.client.gui.widget.ClickableWidget; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ClientPlayerEntityMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClientPlayerEntityMixin.java similarity index 75% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ClientPlayerEntityMixin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClientPlayerEntityMixin.java index 234c8f5..75ef7e6 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClientPlayerEntityMixin.java @@ -1,17 +1,18 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; import com.mojang.authlib.GameProfile; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.controller.MovementHandler; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.controller.MovementHandler; import net.minecraft.client.MinecraftClient; import net.minecraft.client.input.Input; import net.minecraft.client.network.AbstractClientPlayerEntity; @@ -31,7 +32,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; */ @Mixin(ClientPlayerEntity.class) public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity { - private boolean lambdacontrols$driftingPrevented = false; + private boolean midnightcontrols$driftingPrevented = false; @Shadow protected abstract boolean hasMovementInput(); @@ -52,17 +53,17 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity @Inject(method = "move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V")) public void onMove(MovementType type, Vec3d movement, CallbackInfo ci) { - var mod = LambdaControlsClient.get(); + var mod = MidnightControlsClient.get(); if (type == MovementType.SELF) { - if (this.getAbilities().flying && (!mod.config.hasFlyDrifting() || !mod.config.hasFlyVerticalDrifting())) { + if (this.getAbilities().flying && (!MidnightControlsConfig.flyDrifting || !MidnightControlsConfig.verticalFlyDrifting)) { if (!this.hasMovementInput()) { - if (!this.lambdacontrols$driftingPrevented) { - if (!mod.config.hasFlyDrifting()) + if (!this.midnightcontrols$driftingPrevented) { + if (!MidnightControlsConfig.flyDrifting) this.setVelocity(this.getVelocity().multiply(0, 1.0, 0)); } - this.lambdacontrols$driftingPrevented = true; + this.midnightcontrols$driftingPrevented = true; } else - this.lambdacontrols$driftingPrevented = false; + this.midnightcontrols$driftingPrevented = false; } } } @@ -75,7 +76,7 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z")) public void onTickMovement(CallbackInfo ci) { if (this.getAbilities().flying && this.isCamera()) { - if (LambdaControlsClient.get().config.hasFlyVerticalDrifting()) + if (MidnightControlsConfig.verticalFlyDrifting) return; int moving = 0; if (this.input.sneaking) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java new file mode 100644 index 0000000..90ee2c7 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2021 LambdAurora + * + * This file is part of midnightcontrols. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package eu.midnightdust.midnightcontrols.client.mixin; + +import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; +import net.minecraft.client.gui.screen.option.GameOptionsScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.option.GameOptions; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +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; + +/** + * Injects the new controls settings button. + */ +@Mixin(ControlsOptionsScreen.class) +public class ControlsOptionsScreenMixin extends GameOptionsScreen { + public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) { + super(parent, gameOptions, text); + } + @Inject(method = "init", at = @At(value = "INVOKE", ordinal = 4, shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/screen/option/ControlsOptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;")) + private void addControllerButton(CallbackInfo ci) { + int i = this.width / 2 - 155; + int j = i + 160; + int k = this.height / 6 - 12 + 48;; + this.addDrawableChild(new ButtonWidget(j, k, 150, 20, new TranslatableText("midnightcontrols.menu.title.controller").append("..."), (button) -> { + this.client.setScreen(new MidnightControlsSettingsScreen(this, false)); + })); + } +} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/CreativeInventoryScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/CreativeInventoryScreenAccessor.java similarity index 82% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/CreativeInventoryScreenAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/CreativeInventoryScreenAccessor.java index f3e04c6..e820aac 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/CreativeInventoryScreenAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/CreativeInventoryScreenAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.item.ItemGroup; @@ -37,7 +37,7 @@ public interface CreativeInventoryScreenAccessor { * @param group the tab's item group */ @Invoker("setSelectedTab") - void lambdacontrols$setSelectedTab(@NotNull ItemGroup group); + void midnightcontrols$setSelectedTab(@NotNull ItemGroup group); /** * Returns whether the slot belongs to the creative inventory or not. @@ -46,7 +46,7 @@ public interface CreativeInventoryScreenAccessor { * @return true if the slot is from the creative inventory, else false */ @Invoker("isCreativeInventorySlot") - boolean lambdacontrols$isCreativeInventorySlot(@Nullable Slot slot); + boolean midnightcontrols$isCreativeInventorySlot(@Nullable Slot slot); /** * Returns whether the current tab has a scrollbar or not. @@ -54,5 +54,5 @@ public interface CreativeInventoryScreenAccessor { * @return true if the current tab has a scrollbar, else false */ @Invoker("hasScrollbar") - boolean lambdacontrols$hasScrollbar(); + boolean midnightcontrols$hasScrollbar(); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/EntryListWidgetAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/EntryListWidgetAccessor.java similarity index 69% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/EntryListWidgetAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/EntryListWidgetAccessor.java index f333357..e33522c 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/EntryListWidgetAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/EntryListWidgetAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; import net.minecraft.client.gui.widget.EntryListWidget; import org.spongepowered.asm.mixin.Mixin; @@ -16,5 +16,5 @@ import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(EntryListWidget.class) public interface EntryListWidgetAccessor { @Invoker("moveSelection") - void lambdacontrols$moveSelection(EntryListWidget.MoveDirection direction); + void midnightcontrols$moveSelection(EntryListWidget.MoveDirection direction); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/GameOptionsMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameOptionsMixin.java similarity index 89% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/GameOptionsMixin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameOptionsMixin.java index 9b96217..7ce3470 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/GameOptionsMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameOptionsMixin.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; import net.minecraft.client.option.GameOptions; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/GameRendererMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameRendererMixin.java similarity index 63% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/GameRendererMixin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameRendererMixin.java index ea0c041..931071d 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/GameRendererMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameRendererMixin.java @@ -1,16 +1,17 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.GameRenderer; import org.spongepowered.asm.mixin.Final; @@ -28,7 +29,7 @@ public class GameRendererMixin { @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Mouse;getX()D")) private void onRender(float tickDelta, long startTime, boolean fullRender, CallbackInfo ci) { - if (this.client.currentScreen != null && LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) - LambdaControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen); + if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) + MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen); } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/HandledScreenMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/HandledScreenMixin.java new file mode 100644 index 0000000..c54d42e --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/HandledScreenMixin.java @@ -0,0 +1,70 @@ +/* + * Copyright © 2021 LambdAurora + * + * This file is part of midnightcontrols. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package eu.midnightdust.midnightcontrols.client.mixin; + +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.MidnightInput; +import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; +import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer; +import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.screen.slot.Slot; +import net.minecraft.screen.slot.SlotActionType; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.glfw.GLFW; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Represents the mixin for the class ContainerScreen. + */ +@Mixin(HandledScreen.class) +public abstract class HandledScreenMixin implements HandledScreenAccessor { + + @Accessor("x") + public abstract int getX(); + + @Accessor("y") + public abstract int getY(); + + @Invoker("getSlotAt") + public abstract Slot midnightcontrols$getSlotAt(double posX, double posY); + + @Invoker("isClickOutsideBounds") + public abstract boolean midnightcontrols$isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button); + + + @Invoker("onMouseClick") + public abstract void midnightcontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType); + + @Inject(method = "render", at = @At("RETURN")) + public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { + if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) { + var client = MinecraftClient.getInstance(); + int x = 2, y = client.getWindow().getScaledHeight() - 2 - MidnightControlsRenderer.ICON_SIZE; + + x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "midnightcontrols.action.pickup_all", true, client) + 2; + x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "midnightcontrols.action.exit", true, client) + 2; + if (MidnightControlsCompat.isReiPresent()) { + x = 2; + y -= 24; + } + x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "midnightcontrols.action.pickup", true, client) + 2; + MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, "midnightcontrols.action.quick_move", true, client); + } + } +} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/KeyBindingMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java similarity index 75% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/KeyBindingMixin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java index 6e2b903..6d48cf2 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/KeyBindingMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; -import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; +import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; import net.minecraft.client.option.KeyBinding; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -23,7 +23,7 @@ public class KeyBindingMixin implements KeyBindingAccessor { private boolean pressed; @Override - public boolean lambdacontrols$press() { + public boolean midnightcontrols$press() { boolean oldPressed = this.pressed; if (!this.pressed) this.pressed = true; @@ -32,7 +32,7 @@ public class KeyBindingMixin implements KeyBindingAccessor { } @Override - public boolean lambdacontrols$unpress() { + public boolean midnightcontrols$unpress() { if (this.pressed) { this.pressed = false; return true; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java similarity index 72% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java index ff68d4e..f98f39b 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java @@ -1,18 +1,21 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; -import dev.lambdaurora.lambdacontrols.LambdaControlsFeature; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer; +import eu.midnightdust.midnightcontrols.MidnightControls; +import eu.midnightdust.midnightcontrols.MidnightControlsFeature; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightInput; +import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer; import net.minecraft.client.MinecraftClient; +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; @@ -28,6 +31,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -61,13 +65,13 @@ public abstract class MinecraftClientMixin { @Shadow private int itemUseCooldown; - private BlockPos lambdacontrols$lastTargetPos; - private Vec3d lambdacontrols$lastPos; - private Direction lambdacontrols$lastTargetSide; + private BlockPos midnightcontrols$lastTargetPos; + private Vec3d midnightcontrols$lastPos; + private Direction midnightcontrols$lastTargetSide; @Inject(method = "", at = @At("RETURN")) private void onInit(CallbackInfo ci) { - LambdaControlsClient.get().onMcInit((MinecraftClient) (Object) this); + MidnightControlsClient.get().onMcInit((MinecraftClient) (Object) this); } @Inject(method = "tick", at = @At("HEAD")) @@ -75,10 +79,10 @@ public abstract class MinecraftClientMixin { if (this.player == null) return; - if (!LambdaControlsFeature.FAST_BLOCK_PLACING.isAvailable()) + if (!MidnightControlsFeature.FAST_BLOCK_PLACING.isAvailable()) return; - if (this.lambdacontrols$lastPos == null) - this.lambdacontrols$lastPos = this.player.getPos(); + if (this.midnightcontrols$lastPos == null) + this.midnightcontrols$lastPos = this.player.getPos(); int cooldown = this.itemUseCooldown; BlockHitResult hitResult; @@ -87,42 +91,42 @@ public abstract class MinecraftClientMixin { var targetPos = hitResult.getBlockPos(); var side = hitResult.getSide(); - boolean sidewaysBlockPlacing = this.lambdacontrols$lastTargetPos == null || !targetPos.equals(this.lambdacontrols$lastTargetPos.offset(this.lambdacontrols$lastTargetSide)); - boolean backwardsBlockPlacing = this.player.input.movementForward < 0.0f && (this.lambdacontrols$lastTargetPos == null || targetPos.equals(this.lambdacontrols$lastTargetPos.offset(this.lambdacontrols$lastTargetSide))); + boolean sidewaysBlockPlacing = this.midnightcontrols$lastTargetPos == null || !targetPos.equals(this.midnightcontrols$lastTargetPos.offset(this.midnightcontrols$lastTargetSide)); + boolean backwardsBlockPlacing = this.player.input.movementForward < 0.0f && (this.midnightcontrols$lastTargetPos == null || targetPos.equals(this.midnightcontrols$lastTargetPos.offset(this.midnightcontrols$lastTargetSide))); if (cooldown > 1 - && !targetPos.equals(this.lambdacontrols$lastTargetPos) + && !targetPos.equals(this.midnightcontrols$lastTargetPos) && (sidewaysBlockPlacing || backwardsBlockPlacing)) { this.itemUseCooldown = 1; } - this.lambdacontrols$lastTargetPos = targetPos.toImmutable(); - this.lambdacontrols$lastTargetSide = side; + this.midnightcontrols$lastTargetPos = targetPos.toImmutable(); + this.midnightcontrols$lastTargetSide = side; } // Removed front placing sprinting as way too cheaty. /*else if (this.player.isSprinting()) { - hitResult = LambdaControlsClient.get().reacharound.getLastReacharoundResult(); + hitResult = midnightcontrolsClient.get().reacharound.getLastReacharoundResult(); if (hitResult != null) { if (cooldown > 0) this.itemUseCooldown = 0; } }*/ - this.lambdacontrols$lastPos = this.player.getPos(); + this.midnightcontrols$lastPos = this.player.getPos(); } @Inject(method = "render", at = @At("HEAD")) private void onRender(boolean fullRender, CallbackInfo ci) { - LambdaControlsClient.get().onRender((MinecraftClient) (Object) (this)); + MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this)); } @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;render(FJZ)V", shift = At.Shift.AFTER)) private void renderVirtualCursor(boolean fullRender, CallbackInfo ci) { - LambdaControlsRenderer.renderVirtualCursor(new MatrixStack(), (MinecraftClient) (Object) this); + MidnightControlsRenderer.renderVirtualCursor(new MatrixStack(), (MinecraftClient) (Object) this); } @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 onItemUse(CallbackInfo ci, Hand[] hands, int handCount, int handIndex, Hand hand, ItemStack stackInHand) { - var mod = LambdaControlsClient.get(); + var mod = MidnightControlsClient.get(); if (!stackInHand.isEmpty() && this.player.getPitch(0.f) > 35.0F && mod.reacharound.isReacharoundAvailable()) { if (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.MISS && this.player.isOnGround()) { if (!stackInHand.isEmpty() && stackInHand.getItem() instanceof BlockItem) { diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/MouseMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MouseMixin.java similarity index 54% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/MouseMixin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MouseMixin.java index a8a074a..3e014d6 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/MouseMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MouseMixin.java @@ -1,18 +1,18 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; -import dev.lambdaurora.lambdacontrols.ControlsMode; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig; -import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor; +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.util.MouseAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.Mouse; import net.minecraft.client.gui.screen.Screen; @@ -36,13 +36,13 @@ public abstract class MouseMixin implements MouseAccessor { private MinecraftClient client; @Invoker("onCursorPos") - public abstract void lambdacontrols$onCursorPos(long window, double x, double y); + public abstract void midnightcontrols$onCursorPos(long window, double x, double y); - @Inject(method = "method_1605", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/screen/Screen;mouseReleased(DDI)Z")) - private static void onMouseBackButton(boolean[] result, Screen screen, double mouseX, double mouseY, int button, CallbackInfo ci) { - if (!result[0] && button == GLFW.GLFW_MOUSE_BUTTON_4 && screen != null) { - if (LambdaControlsClient.get().input.tryGoBack(screen)) { - result[0] = true; + @Inject(method = "onMouseButton", at = @At(value = "TAIL")) + private void onMouseBackButton(long window, int button, int action, int mods, CallbackInfo ci) { + if (action == 1 && button == GLFW.GLFW_MOUSE_BUTTON_4 && MinecraftClient.getInstance().currentScreen != null) { + if (MidnightControlsClient.get().input.tryGoBack(MinecraftClient.getInstance().currentScreen)) { + action = 0; } } } @@ -50,8 +50,7 @@ public abstract class MouseMixin implements MouseAccessor { @Inject(method = "isCursorLocked", at = @At("HEAD"), cancellable = true) private void isCursorLocked(CallbackInfoReturnable ci) { if (this.client.currentScreen == null) { - var config = LambdaControlsClient.get().config; - if (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()) { + if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse) { ci.setReturnValue(true); ci.cancel(); } @@ -60,9 +59,8 @@ public abstract class MouseMixin implements MouseAccessor { @Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true) private void onCursorLocked(CallbackInfo ci) { - LambdaControlsConfig config = LambdaControlsClient.get().config; if (/*config.getControlsMode() == ControlsMode.TOUCHSCREEN - ||*/ (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse())) + ||*/ (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse)) ci.cancel(); } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/RecipeBookWidgetAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/RecipeBookWidgetAccessor.java similarity index 83% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/RecipeBookWidgetAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/RecipeBookWidgetAccessor.java index 31228d0..71424a0 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/RecipeBookWidgetAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/RecipeBookWidgetAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; @@ -29,5 +29,5 @@ public interface RecipeBookWidgetAccessor { void setCurrentTab(RecipeGroupButtonWidget currentTab); @Invoker("refreshResults") - void lambdacontrols$refreshResults(boolean resetCurrentPage); + void midnightcontrols$refreshResults(boolean resetCurrentPage); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/WorldRendererMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/WorldRendererMixin.java similarity index 86% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/WorldRendererMixin.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/mixin/WorldRendererMixin.java index fdad64b..0f262e1 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/mixin/WorldRendererMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/WorldRendererMixin.java @@ -1,15 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.mixin; +package eu.midnightdust.midnightcontrols.client.mixin; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import net.minecraft.block.ShapeContext; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.*; @@ -62,9 +63,9 @@ public abstract class WorldRendererMixin { ) private void onOutlineRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) { - if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !LambdaControlsClient.get().config.shouldRenderReacharoundOutline()) + if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !MidnightControlsConfig.shouldRenderReacharoundOutline) return; - var result = LambdaControlsClient.get().reacharound.getLastReacharoundResult(); + var result = MidnightControlsClient.get().reacharound.getLastReacharoundResult(); if (result == null) return; var blockPos = result.getBlockPos(); @@ -73,7 +74,7 @@ public abstract class WorldRendererMixin { if (stack == null || !(stack.getItem() instanceof BlockItem)) return; - var mod = LambdaControlsClient.get(); + var mod = MidnightControlsClient.get(); var block = ((BlockItem) stack.getItem()).getBlock(); result = mod.reacharound.withSideForReacharound(result, block); @@ -85,7 +86,7 @@ public abstract class WorldRendererMixin { var pos = camera.getPos(); var outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity())); - int[] color = mod.config.getReacharoundOutlineColor(); + int[] color = MidnightControlsConfig.reacharoundOutlineColor; var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines()); drawShapeOutline(matrices, vertexConsumer, outlineShape, diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/DummyRingAction.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/DummyRingAction.java similarity index 90% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ring/DummyRingAction.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ring/DummyRingAction.java index 8069f94..feb4f6d 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/DummyRingAction.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/DummyRingAction.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.ring; +package eu.midnightdust.midnightcontrols.client.ring; import com.electronwill.nightconfig.core.Config; import net.minecraft.client.font.TextRenderer; diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/KeyBindingRingAction.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/KeyBindingRingAction.java similarity index 84% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ring/KeyBindingRingAction.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ring/KeyBindingRingAction.java index 7cab9c9..8da8fa5 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/KeyBindingRingAction.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/KeyBindingRingAction.java @@ -1,16 +1,16 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.ring; +package eu.midnightdust.midnightcontrols.client.ring; import com.electronwill.nightconfig.core.Config; -import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; +import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.option.KeyBinding; @@ -39,9 +39,9 @@ public class KeyBindingRingAction extends RingAction { public void onAction(@NotNull RingButtonMode mode) { KeyBindingAccessor accessor = (KeyBindingAccessor) this.binding; switch (mode) { - case PRESS, HOLD -> accessor.lambdacontrols$handlePressState(this.activated); + case PRESS, HOLD -> accessor.midnightcontrols$handlePressState(this.activated); case TOGGLE -> { - accessor.lambdacontrols$handlePressState(!this.binding.isPressed()); + accessor.midnightcontrols$handlePressState(!this.binding.isPressed()); this.activated = !this.binding.isPressed(); } } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/LambdaRing.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java similarity index 65% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ring/LambdaRing.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java index 4861f07..df5e966 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/LambdaRing.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/MidnightRing.java @@ -1,16 +1,17 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.ring; +package eu.midnightdust.midnightcontrols.client.ring; import com.electronwill.nightconfig.core.Config; -import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; @@ -26,15 +27,15 @@ import java.util.Map; * @version 1.7.0 * @since 1.4.0 */ -public final class LambdaRing { +public final class MidnightRing { public static final int ELEMENT_SIZE = 50; private final Map actionFactories = new Object2ObjectOpenHashMap<>(); private final List pages = new ArrayList<>(Collections.singletonList(RingPage.DEFAULT)); - private final LambdaControlsClient mod; + private final MidnightControlsClient mod; private int currentPage = 0; - public LambdaRing(@NotNull LambdaControlsClient mod) { + public MidnightRing(@NotNull MidnightControlsClient mod) { this.mod = mod; } @@ -48,20 +49,18 @@ public final class LambdaRing { /** * Loads the ring from configuration. - * - * @param config the configuration */ - public void load(@NotNull Config config) { - List configPages = config.get("ring.pages"); - if (configPages != null) { - this.pages.clear(); - for (var configPage : configPages) { - RingPage.parseRingPage(configPage).ifPresent(this.pages::add); - } - } - if (this.pages.isEmpty()) { - this.pages.add(RingPage.DEFAULT); - } + public void load() { +// List configPages = MidnightControlsConfig.ringPages; +// if (configPages != null) { +// this.pages.clear(); +// for (var configPage : configPages) { +// RingPage.parseRingPage(configPage).ifPresent(this.pages::add); +// } +// } +// if (this.pages.isEmpty()) { +// this.pages.add(RingPage.DEFAULT); +// } } public @NotNull RingPage getCurrentPage() { diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingAction.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingAction.java similarity index 90% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingAction.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingAction.java index 5190ecb..fb2be50 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingAction.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingAction.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.ring; +package eu.midnightdust.midnightcontrols.client.ring; import com.electronwill.nightconfig.core.Config; import net.minecraft.client.font.TextRenderer; @@ -64,7 +64,7 @@ public abstract class RingAction extends DrawableHelper implements Nameable { public abstract void onAction(@NotNull RingButtonMode mode); public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered) { - fill(matrices, x, y, x + LambdaRing.ELEMENT_SIZE, y + LambdaRing.ELEMENT_SIZE, hovered ? 0xbb777777 : 0xbb000000); + fill(matrices, x, y, x + MidnightRing.ELEMENT_SIZE, y + MidnightRing.ELEMENT_SIZE, hovered ? 0xbb777777 : 0xbb000000); drawIcon(matrices, textRenderer, x, y, hovered); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingButtonMode.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingButtonMode.java similarity index 90% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingButtonMode.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingButtonMode.java index 44bd3f7..9ba3e17 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingButtonMode.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingButtonMode.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.ring; +package eu.midnightdust.midnightcontrols.client.ring; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; @@ -52,7 +52,7 @@ public enum RingButtonMode implements Nameable { * @return the translation key of this ring button mode */ public @NotNull String getTranslationKey() { - return "lambdacontrols.ring.button_mode." + this.getName(); + return "midnightcontrols.ring.button_mode." + this.getName(); } /** diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingPage.java b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingPage.java similarity index 90% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingPage.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingPage.java index dc7c507..874b113 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/ring/RingPage.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/ring/RingPage.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.ring; +package eu.midnightdust.midnightcontrols.client.ring; import com.electronwill.nightconfig.core.Config; import net.minecraft.client.font.TextRenderer; @@ -52,7 +52,7 @@ public class RingPage extends DrawableHelper { int centerX = width / 2; int centerY = height / 2; - int offset = LambdaRing.ELEMENT_SIZE + (LambdaRing.ELEMENT_SIZE / 2) + 5; + int offset = MidnightRing.ELEMENT_SIZE + (MidnightRing.ELEMENT_SIZE / 2) + 5; int y = centerY - offset; int x = centerX - offset; @@ -81,7 +81,7 @@ public class RingPage extends DrawableHelper { } private static boolean isHovered(int x, int y, int mouseX, int mouseY) { - return mouseX >= x && mouseY >= y && mouseX <= x + LambdaRing.ELEMENT_SIZE && mouseY <= y + LambdaRing.ELEMENT_SIZE; + return mouseX >= x && mouseY >= y && mouseX <= x + MidnightRing.ELEMENT_SIZE && mouseY <= y + MidnightRing.ELEMENT_SIZE; } /** diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/util/HandledScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/util/HandledScreenAccessor.java similarity index 73% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/util/HandledScreenAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/util/HandledScreenAccessor.java index 82804a8..8f8d221 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/util/HandledScreenAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/util/HandledScreenAccessor.java @@ -1,13 +1,13 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.util; +package eu.midnightdust.midnightcontrols.client.util; import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; @@ -38,9 +38,9 @@ public interface HandledScreenAccessor { * @param posY the Y position to check * @return the slot at the specified position */ - Slot lambdacontrols$getSlotAt(double posX, double posY); + Slot midnightcontrols$getSlotAt(double posX, double posY); - boolean lambdacontrols$isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button); + boolean midnightcontrols$isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button); /** * Handles a mouse click on the specified slot. @@ -50,5 +50,5 @@ public interface HandledScreenAccessor { * @param clickData the click data * @param actionType the action type */ - void lambdacontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType); + void midnightcontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType); } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/util/KeyBindingAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/util/KeyBindingAccessor.java new file mode 100644 index 0000000..fbd1966 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/util/KeyBindingAccessor.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2021 LambdAurora + * + * This file is part of midnightcontrols. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package eu.midnightdust.midnightcontrols.client.util; + +/** + * Represents a Minecraft keybinding with extra access. + */ +public interface KeyBindingAccessor { + boolean midnightcontrols$press(); + + boolean midnightcontrols$unpress(); + + default boolean midnightcontrols$handlePressState(boolean pressed) { + if (pressed) + return this.midnightcontrols$press(); + else + return this.midnightcontrols$unpress(); + } +} diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/client/util/MouseAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/util/MouseAccessor.java similarity index 58% rename from src/main/java/dev/lambdaurora/lambdacontrols/client/util/MouseAccessor.java rename to src/main/java/eu/midnightdust/midnightcontrols/client/util/MouseAccessor.java index bd74c86..9b97031 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/client/util/MouseAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/util/MouseAccessor.java @@ -1,17 +1,17 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.client.util; +package eu.midnightdust.midnightcontrols.client.util; /** * Represents mouse's extra access. */ public interface MouseAccessor { - void lambdacontrols$onCursorPos(long window, double x, double y); + void midnightcontrols$onCursorPos(long window, double x, double y); } diff --git a/src/main/java/dev/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeCallback.java b/src/main/java/eu/midnightdust/midnightcontrols/event/PlayerChangeControlsModeCallback.java similarity index 86% rename from src/main/java/dev/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeCallback.java rename to src/main/java/eu/midnightdust/midnightcontrols/event/PlayerChangeControlsModeCallback.java index 6935051..ab33324 100644 --- a/src/main/java/dev/lambdaurora/lambdacontrols/event/PlayerChangeControlsModeCallback.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/event/PlayerChangeControlsModeCallback.java @@ -1,15 +1,15 @@ /* * Copyright © 2021 LambdAurora * - * This file is part of LambdaControls. + * This file is part of midnightcontrols. * * Licensed under the MIT license. For more information, * see the LICENSE file. */ -package dev.lambdaurora.lambdacontrols.event; +package eu.midnightdust.midnightcontrols.event; -import dev.lambdaurora.lambdacontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.ControlsMode; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.entity.player.PlayerEntity; diff --git a/src/main/resources/assets/lambdacontrols/icon.png b/src/main/resources/assets/lambdacontrols/icon.png deleted file mode 100644 index fea935d4fd37c732c6c989ec55833a4fa0e0bc9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1082 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 diff --git a/src/main/resources/assets/lambdacontrols/lang/en_us.json b/src/main/resources/assets/lambdacontrols/lang/en_us.json deleted file mode 100644 index 93e096e..0000000 --- a/src/main/resources/assets/lambdacontrols/lang/en_us.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "key.lambdacontrols.look_down": "Look down", - "key.lambdacontrols.look_left": "Look left", - "key.lambdacontrols.look_right": "Look right", - "key.lambdacontrols.look_up": "Look up", - "key.lambdacontrols.ring": "Show controls ring", - "lambdacontrols.action.attack": "Attack", - "lambdacontrols.action.back": "Back", - "lambdacontrols.action.chat": "Open Chat", - "lambdacontrols.action.drop_item": "Drop Item", - "lambdacontrols.action.exit": "Exit", - "lambdacontrols.action.forward": "Forward", - "lambdacontrols.action.hit": "Hit", - "lambdacontrols.action.hotbar_left": "Hotbar left", - "lambdacontrols.action.hotbar_right": "Hotbar right", - "lambdacontrols.action.inventory": "Inventory", - "lambdacontrols.action.jump": "Jump", - "lambdacontrols.action.left": "Left", - "lambdacontrols.action.pause_game": "Pause Game", - "lambdacontrols.action.pick_block": "Pick Block", - "lambdacontrols.action.pickup": "Pickup", - "lambdacontrols.action.pickup_all": "Pickup all", - "lambdacontrols.action.place": "Place", - "lambdacontrols.action.player_list": "Player List", - "lambdacontrols.action.quick_move": "Quick move", - "lambdacontrols.action.right": "Right", - "lambdacontrols.action.screenshot": "Take Screenshot", - "lambdacontrols.action.sneak": "Sneak", - "lambdacontrols.action.sprint": "Sprint", - "lambdacontrols.action.swap_hands": "Swap Hands", - "lambdacontrols.action.toggle_perspective": "Toggle Perspective", - "lambdacontrols.action.toggle_smooth_camera": "Toggle Cinematic Camera", - "lambdacontrols.action.use": "Use", - "lambdacontrols.action.zoom": "Zoom", - "lambdacontrols.action.zoom_in": "Increase Zoom", - "lambdacontrols.action.zoom_out": "Decrease Zoom", - "lambdacontrols.action.zoom_reset": "Reset Zoom", - "lambdacontrols.button.a": "A", - "lambdacontrols.button.b": "B", - "lambdacontrols.button.x": "X", - "lambdacontrols.button.y": "Y", - "lambdacontrols.button.left_bumper": "Left bumper", - "lambdacontrols.button.right_bumper": "Right bumper", - "lambdacontrols.button.back": "Back", - "lambdacontrols.button.start": "Start", - "lambdacontrols.button.guide": "Guide", - "lambdacontrols.button.left_thumb": "Left thumb", - "lambdacontrols.button.right_thumb": "Right thumb", - "lambdacontrols.button.dpad_up": "DPAD up", - "lambdacontrols.button.dpad_right": "DPAD right", - "lambdacontrols.button.dpad_down": "DPAD down", - "lambdacontrols.button.dpad_left": "DPAD left", - "lambdacontrols.axis.left_x+": "Left X+", - "lambdacontrols.axis.left_y+": "Left Y+", - "lambdacontrols.axis.right_x+": "Right X+", - "lambdacontrols.axis.right_y+": "Right Y+", - "lambdacontrols.axis.left_trigger": "Left trigger", - "lambdacontrols.axis.right_trigger": "Right trigger", - "lambdacontrols.axis.left_x-": "Left X-", - "lambdacontrols.axis.left_y-": "Left Y-", - "lambdacontrols.axis.right_x-": "Right X-", - "lambdacontrols.axis.right_y-": "Right Y-", - "lambdacontrols.button.unknown": "Unknown (%d)", - "lambdacontrols.controller.connected": "Controller %d connected.", - "lambdacontrols.controller.disconnected": "Controller %d disconnected.", - "lambdacontrols.controller.mappings.1": "To configure the controller mappings, please use %s", - "lambdacontrols.controller.mappings.3": "and paste the mapping in the mappings file editor.", - "lambdacontrols.controller.mappings.error": "Error while loading mappings.", - "lambdacontrols.controller.mappings.error.write": "Error while writing mappings to file.", - "lambdacontrols.controller.mappings.updated": "Updated mappings!", - "lambdacontrols.controller_type.default": "default", - "lambdacontrols.controller_type.dualshock": "DualShock", - "lambdacontrols.controller_type.switch": "Switch", - "lambdacontrols.controller_type.xbox": "Xbox", - "lambdacontrols.controller_type.steam": "Steam", - "lambdacontrols.controller_type.ouya": "OUYA", - "lambdacontrols.controls_mode.default": "Keyboard/Mouse", - "lambdacontrols.controls_mode.controller": "Controller", - "lambdacontrols.controls_mode.touchscreen": "Touchscreen", - "lambdacontrols.hud_side.left": "left", - "lambdacontrols.hud_side.right": "right", - "lambdacontrols.menu.analog_movement": "Analog Movement", - "lambdacontrols.menu.auto_switch_mode": "Auto Switch Mode", - "lambdacontrols.menu.controller": "Controller", - "lambdacontrols.menu.controller2": "Second Controller", - "lambdacontrols.menu.controller_type": "Controller Type", - "lambdacontrols.menu.controls_mode": "Mode", - "lambdacontrols.menu.fast_block_placing": "Fast Block Placing", - "lambdacontrols.menu.fly_drifting": "Fly Drifting", - "lambdacontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting", - "lambdacontrols.menu.hud_enable": "Enable HUD", - "lambdacontrols.menu.hud_side": "HUD Side", - "lambdacontrols.menu.invert_right_x_axis": "Invert Right X", - "lambdacontrols.menu.invert_right_y_axis": "Invert Right Y", - "lambdacontrols.menu.keyboard_controls": "Keyboard Controls...", - "lambdacontrols.menu.left_dead_zone": "Left Dead Zone", - "lambdacontrols.menu.mappings.open_input_str": "Open Mappings File Editor", - "lambdacontrols.menu.max_left_x_value": "Left X Axis Max Value", - "lambdacontrols.menu.max_left_y_value": "Left Y Axis Max Value", - "lambdacontrols.menu.max_right_x_value": "Right X Axis Max Value", - "lambdacontrols.menu.max_right_y_value": "Right Y Axis Max Value", - "lambdacontrols.menu.mouse_speed": "Mouse Speed", - "lambdacontrols.menu.reacharound.horizontal": "Front Block Placing", - "lambdacontrols.menu.reacharound.vertical": "Vertical Reacharound", - "lambdacontrols.menu.reload_controller_mappings": "Reload Controller Mappings", - "lambdacontrols.menu.right_dead_zone": "Right Dead Zone", - "lambdacontrols.menu.rotation_speed": "Rotation Speed", - "lambdacontrols.menu.separator.controller": "Controller", - "lambdacontrols.menu.separator.general": "General", - "lambdacontrols.menu.title": "LambdaControls - Settings", - "lambdacontrols.menu.title.controller": "Controller Options", - "lambdacontrols.menu.title.controller_controls": "Controller Controls", - "lambdacontrols.menu.title.gameplay": "Gameplay Options", - "lambdacontrols.menu.title.general": "General Options", - "lambdacontrols.menu.title.hud": "HUD Options", - "lambdacontrols.menu.title.mappings.string": "Mappings File Editor", - "lambdacontrols.menu.title.visual": "Appearance Options", - "lambdacontrols.menu.unfocused_input": "Unfocused Input", - "lambdacontrols.menu.virtual_mouse": "Virtual Mouse", - "lambdacontrols.menu.virtual_mouse.skin": "Virtual Mouse Skin", - "lambdacontrols.narrator.unbound": "Unbound %s", - "lambdacontrols.not_bound": "Not bound", - "lambdacontrols.tooltip.analog_movement": "Enables analog movement when possible.", - "lambdacontrols.tooltip.auto_switch_mode": "If the controls mode should be switched to Controller automatically if one is connected.", - "lambdacontrols.tooltip.controller2": "Second controller to use, which allows Joy-Cons support for example.", - "lambdacontrols.tooltip.controller_type": "The controller type to display the correct buttons.", - "lambdacontrols.tooltip.controls_mode": "The controls mode.", - "lambdacontrols.tooltip.fast_block_placing": "While flying in creative mode, enables fast block placing depending on your speed. §cOn some servers this might be considered as cheating.", - "lambdacontrols.tooltip.fly_drifting": "While flying, enables Vanilla drifting/inertia.", - "lambdacontrols.tooltip.fly_drifting_vertical": "While flying, enables Vanilla vertical drifting/intertia.", - "lambdacontrols.tooltip.hud_enable": "Toggles the on-screen controller button indicator.", - "lambdacontrols.tooltip.hud_side": "The position of the HUD.", - "lambdacontrols.tooltip.left_dead_zone": "The dead zone for the controller's left analogue stick.", - "lambdacontrols.tooltip.max_left_x_value": "Changes what the mod considers the highest value for the left X axis. Useful if your axis does not use the full range and seems slow.", - "lambdacontrols.tooltip.max_left_y_value": "Changes what the mod considers the highest value for the left Y axis. Useful if your axis does not use the full range and seems slow.", - "lambdacontrols.tooltip.max_right_x_value": "Changes what the mod considers the highest value for the right X axis. Useful if your axis does not use the full range and seems slow.", - "lambdacontrols.tooltip.max_right_y_value": "Changes what the mod considers the highest value for the right Y axis. Useful if your axis does not use the full range and seems slow.", - "lambdacontrols.tooltip.mouse_speed": "The controller's emulated mouse speed.", - "lambdacontrols.tooltip.reacharound.horizontal": "Enables front block placing, §cmight be considered cheating on some servers§r.", - "lambdacontrols.tooltip.reacharound.vertical": "Enables vertical reacharound, §cmight be considered cheating on some servers§r.", - "lambdacontrols.tooltip.reload_controller_mappings": "Reloads the controller mappings file.", - "lambdacontrols.tooltip.right_dead_zone": "The dead zone for the controller's right analogue stick.", - "lambdacontrols.tooltip.rotation_speed": "The camera rotation speed in controller mode.", - "lambdacontrols.tooltip.unfocused_input": "Allow controller input when the window is not focused.", - "lambdacontrols.tooltip.virtual_mouse": "Enable the virtual mouse which is handful in the case of a splitscreen.", - "lambdacontrols.virtual_mouse.skin.default_light": "Default Light", - "lambdacontrols.virtual_mouse.skin.default_dark": "Default Dark", - "lambdacontrols.virtual_mouse.skin.second_light": "Second Light", - "lambdacontrols.virtual_mouse.skin.second_dark": "Second Dark" -} \ No newline at end of file diff --git a/src/main/resources/assets/lambdacontrols/lang/es_mx.json b/src/main/resources/assets/lambdacontrols/lang/es_mx.json deleted file mode 100644 index 3135ed0..0000000 --- a/src/main/resources/assets/lambdacontrols/lang/es_mx.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "key.lambdacontrols.look_down": "Mirar hacia abajo", - "key.lambdacontrols.look_left": "Mirar hacia izquierda", - "key.lambdacontrols.look_right": "Mirar hacia derecha", - "key.lambdacontrols.look_up": "Mirar hacia arriba", - "key.lambdacontrols.ring": "Mostrar anillo de controles", - "lambdacontrols.action.attack": "Atacar", - "lambdacontrols.action.back": "Retroceder", - "lambdacontrols.action.chat": "Abrir chat", - "lambdacontrols.action.drop_item": "Tirar ítem", - "lambdacontrols.action.exit": "Salir", - "lambdacontrols.action.forward": "Avanzar", - "lambdacontrols.action.hit": "Golpear", - "lambdacontrols.action.hotbar_left": "Hotbar a la izquierda", - "lambdacontrols.action.hotbar_right": "Hotbar a la derecha", - "lambdacontrols.action.inventory": "Inventario", - "lambdacontrols.action.jump": "Saltar", - "lambdacontrols.action.left": "Izquierda", - "lambdacontrols.action.pause_game": "Pausar juego", - "lambdacontrols.action.pick_block": "Recoger bloque", - "lambdacontrols.action.pickup": "Recoger", - "lambdacontrols.action.pickup_all": "Recoger todo", - "lambdacontrols.action.place": "Poner", - "lambdacontrols.action.player_list": "Lista de jugadores", - "lambdacontrols.action.quick_move": "Mover items rápidamente", - "lambdacontrols.action.right": "Derecha", - "lambdacontrols.action.screenshot": "Tomar captura de pantalla", - "lambdacontrols.action.sneak": "Agacharse", - "lambdacontrols.action.sprint": "Correr", - "lambdacontrols.action.swap_hands": "Intercambiar manos", - "lambdacontrols.action.toggle_perspective": "Cambiar perspectiva", - "lambdacontrols.action.toggle_smooth_camera": "Cambiar cámara cinematográfica", - "lambdacontrols.action.use": "Usar", - "lambdacontrols.action.zoom": "Zoom", - "lambdacontrols.action.zoom_in": "Aumentar zoom", - "lambdacontrols.action.zoom_out": "Disminuir zoom", - "lambdacontrols.action.zoom_reset": "Restablecer zoom", - "lambdacontrols.button.a": "A", - "lambdacontrols.button.b": "B", - "lambdacontrols.button.x": "X", - "lambdacontrols.button.y": "Y", - "lambdacontrols.button.left_bumper": "Bumper izquierda", - "lambdacontrols.button.right_bumper": "Bumper derecha", - "lambdacontrols.button.back": "Regresar", - "lambdacontrols.button.start": "Iniciar", - "lambdacontrols.button.guide": "Guía", - "lambdacontrols.button.left_thumb": "Joystick izquierda", - "lambdacontrols.button.right_thumb": "Joystick derecha", - "lambdacontrols.button.dpad_up": "Cruceta arriba", - "lambdacontrols.button.dpad_right": "Cruceta derecha", - "lambdacontrols.button.dpad_down": "Cruceta abajo", - "lambdacontrols.button.dpad_left": "Cruceta izquierda", - "lambdacontrols.axis.left_x+": "Izquierda X+", - "lambdacontrols.axis.left_y+": "Izquierda Y+", - "lambdacontrols.axis.right_x+": "Derecha X+", - "lambdacontrols.axis.right_y+": "Derecha Y+", - "lambdacontrols.axis.left_trigger": "Gatillo izquierda", - "lambdacontrols.axis.right_trigger": "Gatillo derecha", - "lambdacontrols.axis.left_x-": "Izquierda X-", - "lambdacontrols.axis.left_y-": "Izquierda Y-", - "lambdacontrols.axis.right_x-": "Derecha X-", - "lambdacontrols.axis.right_y-": "Derecha Y-", - "lambdacontrols.button.unknown": "Desconocido (%d)", - "lambdacontrols.controller.connected": "Controlador %d conectado.", - "lambdacontrols.controller.disconnected": "Controlador %d desconectado.", - "lambdacontrols.controller.mappings.1": "Para configurar las asignaciones del controlador, utilice %s", - "lambdacontrols.controller.mappings.3": "y poner el mapeo de asignaciones en `%s.minecraft/config/gamecontrollerdb.txt%s`.", - "lambdacontrols.controller.mappings.error": "Error al cargar asignaciones.", - "lambdacontrols.controller.mappings.error.write": "Error al escribir asignaciones al archivo.", - "lambdacontrols.controller.mappings.updated": "Asignaciones actualizados!", - "lambdacontrols.controller_type.default": "por defecto", - "lambdacontrols.controller_type.dualshock": "DualShock", - "lambdacontrols.controller_type.switch": "Switch", - "lambdacontrols.controller_type.xbox": "Xbox", - "lambdacontrols.controller_type.steam": "Steam", - "lambdacontrols.controller_type.ouya": "OUYA", - "lambdacontrols.controls_mode.default": "Teclado/Ratón", - "lambdacontrols.controls_mode.controller": "Controlador", - "lambdacontrols.controls_mode.touchscreen": "Pantalla táctil", - "lambdacontrols.hud_side.left": "izquierda", - "lambdacontrols.hud_side.right": "derecha", - "lambdacontrols.menu.analog_movement": "Movimiento analógico", - "lambdacontrols.menu.auto_switch_mode": "Cambio de modo automático", - "lambdacontrols.menu.controller": "Controlador", - "lambdacontrols.menu.controller2": "Segundo controlador", - "lambdacontrols.menu.controller_type": "Tipo de controlador", - "lambdacontrols.menu.controls_mode": "Modo", - "lambdacontrols.menu.fast_block_placing": "Colocación rápida de bloques", - "lambdacontrols.menu.fly_drifting": "Volar a la deriva", - "lambdacontrols.menu.fly_drifting_vertical": "Volar a la deriva vertical", - "lambdacontrols.menu.hud_enable": "Habilitar HUD", - "lambdacontrols.menu.hud_side": "Lado de HUD", - "lambdacontrols.menu.invert_right_x_axis": "Invertir derecha X", - "lambdacontrols.menu.invert_right_y_axis": "Invertir derecha Y", - "lambdacontrols.menu.keyboard_controls": "Controles del teclado...", - "lambdacontrols.menu.left_dead_zone": "Zona muerta izquierda", - "lambdacontrols.menu.mappings.open_input_str": "Abrir el editor de archivo de asignaciones", - "lambdacontrols.menu.max_left_x_value": "Valor máximo del eje X izquierdo", - "lambdacontrols.menu.max_left_y_value": "Valor máximo del eje Y izquierdo", - "lambdacontrols.menu.max_right_x_value": "Valor máximo del eje X derecho", - "lambdacontrols.menu.max_right_y_value": "Valor máximo del eje Y derecho", - "lambdacontrols.menu.mouse_speed": "Velocidad del ratón", - "lambdacontrols.menu.reacharound.horizontal": "Colocación de bloque frontal", - "lambdacontrols.menu.reacharound.vertical": "Alcance vertical", - "lambdacontrols.menu.reload_controller_mappings": "Recargar asignaciones de controlador", - "lambdacontrols.menu.right_dead_zone": "Zona muerta derecha", - "lambdacontrols.menu.rotation_speed": "Velocidad de rotación", - "lambdacontrols.menu.separator.controller": "Controlador", - "lambdacontrols.menu.separator.general": "General", - "lambdacontrols.menu.title": "LambdaControls - Configuraciones", - "lambdacontrols.menu.title.controller": "Opciones de controlador", - "lambdacontrols.menu.title.controller_controls": "Controles de controlador", - "lambdacontrols.menu.title.gameplay": "Opciones de juego", - "lambdacontrols.menu.title.general": "Opciones generales", - "lambdacontrols.menu.title.hud": "Opciones de HUD", - "lambdacontrols.menu.title.mappings.string": "Editor de archivo de asignaciones", - "lambdacontrols.menu.title.visual": "Opciones de apariencia", - "lambdacontrols.menu.unfocused_input": "Entrada desenfocada", - "lambdacontrols.menu.virtual_mouse": "Ratón virtual", - "lambdacontrols.menu.virtual_mouse.skin": "Piel de ratón virtual", - "lambdacontrols.narrator.unbound": "Resetear %s", - "lambdacontrols.not_bound": "No ligado", - "lambdacontrols.tooltip.analog_movement": "Habilita el movimiento analógico cuando es posible.", - "lambdacontrols.tooltip.auto_switch_mode": "Si el modo de controles debe cambiarse a Controlador automáticamente si hay uno conectado.", - "lambdacontrols.tooltip.controller2": "Segundo controlador a uso, que permite el soporte de Joy-Cons por ejemplo.", - "lambdacontrols.tooltip.controller_type": "El tipo de controlador para mostrar los botones correctos.", - "lambdacontrols.tooltip.controls_mode": "El modo de controles.", - "lambdacontrols.tooltip.fast_block_placing": "Mientras vuela en modo creativo, permite la colocación rápida de bloques dependiendo su velocidad. §cEn algunos servidores, esto podría considerarse como trampa.", - "lambdacontrols.tooltip.fly_drifting": "Mientras vuela, habilita la deriva/inercia de vainilla.", - "lambdacontrols.tooltip.fly_drifting_vertical": "Mientras vuela, habilita la deriva/inercia vertical de vainilla.", - "lambdacontrols.tooltip.hud_enable": "Alterna el indicador del botón del controlador en pantalla.", - "lambdacontrols.tooltip.hud_side": "La posición del HUD.", - "lambdacontrols.tooltip.left_dead_zone": "La zona muerta de la palanca analógica izquierda del controlador.", - "lambdacontrols.tooltip.max_left_x_value": "Cambia lo que el mod considera el valor más alto para el eje X izquierdo. Útil si su eje no usa el rango completo y parece lento.", - "lambdacontrols.tooltip.max_left_y_value": "Cambia lo que el mod considera el valor más alto para el eje Y izquierdo. Útil si su eje no usa el rango completo y parece lento.", - "lambdacontrols.tooltip.max_right_x_value": "Cambia lo que el mod considera el valor más alto para el eje X derecho. Útil si su eje no usa el rango completo y parece lento.", - "lambdacontrols.tooltip.max_right_y_value": "Cambia lo que el mod considera el valor más alto para el eje Y derecho. Útil si su eje no usa el rango completo y parece lento.", - "lambdacontrols.tooltip.mouse_speed": "La velocidad del ratón emulada del controlador.", - "lambdacontrols.tooltip.reacharound.horizontal": "Habilita la colocación del bloque frontal, §cpodría considerarse trampa en algunos servidores§r.", - "lambdacontrols.tooltip.reacharound.vertical": "Habilita el alcance vertical, §cpodría considerarse trampa en algunos servidores§r.", - "lambdacontrols.tooltip.reload_controller_mappings": "Vuelve a cargar el archivo de asignaciones del controlador.", - "lambdacontrols.tooltip.right_dead_zone": "La zona muerta de la palanca analógica derecha del controlador.", - "lambdacontrols.tooltip.rotation_speed": "La velocidad de rotación de la cámara en modo controlador.", - "lambdacontrols.tooltip.unfocused_input": "Habilita entrada del controlador cuando la ventana no está enfocada.", - "lambdacontrols.tooltip.virtual_mouse": "Habilite el ratón virtual que es útil en el caso de una pantalla dividida.", - "lambdacontrols.virtual_mouse.skin.default_light": "Ligera por defecto", - "lambdacontrols.virtual_mouse.skin.default_dark": "Oscura por defecto", - "lambdacontrols.virtual_mouse.skin.second_light": "Ligera segundario", - "lambdacontrols.virtual_mouse.skin.second_dark": "Oscura segundario" -} \ No newline at end of file diff --git a/src/main/resources/assets/lambdacontrols/lang/fr_ca.json b/src/main/resources/assets/lambdacontrols/lang/fr_ca.json deleted file mode 100644 index b42ba21..0000000 --- a/src/main/resources/assets/lambdacontrols/lang/fr_ca.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "key.lambdacontrols.look_down": "Regarder en bas", - "key.lambdacontrols.look_left": "Regarder à gauche", - "key.lambdacontrols.look_right": "Regarder à droite", - "key.lambdacontrols.look_up": "Regarder en haut", - "key.lambdacontrols.ring": "Affiche l'anneau de contrôle", - "lambdacontrols.action.attack": "Attaquer", - "lambdacontrols.action.back": "Reculer", - "lambdacontrols.action.chat": "Ouvrir le tchat", - "lambdacontrols.action.drop_item": "Jeter l'objet", - "lambdacontrols.action.exit": "Sortir", - "lambdacontrols.action.forward": "Avancer", - "lambdacontrols.action.hit": "Taper", - "lambdacontrols.action.hotbar_left": "Case à gauche de la barre d'action", - "lambdacontrols.action.hotbar_right": "Case à droite de la barre d'action", - "lambdacontrols.action.inventory": "Inventaire", - "lambdacontrols.action.jump": "Sauter", - "lambdacontrols.action.left": "Aller à gauche", - "lambdacontrols.action.pause_game": "Mettre en pause le jeu", - "lambdacontrols.action.pick_block": "Choisir le bloc", - "lambdacontrols.action.pickup": "Prendre", - "lambdacontrols.action.pickup_all": "Prendre tout", - "lambdacontrols.action.place": "Placer", - "lambdacontrols.action.player_list": "Afficher la liste des joueurs", - "lambdacontrols.action.quick_move": "Mouvement rapide", - "lambdacontrols.action.right": "Aller à droite", - "lambdacontrols.action.screenshot": "Prendre une capture d'écran", - "lambdacontrols.action.sneak": "S'accroupir", - "lambdacontrols.action.sprint": "Courir", - "lambdacontrols.action.swap_hands": "Échanger de mains", - "lambdacontrols.action.toggle_perspective": "Changer de point de vue", - "lambdacontrols.action.toggle_smooth_camera": "Basculer en mode cinématique", - "lambdacontrols.action.use": "Utiliser", - "lambdacontrols.action.zoom": "Zoom", - "lambdacontrols.action.zoom_in": "Augmenter le zoom", - "lambdacontrols.action.zoom_out": "Diminuer le zoom", - "lambdacontrols.action.zoom_reset": "Remettre le zoom à zéro", - "lambdacontrols.button.a": "A", - "lambdacontrols.button.b": "B", - "lambdacontrols.button.x": "X", - "lambdacontrols.button.y": "Y", - "lambdacontrols.button.left_bumper": "Gâchette gauche", - "lambdacontrols.button.right_bumper": "Gâchette droite", - "lambdacontrols.button.back": "Retour", - "lambdacontrols.button.start": "Touche Menu", - "lambdacontrols.button.guide": "Guide", - "lambdacontrols.button.left_thumb": "Stick gauche", - "lambdacontrols.button.right_thumb": "Stick droit", - "lambdacontrols.button.dpad_up": "D-Pad haut", - "lambdacontrols.button.dpad_right": "D-Pad droit", - "lambdacontrols.button.dpad_down": "D-Pad bas", - "lambdacontrols.button.dpad_left": "D-Pad gauche", - "lambdacontrols.axis.left_x+": "X+ Gauche", - "lambdacontrols.axis.left_y+": "Y+ Gauche", - "lambdacontrols.axis.right_x+": "X+ Droit", - "lambdacontrols.axis.right_y+": "Y+ Droit", - "lambdacontrols.axis.left_trigger": "Gâchette gauche", - "lambdacontrols.axis.right_trigger": "Gâchette droite", - "lambdacontrols.axis.left_x-": "X- Gauche", - "lambdacontrols.axis.left_y-": "Y- Gauche", - "lambdacontrols.axis.right_x-": "X- Droit", - "lambdacontrols.axis.right_y-": "Y- Droit", - "lambdacontrols.button.unknown": "Inconnu (%d)", - "lambdacontrols.controller.connected": "Manette %d connecté.", - "lambdacontrols.controller.disconnected": "Manette %d déconnecté.", - "lambdacontrols.controller.mappings.1": "Pour configurer les correspondances de la manette, veuillez utiliser %s", - "lambdacontrols.controller.mappings.3": "et copier/coller les correspondances dans l'éditeur de manette.", - "lambdacontrols.controller.mappings.error": "Une erreur est apparue pendant le chargement des manettes.", - "lambdacontrols.controller.mappings.error.write": "Une erreur est apparue pendant l'écriture des manettes au fichier.", - "lambdacontrols.controller.mappings.updated": "Configuration des manettes mise à jour!", - "lambdacontrols.controller_type.default": "default", - "lambdacontrols.controller_type.dualshock": "DualShock", - "lambdacontrols.controller_type.switch": "Switch", - "lambdacontrols.controller_type.xbox": "Xbox", - "lambdacontrols.controller_type.steam": "Steam", - "lambdacontrols.controller_type.ouya": "OUYA", - "lambdacontrols.controls_mode.default": "Clavier/Souris", - "lambdacontrols.controls_mode.controller": "Manette", - "lambdacontrols.controls_mode.touchscreen": "Tactile", - "lambdacontrols.hud_side.left": "gauche", - "lambdacontrols.hud_side.right": "droit", - "lambdacontrols.menu.analog_movement": "Mouvement analogique", - "lambdacontrols.menu.auto_switch_mode": "Changement auto de mode", - "lambdacontrols.menu.controller": "Manette", - "lambdacontrols.menu.controller2": "Deuxième manette", - "lambdacontrols.menu.controller_type": "Type de manette", - "lambdacontrols.menu.controls_mode": "Mode", - "lambdacontrols.menu.fast_block_placing": "Placement rapide de blocs", - "lambdacontrols.menu.fly_drifting": "Inertie de vol", - "lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol", - "lambdacontrols.menu.hud_enable": "Activer le HUD", - "lambdacontrols.menu.hud_side": "Côté du HUD", - "lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)", - "lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)", - "lambdacontrols.menu.keyboard_controls": "Contrôles clavier...", - "lambdacontrols.menu.left_dead_zone": "Zone morte axe gauche", - "lambdacontrols.menu.mappings.open_input_str": "Ouvrir l'éditeur de fichier des manettes", - "lambdacontrols.menu.max_left_x_value": "Valeur maximale de l'axe X gauche", - "lambdacontrols.menu.max_left_y_value": "Valeur maximale de l'axe Y gauche", - "lambdacontrols.menu.max_right_x_value": "Valeur maximale de l'axe X droit", - "lambdacontrols.menu.max_right_y_value": "Valeur maximale de l'axe Y droit", - "lambdacontrols.menu.mouse_speed": "Vitesse de la souris", - "lambdacontrols.menu.reacharound.horizontal": "Placement avant de bloc", - "lambdacontrols.menu.reacharound.vertical": "Placement vertical", - "lambdacontrols.menu.reload_controller_mappings": "Recharger les manettes", - "lambdacontrols.menu.right_dead_zone": "Zone morte axe droit", - "lambdacontrols.menu.rotation_speed": "Vitesse de rotation", - "lambdacontrols.menu.separator.general": "Général", - "lambdacontrols.menu.separator.controller": "Manette", - "lambdacontrols.menu.title": "LambdaControls - Paramètres", - "lambdacontrols.menu.title.controller": "Options de manettes", - "lambdacontrols.menu.title.controller_controls": "Contrôles de la manette", - "lambdacontrols.menu.title.gameplay": "Options de Gameplay", - "lambdacontrols.menu.title.general": "Options générales", - "lambdacontrols.menu.title.hud": "Options du HUD", - "lambdacontrols.menu.title.mappings.string": "Éditeur de manettes", - "lambdacontrols.menu.title.visual": "Options d'apparences", - "lambdacontrols.menu.unfocused_input": "Entrée en fond", - "lambdacontrols.menu.virtual_mouse": "Souris virtuelle", - "lambdacontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle", - "lambdacontrols.narrator.unbound": "Délier %s", - "lambdacontrols.not_bound": "Non défini", - "lambdacontrols.tooltip.analog_movement": "Active le mouvement analogique si possible.", - "lambdacontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.", - "lambdacontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.", - "lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.", - "lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.", - "lambdacontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.", - "lambdacontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.", - "lambdacontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical Vanilla.", - "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.", - "lambdacontrols.tooltip.left_dead_zone": "Zone morte de l'axe gauche de la manette.", - "lambdacontrols.tooltip.max_left_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.max_left_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.max_right_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.max_right_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.", - "lambdacontrols.tooltip.reacharound.horizontal": "Active le placement avant de blocs, §cpeut être considérer comme de la triche sur certains serveurs§r.", - "lambdacontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.", - "lambdacontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.", - "lambdacontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.", - "lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.", - "lambdacontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.", - "lambdacontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.", - "lambdacontrols.virtual_mouse.skin.default_light": "défaut clair", - "lambdacontrols.virtual_mouse.skin.default_dark": "défaut foncé", - "lambdacontrols.virtual_mouse.skin.second_light": "second clair", - "lambdacontrols.virtual_mouse.skin.second_dark": "second foncé" -} \ No newline at end of file diff --git a/src/main/resources/assets/lambdacontrols/lang/fr_fr.json b/src/main/resources/assets/lambdacontrols/lang/fr_fr.json deleted file mode 100644 index b42ba21..0000000 --- a/src/main/resources/assets/lambdacontrols/lang/fr_fr.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "key.lambdacontrols.look_down": "Regarder en bas", - "key.lambdacontrols.look_left": "Regarder à gauche", - "key.lambdacontrols.look_right": "Regarder à droite", - "key.lambdacontrols.look_up": "Regarder en haut", - "key.lambdacontrols.ring": "Affiche l'anneau de contrôle", - "lambdacontrols.action.attack": "Attaquer", - "lambdacontrols.action.back": "Reculer", - "lambdacontrols.action.chat": "Ouvrir le tchat", - "lambdacontrols.action.drop_item": "Jeter l'objet", - "lambdacontrols.action.exit": "Sortir", - "lambdacontrols.action.forward": "Avancer", - "lambdacontrols.action.hit": "Taper", - "lambdacontrols.action.hotbar_left": "Case à gauche de la barre d'action", - "lambdacontrols.action.hotbar_right": "Case à droite de la barre d'action", - "lambdacontrols.action.inventory": "Inventaire", - "lambdacontrols.action.jump": "Sauter", - "lambdacontrols.action.left": "Aller à gauche", - "lambdacontrols.action.pause_game": "Mettre en pause le jeu", - "lambdacontrols.action.pick_block": "Choisir le bloc", - "lambdacontrols.action.pickup": "Prendre", - "lambdacontrols.action.pickup_all": "Prendre tout", - "lambdacontrols.action.place": "Placer", - "lambdacontrols.action.player_list": "Afficher la liste des joueurs", - "lambdacontrols.action.quick_move": "Mouvement rapide", - "lambdacontrols.action.right": "Aller à droite", - "lambdacontrols.action.screenshot": "Prendre une capture d'écran", - "lambdacontrols.action.sneak": "S'accroupir", - "lambdacontrols.action.sprint": "Courir", - "lambdacontrols.action.swap_hands": "Échanger de mains", - "lambdacontrols.action.toggle_perspective": "Changer de point de vue", - "lambdacontrols.action.toggle_smooth_camera": "Basculer en mode cinématique", - "lambdacontrols.action.use": "Utiliser", - "lambdacontrols.action.zoom": "Zoom", - "lambdacontrols.action.zoom_in": "Augmenter le zoom", - "lambdacontrols.action.zoom_out": "Diminuer le zoom", - "lambdacontrols.action.zoom_reset": "Remettre le zoom à zéro", - "lambdacontrols.button.a": "A", - "lambdacontrols.button.b": "B", - "lambdacontrols.button.x": "X", - "lambdacontrols.button.y": "Y", - "lambdacontrols.button.left_bumper": "Gâchette gauche", - "lambdacontrols.button.right_bumper": "Gâchette droite", - "lambdacontrols.button.back": "Retour", - "lambdacontrols.button.start": "Touche Menu", - "lambdacontrols.button.guide": "Guide", - "lambdacontrols.button.left_thumb": "Stick gauche", - "lambdacontrols.button.right_thumb": "Stick droit", - "lambdacontrols.button.dpad_up": "D-Pad haut", - "lambdacontrols.button.dpad_right": "D-Pad droit", - "lambdacontrols.button.dpad_down": "D-Pad bas", - "lambdacontrols.button.dpad_left": "D-Pad gauche", - "lambdacontrols.axis.left_x+": "X+ Gauche", - "lambdacontrols.axis.left_y+": "Y+ Gauche", - "lambdacontrols.axis.right_x+": "X+ Droit", - "lambdacontrols.axis.right_y+": "Y+ Droit", - "lambdacontrols.axis.left_trigger": "Gâchette gauche", - "lambdacontrols.axis.right_trigger": "Gâchette droite", - "lambdacontrols.axis.left_x-": "X- Gauche", - "lambdacontrols.axis.left_y-": "Y- Gauche", - "lambdacontrols.axis.right_x-": "X- Droit", - "lambdacontrols.axis.right_y-": "Y- Droit", - "lambdacontrols.button.unknown": "Inconnu (%d)", - "lambdacontrols.controller.connected": "Manette %d connecté.", - "lambdacontrols.controller.disconnected": "Manette %d déconnecté.", - "lambdacontrols.controller.mappings.1": "Pour configurer les correspondances de la manette, veuillez utiliser %s", - "lambdacontrols.controller.mappings.3": "et copier/coller les correspondances dans l'éditeur de manette.", - "lambdacontrols.controller.mappings.error": "Une erreur est apparue pendant le chargement des manettes.", - "lambdacontrols.controller.mappings.error.write": "Une erreur est apparue pendant l'écriture des manettes au fichier.", - "lambdacontrols.controller.mappings.updated": "Configuration des manettes mise à jour!", - "lambdacontrols.controller_type.default": "default", - "lambdacontrols.controller_type.dualshock": "DualShock", - "lambdacontrols.controller_type.switch": "Switch", - "lambdacontrols.controller_type.xbox": "Xbox", - "lambdacontrols.controller_type.steam": "Steam", - "lambdacontrols.controller_type.ouya": "OUYA", - "lambdacontrols.controls_mode.default": "Clavier/Souris", - "lambdacontrols.controls_mode.controller": "Manette", - "lambdacontrols.controls_mode.touchscreen": "Tactile", - "lambdacontrols.hud_side.left": "gauche", - "lambdacontrols.hud_side.right": "droit", - "lambdacontrols.menu.analog_movement": "Mouvement analogique", - "lambdacontrols.menu.auto_switch_mode": "Changement auto de mode", - "lambdacontrols.menu.controller": "Manette", - "lambdacontrols.menu.controller2": "Deuxième manette", - "lambdacontrols.menu.controller_type": "Type de manette", - "lambdacontrols.menu.controls_mode": "Mode", - "lambdacontrols.menu.fast_block_placing": "Placement rapide de blocs", - "lambdacontrols.menu.fly_drifting": "Inertie de vol", - "lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol", - "lambdacontrols.menu.hud_enable": "Activer le HUD", - "lambdacontrols.menu.hud_side": "Côté du HUD", - "lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)", - "lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)", - "lambdacontrols.menu.keyboard_controls": "Contrôles clavier...", - "lambdacontrols.menu.left_dead_zone": "Zone morte axe gauche", - "lambdacontrols.menu.mappings.open_input_str": "Ouvrir l'éditeur de fichier des manettes", - "lambdacontrols.menu.max_left_x_value": "Valeur maximale de l'axe X gauche", - "lambdacontrols.menu.max_left_y_value": "Valeur maximale de l'axe Y gauche", - "lambdacontrols.menu.max_right_x_value": "Valeur maximale de l'axe X droit", - "lambdacontrols.menu.max_right_y_value": "Valeur maximale de l'axe Y droit", - "lambdacontrols.menu.mouse_speed": "Vitesse de la souris", - "lambdacontrols.menu.reacharound.horizontal": "Placement avant de bloc", - "lambdacontrols.menu.reacharound.vertical": "Placement vertical", - "lambdacontrols.menu.reload_controller_mappings": "Recharger les manettes", - "lambdacontrols.menu.right_dead_zone": "Zone morte axe droit", - "lambdacontrols.menu.rotation_speed": "Vitesse de rotation", - "lambdacontrols.menu.separator.general": "Général", - "lambdacontrols.menu.separator.controller": "Manette", - "lambdacontrols.menu.title": "LambdaControls - Paramètres", - "lambdacontrols.menu.title.controller": "Options de manettes", - "lambdacontrols.menu.title.controller_controls": "Contrôles de la manette", - "lambdacontrols.menu.title.gameplay": "Options de Gameplay", - "lambdacontrols.menu.title.general": "Options générales", - "lambdacontrols.menu.title.hud": "Options du HUD", - "lambdacontrols.menu.title.mappings.string": "Éditeur de manettes", - "lambdacontrols.menu.title.visual": "Options d'apparences", - "lambdacontrols.menu.unfocused_input": "Entrée en fond", - "lambdacontrols.menu.virtual_mouse": "Souris virtuelle", - "lambdacontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle", - "lambdacontrols.narrator.unbound": "Délier %s", - "lambdacontrols.not_bound": "Non défini", - "lambdacontrols.tooltip.analog_movement": "Active le mouvement analogique si possible.", - "lambdacontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.", - "lambdacontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.", - "lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.", - "lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.", - "lambdacontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.", - "lambdacontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.", - "lambdacontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical Vanilla.", - "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.", - "lambdacontrols.tooltip.left_dead_zone": "Zone morte de l'axe gauche de la manette.", - "lambdacontrols.tooltip.max_left_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.max_left_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.max_right_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.max_right_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", - "lambdacontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.", - "lambdacontrols.tooltip.reacharound.horizontal": "Active le placement avant de blocs, §cpeut être considérer comme de la triche sur certains serveurs§r.", - "lambdacontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.", - "lambdacontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.", - "lambdacontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.", - "lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.", - "lambdacontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.", - "lambdacontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.", - "lambdacontrols.virtual_mouse.skin.default_light": "défaut clair", - "lambdacontrols.virtual_mouse.skin.default_dark": "défaut foncé", - "lambdacontrols.virtual_mouse.skin.second_light": "second clair", - "lambdacontrols.virtual_mouse.skin.second_dark": "second foncé" -} \ No newline at end of file diff --git a/src/main/resources/assets/lambdacontrols/lang/tr_tr.json b/src/main/resources/assets/lambdacontrols/lang/tr_tr.json deleted file mode 100644 index 637bf24..0000000 --- a/src/main/resources/assets/lambdacontrols/lang/tr_tr.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "key.lambdacontrols.look_down": "Aşağı bak", - "key.lambdacontrols.look_left": "Sola bak", - "key.lambdacontrols.look_right": "Sağa bak", - "key.lambdacontrols.look_up": "Yukarıya bak", - "key.lambdacontrols.ring": "Kontroller halkasını göster", - "lambdacontrols.action.attack": "Saldırma/Kazma", - "lambdacontrols.action.back": "Geri", - "lambdacontrols.action.chat": "Sohbeti Açma", - "lambdacontrols.action.drop_item": "Seçili Eşyayı Bırakma", - "lambdacontrols.action.exit": "Çık", - "lambdacontrols.action.forward": "İleri", - "lambdacontrols.action.hit": "Vurma", - "lambdacontrols.action.hotbar_left": "Sık Kullanılanlar'da sola git", - "lambdacontrols.action.hotbar_right": "Sık Kullanılanlar'da sağa git", - "lambdacontrols.action.inventory": "Envanter", - "lambdacontrols.action.jump": "Zıplama", - "lambdacontrols.action.left": "Sol", - "lambdacontrols.action.pause_game": "Oyunu durdur", - "lambdacontrols.action.pick_block": "Blok Seçme", - "lambdacontrols.action.pickup": "Al", - "lambdacontrols.action.pickup_all": "Hepsini Al", - "lambdacontrols.action.place": "Yerleştir", - "lambdacontrols.action.player_list": "Oyuncu Listesi", - "lambdacontrols.action.quick_move": "Hızlı Hareket", - "lambdacontrols.action.right": "Sağ", - "lambdacontrols.action.screenshot": "Ekran Görüntüsü Alma", - "lambdacontrols.action.sneak": "Eğilme", - "lambdacontrols.action.sprint": "Koşma", - "lambdacontrols.action.swap_hands": "Ögeyi Elden Ele Değiştir", - "lambdacontrols.action.toggle_perspective": "Perspektifi Değiştirme", - "lambdacontrols.action.toggle_smooth_camera": "Sinemaitk Kameraya Geçme", - "lambdacontrols.action.use": "Kullanma", - "lambdacontrols.action.zoom": "Büyütme", - "lambdacontrols.action.zoom_in": "Büyütmeyi Arttır", - "lambdacontrols.action.zoom_out": "Büyütmeyi Azalt", - "lambdacontrols.action.zoom_reset": "Büyütmeyi Sıfırla", - "lambdacontrols.button.a": "A", - "lambdacontrols.button.b": "B", - "lambdacontrols.button.x": "X", - "lambdacontrols.button.y": "Y", - "lambdacontrols.button.left_bumper": "Sol yassı tuş", - "lambdacontrols.button.right_bumper": "Sağ yassı tuş", - "lambdacontrols.button.back": "Back", - "lambdacontrols.button.start": "Start", - "lambdacontrols.button.guide": "Guide", - "lambdacontrols.button.left_thumb": "Sol çubuk", - "lambdacontrols.button.right_thumb": "Sağ çubuk", - "lambdacontrols.button.dpad_up": "Yukarı yön tuşu", - "lambdacontrols.button.dpad_right": "Sağ yön tuşu", - "lambdacontrols.button.dpad_down": "Aşağı yön tuşu", - "lambdacontrols.button.dpad_left": "Sol yön tuşu", - "lambdacontrols.axis.left_x+": "Sol X+", - "lambdacontrols.axis.left_y+": "Sol Y+", - "lambdacontrols.axis.right_x+": "Sağ X+", - "lambdacontrols.axis.right_y+": "Sağ Y+", - "lambdacontrols.axis.left_trigger": "Sol tetik tuşu", - "lambdacontrols.axis.right_trigger": "Sağ tetik tuşu", - "lambdacontrols.axis.left_x-": "Sol X-", - "lambdacontrols.axis.left_y-": "Sol Y-", - "lambdacontrols.axis.right_x-": "Sağ X-", - "lambdacontrols.axis.right_y-": "Sağ Y-", - "lambdacontrols.button.unknown": "Bilinmeyen (%d)", - "lambdacontrols.controller.connected": "%d oyun kolu bağlandı.", - "lambdacontrols.controller.disconnected": "%d oyun kolunun bağlantısı kesildi.", - "lambdacontrols.controller.mappings.1": "Oyun kolunun tuş eşleştirme ayarını yapacaksanız, lütfen sunu kullanın: %sSDL2 Gamepad Tool%s", - "lambdacontrols.controller.mappings.3": "ve eşleştirme dosyasını da şuraya koyun: `%s.minecraft/config/gamecontrollerdb.txt%s`.", - "lambdacontrols.controller.mappings.error": "Eşleştirme yüklenirken hata oluştu.", - "lambdacontrols.controller.mappings.error.write": "Dosyaya eşleştirme yazılırken hata oluştu.", - "lambdacontrols.controller.mappings.updated": "Eşleştirme güncellendi!", - "lambdacontrols.controller_type.default": "varsayılan", - "lambdacontrols.controller_type.dualshock": "DualShock", - "lambdacontrols.controller_type.switch": "Switch", - "lambdacontrols.controller_type.xbox": "Xbox", - "lambdacontrols.controller_type.steam": "Steam", - "lambdacontrols.controller_type.ouya": "OUYA", - "lambdacontrols.controls_mode.default": "Klavye/Fare", - "lambdacontrols.controls_mode.controller": "Oyun Kolu", - "lambdacontrols.controls_mode.touchscreen": "Dokunmatik Ekran", - "lambdacontrols.hud_side.left": "sol", - "lambdacontrols.hud_side.right": "sağ", - "lambdacontrols.menu.auto_switch_mode": "Otomatik Değiştirme Modu", - "lambdacontrols.menu.controller": "Oyun Kolu", - "lambdacontrols.menu.controller2": "İkincil Oyun Kolu", - "lambdacontrols.menu.controller_type": "Oyun Kolu Türü", - "lambdacontrols.menu.controls_mode": "Mod", - "lambdacontrols.menu.dead_zone": "Ölü Bölge", - "lambdacontrols.menu.fast_block_placing": "Hızlı Blok Yerleştirme", - "lambdacontrols.menu.fly_drifting": "Kayarak Uç", - "lambdacontrols.menu.fly_drifting_vertical": "Dikey uçuşta kayaaak git", - "lambdacontrols.menu.hud_enable": "HUD'u Etkinleştir", - "lambdacontrols.menu.hud_side": "HUD Yanı", - "lambdacontrols.menu.invert_right_x_axis": "Sağ X'i Terse Çevir", - "lambdacontrols.menu.invert_right_y_axis": "Sağ Y'i Terse Çevir.", - "lambdacontrols.menu.keyboard_controls": "Klavye Kontrolleri...", - "lambdacontrols.menu.mappings.open_input_str": "Eşleştirme Dosya Editörünü Aç", - "lambdacontrols.menu.mouse_speed": "Fare Hızı", - "lambdacontrols.menu.reacharound.horizontal": "Alt Öne Blok Koyma", - "lambdacontrols.menu.reacharound.vertical": "En Alta Blok Koyma", - "lambdacontrols.menu.reload_controller_mappings": "Oyun Kolu Eşleştirmelerini Yenile", - "lambdacontrols.menu.rotation_speed": "Dönme Hızı", - "lambdacontrols.menu.title": "LambdaControls - Ayarlar", - "lambdacontrols.menu.title.controller": "Oyun Kolu Seçenekleri", - "lambdacontrols.menu.title.controller_controls": "Oyun Kolu Kontrolleri", - "lambdacontrols.menu.title.gameplay": "Oynanış Seçenekleri", - "lambdacontrols.menu.title.general": "Genel Seçenekler", - "lambdacontrols.menu.title.hud": "HUD Seçenekleri", - "lambdacontrols.menu.title.mappings.string": "Eşleştirme Dosya Editörü", - "lambdacontrols.menu.unfocused_input": "Odaklanmamış Giriş Aygıtı", - "lambdacontrols.menu.virtual_mouse": "Sanal Fare", - "lambdacontrols.menu.virtual_mouse.skin": "Sanal Fare Görünümü", - "lambdacontrols.narrator.unbound": "%s Atanmamış", - "lambdacontrols.not_bound": "Tuş ataması yok", - "lambdacontrols.tooltip.auto_switch_mode": "Eğer bir tanesi bağlandıysa, kontrol modu Oyun Kolu olarak değişmeli.", - "lambdacontrols.tooltip.controller2": "Kullanılacak ikinci oyun kolu, örnek olarak Joy-Con desteği de mümkün.", - "lambdacontrols.tooltip.controller_type": "Doğru tuşları göstermesi için oyun kolu türü.", - "lambdacontrols.tooltip.controls_mode": "Kontrol Modu", - "lambdacontrols.tooltip.dead_zone": "Oyun kolunun analog çubukları için ayarlanan ölü bölge/dead zone", - "lambdacontrols.tooltip.fast_block_placing": "Yaratıcı modda uçarken, hızına bağlı olarak hızlı blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.", - "lambdacontrols.tooltip.fly_drifting": "Uçarken, Vanilla'daki gibi ani duruşlarda kayma efektini etkinleştirir.", - "lambdacontrols.tooltip.fly_drifting_vertical": "Yukarı/aşağı uçarken, Vanilla'daki gibi ani duruşlarda kayma efektini etkinleştirir.", - "lambdacontrols.tooltip.hud_enable": "Ekranın üstünde oyun kolu tuşu göstergesini açar/kapatır.", - "lambdacontrols.tooltip.hud_side": "HUD'un konumu", - "lambdacontrols.tooltip.mouse_speed": "Oyun kolunun taklit edilen fare hızı.", - "lambdacontrols.tooltip.reacharound.horizontal": "Hızlı blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.§r.", - "lambdacontrols.tooltip.reacharound.vertical": "En alta blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.§r.", - "lambdacontrols.tooltip.reload_controller_mappings": "Oyun kolu için eşleştirme dosyasını yeniler.", - "lambdacontrols.tooltip.rotation_speed": "Oyun kolu modunda olan kamera dönme hızı", - "lambdacontrols.tooltip.unfocused_input": "Oyun penceresinde değilken oyun kolu girişine izine verir.", - "lambdacontrols.tooltip.virtual_mouse": "Sanal fareyi etkinleştirir. Çift ekran oynanılacağı zaman işe yarar.", - "lambdacontrols.virtual_mouse.skin.default_light": "Varsayılan Aydınlık Tema", - "lambdacontrols.virtual_mouse.skin.default_dark": "Varsayılan Karanlık Tema", - "lambdacontrols.virtual_mouse.skin.second_light": "İkincil Aydınlık Tema", - "lambdacontrols.virtual_mouse.skin.second_dark": "İkincil Karanlık Tema" -} diff --git a/src/main/resources/assets/lambdacontrols/lang/zh_cn.json b/src/main/resources/assets/lambdacontrols/lang/zh_cn.json deleted file mode 100644 index b7e44ce..0000000 --- a/src/main/resources/assets/lambdacontrols/lang/zh_cn.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "key.lambdacontrols.look_down": "视角下移", - "key.lambdacontrols.look_left": "视角左移", - "key.lambdacontrols.look_right": "视角右移", - "key.lambdacontrols.look_up": "视角上移", - "key.lambdacontrols.ring": "显示额外按键菜单", - "lambdacontrols.action.attack": "攻击", - "lambdacontrols.action.back": "向后移动", - "lambdacontrols.action.chat": "打开聊天栏", - "lambdacontrols.action.drop_item": "丢弃所选物品", - "lambdacontrols.action.exit": "退出", - "lambdacontrols.action.forward": "向前移动", - "lambdacontrols.action.hit": "挖掘", - "lambdacontrols.action.hotbar_left": "向左循环选择快捷栏", - "lambdacontrols.action.hotbar_right": "向右循环选择快捷栏", - "lambdacontrols.action.inventory": "物品栏", - "lambdacontrols.action.jump": "跳跃", - "lambdacontrols.action.left": "向左移动", - "lambdacontrols.action.pause_game": "暂停游戏", - "lambdacontrols.action.pick_block": "选取方块", - "lambdacontrols.action.pickup": "拿取一个/拿取一半", - "lambdacontrols.action.pickup_all": "拿取一组/拿取全部", - "lambdacontrols.action.place": "放置方块", - "lambdacontrols.action.player_list": "玩家列表", - "lambdacontrols.action.quick_move": "快速移动物品", - "lambdacontrols.action.right": "向右移动", - "lambdacontrols.action.screenshot": "截图", - "lambdacontrols.action.sneak": "潜行", - "lambdacontrols.action.sprint": "疾跑", - "lambdacontrols.action.swap_hands": "与副手交换", - "lambdacontrols.action.toggle_perspective": "切换视角", - "lambdacontrols.action.toggle_smooth_camera": "切换电影视角", - "lambdacontrols.action.use": "使用物品/放置方块", - "lambdacontrols.action.zoom": "视野缩放", - "lambdacontrols.action.zoom_in": "缩放时将视野推近", - "lambdacontrols.action.zoom_out": "缩放时将视野拉远", - "lambdacontrols.action.zoom_reset": "缩放时重置缩放距离", - "lambdacontrols.button.a": "A", - "lambdacontrols.button.b": "B", - "lambdacontrols.button.x": "X", - "lambdacontrols.button.y": "Y", - "lambdacontrols.button.left_bumper": "左肩键", - "lambdacontrols.button.right_bumper": "右肩键", - "lambdacontrols.button.back": "选择键", - "lambdacontrols.button.start": "开始键", - "lambdacontrols.button.guide": "功能键", - "lambdacontrols.button.left_thumb": "左摇杆(按压)", - "lambdacontrols.button.right_thumb": "右摇杆(按压)", - "lambdacontrols.button.dpad_up": "十字键上", - "lambdacontrols.button.dpad_right": "十字键右", - "lambdacontrols.button.dpad_down": "十字键下", - "lambdacontrols.button.dpad_left": "十字键左", - "lambdacontrols.axis.left_x+": "左摇杆右(X轴正向)", - "lambdacontrols.axis.left_y+": "左摇杆上(Y轴正向)", - "lambdacontrols.axis.right_x+": "右摇杆右(X轴正向)", - "lambdacontrols.axis.right_y+": "右摇杆上(Y轴正向)", - "lambdacontrols.axis.left_trigger": "左扳机键", - "lambdacontrols.axis.right_trigger": "右扳机键", - "lambdacontrols.axis.left_x-": "左摇杆左(X轴负向)", - "lambdacontrols.axis.left_y-": "左摇杆下(Y轴负向)", - "lambdacontrols.axis.right_x-": "右摇杆左(X轴负向)", - "lambdacontrols.axis.right_y-": "右摇杆下(Y轴负向)", - "lambdacontrols.button.unknown": "未知(%d)", - "lambdacontrols.controller.connected": "手柄 %d 已连接。", - "lambdacontrols.controller.disconnected": "手柄 %d 已断开。", - "lambdacontrols.controller.mappings.1": "请使用 %s 配置手柄按键映射", - "lambdacontrols.controller.mappings.3": "并将按键映射文件放入此路径:`%s.minecraft/config/gamecontrollerdb.txt%s`。", - "lambdacontrols.controller.mappings.error": "发生错误,无法读取按键映射文件。", - "lambdacontrols.controller.mappings.error.write": "发生错误,无法保存按键映射文件。", - "lambdacontrols.controller.mappings.updated": "按键映射已更新!", - "lambdacontrols.controller_type.default": "默认", - "lambdacontrols.controller_type.dualshock": "DualShock", - "lambdacontrols.controller_type.switch": "Switch", - "lambdacontrols.controller_type.xbox": "Xbox", - "lambdacontrols.controller_type.steam": "Steam", - "lambdacontrols.controller_type.ouya": "OUYA", - "lambdacontrols.controls_mode.default": "键鼠", - "lambdacontrols.controls_mode.controller": "手柄", - "lambdacontrols.controls_mode.touchscreen": "触摸屏", - "lambdacontrols.hud_side.left": "左侧", - "lambdacontrols.hud_side.right": "右侧", - "lambdacontrols.menu.analog_movement": "识别摇杆输入的精确值", - "lambdacontrols.menu.auto_switch_mode": "自动切换模式", - "lambdacontrols.menu.controller": "手柄", - "lambdacontrols.menu.controller2": "额外手柄", - "lambdacontrols.menu.controller_type": "手柄类型", - "lambdacontrols.menu.controls_mode": "模式", - "lambdacontrols.menu.fast_block_placing": "方块快速放置", - "lambdacontrols.menu.fly_drifting": "水平方向飞行惯性", - "lambdacontrols.menu.fly_drifting_vertical": "垂直方向飞行惯性", - "lambdacontrols.menu.hud_enable": "启用HUD", - "lambdacontrols.menu.hud_side": "HUD位置", - "lambdacontrols.menu.invert_right_x_axis": "反转右摇杆X轴", - "lambdacontrols.menu.invert_right_y_axis": "反转右摇杆Y轴", - "lambdacontrols.menu.keyboard_controls": "键盘控制…", - "lambdacontrols.menu.left_dead_zone": "左摇杆死区", - "lambdacontrols.menu.mappings.open_input_str": "编辑按键映射文件", - "lambdacontrols.menu.max_left_x_value": "左摇杆X轴最大值识别范围", - "lambdacontrols.menu.max_left_y_value": "左摇杆Y轴最大值识别范围", - "lambdacontrols.menu.max_right_x_value": "右摇杆X轴最大值识别范围", - "lambdacontrols.menu.max_right_y_value": "右摇杆Y轴最大值识别范围", - "lambdacontrols.menu.mouse_speed": "鼠标移动速度", - "lambdacontrols.menu.reacharound.horizontal": "水平方向方块放置辅助", - "lambdacontrols.menu.reacharound.vertical": "垂直方向方块放置辅助", - "lambdacontrols.menu.reload_controller_mappings": "重新加载手柄按键映射", - "lambdacontrols.menu.right_dead_zone": "右摇杆死区", - "lambdacontrols.menu.rotation_speed": "镜头旋转速度", - "lambdacontrols.menu.separator.controller": "手柄", - "lambdacontrols.menu.separator.general": "通用", - "lambdacontrols.menu.title": "LambdaControls — 设置", - "lambdacontrols.menu.title.controller": "手柄选项", - "lambdacontrols.menu.title.controller_controls": "手柄控制", - "lambdacontrols.menu.title.gameplay": "游戏内容选项", - "lambdacontrols.menu.title.general": "通用选项", - "lambdacontrols.menu.title.hud": "HUD选项", - "lambdacontrols.menu.title.mappings.string": "编辑按键映射文件", - "lambdacontrols.menu.title.visual": "界面选项", - "lambdacontrols.menu.unfocused_input": "非活动状态输入", - "lambdacontrols.menu.virtual_mouse": "虚拟鼠标", - "lambdacontrols.menu.virtual_mouse.skin": "虚拟鼠标指针样式", - "lambdacontrols.narrator.unbound": "取消绑定 %s", - "lambdacontrols.not_bound": "未绑定", - "lambdacontrols.tooltip.analog_movement": "若游戏机制允许,则可根据推动摇杆的力度与幅度决定移动的速度。", - "lambdacontrols.tooltip.auto_switch_mode": "如果已有手柄连接,则自动切换为手柄操作模式。", - "lambdacontrols.tooltip.controller2": "使用额外的手柄,比如将一左一右的两个 Joy-Con 合为一个功能完全的手柄。", - "lambdacontrols.tooltip.controller_type": "选择手柄类型,以显示对应的按键图标。", - "lambdacontrols.tooltip.controls_mode": "操作模式", - "lambdacontrols.tooltip.fast_block_placing": "在创造模式中处于飞行状态时,可以根据你飞行的速度快速放置方块。\n§c在部分服务器可能会被认定为作弊。", - "lambdacontrols.tooltip.fly_drifting": "处于飞行状态时,启用原版的水平方向飞行惯性(缓停滑行)。", - "lambdacontrols.tooltip.fly_drifting_vertical": "处于飞行状态时,启用原版的垂直方向飞行惯性(缓停滑行)。", - "lambdacontrols.tooltip.hud_enable": "显示手柄按键操作提示。", - "lambdacontrols.tooltip.hud_side": "HUD的位置位于画面的哪一侧。", - "lambdacontrols.tooltip.left_dead_zone": "左摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。", - "lambdacontrols.tooltip.max_left_x_value": "更改左摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致在识别摇杆输入的精确值的情况下,左右移动较为缓慢等问题,本项可能会有所帮助。", - "lambdacontrols.tooltip.max_left_y_value": "更改左摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致在识别摇杆输入的精确值的情况下,前后移动较为缓慢等问题,本项可能会有所帮助。", - "lambdacontrols.tooltip.max_right_x_value": "更改右摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致镜头左右旋转较为缓慢等问题,本项可能会有所帮助。", - "lambdacontrols.tooltip.max_right_y_value": "更改右摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致镜头上下旋转较为缓慢等问题,本项可能会有所帮助。", - "lambdacontrols.tooltip.mouse_speed": "手柄模拟的鼠标的移动速度。", - "lambdacontrols.tooltip.reacharound.horizontal": "启用水平方向方块放置辅助,可在脚下方块的前方放置方块。\n§c在部分服务器可能会被认定为作弊。", - "lambdacontrols.tooltip.reacharound.vertical": "启用垂直方向方块放置辅助,可在脚下方块的下方放置方块。\n§c在部分服务器可能会被认定为作弊。", - "lambdacontrols.tooltip.reload_controller_mappings": "重新加载手柄的按键映射文件。", - "lambdacontrols.tooltip.right_dead_zone": "右摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。", - "lambdacontrols.tooltip.rotation_speed": "手柄操作模式下的镜头旋转速度。", - "lambdacontrols.tooltip.unfocused_input": "即使游戏窗口处于非活动状态,也允许手柄进行按键输入。", - "lambdacontrols.tooltip.virtual_mouse": "启用虚拟鼠标,在分屏的情况下很有用。", - "lambdacontrols.virtual_mouse.skin.default_light": "默认样式(白色)", - "lambdacontrols.virtual_mouse.skin.default_dark": "默认样式(黑色)", - "lambdacontrols.virtual_mouse.skin.second_light": "额外样式(白色)", - "lambdacontrols.virtual_mouse.skin.second_dark": "额外样式(黑色)" -} diff --git a/src/main/resources/assets/lambdacontrols/textures/gui/controller_axis.png b/src/main/resources/assets/lambdacontrols/textures/gui/controller_axis.png deleted file mode 100644 index c6dcfaecd5f6f8d0b86438c7ca7664fd0cecc65f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1688 zcmbtUX;70_6#Y^b!={8)qDB@A62KzK7X(o>4Iv;Pi7A^K4j8h~h=3SEOAw=iLc^jW zUr@^?Ad$UN1ZqYpA|%QhK+2*))RBl48U(6oz|ORtX@B+4IrrUp=lwY6-j^O2;BBCb z)CB;*z=uSj002x~!T`92npmO`s+#Nq{it4Q_VDn)ukELA;0NU$(2)n7ACyIin+)A{em!dVB?mnYxaV@gO zr1Z+P2i{^QqrvCcE^*K-cj?iU;Vq||b^SMS0?O8;2t~?V#^6zG zCGS>ZtEw5yg(|zt*IlrPvTY&uiSL50hkYlj%Cqr=saF~G?I$ilG@TlYM_OX!A&`;= zx#m5FoJm1_TVM&F88Qg0l8d-xt{yC8)kEeMRLY`02intKYf-}}Ij9*6i8n;l57!f%&2?uP4 z&RR^A1q+WqUN@`kce)FqvA)ip6JOIVf%|FT6CE~9CQTQ@g}DM<|Ml5N$0PD6mu~cg zhHu?Bb`8afCiEVqlr`OBIP-S7^$+D5&3<$6N(Ua6Ay%13mt}hb)v1`}LCdK{Xd44-L`NSMB$C9S?>aq*3JJ z;;F%tNB|^>hA&fuCTSAC>xCQ3))~u(2AOBKSyV{lTD#}mbyp$}WSbV+ zNDaN)JSTEXsj}$&0lM8-U$bt}@UE_!%P(FGl&2b5p3!Z?8QLtmQ(HG`u{3_^3 zH-c=uv!7KJgOqFxTn#EqT(5{K1{x;w-!#sm@m>6xAOj{g6OG^FoJ{T5cB`iMHfixR z#cT(D4&Gx!5E%Yjaje^BQXu9vdDE+4zduD4#yQ}RjoCB=BcSAjCC_>Ig8Qfr)K~#$ zVB{}V*CM7jFniNVx=M(%i}9|s_P6G*f7OF5hbrLq(i3QWyJYPLX|hO0NG*RNxAXY1 zvIje)6Nag1(#^b68bX-|l(P_`M5eZ_=67t^+x11!z}$%;94 zU?=OIWvG9%Cj9z`@l8NBF&_B)1{kKW?SS7b-eU7IA~4~7q-OZ!XEhDCB;Rg7qaWD1 zAH+!+}dXBWtk-i9jqaPyk z`x$>l5mkR9C@wv=!`{>?7aW&iZ^Ew@x~U_$Nm`UsWQP?9^p@QDSBRYRC@Xs<+!S>& z_zl8nRAJqD@QkgI$r6u=HAqO6`PF*U_ZDj=?NG;U7IkV|u_9;+6J$9K*7ezJ>Wb`4 z76j&i`6#Q}H3fNgDK5V(@w%Rs2P1osI!Fwu!h17n62AlgBqj$YB#LZ1)stE1MKp*l zMOj^iEi8jtDpdP}vB=V_dx)7BMyS9@Mj9j9N-j)KaRO zed`PrR8&Q5ouWm9inf-dYE0T9Po6*Enft?iea`3J`@Z*{^Eu~zZ?=mQQ4Dni1pt7U zt<4!X0DuTW2!Iq4Ao7WqhX83V4jyL()Ya8BvdC(0Z=au^SH{I?#lF{hq$x=17Mlz5 zC)-b$w%ePVn_JivSX*1$+S&%!%mz1x2wHS>^fhjDLPA1D?rc?6l|Z3=QF%;CVJaqL zit=J=YDyr;l8|MUc7?PVNE% zz(AyM3jiEiusvhtk??lY_jk{Ccqy@W;x2)`agle%2=-MHZx{X{)5edC*{FJNJEy*F zE*%xo2tHQ4^_R_?1eGRFS$fcF%S&@<2Le4tsq|pm>syxh1#b1((9XsR-V7u(V2a3i z-Q`$qTPyA0JFQ}PaYj$lK{VjEA}6GQRsWnzLt?96%X*zyejWWxbVXUC7(kPmi;w#5 zE_ahy?Z5Xz8ot6y*F-#-G0u=#cDr60I7W|*5Z)}1xuB8lc=2%7^=g;=k?TbI2g6$; zG&E4-$BLldWz5DGx?j;fa=F8I_-&^9GYdVGi-+k7#oJy}EL)^Sd4(#KctdM{=*f)^ zMI)nYid^W#dqu^(U(dKZi{?=ixlWw1m#)>!GTvsa8jyOmS9Z5d$6Z9c;ZPaNal04; zYjE)K`HQ#; zqs|oHOsjFf+`2bD(?so!VC~dP&gV?NGw08NI5UKY8~AG6Jq;>CTX+HGIqx&#jive=|fOY$hEgQ z2|V8?H-mNUf4y((F71RpvLQq2&RXE9;0_I)E_1JDBQxni#IG*l&=YK2XPoJ`ti-T> zifk$3D0HhGJw`i(C_9|HTH}gxd|vO(u3}r^&AZ0gNI(^8wAw0yDlO~t2|2pV79xPCdPTA^h*KhXhs3w96q; zD*${!S+F#h0gZcs7R0<&Dmp+E1tr+Y2Q5LY6W62(2Y%CctpKBRfVl&W5rQ~uu3T`d z>QAM@04%tl0|zIfl$Bm0SxNb;jirP5L9FLJs`7Uk73_t*uXpkyG6UopxHx zia0BcOUIcj&R)v0B0&J+rU*>oPctCr*!pK!c2$b6=BH4h7Ew*oagbQ94$?_879ieiEkG5 zH%UtIep2|exmpw-BScIa8*rX5fx9b1vaHD;3Qzg*`(p3$e`B9N`3Xm3har|ZWm7*r zj>7BMC()sfK~AC*BC4hr3Vl@zR6KyYlgHr^Z-sPIdSX|5p|brBc9|oN5uTZ(giF?+ zc&5rOTS5Bbw=?toH&=0i&FGSv38je1of`~eL+ySwW?A2LrJbuG>ULqWNkg&AYMFG! z&tsv8ucRe|AJOgx!{>iYtr@n^q%+;Kg#URIj`J)x{c1LX9_MY7P0Y;gxFKzWZ3~x7 zMa|;uN&F3xn<0aVb~bvUb_!pHxv5DUwavJ`(MZCY{9$CK@E{#AvaEJVu3*UfK!V?Z z)rhe$D}OVZe=eM@H!|rxxAet#)+-KQ`mA81x%zNm=p~AYoMy%?bK2v6g#a}ZRG*%i zLe8_WIQ%!i8#_Q4aV@h3Xf`+V9i9s;xr@n#+q4bFR;Xi#+Xg4~&rD$r7-DQYeJYDA zFKz?VOd^zFm?#o$qnQh`lGe2#A%!}yG`9{ev<_zO@IHl5))43)mndU4?461b z%Jd#*V1t{Wxue%Q_;|-yT(oVl@PT4AcT%N9Ty|?yiTuR#j%@YL+%j@6E&nIElz5;= z$j!(ywWlLML{ZUS$Lq%EXrG{8TT_y~BocZuk=Ls$bV9wboOeR{{Lzx=} z4?033llg6AD~7RGWl;j+1*CikI(sWYN(<@=OM3!LB7E|LBhEjxg(g4SSAp>!5G7bw zLik;Btc%xAiAUaidWlT#lX;3xIbwPa1>TgS9Rx$Ty?B|=i2V2vZM#<*Fp>}m>)y{o zbH#i874@?JbYGIhfbeD%@OL%$!UvAy=NJh;q(3k-{M=jy=*$OZ@3jDVX!$(ma&Eh8 zTnXKBjp@Syx;{WnAlG-9qUFG;A7nBTqP)Y1|8PZyhxP|-V8|1|z6{Lf6wRF~?B)rS zNP_4Dh)xDz1oHxx$DtBr$pBqAFM95uCXO4}q1t^|u^D32fA{rJ4xFU-1$!7^H7F{> zXYuen>nkZ;^P85fUAg?9Q33oyU<2Y?`6ntWG=WA*F=v%^zvIs+DOF|w&f<5BgV5d2 zl2fIiJ^8>pi-Wq*0s1yaCO~Smghl_m+l{#4l07MNN~FUR)0RwE2ssx@bK zcK)8KoYuzbkYl~|hga@NB($DSJ4%-6ZaJT3tWUcu*ifP2t|Djh53<^Y+uKQ|1tm9% z<(hN|+he>V`Ndr-lTl63mI!!vee6Vs6f4^k;_L(-^?}dhA&cQM+}&b7gt^6Tk%a~O z4MgJNb8K&!;i@Cu4kq6ybg~~Kybdxo$|`{TPtx5#f1imy#>{$W9GfYdhK#pOCPUMA;yz zZypi3wk}4+I{izP3PwBKRsTz(R|z=)RaT2h+cjnyD%6=@dkdG z5$%21QzKWZ18@{NvX!xj?TgRj@v6Y7eyBIhl zs3$NgPF@9)+&B~J{5$FN?4;0rK<1~~ZD^I8&U-VRg1|55s!Tf(9?2rze~-A!f)15J z$*sKDl7W>c)3Q%5cO-C{t7Js;O4n8uTuNhZO1!IH3l-d<{>*96;W-L6(6rh+c){V% z%Xc^!bbG;kfD`B&=VfuZ_WRQ$%HxV%G^P05e$# z6qiWfHJ=`-g{aPiJ>Y9TO&M7F;OgTE{0JM^2jjV#PkRRfv0x7T%OzpsGfv-JeUdT< zmtB2gj0qWox%`Kgc9G*GFLS#{?JLMRxA?)0*GhG<-J}xUy)U)x6Z?O=`UuqjazcHq zZBKny+aAMd-ojYylXwkDlte9^n*KX(M!Z*%)l-X0mm@BI@xVKnF}hWfiRuet_&1Az zeUdS&dgz2XD}aHX!3v6LIT=r-P_NWKbY%4u{GwoLmTb?~6};704*H;BFW_Bp`#(68 z%Mg@XqoxgR#3WfB>cY}Z?gtr#7sE~?q-Z3ao-w&lSi|FQiUw484aAMeY*kZGL~@rk z((0g56)+PylD*kI4tBa}sW(SoiYBl-y27N;=kqxmwgI zL0fs4xOE^`))r7Q_xFD3wH+J7;dV;2DkO25O-6bL?cHksi1+#j&F}0TL}gl6yJ$-P zU+~TWMTCEy@o%gDW$ZZEqFEM3=<5t%(&xR)Z^3dc>_9eVu>9!%ti@6e&h!ID-ZO>b zP1J~9sNYQGu#T6=LGPUQ1a{wW>Affo<>3T82G72$ z9JOn(7QubEg=)9yJ9V$4xv1&^CphiRGGm~+?RR0m`0ToOrNKkj(f@sTY|lEKX|xWw F@n19lO4I-V diff --git a/src/main/resources/assets/lambdacontrols/textures/gui/widgets.png b/src/main/resources/assets/lambdacontrols/textures/gui/widgets.png deleted file mode 100644 index 9b923da51561dc7cb8902f92d35e5617ff6f135a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4345 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 diff --git a/src/main/resources/assets/midnightcontrols/icon.png b/src/main/resources/assets/midnightcontrols/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..001624c7113d6604269b7e892df267600f5a64e3 GIT binary patch literal 4811 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/midnightcontrols/lang/en_us.json b/src/main/resources/assets/midnightcontrols/lang/en_us.json new file mode 100644 index 0000000..5ccbb06 --- /dev/null +++ b/src/main/resources/assets/midnightcontrols/lang/en_us.json @@ -0,0 +1,157 @@ +{ + "midnightcontrols.midnightconfig.title": "MidnightControls Advanced Config", + "key.midnightcontrols.look_down": "Look down", + "key.midnightcontrols.look_left": "Look left", + "key.midnightcontrols.look_right": "Look right", + "key.midnightcontrols.look_up": "Look up", + "key.midnightcontrols.ring": "Show controls ring", + "midnightcontrols.action.attack": "Attack", + "midnightcontrols.action.back": "Back", + "midnightcontrols.action.chat": "Open Chat", + "midnightcontrols.action.drop_item": "Drop Item", + "midnightcontrols.action.exit": "Exit", + "midnightcontrols.action.forward": "Forward", + "midnightcontrols.action.hit": "Hit", + "midnightcontrols.action.hotbar_left": "Hotbar left", + "midnightcontrols.action.hotbar_right": "Hotbar right", + "midnightcontrols.action.inventory": "Inventory", + "midnightcontrols.action.jump": "Jump", + "midnightcontrols.action.left": "Left", + "midnightcontrols.action.pause_game": "Pause Game", + "midnightcontrols.action.pick_block": "Pick Block", + "midnightcontrols.action.pickup": "Pickup", + "midnightcontrols.action.pickup_all": "Pickup all", + "midnightcontrols.action.place": "Place", + "midnightcontrols.action.player_list": "Player List", + "midnightcontrols.action.quick_move": "Quick move", + "midnightcontrols.action.right": "Right", + "midnightcontrols.action.screenshot": "Take Screenshot", + "midnightcontrols.action.sneak": "Sneak", + "midnightcontrols.action.sprint": "Sprint", + "midnightcontrols.action.swap_hands": "Swap Hands", + "midnightcontrols.action.toggle_perspective": "Toggle Perspective", + "midnightcontrols.action.toggle_smooth_camera": "Toggle Cinematic Camera", + "midnightcontrols.action.use": "Use", + "midnightcontrols.action.zoom": "Zoom", + "midnightcontrols.action.zoom_in": "Increase Zoom", + "midnightcontrols.action.zoom_out": "Decrease Zoom", + "midnightcontrols.action.zoom_reset": "Reset Zoom", + "midnightcontrols.action.key.emotecraft.fastchoose": "Fast Choose Emote", + "midnightcontrols.action.key.emotecraft.stop": "Stop Emote", + "midnightcontrols.button.a": "A", + "midnightcontrols.button.b": "B", + "midnightcontrols.button.x": "X", + "midnightcontrols.button.y": "Y", + "midnightcontrols.button.left_bumper": "Left bumper", + "midnightcontrols.button.right_bumper": "Right bumper", + "midnightcontrols.button.back": "Back", + "midnightcontrols.button.start": "Start", + "midnightcontrols.button.guide": "Guide", + "midnightcontrols.button.left_thumb": "Left thumb", + "midnightcontrols.button.right_thumb": "Right thumb", + "midnightcontrols.button.dpad_up": "DPAD up", + "midnightcontrols.button.dpad_right": "DPAD right", + "midnightcontrols.button.dpad_down": "DPAD down", + "midnightcontrols.button.dpad_left": "DPAD left", + "midnightcontrols.button.l4": "L4", + "midnightcontrols.button.l5": "L5", + "midnightcontrols.button.r4": "R4", + "midnightcontrols.button.r5": "L5", + "midnightcontrols.axis.left_x+": "Left X+", + "midnightcontrols.axis.left_y+": "Left Y+", + "midnightcontrols.axis.right_x+": "Right X+", + "midnightcontrols.axis.right_y+": "Right Y+", + "midnightcontrols.axis.left_trigger": "Left trigger", + "midnightcontrols.axis.right_trigger": "Right trigger", + "midnightcontrols.axis.left_x-": "Left X-", + "midnightcontrols.axis.left_y-": "Left Y-", + "midnightcontrols.axis.right_x-": "Right X-", + "midnightcontrols.axis.right_y-": "Right Y-", + "midnightcontrols.button.unknown": "Unknown (%d)", + "midnightcontrols.controller.connected": "Controller %d connected.", + "midnightcontrols.controller.disconnected": "Controller %d disconnected.", + "midnightcontrols.controller.mappings.1": "To configure the controller mappings, please use %s", + "midnightcontrols.controller.mappings.3": "and paste the mapping in the mappings file editor.", + "midnightcontrols.controller.mappings.error": "Error while loading mappings.", + "midnightcontrols.controller.mappings.error.write": "Error while writing mappings to file.", + "midnightcontrols.controller.mappings.updated": "Updated mappings!", + "midnightcontrols.controller_type.default": "default", + "midnightcontrols.controller_type.dualshock": "DualShock", + "midnightcontrols.controller_type.switch": "Switch", + "midnightcontrols.controller_type.xbox": "Xbox", + "midnightcontrols.controller_type.steam": "Steam", + "midnightcontrols.controller_type.ouya": "OUYA", + "midnightcontrols.controls_mode.default": "Keyboard/Mouse", + "midnightcontrols.controls_mode.controller": "Controller", + "midnightcontrols.controls_mode.touchscreen": "Touchscreen", + "midnightcontrols.hud_side.left": "left", + "midnightcontrols.hud_side.right": "right", + "midnightcontrols.menu.analog_movement": "Analog Movement", + "midnightcontrols.menu.auto_switch_mode": "Auto Switch Mode", + "midnightcontrols.menu.controller": "Controller", + "midnightcontrols.menu.controller2": "Second Controller", + "midnightcontrols.menu.controller_type": "Controller Type", + "midnightcontrols.menu.controls_mode": "Mode", + "midnightcontrols.menu.fast_block_placing": "Fast Block Placing", + "midnightcontrols.menu.fly_drifting": "Fly Drifting", + "midnightcontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting", + "midnightcontrols.menu.hud_enable": "Enable HUD", + "midnightcontrols.menu.hud_side": "HUD Side", + "midnightcontrols.menu.invert_right_x_axis": "Invert Right X", + "midnightcontrols.menu.invert_right_y_axis": "Invert Right Y", + "midnightcontrols.menu.keyboard_controls": "Keyboard Controls...", + "midnightcontrols.menu.left_dead_zone": "Left Dead Zone", + "midnightcontrols.menu.mappings.open_input_str": "Open Mappings File Editor", + "midnightcontrols.menu.max_left_x_value": "Left X Axis Max Value", + "midnightcontrols.menu.max_left_y_value": "Left Y Axis Max Value", + "midnightcontrols.menu.max_right_x_value": "Right X Axis Max Value", + "midnightcontrols.menu.max_right_y_value": "Right Y Axis Max Value", + "midnightcontrols.menu.mouse_speed": "Mouse Speed", + "midnightcontrols.menu.reacharound.horizontal": "Front Block Placing", + "midnightcontrols.menu.reacharound.vertical": "Vertical Reacharound", + "midnightcontrols.menu.reload_controller_mappings": "Reload Controller Mappings", + "midnightcontrols.menu.right_dead_zone": "Right Dead Zone", + "midnightcontrols.menu.rotation_speed": "Rotation Speed", + "midnightcontrols.menu.separator.controller": "Controller", + "midnightcontrols.menu.separator.general": "General", + "midnightcontrols.menu.title": "MidnightControls - Settings", + "midnightcontrols.menu.title.controller": "Controller Options", + "midnightcontrols.menu.title.controller_controls": "Controller Controls", + "midnightcontrols.menu.title.gameplay": "Gameplay Options", + "midnightcontrols.menu.title.general": "General Options", + "midnightcontrols.menu.title.hud": "HUD Options", + "midnightcontrols.menu.title.mappings.string": "Mappings File Editor", + "midnightcontrols.menu.title.visual": "Appearance Options", + "midnightcontrols.menu.unfocused_input": "Unfocused Input", + "midnightcontrols.menu.virtual_mouse": "Virtual Mouse", + "midnightcontrols.menu.virtual_mouse.skin": "Virtual Mouse Skin", + "midnightcontrols.narrator.unbound": "Unbound %s", + "midnightcontrols.not_bound": "Not bound", + "midnightcontrols.tooltip.analog_movement": "Enables analog movement when possible.", + "midnightcontrols.tooltip.auto_switch_mode": "If the controls mode should be switched to Controller automatically if one is connected.", + "midnightcontrols.tooltip.controller2": "Second controller to use, which allows Joy-Cons support for example.", + "midnightcontrols.tooltip.controller_type": "The controller type to display the correct buttons.", + "midnightcontrols.tooltip.controls_mode": "The controls mode.", + "midnightcontrols.tooltip.fast_block_placing": "While flying in creative mode, enables fast block placing depending on your speed. §cOn some servers this might be considered as cheating.", + "midnightcontrols.tooltip.fly_drifting": "While flying, enables Vanilla drifting/inertia.", + "midnightcontrols.tooltip.fly_drifting_vertical": "While flying, enables Vanilla vertical drifting/intertia.", + "midnightcontrols.tooltip.hud_enable": "Toggles the on-screen controller button indicator.", + "midnightcontrols.tooltip.hud_side": "The position of the HUD.", + "midnightcontrols.tooltip.left_dead_zone": "The dead zone for the controller's left analogue stick.", + "midnightcontrols.tooltip.max_left_x_value": "Changes what the mod considers the highest value for the left X axis. Useful if your axis does not use the full range and seems slow.", + "midnightcontrols.tooltip.max_left_y_value": "Changes what the mod considers the highest value for the left Y axis. Useful if your axis does not use the full range and seems slow.", + "midnightcontrols.tooltip.max_right_x_value": "Changes what the mod considers the highest value for the right X axis. Useful if your axis does not use the full range and seems slow.", + "midnightcontrols.tooltip.max_right_y_value": "Changes what the mod considers the highest value for the right Y axis. Useful if your axis does not use the full range and seems slow.", + "midnightcontrols.tooltip.mouse_speed": "The controller's emulated mouse speed.", + "midnightcontrols.tooltip.reacharound.horizontal": "Enables front block placing, §cmight be considered cheating on some servers§r.", + "midnightcontrols.tooltip.reacharound.vertical": "Enables vertical reacharound, §cmight be considered cheating on some servers§r.", + "midnightcontrols.tooltip.reload_controller_mappings": "Reloads the controller mappings file.", + "midnightcontrols.tooltip.right_dead_zone": "The dead zone for the controller's right analogue stick.", + "midnightcontrols.tooltip.rotation_speed": "The camera rotation speed in controller mode.", + "midnightcontrols.tooltip.unfocused_input": "Allow controller input when the window is not focused.", + "midnightcontrols.tooltip.virtual_mouse": "Enable the virtual mouse which is handful in the case of a splitscreen.", + "midnightcontrols.virtual_mouse.skin.default_light": "Default Light", + "midnightcontrols.virtual_mouse.skin.default_dark": "Default Dark", + "midnightcontrols.virtual_mouse.skin.second_light": "Second Light", + "midnightcontrols.virtual_mouse.skin.second_dark": "Second Dark" +} \ No newline at end of file diff --git a/src/main/resources/assets/midnightcontrols/lang/es_mx.json b/src/main/resources/assets/midnightcontrols/lang/es_mx.json new file mode 100644 index 0000000..f61731a --- /dev/null +++ b/src/main/resources/assets/midnightcontrols/lang/es_mx.json @@ -0,0 +1,150 @@ +{ + "key.midnightcontrols.look_down": "Mirar hacia abajo", + "key.midnightcontrols.look_left": "Mirar hacia izquierda", + "key.midnightcontrols.look_right": "Mirar hacia derecha", + "key.midnightcontrols.look_up": "Mirar hacia arriba", + "key.midnightcontrols.ring": "Mostrar anillo de controles", + "midnightcontrols.action.attack": "Atacar", + "midnightcontrols.action.back": "Retroceder", + "midnightcontrols.action.chat": "Abrir chat", + "midnightcontrols.action.drop_item": "Tirar ítem", + "midnightcontrols.action.exit": "Salir", + "midnightcontrols.action.forward": "Avanzar", + "midnightcontrols.action.hit": "Golpear", + "midnightcontrols.action.hotbar_left": "Hotbar a la izquierda", + "midnightcontrols.action.hotbar_right": "Hotbar a la derecha", + "midnightcontrols.action.inventory": "Inventario", + "midnightcontrols.action.jump": "Saltar", + "midnightcontrols.action.left": "Izquierda", + "midnightcontrols.action.pause_game": "Pausar juego", + "midnightcontrols.action.pick_block": "Recoger bloque", + "midnightcontrols.action.pickup": "Recoger", + "midnightcontrols.action.pickup_all": "Recoger todo", + "midnightcontrols.action.place": "Poner", + "midnightcontrols.action.player_list": "Lista de jugadores", + "midnightcontrols.action.quick_move": "Mover items rápidamente", + "midnightcontrols.action.right": "Derecha", + "midnightcontrols.action.screenshot": "Tomar captura de pantalla", + "midnightcontrols.action.sneak": "Agacharse", + "midnightcontrols.action.sprint": "Correr", + "midnightcontrols.action.swap_hands": "Intercambiar manos", + "midnightcontrols.action.toggle_perspective": "Cambiar perspectiva", + "midnightcontrols.action.toggle_smooth_camera": "Cambiar cámara cinematográfica", + "midnightcontrols.action.use": "Usar", + "midnightcontrols.action.zoom": "Zoom", + "midnightcontrols.action.zoom_in": "Aumentar zoom", + "midnightcontrols.action.zoom_out": "Disminuir zoom", + "midnightcontrols.action.zoom_reset": "Restablecer zoom", + "midnightcontrols.button.a": "A", + "midnightcontrols.button.b": "B", + "midnightcontrols.button.x": "X", + "midnightcontrols.button.y": "Y", + "midnightcontrols.button.left_bumper": "Bumper izquierda", + "midnightcontrols.button.right_bumper": "Bumper derecha", + "midnightcontrols.button.back": "Regresar", + "midnightcontrols.button.start": "Iniciar", + "midnightcontrols.button.guide": "Guía", + "midnightcontrols.button.left_thumb": "Joystick izquierda", + "midnightcontrols.button.right_thumb": "Joystick derecha", + "midnightcontrols.button.dpad_up": "Cruceta arriba", + "midnightcontrols.button.dpad_right": "Cruceta derecha", + "midnightcontrols.button.dpad_down": "Cruceta abajo", + "midnightcontrols.button.dpad_left": "Cruceta izquierda", + "midnightcontrols.axis.left_x+": "Izquierda X+", + "midnightcontrols.axis.left_y+": "Izquierda Y+", + "midnightcontrols.axis.right_x+": "Derecha X+", + "midnightcontrols.axis.right_y+": "Derecha Y+", + "midnightcontrols.axis.left_trigger": "Gatillo izquierda", + "midnightcontrols.axis.right_trigger": "Gatillo derecha", + "midnightcontrols.axis.left_x-": "Izquierda X-", + "midnightcontrols.axis.left_y-": "Izquierda Y-", + "midnightcontrols.axis.right_x-": "Derecha X-", + "midnightcontrols.axis.right_y-": "Derecha Y-", + "midnightcontrols.button.unknown": "Desconocido (%d)", + "midnightcontrols.controller.connected": "Controlador %d conectado.", + "midnightcontrols.controller.disconnected": "Controlador %d desconectado.", + "midnightcontrols.controller.mappings.1": "Para configurar las asignaciones del controlador, utilice %s", + "midnightcontrols.controller.mappings.3": "y poner el mapeo de asignaciones en `%s.minecraft/config/gamecontrollerdb.txt%s`.", + "midnightcontrols.controller.mappings.error": "Error al cargar asignaciones.", + "midnightcontrols.controller.mappings.error.write": "Error al escribir asignaciones al archivo.", + "midnightcontrols.controller.mappings.updated": "Asignaciones actualizados!", + "midnightcontrols.controller_type.default": "por defecto", + "midnightcontrols.controller_type.dualshock": "DualShock", + "midnightcontrols.controller_type.switch": "Switch", + "midnightcontrols.controller_type.xbox": "Xbox", + "midnightcontrols.controller_type.steam": "Steam", + "midnightcontrols.controller_type.ouya": "OUYA", + "midnightcontrols.controls_mode.default": "Teclado/Ratón", + "midnightcontrols.controls_mode.controller": "Controlador", + "midnightcontrols.controls_mode.touchscreen": "Pantalla táctil", + "midnightcontrols.hud_side.left": "izquierda", + "midnightcontrols.hud_side.right": "derecha", + "midnightcontrols.menu.analog_movement": "Movimiento analógico", + "midnightcontrols.menu.auto_switch_mode": "Cambio de modo automático", + "midnightcontrols.menu.controller": "Controlador", + "midnightcontrols.menu.controller2": "Segundo controlador", + "midnightcontrols.menu.controller_type": "Tipo de controlador", + "midnightcontrols.menu.controls_mode": "Modo", + "midnightcontrols.menu.fast_block_placing": "Colocación rápida de bloques", + "midnightcontrols.menu.fly_drifting": "Volar a la deriva", + "midnightcontrols.menu.fly_drifting_vertical": "Volar a la deriva vertical", + "midnightcontrols.menu.hud_enable": "Habilitar HUD", + "midnightcontrols.menu.hud_side": "Lado de HUD", + "midnightcontrols.menu.invert_right_x_axis": "Invertir derecha X", + "midnightcontrols.menu.invert_right_y_axis": "Invertir derecha Y", + "midnightcontrols.menu.keyboard_controls": "Controles del teclado...", + "midnightcontrols.menu.left_dead_zone": "Zona muerta izquierda", + "midnightcontrols.menu.mappings.open_input_str": "Abrir el editor de archivo de asignaciones", + "midnightcontrols.menu.max_left_x_value": "Valor máximo del eje X izquierdo", + "midnightcontrols.menu.max_left_y_value": "Valor máximo del eje Y izquierdo", + "midnightcontrols.menu.max_right_x_value": "Valor máximo del eje X derecho", + "midnightcontrols.menu.max_right_y_value": "Valor máximo del eje Y derecho", + "midnightcontrols.menu.mouse_speed": "Velocidad del ratón", + "midnightcontrols.menu.reacharound.horizontal": "Colocación de bloque frontal", + "midnightcontrols.menu.reacharound.vertical": "Alcance vertical", + "midnightcontrols.menu.reload_controller_mappings": "Recargar asignaciones de controlador", + "midnightcontrols.menu.right_dead_zone": "Zona muerta derecha", + "midnightcontrols.menu.rotation_speed": "Velocidad de rotación", + "midnightcontrols.menu.separator.controller": "Controlador", + "midnightcontrols.menu.separator.general": "General", + "midnightcontrols.menu.title": "midnightcontrols - Configuraciones", + "midnightcontrols.menu.title.controller": "Opciones de controlador", + "midnightcontrols.menu.title.controller_controls": "Controles de controlador", + "midnightcontrols.menu.title.gameplay": "Opciones de juego", + "midnightcontrols.menu.title.general": "Opciones generales", + "midnightcontrols.menu.title.hud": "Opciones de HUD", + "midnightcontrols.menu.title.mappings.string": "Editor de archivo de asignaciones", + "midnightcontrols.menu.title.visual": "Opciones de apariencia", + "midnightcontrols.menu.unfocused_input": "Entrada desenfocada", + "midnightcontrols.menu.virtual_mouse": "Ratón virtual", + "midnightcontrols.menu.virtual_mouse.skin": "Piel de ratón virtual", + "midnightcontrols.narrator.unbound": "Resetear %s", + "midnightcontrols.not_bound": "No ligado", + "midnightcontrols.tooltip.analog_movement": "Habilita el movimiento analógico cuando es posible.", + "midnightcontrols.tooltip.auto_switch_mode": "Si el modo de controles debe cambiarse a Controlador automáticamente si hay uno conectado.", + "midnightcontrols.tooltip.controller2": "Segundo controlador a uso, que permite el soporte de Joy-Cons por ejemplo.", + "midnightcontrols.tooltip.controller_type": "El tipo de controlador para mostrar los botones correctos.", + "midnightcontrols.tooltip.controls_mode": "El modo de controles.", + "midnightcontrols.tooltip.fast_block_placing": "Mientras vuela en modo creativo, permite la colocación rápida de bloques dependiendo su velocidad. §cEn algunos servidores, esto podría considerarse como trampa.", + "midnightcontrols.tooltip.fly_drifting": "Mientras vuela, habilita la deriva/inercia de vainilla.", + "midnightcontrols.tooltip.fly_drifting_vertical": "Mientras vuela, habilita la deriva/inercia vertical de vainilla.", + "midnightcontrols.tooltip.hud_enable": "Alterna el indicador del botón del controlador en pantalla.", + "midnightcontrols.tooltip.hud_side": "La posición del HUD.", + "midnightcontrols.tooltip.left_dead_zone": "La zona muerta de la palanca analógica izquierda del controlador.", + "midnightcontrols.tooltip.max_left_x_value": "Cambia lo que el mod considera el valor más alto para el eje X izquierdo. Útil si su eje no usa el rango completo y parece lento.", + "midnightcontrols.tooltip.max_left_y_value": "Cambia lo que el mod considera el valor más alto para el eje Y izquierdo. Útil si su eje no usa el rango completo y parece lento.", + "midnightcontrols.tooltip.max_right_x_value": "Cambia lo que el mod considera el valor más alto para el eje X derecho. Útil si su eje no usa el rango completo y parece lento.", + "midnightcontrols.tooltip.max_right_y_value": "Cambia lo que el mod considera el valor más alto para el eje Y derecho. Útil si su eje no usa el rango completo y parece lento.", + "midnightcontrols.tooltip.mouse_speed": "La velocidad del ratón emulada del controlador.", + "midnightcontrols.tooltip.reacharound.horizontal": "Habilita la colocación del bloque frontal, §cpodría considerarse trampa en algunos servidores§r.", + "midnightcontrols.tooltip.reacharound.vertical": "Habilita el alcance vertical, §cpodría considerarse trampa en algunos servidores§r.", + "midnightcontrols.tooltip.reload_controller_mappings": "Vuelve a cargar el archivo de asignaciones del controlador.", + "midnightcontrols.tooltip.right_dead_zone": "La zona muerta de la palanca analógica derecha del controlador.", + "midnightcontrols.tooltip.rotation_speed": "La velocidad de rotación de la cámara en modo controlador.", + "midnightcontrols.tooltip.unfocused_input": "Habilita entrada del controlador cuando la ventana no está enfocada.", + "midnightcontrols.tooltip.virtual_mouse": "Habilite el ratón virtual que es útil en el caso de una pantalla dividida.", + "midnightcontrols.virtual_mouse.skin.default_light": "Ligera por defecto", + "midnightcontrols.virtual_mouse.skin.default_dark": "Oscura por defecto", + "midnightcontrols.virtual_mouse.skin.second_light": "Ligera segundario", + "midnightcontrols.virtual_mouse.skin.second_dark": "Oscura segundario" +} \ No newline at end of file diff --git a/src/main/resources/assets/midnightcontrols/lang/fr_ca.json b/src/main/resources/assets/midnightcontrols/lang/fr_ca.json new file mode 100644 index 0000000..d8129ad --- /dev/null +++ b/src/main/resources/assets/midnightcontrols/lang/fr_ca.json @@ -0,0 +1,150 @@ +{ + "key.midnightcontrols.look_down": "Regarder en bas", + "key.midnightcontrols.look_left": "Regarder à gauche", + "key.midnightcontrols.look_right": "Regarder à droite", + "key.midnightcontrols.look_up": "Regarder en haut", + "key.midnightcontrols.ring": "Affiche l'anneau de contrôle", + "midnightcontrols.action.attack": "Attaquer", + "midnightcontrols.action.back": "Reculer", + "midnightcontrols.action.chat": "Ouvrir le tchat", + "midnightcontrols.action.drop_item": "Jeter l'objet", + "midnightcontrols.action.exit": "Sortir", + "midnightcontrols.action.forward": "Avancer", + "midnightcontrols.action.hit": "Taper", + "midnightcontrols.action.hotbar_left": "Case à gauche de la barre d'action", + "midnightcontrols.action.hotbar_right": "Case à droite de la barre d'action", + "midnightcontrols.action.inventory": "Inventaire", + "midnightcontrols.action.jump": "Sauter", + "midnightcontrols.action.left": "Aller à gauche", + "midnightcontrols.action.pause_game": "Mettre en pause le jeu", + "midnightcontrols.action.pick_block": "Choisir le bloc", + "midnightcontrols.action.pickup": "Prendre", + "midnightcontrols.action.pickup_all": "Prendre tout", + "midnightcontrols.action.place": "Placer", + "midnightcontrols.action.player_list": "Afficher la liste des joueurs", + "midnightcontrols.action.quick_move": "Mouvement rapide", + "midnightcontrols.action.right": "Aller à droite", + "midnightcontrols.action.screenshot": "Prendre une capture d'écran", + "midnightcontrols.action.sneak": "S'accroupir", + "midnightcontrols.action.sprint": "Courir", + "midnightcontrols.action.swap_hands": "Échanger de mains", + "midnightcontrols.action.toggle_perspective": "Changer de point de vue", + "midnightcontrols.action.toggle_smooth_camera": "Basculer en mode cinématique", + "midnightcontrols.action.use": "Utiliser", + "midnightcontrols.action.zoom": "Zoom", + "midnightcontrols.action.zoom_in": "Augmenter le zoom", + "midnightcontrols.action.zoom_out": "Diminuer le zoom", + "midnightcontrols.action.zoom_reset": "Remettre le zoom à zéro", + "midnightcontrols.button.a": "A", + "midnightcontrols.button.b": "B", + "midnightcontrols.button.x": "X", + "midnightcontrols.button.y": "Y", + "midnightcontrols.button.left_bumper": "Gâchette gauche", + "midnightcontrols.button.right_bumper": "Gâchette droite", + "midnightcontrols.button.back": "Retour", + "midnightcontrols.button.start": "Touche Menu", + "midnightcontrols.button.guide": "Guide", + "midnightcontrols.button.left_thumb": "Stick gauche", + "midnightcontrols.button.right_thumb": "Stick droit", + "midnightcontrols.button.dpad_up": "D-Pad haut", + "midnightcontrols.button.dpad_right": "D-Pad droit", + "midnightcontrols.button.dpad_down": "D-Pad bas", + "midnightcontrols.button.dpad_left": "D-Pad gauche", + "midnightcontrols.axis.left_x+": "X+ Gauche", + "midnightcontrols.axis.left_y+": "Y+ Gauche", + "midnightcontrols.axis.right_x+": "X+ Droit", + "midnightcontrols.axis.right_y+": "Y+ Droit", + "midnightcontrols.axis.left_trigger": "Gâchette gauche", + "midnightcontrols.axis.right_trigger": "Gâchette droite", + "midnightcontrols.axis.left_x-": "X- Gauche", + "midnightcontrols.axis.left_y-": "Y- Gauche", + "midnightcontrols.axis.right_x-": "X- Droit", + "midnightcontrols.axis.right_y-": "Y- Droit", + "midnightcontrols.button.unknown": "Inconnu (%d)", + "midnightcontrols.controller.connected": "Manette %d connecté.", + "midnightcontrols.controller.disconnected": "Manette %d déconnecté.", + "midnightcontrols.controller.mappings.1": "Pour configurer les correspondances de la manette, veuillez utiliser %s", + "midnightcontrols.controller.mappings.3": "et copier/coller les correspondances dans l'éditeur de manette.", + "midnightcontrols.controller.mappings.error": "Une erreur est apparue pendant le chargement des manettes.", + "midnightcontrols.controller.mappings.error.write": "Une erreur est apparue pendant l'écriture des manettes au fichier.", + "midnightcontrols.controller.mappings.updated": "Configuration des manettes mise à jour!", + "midnightcontrols.controller_type.default": "default", + "midnightcontrols.controller_type.dualshock": "DualShock", + "midnightcontrols.controller_type.switch": "Switch", + "midnightcontrols.controller_type.xbox": "Xbox", + "midnightcontrols.controller_type.steam": "Steam", + "midnightcontrols.controller_type.ouya": "OUYA", + "midnightcontrols.controls_mode.default": "Clavier/Souris", + "midnightcontrols.controls_mode.controller": "Manette", + "midnightcontrols.controls_mode.touchscreen": "Tactile", + "midnightcontrols.hud_side.left": "gauche", + "midnightcontrols.hud_side.right": "droit", + "midnightcontrols.menu.analog_movement": "Mouvement analogique", + "midnightcontrols.menu.auto_switch_mode": "Changement auto de mode", + "midnightcontrols.menu.controller": "Manette", + "midnightcontrols.menu.controller2": "Deuxième manette", + "midnightcontrols.menu.controller_type": "Type de manette", + "midnightcontrols.menu.controls_mode": "Mode", + "midnightcontrols.menu.fast_block_placing": "Placement rapide de blocs", + "midnightcontrols.menu.fly_drifting": "Inertie de vol", + "midnightcontrols.menu.fly_drifting_vertical": "Inertie verticale de vol", + "midnightcontrols.menu.hud_enable": "Activer le HUD", + "midnightcontrols.menu.hud_side": "Côté du HUD", + "midnightcontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)", + "midnightcontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)", + "midnightcontrols.menu.keyboard_controls": "Contrôles clavier...", + "midnightcontrols.menu.left_dead_zone": "Zone morte axe gauche", + "midnightcontrols.menu.mappings.open_input_str": "Ouvrir l'éditeur de fichier des manettes", + "midnightcontrols.menu.max_left_x_value": "Valeur maximale de l'axe X gauche", + "midnightcontrols.menu.max_left_y_value": "Valeur maximale de l'axe Y gauche", + "midnightcontrols.menu.max_right_x_value": "Valeur maximale de l'axe X droit", + "midnightcontrols.menu.max_right_y_value": "Valeur maximale de l'axe Y droit", + "midnightcontrols.menu.mouse_speed": "Vitesse de la souris", + "midnightcontrols.menu.reacharound.horizontal": "Placement avant de bloc", + "midnightcontrols.menu.reacharound.vertical": "Placement vertical", + "midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes", + "midnightcontrols.menu.right_dead_zone": "Zone morte axe droit", + "midnightcontrols.menu.rotation_speed": "Vitesse de rotation", + "midnightcontrols.menu.separator.general": "Général", + "midnightcontrols.menu.separator.controller": "Manette", + "midnightcontrols.menu.title": "midnightcontrols - Paramètres", + "midnightcontrols.menu.title.controller": "Options de manettes", + "midnightcontrols.menu.title.controller_controls": "Contrôles de la manette", + "midnightcontrols.menu.title.gameplay": "Options de Gameplay", + "midnightcontrols.menu.title.general": "Options générales", + "midnightcontrols.menu.title.hud": "Options du HUD", + "midnightcontrols.menu.title.mappings.string": "Éditeur de manettes", + "midnightcontrols.menu.title.visual": "Options d'apparences", + "midnightcontrols.menu.unfocused_input": "Entrée en fond", + "midnightcontrols.menu.virtual_mouse": "Souris virtuelle", + "midnightcontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle", + "midnightcontrols.narrator.unbound": "Délier %s", + "midnightcontrols.not_bound": "Non défini", + "midnightcontrols.tooltip.analog_movement": "Active le mouvement analogique si possible.", + "midnightcontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.", + "midnightcontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.", + "midnightcontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.", + "midnightcontrols.tooltip.controls_mode": "Change le mode de contrôle.", + "midnightcontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.", + "midnightcontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.", + "midnightcontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical Vanilla.", + "midnightcontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.", + "midnightcontrols.tooltip.hud_side": "Change la position du HUD.", + "midnightcontrols.tooltip.left_dead_zone": "Zone morte de l'axe gauche de la manette.", + "midnightcontrols.tooltip.max_left_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.max_left_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.max_right_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.max_right_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.", + "midnightcontrols.tooltip.reacharound.horizontal": "Active le placement avant de blocs, §cpeut être considérer comme de la triche sur certains serveurs§r.", + "midnightcontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.", + "midnightcontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.", + "midnightcontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.", + "midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.", + "midnightcontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.", + "midnightcontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.", + "midnightcontrols.virtual_mouse.skin.default_light": "défaut clair", + "midnightcontrols.virtual_mouse.skin.default_dark": "défaut foncé", + "midnightcontrols.virtual_mouse.skin.second_light": "second clair", + "midnightcontrols.virtual_mouse.skin.second_dark": "second foncé" +} \ No newline at end of file diff --git a/src/main/resources/assets/midnightcontrols/lang/fr_fr.json b/src/main/resources/assets/midnightcontrols/lang/fr_fr.json new file mode 100644 index 0000000..d8129ad --- /dev/null +++ b/src/main/resources/assets/midnightcontrols/lang/fr_fr.json @@ -0,0 +1,150 @@ +{ + "key.midnightcontrols.look_down": "Regarder en bas", + "key.midnightcontrols.look_left": "Regarder à gauche", + "key.midnightcontrols.look_right": "Regarder à droite", + "key.midnightcontrols.look_up": "Regarder en haut", + "key.midnightcontrols.ring": "Affiche l'anneau de contrôle", + "midnightcontrols.action.attack": "Attaquer", + "midnightcontrols.action.back": "Reculer", + "midnightcontrols.action.chat": "Ouvrir le tchat", + "midnightcontrols.action.drop_item": "Jeter l'objet", + "midnightcontrols.action.exit": "Sortir", + "midnightcontrols.action.forward": "Avancer", + "midnightcontrols.action.hit": "Taper", + "midnightcontrols.action.hotbar_left": "Case à gauche de la barre d'action", + "midnightcontrols.action.hotbar_right": "Case à droite de la barre d'action", + "midnightcontrols.action.inventory": "Inventaire", + "midnightcontrols.action.jump": "Sauter", + "midnightcontrols.action.left": "Aller à gauche", + "midnightcontrols.action.pause_game": "Mettre en pause le jeu", + "midnightcontrols.action.pick_block": "Choisir le bloc", + "midnightcontrols.action.pickup": "Prendre", + "midnightcontrols.action.pickup_all": "Prendre tout", + "midnightcontrols.action.place": "Placer", + "midnightcontrols.action.player_list": "Afficher la liste des joueurs", + "midnightcontrols.action.quick_move": "Mouvement rapide", + "midnightcontrols.action.right": "Aller à droite", + "midnightcontrols.action.screenshot": "Prendre une capture d'écran", + "midnightcontrols.action.sneak": "S'accroupir", + "midnightcontrols.action.sprint": "Courir", + "midnightcontrols.action.swap_hands": "Échanger de mains", + "midnightcontrols.action.toggle_perspective": "Changer de point de vue", + "midnightcontrols.action.toggle_smooth_camera": "Basculer en mode cinématique", + "midnightcontrols.action.use": "Utiliser", + "midnightcontrols.action.zoom": "Zoom", + "midnightcontrols.action.zoom_in": "Augmenter le zoom", + "midnightcontrols.action.zoom_out": "Diminuer le zoom", + "midnightcontrols.action.zoom_reset": "Remettre le zoom à zéro", + "midnightcontrols.button.a": "A", + "midnightcontrols.button.b": "B", + "midnightcontrols.button.x": "X", + "midnightcontrols.button.y": "Y", + "midnightcontrols.button.left_bumper": "Gâchette gauche", + "midnightcontrols.button.right_bumper": "Gâchette droite", + "midnightcontrols.button.back": "Retour", + "midnightcontrols.button.start": "Touche Menu", + "midnightcontrols.button.guide": "Guide", + "midnightcontrols.button.left_thumb": "Stick gauche", + "midnightcontrols.button.right_thumb": "Stick droit", + "midnightcontrols.button.dpad_up": "D-Pad haut", + "midnightcontrols.button.dpad_right": "D-Pad droit", + "midnightcontrols.button.dpad_down": "D-Pad bas", + "midnightcontrols.button.dpad_left": "D-Pad gauche", + "midnightcontrols.axis.left_x+": "X+ Gauche", + "midnightcontrols.axis.left_y+": "Y+ Gauche", + "midnightcontrols.axis.right_x+": "X+ Droit", + "midnightcontrols.axis.right_y+": "Y+ Droit", + "midnightcontrols.axis.left_trigger": "Gâchette gauche", + "midnightcontrols.axis.right_trigger": "Gâchette droite", + "midnightcontrols.axis.left_x-": "X- Gauche", + "midnightcontrols.axis.left_y-": "Y- Gauche", + "midnightcontrols.axis.right_x-": "X- Droit", + "midnightcontrols.axis.right_y-": "Y- Droit", + "midnightcontrols.button.unknown": "Inconnu (%d)", + "midnightcontrols.controller.connected": "Manette %d connecté.", + "midnightcontrols.controller.disconnected": "Manette %d déconnecté.", + "midnightcontrols.controller.mappings.1": "Pour configurer les correspondances de la manette, veuillez utiliser %s", + "midnightcontrols.controller.mappings.3": "et copier/coller les correspondances dans l'éditeur de manette.", + "midnightcontrols.controller.mappings.error": "Une erreur est apparue pendant le chargement des manettes.", + "midnightcontrols.controller.mappings.error.write": "Une erreur est apparue pendant l'écriture des manettes au fichier.", + "midnightcontrols.controller.mappings.updated": "Configuration des manettes mise à jour!", + "midnightcontrols.controller_type.default": "default", + "midnightcontrols.controller_type.dualshock": "DualShock", + "midnightcontrols.controller_type.switch": "Switch", + "midnightcontrols.controller_type.xbox": "Xbox", + "midnightcontrols.controller_type.steam": "Steam", + "midnightcontrols.controller_type.ouya": "OUYA", + "midnightcontrols.controls_mode.default": "Clavier/Souris", + "midnightcontrols.controls_mode.controller": "Manette", + "midnightcontrols.controls_mode.touchscreen": "Tactile", + "midnightcontrols.hud_side.left": "gauche", + "midnightcontrols.hud_side.right": "droit", + "midnightcontrols.menu.analog_movement": "Mouvement analogique", + "midnightcontrols.menu.auto_switch_mode": "Changement auto de mode", + "midnightcontrols.menu.controller": "Manette", + "midnightcontrols.menu.controller2": "Deuxième manette", + "midnightcontrols.menu.controller_type": "Type de manette", + "midnightcontrols.menu.controls_mode": "Mode", + "midnightcontrols.menu.fast_block_placing": "Placement rapide de blocs", + "midnightcontrols.menu.fly_drifting": "Inertie de vol", + "midnightcontrols.menu.fly_drifting_vertical": "Inertie verticale de vol", + "midnightcontrols.menu.hud_enable": "Activer le HUD", + "midnightcontrols.menu.hud_side": "Côté du HUD", + "midnightcontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)", + "midnightcontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)", + "midnightcontrols.menu.keyboard_controls": "Contrôles clavier...", + "midnightcontrols.menu.left_dead_zone": "Zone morte axe gauche", + "midnightcontrols.menu.mappings.open_input_str": "Ouvrir l'éditeur de fichier des manettes", + "midnightcontrols.menu.max_left_x_value": "Valeur maximale de l'axe X gauche", + "midnightcontrols.menu.max_left_y_value": "Valeur maximale de l'axe Y gauche", + "midnightcontrols.menu.max_right_x_value": "Valeur maximale de l'axe X droit", + "midnightcontrols.menu.max_right_y_value": "Valeur maximale de l'axe Y droit", + "midnightcontrols.menu.mouse_speed": "Vitesse de la souris", + "midnightcontrols.menu.reacharound.horizontal": "Placement avant de bloc", + "midnightcontrols.menu.reacharound.vertical": "Placement vertical", + "midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes", + "midnightcontrols.menu.right_dead_zone": "Zone morte axe droit", + "midnightcontrols.menu.rotation_speed": "Vitesse de rotation", + "midnightcontrols.menu.separator.general": "Général", + "midnightcontrols.menu.separator.controller": "Manette", + "midnightcontrols.menu.title": "midnightcontrols - Paramètres", + "midnightcontrols.menu.title.controller": "Options de manettes", + "midnightcontrols.menu.title.controller_controls": "Contrôles de la manette", + "midnightcontrols.menu.title.gameplay": "Options de Gameplay", + "midnightcontrols.menu.title.general": "Options générales", + "midnightcontrols.menu.title.hud": "Options du HUD", + "midnightcontrols.menu.title.mappings.string": "Éditeur de manettes", + "midnightcontrols.menu.title.visual": "Options d'apparences", + "midnightcontrols.menu.unfocused_input": "Entrée en fond", + "midnightcontrols.menu.virtual_mouse": "Souris virtuelle", + "midnightcontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle", + "midnightcontrols.narrator.unbound": "Délier %s", + "midnightcontrols.not_bound": "Non défini", + "midnightcontrols.tooltip.analog_movement": "Active le mouvement analogique si possible.", + "midnightcontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.", + "midnightcontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.", + "midnightcontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.", + "midnightcontrols.tooltip.controls_mode": "Change le mode de contrôle.", + "midnightcontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.", + "midnightcontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.", + "midnightcontrols.tooltip.fly_drifting_vertical": "Pendant que le joueur vole, active le glissement vertical Vanilla.", + "midnightcontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.", + "midnightcontrols.tooltip.hud_side": "Change la position du HUD.", + "midnightcontrols.tooltip.left_dead_zone": "Zone morte de l'axe gauche de la manette.", + "midnightcontrols.tooltip.max_left_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.max_left_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y gauche. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.max_right_x_value": "Change ce que le mod considère comme valeur maximale pour l'axe X droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.max_right_y_value": "Change ce que le mod considère comme valeur maximale pour l'axe Y droit. Utile si votre axe n'utilise pas l'entièreté de l'ensemble des valeurs et paraît lent.", + "midnightcontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.", + "midnightcontrols.tooltip.reacharound.horizontal": "Active le placement avant de blocs, §cpeut être considérer comme de la triche sur certains serveurs§r.", + "midnightcontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.", + "midnightcontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.", + "midnightcontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.", + "midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.", + "midnightcontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.", + "midnightcontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.", + "midnightcontrols.virtual_mouse.skin.default_light": "défaut clair", + "midnightcontrols.virtual_mouse.skin.default_dark": "défaut foncé", + "midnightcontrols.virtual_mouse.skin.second_light": "second clair", + "midnightcontrols.virtual_mouse.skin.second_dark": "second foncé" +} \ No newline at end of file diff --git a/src/main/resources/assets/midnightcontrols/lang/tr_tr.json b/src/main/resources/assets/midnightcontrols/lang/tr_tr.json new file mode 100644 index 0000000..0a7c2cc --- /dev/null +++ b/src/main/resources/assets/midnightcontrols/lang/tr_tr.json @@ -0,0 +1,135 @@ +{ + "key.midnightcontrols.look_down": "Aşağı bak", + "key.midnightcontrols.look_left": "Sola bak", + "key.midnightcontrols.look_right": "Sağa bak", + "key.midnightcontrols.look_up": "Yukarıya bak", + "key.midnightcontrols.ring": "Kontroller halkasını göster", + "midnightcontrols.action.attack": "Saldırma/Kazma", + "midnightcontrols.action.back": "Geri", + "midnightcontrols.action.chat": "Sohbeti Açma", + "midnightcontrols.action.drop_item": "Seçili Eşyayı Bırakma", + "midnightcontrols.action.exit": "Çık", + "midnightcontrols.action.forward": "İleri", + "midnightcontrols.action.hit": "Vurma", + "midnightcontrols.action.hotbar_left": "Sık Kullanılanlar'da sola git", + "midnightcontrols.action.hotbar_right": "Sık Kullanılanlar'da sağa git", + "midnightcontrols.action.inventory": "Envanter", + "midnightcontrols.action.jump": "Zıplama", + "midnightcontrols.action.left": "Sol", + "midnightcontrols.action.pause_game": "Oyunu durdur", + "midnightcontrols.action.pick_block": "Blok Seçme", + "midnightcontrols.action.pickup": "Al", + "midnightcontrols.action.pickup_all": "Hepsini Al", + "midnightcontrols.action.place": "Yerleştir", + "midnightcontrols.action.player_list": "Oyuncu Listesi", + "midnightcontrols.action.quick_move": "Hızlı Hareket", + "midnightcontrols.action.right": "Sağ", + "midnightcontrols.action.screenshot": "Ekran Görüntüsü Alma", + "midnightcontrols.action.sneak": "Eğilme", + "midnightcontrols.action.sprint": "Koşma", + "midnightcontrols.action.swap_hands": "Ögeyi Elden Ele Değiştir", + "midnightcontrols.action.toggle_perspective": "Perspektifi Değiştirme", + "midnightcontrols.action.toggle_smooth_camera": "Sinemaitk Kameraya Geçme", + "midnightcontrols.action.use": "Kullanma", + "midnightcontrols.action.zoom": "Büyütme", + "midnightcontrols.action.zoom_in": "Büyütmeyi Arttır", + "midnightcontrols.action.zoom_out": "Büyütmeyi Azalt", + "midnightcontrols.action.zoom_reset": "Büyütmeyi Sıfırla", + "midnightcontrols.button.a": "A", + "midnightcontrols.button.b": "B", + "midnightcontrols.button.x": "X", + "midnightcontrols.button.y": "Y", + "midnightcontrols.button.left_bumper": "Sol yassı tuş", + "midnightcontrols.button.right_bumper": "Sağ yassı tuş", + "midnightcontrols.button.back": "Back", + "midnightcontrols.button.start": "Start", + "midnightcontrols.button.guide": "Guide", + "midnightcontrols.button.left_thumb": "Sol çubuk", + "midnightcontrols.button.right_thumb": "Sağ çubuk", + "midnightcontrols.button.dpad_up": "Yukarı yön tuşu", + "midnightcontrols.button.dpad_right": "Sağ yön tuşu", + "midnightcontrols.button.dpad_down": "Aşağı yön tuşu", + "midnightcontrols.button.dpad_left": "Sol yön tuşu", + "midnightcontrols.axis.left_x+": "Sol X+", + "midnightcontrols.axis.left_y+": "Sol Y+", + "midnightcontrols.axis.right_x+": "Sağ X+", + "midnightcontrols.axis.right_y+": "Sağ Y+", + "midnightcontrols.axis.left_trigger": "Sol tetik tuşu", + "midnightcontrols.axis.right_trigger": "Sağ tetik tuşu", + "midnightcontrols.axis.left_x-": "Sol X-", + "midnightcontrols.axis.left_y-": "Sol Y-", + "midnightcontrols.axis.right_x-": "Sağ X-", + "midnightcontrols.axis.right_y-": "Sağ Y-", + "midnightcontrols.button.unknown": "Bilinmeyen (%d)", + "midnightcontrols.controller.connected": "%d oyun kolu bağlandı.", + "midnightcontrols.controller.disconnected": "%d oyun kolunun bağlantısı kesildi.", + "midnightcontrols.controller.mappings.1": "Oyun kolunun tuş eşleştirme ayarını yapacaksanız, lütfen sunu kullanın: %sSDL2 Gamepad Tool%s", + "midnightcontrols.controller.mappings.3": "ve eşleştirme dosyasını da şuraya koyun: `%s.minecraft/config/gamecontrollerdb.txt%s`.", + "midnightcontrols.controller.mappings.error": "Eşleştirme yüklenirken hata oluştu.", + "midnightcontrols.controller.mappings.error.write": "Dosyaya eşleştirme yazılırken hata oluştu.", + "midnightcontrols.controller.mappings.updated": "Eşleştirme güncellendi!", + "midnightcontrols.controller_type.default": "varsayılan", + "midnightcontrols.controller_type.dualshock": "DualShock", + "midnightcontrols.controller_type.switch": "Switch", + "midnightcontrols.controller_type.xbox": "Xbox", + "midnightcontrols.controller_type.steam": "Steam", + "midnightcontrols.controller_type.ouya": "OUYA", + "midnightcontrols.controls_mode.default": "Klavye/Fare", + "midnightcontrols.controls_mode.controller": "Oyun Kolu", + "midnightcontrols.controls_mode.touchscreen": "Dokunmatik Ekran", + "midnightcontrols.hud_side.left": "sol", + "midnightcontrols.hud_side.right": "sağ", + "midnightcontrols.menu.auto_switch_mode": "Otomatik Değiştirme Modu", + "midnightcontrols.menu.controller": "Oyun Kolu", + "midnightcontrols.menu.controller2": "İkincil Oyun Kolu", + "midnightcontrols.menu.controller_type": "Oyun Kolu Türü", + "midnightcontrols.menu.controls_mode": "Mod", + "midnightcontrols.menu.dead_zone": "Ölü Bölge", + "midnightcontrols.menu.fast_block_placing": "Hızlı Blok Yerleştirme", + "midnightcontrols.menu.fly_drifting": "Kayarak Uç", + "midnightcontrols.menu.fly_drifting_vertical": "Dikey uçuşta kayaaak git", + "midnightcontrols.menu.hud_enable": "HUD'u Etkinleştir", + "midnightcontrols.menu.hud_side": "HUD Yanı", + "midnightcontrols.menu.invert_right_x_axis": "Sağ X'i Terse Çevir", + "midnightcontrols.menu.invert_right_y_axis": "Sağ Y'i Terse Çevir.", + "midnightcontrols.menu.keyboard_controls": "Klavye Kontrolleri...", + "midnightcontrols.menu.mappings.open_input_str": "Eşleştirme Dosya Editörünü Aç", + "midnightcontrols.menu.mouse_speed": "Fare Hızı", + "midnightcontrols.menu.reacharound.horizontal": "Alt Öne Blok Koyma", + "midnightcontrols.menu.reacharound.vertical": "En Alta Blok Koyma", + "midnightcontrols.menu.reload_controller_mappings": "Oyun Kolu Eşleştirmelerini Yenile", + "midnightcontrols.menu.rotation_speed": "Dönme Hızı", + "midnightcontrols.menu.title": "midnightcontrols - Ayarlar", + "midnightcontrols.menu.title.controller": "Oyun Kolu Seçenekleri", + "midnightcontrols.menu.title.controller_controls": "Oyun Kolu Kontrolleri", + "midnightcontrols.menu.title.gameplay": "Oynanış Seçenekleri", + "midnightcontrols.menu.title.general": "Genel Seçenekler", + "midnightcontrols.menu.title.hud": "HUD Seçenekleri", + "midnightcontrols.menu.title.mappings.string": "Eşleştirme Dosya Editörü", + "midnightcontrols.menu.unfocused_input": "Odaklanmamış Giriş Aygıtı", + "midnightcontrols.menu.virtual_mouse": "Sanal Fare", + "midnightcontrols.menu.virtual_mouse.skin": "Sanal Fare Görünümü", + "midnightcontrols.narrator.unbound": "%s Atanmamış", + "midnightcontrols.not_bound": "Tuş ataması yok", + "midnightcontrols.tooltip.auto_switch_mode": "Eğer bir tanesi bağlandıysa, kontrol modu Oyun Kolu olarak değişmeli.", + "midnightcontrols.tooltip.controller2": "Kullanılacak ikinci oyun kolu, örnek olarak Joy-Con desteği de mümkün.", + "midnightcontrols.tooltip.controller_type": "Doğru tuşları göstermesi için oyun kolu türü.", + "midnightcontrols.tooltip.controls_mode": "Kontrol Modu", + "midnightcontrols.tooltip.dead_zone": "Oyun kolunun analog çubukları için ayarlanan ölü bölge/dead zone", + "midnightcontrols.tooltip.fast_block_placing": "Yaratıcı modda uçarken, hızına bağlı olarak hızlı blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.", + "midnightcontrols.tooltip.fly_drifting": "Uçarken, Vanilla'daki gibi ani duruşlarda kayma efektini etkinleştirir.", + "midnightcontrols.tooltip.fly_drifting_vertical": "Yukarı/aşağı uçarken, Vanilla'daki gibi ani duruşlarda kayma efektini etkinleştirir.", + "midnightcontrols.tooltip.hud_enable": "Ekranın üstünde oyun kolu tuşu göstergesini açar/kapatır.", + "midnightcontrols.tooltip.hud_side": "HUD'un konumu", + "midnightcontrols.tooltip.mouse_speed": "Oyun kolunun taklit edilen fare hızı.", + "midnightcontrols.tooltip.reacharound.horizontal": "Hızlı blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.§r.", + "midnightcontrols.tooltip.reacharound.vertical": "En alta blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.§r.", + "midnightcontrols.tooltip.reload_controller_mappings": "Oyun kolu için eşleştirme dosyasını yeniler.", + "midnightcontrols.tooltip.rotation_speed": "Oyun kolu modunda olan kamera dönme hızı", + "midnightcontrols.tooltip.unfocused_input": "Oyun penceresinde değilken oyun kolu girişine izine verir.", + "midnightcontrols.tooltip.virtual_mouse": "Sanal fareyi etkinleştirir. Çift ekran oynanılacağı zaman işe yarar.", + "midnightcontrols.virtual_mouse.skin.default_light": "Varsayılan Aydınlık Tema", + "midnightcontrols.virtual_mouse.skin.default_dark": "Varsayılan Karanlık Tema", + "midnightcontrols.virtual_mouse.skin.second_light": "İkincil Aydınlık Tema", + "midnightcontrols.virtual_mouse.skin.second_dark": "İkincil Karanlık Tema" +} diff --git a/src/main/resources/assets/midnightcontrols/lang/zh_cn.json b/src/main/resources/assets/midnightcontrols/lang/zh_cn.json new file mode 100644 index 0000000..c04a639 --- /dev/null +++ b/src/main/resources/assets/midnightcontrols/lang/zh_cn.json @@ -0,0 +1,150 @@ +{ + "key.midnightcontrols.look_down": "视角下移", + "key.midnightcontrols.look_left": "视角左移", + "key.midnightcontrols.look_right": "视角右移", + "key.midnightcontrols.look_up": "视角上移", + "key.midnightcontrols.ring": "显示额外按键菜单", + "midnightcontrols.action.attack": "攻击", + "midnightcontrols.action.back": "向后移动", + "midnightcontrols.action.chat": "打开聊天栏", + "midnightcontrols.action.drop_item": "丢弃所选物品", + "midnightcontrols.action.exit": "退出", + "midnightcontrols.action.forward": "向前移动", + "midnightcontrols.action.hit": "挖掘", + "midnightcontrols.action.hotbar_left": "向左循环选择快捷栏", + "midnightcontrols.action.hotbar_right": "向右循环选择快捷栏", + "midnightcontrols.action.inventory": "物品栏", + "midnightcontrols.action.jump": "跳跃", + "midnightcontrols.action.left": "向左移动", + "midnightcontrols.action.pause_game": "暂停游戏", + "midnightcontrols.action.pick_block": "选取方块", + "midnightcontrols.action.pickup": "拿取一个/拿取一半", + "midnightcontrols.action.pickup_all": "拿取一组/拿取全部", + "midnightcontrols.action.place": "放置方块", + "midnightcontrols.action.player_list": "玩家列表", + "midnightcontrols.action.quick_move": "快速移动物品", + "midnightcontrols.action.right": "向右移动", + "midnightcontrols.action.screenshot": "截图", + "midnightcontrols.action.sneak": "潜行", + "midnightcontrols.action.sprint": "疾跑", + "midnightcontrols.action.swap_hands": "与副手交换", + "midnightcontrols.action.toggle_perspective": "切换视角", + "midnightcontrols.action.toggle_smooth_camera": "切换电影视角", + "midnightcontrols.action.use": "使用物品/放置方块", + "midnightcontrols.action.zoom": "视野缩放", + "midnightcontrols.action.zoom_in": "缩放时将视野推近", + "midnightcontrols.action.zoom_out": "缩放时将视野拉远", + "midnightcontrols.action.zoom_reset": "缩放时重置缩放距离", + "midnightcontrols.button.a": "A", + "midnightcontrols.button.b": "B", + "midnightcontrols.button.x": "X", + "midnightcontrols.button.y": "Y", + "midnightcontrols.button.left_bumper": "左肩键", + "midnightcontrols.button.right_bumper": "右肩键", + "midnightcontrols.button.back": "选择键", + "midnightcontrols.button.start": "开始键", + "midnightcontrols.button.guide": "功能键", + "midnightcontrols.button.left_thumb": "左摇杆(按压)", + "midnightcontrols.button.right_thumb": "右摇杆(按压)", + "midnightcontrols.button.dpad_up": "十字键上", + "midnightcontrols.button.dpad_right": "十字键右", + "midnightcontrols.button.dpad_down": "十字键下", + "midnightcontrols.button.dpad_left": "十字键左", + "midnightcontrols.axis.left_x+": "左摇杆右(X轴正向)", + "midnightcontrols.axis.left_y+": "左摇杆上(Y轴正向)", + "midnightcontrols.axis.right_x+": "右摇杆右(X轴正向)", + "midnightcontrols.axis.right_y+": "右摇杆上(Y轴正向)", + "midnightcontrols.axis.left_trigger": "左扳机键", + "midnightcontrols.axis.right_trigger": "右扳机键", + "midnightcontrols.axis.left_x-": "左摇杆左(X轴负向)", + "midnightcontrols.axis.left_y-": "左摇杆下(Y轴负向)", + "midnightcontrols.axis.right_x-": "右摇杆左(X轴负向)", + "midnightcontrols.axis.right_y-": "右摇杆下(Y轴负向)", + "midnightcontrols.button.unknown": "未知(%d)", + "midnightcontrols.controller.connected": "手柄 %d 已连接。", + "midnightcontrols.controller.disconnected": "手柄 %d 已断开。", + "midnightcontrols.controller.mappings.1": "请使用 %s 配置手柄按键映射", + "midnightcontrols.controller.mappings.3": "并将按键映射文件放入此路径:`%s.minecraft/config/gamecontrollerdb.txt%s`。", + "midnightcontrols.controller.mappings.error": "发生错误,无法读取按键映射文件。", + "midnightcontrols.controller.mappings.error.write": "发生错误,无法保存按键映射文件。", + "midnightcontrols.controller.mappings.updated": "按键映射已更新!", + "midnightcontrols.controller_type.default": "默认", + "midnightcontrols.controller_type.dualshock": "DualShock", + "midnightcontrols.controller_type.switch": "Switch", + "midnightcontrols.controller_type.xbox": "Xbox", + "midnightcontrols.controller_type.steam": "Steam", + "midnightcontrols.controller_type.ouya": "OUYA", + "midnightcontrols.controls_mode.default": "键鼠", + "midnightcontrols.controls_mode.controller": "手柄", + "midnightcontrols.controls_mode.touchscreen": "触摸屏", + "midnightcontrols.hud_side.left": "左侧", + "midnightcontrols.hud_side.right": "右侧", + "midnightcontrols.menu.analog_movement": "识别摇杆输入的精确值", + "midnightcontrols.menu.auto_switch_mode": "自动切换模式", + "midnightcontrols.menu.controller": "手柄", + "midnightcontrols.menu.controller2": "额外手柄", + "midnightcontrols.menu.controller_type": "手柄类型", + "midnightcontrols.menu.controls_mode": "模式", + "midnightcontrols.menu.fast_block_placing": "方块快速放置", + "midnightcontrols.menu.fly_drifting": "水平方向飞行惯性", + "midnightcontrols.menu.fly_drifting_vertical": "垂直方向飞行惯性", + "midnightcontrols.menu.hud_enable": "启用HUD", + "midnightcontrols.menu.hud_side": "HUD位置", + "midnightcontrols.menu.invert_right_x_axis": "反转右摇杆X轴", + "midnightcontrols.menu.invert_right_y_axis": "反转右摇杆Y轴", + "midnightcontrols.menu.keyboard_controls": "键盘控制…", + "midnightcontrols.menu.left_dead_zone": "左摇杆死区", + "midnightcontrols.menu.mappings.open_input_str": "编辑按键映射文件", + "midnightcontrols.menu.max_left_x_value": "左摇杆X轴最大值识别范围", + "midnightcontrols.menu.max_left_y_value": "左摇杆Y轴最大值识别范围", + "midnightcontrols.menu.max_right_x_value": "右摇杆X轴最大值识别范围", + "midnightcontrols.menu.max_right_y_value": "右摇杆Y轴最大值识别范围", + "midnightcontrols.menu.mouse_speed": "鼠标移动速度", + "midnightcontrols.menu.reacharound.horizontal": "水平方向方块放置辅助", + "midnightcontrols.menu.reacharound.vertical": "垂直方向方块放置辅助", + "midnightcontrols.menu.reload_controller_mappings": "重新加载手柄按键映射", + "midnightcontrols.menu.right_dead_zone": "右摇杆死区", + "midnightcontrols.menu.rotation_speed": "镜头旋转速度", + "midnightcontrols.menu.separator.controller": "手柄", + "midnightcontrols.menu.separator.general": "通用", + "midnightcontrols.menu.title": "midnightcontrols — 设置", + "midnightcontrols.menu.title.controller": "手柄选项", + "midnightcontrols.menu.title.controller_controls": "手柄控制", + "midnightcontrols.menu.title.gameplay": "游戏内容选项", + "midnightcontrols.menu.title.general": "通用选项", + "midnightcontrols.menu.title.hud": "HUD选项", + "midnightcontrols.menu.title.mappings.string": "编辑按键映射文件", + "midnightcontrols.menu.title.visual": "界面选项", + "midnightcontrols.menu.unfocused_input": "非活动状态输入", + "midnightcontrols.menu.virtual_mouse": "虚拟鼠标", + "midnightcontrols.menu.virtual_mouse.skin": "虚拟鼠标指针样式", + "midnightcontrols.narrator.unbound": "取消绑定 %s", + "midnightcontrols.not_bound": "未绑定", + "midnightcontrols.tooltip.analog_movement": "若游戏机制允许,则可根据推动摇杆的力度与幅度决定移动的速度。", + "midnightcontrols.tooltip.auto_switch_mode": "如果已有手柄连接,则自动切换为手柄操作模式。", + "midnightcontrols.tooltip.controller2": "使用额外的手柄,比如将一左一右的两个 Joy-Con 合为一个功能完全的手柄。", + "midnightcontrols.tooltip.controller_type": "选择手柄类型,以显示对应的按键图标。", + "midnightcontrols.tooltip.controls_mode": "操作模式", + "midnightcontrols.tooltip.fast_block_placing": "在创造模式中处于飞行状态时,可以根据你飞行的速度快速放置方块。\n§c在部分服务器可能会被认定为作弊。", + "midnightcontrols.tooltip.fly_drifting": "处于飞行状态时,启用原版的水平方向飞行惯性(缓停滑行)。", + "midnightcontrols.tooltip.fly_drifting_vertical": "处于飞行状态时,启用原版的垂直方向飞行惯性(缓停滑行)。", + "midnightcontrols.tooltip.hud_enable": "显示手柄按键操作提示。", + "midnightcontrols.tooltip.hud_side": "HUD的位置位于画面的哪一侧。", + "midnightcontrols.tooltip.left_dead_zone": "左摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。", + "midnightcontrols.tooltip.max_left_x_value": "更改左摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致在识别摇杆输入的精确值的情况下,左右移动较为缓慢等问题,本项可能会有所帮助。", + "midnightcontrols.tooltip.max_left_y_value": "更改左摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致在识别摇杆输入的精确值的情况下,前后移动较为缓慢等问题,本项可能会有所帮助。", + "midnightcontrols.tooltip.max_right_x_value": "更改右摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致镜头左右旋转较为缓慢等问题,本项可能会有所帮助。", + "midnightcontrols.tooltip.max_right_y_value": "更改右摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值,导致镜头上下旋转较为缓慢等问题,本项可能会有所帮助。", + "midnightcontrols.tooltip.mouse_speed": "手柄模拟的鼠标的移动速度。", + "midnightcontrols.tooltip.reacharound.horizontal": "启用水平方向方块放置辅助,可在脚下方块的前方放置方块。\n§c在部分服务器可能会被认定为作弊。", + "midnightcontrols.tooltip.reacharound.vertical": "启用垂直方向方块放置辅助,可在脚下方块的下方放置方块。\n§c在部分服务器可能会被认定为作弊。", + "midnightcontrols.tooltip.reload_controller_mappings": "重新加载手柄的按键映射文件。", + "midnightcontrols.tooltip.right_dead_zone": "右摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。", + "midnightcontrols.tooltip.rotation_speed": "手柄操作模式下的镜头旋转速度。", + "midnightcontrols.tooltip.unfocused_input": "即使游戏窗口处于非活动状态,也允许手柄进行按键输入。", + "midnightcontrols.tooltip.virtual_mouse": "启用虚拟鼠标,在分屏的情况下很有用。", + "midnightcontrols.virtual_mouse.skin.default_light": "默认样式(白色)", + "midnightcontrols.virtual_mouse.skin.default_dark": "默认样式(黑色)", + "midnightcontrols.virtual_mouse.skin.second_light": "额外样式(白色)", + "midnightcontrols.virtual_mouse.skin.second_dark": "额外样式(黑色)" +} diff --git a/src/main/resources/assets/midnightcontrols/textures/gui/controller_axis.png b/src/main/resources/assets/midnightcontrols/textures/gui/controller_axis.png new file mode 100644 index 0000000000000000000000000000000000000000..de1f6b5e2dda2ae91d0e433a01fca8243956b092 GIT binary patch literal 14130 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/midnightcontrols/textures/gui/controller_expanded.png b/src/main/resources/assets/midnightcontrols/textures/gui/controller_expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..79b6e8718b1f7cdf4eed443c7e60880a87229cb7 GIT binary patch literal 13171 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/config.toml b/src/main/resources/config.toml deleted file mode 100644 index 23e2eb0..0000000 --- a/src/main/resources/config.toml +++ /dev/null @@ -1,119 +0,0 @@ -# LambdaControls configuration. - -# The controls mode. Available modes: default, controller, touchscreen -controls = "default" -# Auto switch mode. -auto_switch_mode = false -# Debug mode -debug = false - -[hud] - # Enables the HUD. - enable = true - # Dertermines where the movements buttons are. - side = "left" - -# Gameplay settings -[gameplay] - # Enables fast block placing like in Bedrock Edition. - fast_block_placing = true - # Enables analogic movement if possible. - analog_movement = true - # Fly behaviors - [gameplay.fly] - # Enables fly drifting. - drifting = false - # Enables vertical fly drifting. - vertical_drifting = true - [gameplay.reacharound] - # Enables front block placing like in Bedrock Edition. - horizontal = false - # Enables vertical reacharound. - vertical = false - # Enables front block placing outline. - outline = true - # The color in a hexadecimal format of the outline. - outline_color = "#ffffff66" - -# Controller settings -[controller] - # Controller to use. - id = 0 - # Second controller to use. - id2 = -1 - # Controller's type. - type = "default" - # Controller's dead zone. - dead_zone = 0.20 - # Rotation speed for look directions. - rotation_speed = 10.0 - # Mouse speed in GUI. - mouse_speed = 30.0 - # Inverts the right X axis. - invert_right_x_axis = false - # Inverts the right Y axis. - invert_right_y_axis = false - # Allow unfocused input. - unfocused_input = false - # Virtual mouse. - virtual_mouse = false - # Virtual mouse skin - virtual_mouse_skin = "default_light" - # Controller controls. - [controller.controls] - # Attack control. - attack = "105" - # Back control. - back = "201" - # Open chat control. - chat = "12" - # Drop item control. - drop_item = "1" - # Forward control. - forward = "101" - # Hot-bar left control. - hotbar_left = "4" - # Hot-bar right control. - hotbar_right = "5" - # Inventory control. - 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 back tab control. - tab_back = "4" - # Switch to next tab control. - tab_next = "5" - # Toggle perspective control. - toggle_perspective = "11+3" - # Toggle smooth camera control. - toggle_smooth_camera = "-1" - # Use control. - use = "104" - # Zoom control. - zoom = "11+2" diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f6d48c6..9dcac8e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,35 +1,36 @@ { "schemaVersion": 1, - "id": "lambdacontrols", - "name": "LambdaControls", + "id": "midnightcontrols", + "name": "MidnightControls", "version": "${version}", "description": "Adds better controls, and controller support.", "authors": [ - "LambdAurora" + "LambdAurora", + "Motschen" ], "contact": { - "homepage": "https://modrinth.com/mod/lambdacontrols", - "sources": "https://github.com/LambdAurora/LambdaControls.git", - "issues": "https://github.com/LambdAurora/LambdaControls/issues" + "homepage": "https://modrinth.com/mod/midnightcontrols", + "sources": "https://github.com/LambdAurora/midnightcontrols.git", + "issues": "https://github.com/LambdAurora/midnightcontrols/issues" }, "license": "MIT", - "icon": "assets/lambdacontrols/icon.png", + "icon": "assets/midnightcontrols/icon.png", "environment": "client", "entrypoints": { "main": [ - "dev.lambdaurora.lambdacontrols.LambdaControls" + "eu.midnightdust.midnightcontrols.MidnightControls" ], "client": [ - "dev.lambdaurora.lambdacontrols.client.LambdaControlsClient" + "eu.midnightdust.midnightcontrols.client.MidnightControlsClient" ], "modmenu": [ - "dev.lambdaurora.lambdacontrols.client.LambdaControlsModMenu" + "eu.midnightdust.midnightcontrols.client.MidnightControlsModMenu" ] }, - "accessWidener": "lambdacontrols.accesswidener", + "accessWidener": "midnightcontrols.accesswidener", "mixins": [ - "lambdacontrols.mixins.json", - "lambdacontrols_compat.mixins.json" + "midnightcontrols.mixins.json", + "midnightcontrols_compat.mixins.json" ], "depends": { "fabricloader": ">=0.11.3", @@ -45,13 +46,8 @@ "flamingo": "*" }, "breaks": { + "lambdacontrols": "*", "modmenu": "<1.12.2", "optifabric": "*" - }, - "custom": { - "modupdater": { - "strategy": "curseforge", - "projectID": 354231 - } } } diff --git a/src/main/resources/lambdacontrols_compat.mixins.json b/src/main/resources/lambdacontrols_compat.mixins.json deleted file mode 100644 index 47767ad..0000000 --- a/src/main/resources/lambdacontrols_compat.mixins.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "package": "dev.lambdaurora.lambdacontrols.client.compat.mixin", - "plugin": "dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsMixinPlugin", - "compatibilityLevel": "JAVA_16", - "client": [ - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/src/main/resources/lambdacontrols.accesswidener b/src/main/resources/midnightcontrols.accesswidener similarity index 100% rename from src/main/resources/lambdacontrols.accesswidener rename to src/main/resources/midnightcontrols.accesswidener diff --git a/src/main/resources/lambdacontrols.mixins.json b/src/main/resources/midnightcontrols.mixins.json similarity index 85% rename from src/main/resources/lambdacontrols.mixins.json rename to src/main/resources/midnightcontrols.mixins.json index c3d25fa..0faa7c4 100644 --- a/src/main/resources/lambdacontrols.mixins.json +++ b/src/main/resources/midnightcontrols.mixins.json @@ -1,6 +1,6 @@ { "required": true, - "package": "dev.lambdaurora.lambdacontrols.client.mixin", + "package": "eu.midnightdust.midnightcontrols.client.mixin", "compatibilityLevel": "JAVA_16", "client": [ "ClickableWidgetAccessor", @@ -15,7 +15,6 @@ "KeyBindingMixin", "MinecraftClientMixin", "MouseMixin", - "OptionsScreenMixin", "RecipeBookWidgetAccessor", "WorldRendererMixin" ], diff --git a/src/main/resources/midnightcontrols_compat.mixins.json b/src/main/resources/midnightcontrols_compat.mixins.json new file mode 100644 index 0000000..a41c333 --- /dev/null +++ b/src/main/resources/midnightcontrols_compat.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "dev.lambdaurora.midnightcontrols.client.compat.mixin", + "plugin": "eu.midnightdust.midnightcontrols.client.compat.MidnightControlsMixinPlugin", + "compatibilityLevel": "JAVA_16", + "client": [ + ], + "injectors": { + "defaultRequire": 1 + } +}