Compare commits

..

115 Commits

Author SHA1 Message Date
Motschen
afee0b407d Fix #210 2023-10-03 22:32:03 +02:00
Motschen
d32aefccac Wait for Wynntils keybinding registration
- When Wynntils is present, the keybindings are now loaded only after the keybinding category was created, allowing them to be handled by MidnightControls
2023-10-03 21:37:28 +02:00
Motschen
98797b03ea Get modded keybinds from vanilla instead of fabric
Additional keybinds are now loaded from the vanilla list instead of fabric's modded list
- Better support for mods not using the Fabric Keybinding API (Closes #218)
- Also now supports Forge mods via Sinytra Connector
- Added configurable list to exclude certain keybinds
2023-10-03 18:49:09 +02:00
Motschen
e1d53ee463 Completely rewritten joystick input
- Joystick input is now processed using polar coordinates, resulting in better accuracy and fixing tons of issues (Fixes #135, #138, #186 & #180)
- Camera movement is now way smoother by including the previous stick values in the calculation (Fixes #217 & #167)
- updateMappings() is now called asyncronously (Closes #219)
2023-10-03 17:36:30 +02:00
Motschen
233ae36343 Even more touchscreen improvements
- Fixed #222
Touch-specific improvements
- Interactive items can now be used correctly
- Drop button now works
- Most Keybinds will now work correctly while in touchscreen mode
- Added Touch category to simple options screen
2023-10-02 20:33:12 +02:00
Motschen
eb4f30913a Update pause button texture & version number 2023-09-30 21:23:43 +02:00
Motschen
1186c9c241 Another round of improvements
Mostly related to touch screen support
- Added selection outlines for Break-at-Finger mode
- Breaking blocks/interacting with entities will now just check if the target changed, not the finger position
- Added the ability to create custom touch buttons out of ButtonBindings
- Redesigned top touch buttons
- Added emote touch button when Emotecraft is installed
- Updated SpruceUI
- Removed old mixins
2023-09-30 20:27:03 +02:00
Martin Prokoph
de7cf8a307 Merge pull request #225 from m-jxx1/1.20
Update ko_kr.json
2023-09-30 10:13:49 +02:00
MJ
15510b5997 Update ko_kr.json 2023-09-25 13:28:32 +09:00
Motschen
cb56632ec4 Port to 1.20.2 & Revamp Touchscreen Input
- Port to 1.20.2
- Fixed virtual mouse cursor sometimes being hidden behind objects (closes #221)
- Touchscreen is now actually usable (in theory, I'll have to wait a few weeks for my tablet to arrive to test further)
  - Made it possible to place/break blocks and interact with entities
  - Added a touchscreen mode for interacting with entities and blocks at the position the click was registered at, not just at the crosshair
  - Added a close button to screens without their own back button
- Will be officially released when SpruceUI is updated
2023-09-23 23:13:13 +02:00
Martin Prokoph
9d11d08807 Merge pull request #215 from ImVietnam/patch-1
Add vi_vn.json
2023-09-23 12:18:07 +02:00
Martin Prokoph
54f731c7f0 Merge pull request #209 from notlin4/patch-2
Update Traditional Chinese
2023-09-23 12:17:17 +02:00
Martin Prokoph
3e3ab8743d Merge pull request #208 from kabliz/eyetracking
Eye Tracking Support, No-Hands Minecraft
2023-09-23 12:16:35 +02:00
I_am_Vietnam
ae3d6cc846 Update vi_vn.json 2023-07-04 11:10:33 +07:00
I_am_Vietnam
00c68004e8 Update vi_vn.json 2023-07-03 14:44:21 +07:00
I_am_Vietnam
f0f6a443bf Update vi_vn.json 2023-07-03 14:40:57 +07:00
I_am_Vietnam
d8ff51b3d3 Update vi_vn.json 2023-07-03 12:16:45 +07:00
I_am_Vietnam
0315784a47 Update vi_vn.json 2023-07-03 12:15:56 +07:00
I_am_Vietnam
3a4d23fb91 Update vi_vn.json 2023-07-03 11:36:46 +07:00
I_am_Vietnam
8bce9170a2 Update vi_vn.json 2023-07-03 11:10:15 +07:00
I_am_Vietnam
ec0c334d4a Create vi_vn.json 2023-07-03 11:05:26 +07:00
notlin4
b4209785e0 Update Traditional Chinese 2023-06-17 21:00:49 +08:00
notlin4
fa3d56eb25 Update Traditional Chinese 2023-06-17 20:57:46 +08:00
Kabliz
60bd283c4c Eye Tracking Support, Minecraft Without Hands
Add support for eye tracking hardware, eg the Tobii 5.
Add settings to toggle eye tracking in the settings menu.
Add settings to adjust the deadzone while looking at the crosshair.
Disable mouse raw input while eye tracking is in use, as these two modes are not compatible.
2023-06-11 14:53:36 -07:00
Motschen
889a5d8d58 MidnightControls 1.8.2 - 1.20 & Bug Fixes
- Update to 1.20
- Fix virtual mouse cursor not being visible
- Add option to hide the normal mouse cursor
2023-06-10 14:59:26 +02:00
Martin Prokoph
febf171b88 Merge pull request #195 from notlin4/patch-1
Update Traditional Chinese
2023-06-09 14:27:50 +02:00
notlin4
d133fed2f6 Update zh_tw.json 2023-04-29 21:36:37 +08:00
notlin4
9a61a13fb3 Update zh_tw.json 2023-04-27 18:00:34 +08:00
notlin4
e97223e316 Update zh_tw.json 2023-04-15 16:21:35 +08:00
notlin4
f16f7416ea Update Traditional Chinese 2023-04-15 16:20:26 +08:00
Motschen
c086ecfcef MidnightControls 1.8.1 - Bugfix and Ukrainian Translation
- Fixes #185 (Left joystick not working like a mouse when it's supposed to)
- Includes Ukrainian translation by @forditt (from #170)
2023-03-18 18:53:21 +01:00
Motschen
66cdca30fe MidnightControls 1.8.0 - 1.19.4, New GUI handling, Better reacharound
- Port to 1.19.4
- Drastically improve GUI handling
  - Directions are now respected instead of acting like the Tab key (possible thanks to 1.19.4)
  - The new tabs can be navigated using the shoulder buttons
- Sodium and Iris now have way better controller navigation thanks to isXander's PRs to them
- Improved reacharound thanks to MonstoBusta
- Cleaner advanced options screen
- Better auto-detection of the Steam Deck
2023-03-15 19:14:48 +01:00
Martin Prokoph
6e49667ada Merge pull request #178 from MonstoBusta/1.19.4-Atlas
Partially Rewrite Horizontal Reacharound
2023-03-15 14:21:53 +01:00
Martin Prokoph
d4c3208cee Merge branch '1.19.4' into 1.19.4-Atlas 2023-03-15 14:18:44 +01:00
Motschen
35a4fbee1b Many improvements for new GUI handling 2023-03-09 19:49:21 +01:00
MonstoBusta
2aac2ad4e7 Partially Rewrite Horizontal Reacharound
Replace use of BlockPos with Vec3d to allow double increased clamp on vector instead of integer.
2023-02-27 01:16:24 -06:00
Motschen
4b2919bfca Disable access widener 2023-02-15 11:13:21 +01:00
Motschen
1c999137ba Experimental port to 23w06a
Some stuff is still broken, but I managed to implement directional movement in screens
2023-02-15 11:11:39 +01:00
Motschen
d48952fec9 Fix YACL category switching with bumpers 2023-01-03 18:47:41 +01:00
Martin Prokoph
9deab7228d Merge pull request #144 from isXander/compat/yacl
YACL compatibility.
2023-01-03 17:25:21 +00:00
Martin Prokoph
b4d82a7230 Merge branch '1.19.3' into compat/yacl 2023-01-03 17:23:48 +00:00
Motschen
36e241e438 MidnightControls 1.7.3 - FAPI 0.71 hotfix 2023-01-03 18:18:21 +01:00
Martin Prokoph
bdbee99fe2 Merge pull request #155 from HttpRafa/1.19.3
Fixed error with Fabric API version 0.71.0+1.19.3
2023-01-03 17:02:12 +00:00
Martin Prokoph
439cd0858e Merge pull request #149 from glaav/patch-1
it_it.json (italian translations)
2023-01-03 17:01:08 +00:00
HttpRafa
617648cf57 Fixed error with Fabric API version 0.71.0+1.19.3 2023-01-03 03:11:44 +01:00
glaav
89914a1b6e Italian Translations 2022-12-15 19:51:03 +01:00
isXander
c272fb457f YACL compat (WIP) 2022-12-09 22:50:51 +00:00
Motschen
308b41094f MidnightControls 1.7.2 - Port to 1.19.3, various new options
- Update to 1.19.3 (Tabbing through creative tabs behaves the same as before, that was hard)
- Add an option to move the chat input field to the top of the screen for better input on devices using an on-screen keyboard
- Add an option to make the left joystick behave like a mouse in every screen
- Add a button to more easily access the Advanced Config
2022-12-09 20:02:59 +01:00
Martin Prokoph
bf7209083a Merge pull request #140 from eric122804/patch-1
Create zh_tw
2022-12-09 13:19:55 +00:00
Martin Prokoph
187844db2b Merge pull request #142 from eric122805/patch-1
Create zh_tw
2022-12-09 13:19:19 +00:00
eric122805
24ced76d06 Create zh_tw 2022-12-08 20:30:20 +08:00
eric122804
aa75a58a4d Create zh_tw 2022-12-07 20:30:51 +08:00
Motschen
1f675622f0 Use MidnightLib 22w43a version from Modrinth 2022-10-27 20:51:17 +02:00
Motschen
2d902bbf3c Port to 22w43a 2022-10-27 20:25:26 +02:00
Motschen
9cc5393703 More mod compatibility & Add missing contributor names 2022-10-27 20:00:14 +02:00
Motschen
8d08fdedf4 MidnightControls 1.7.0 - Fixes & Controller Profiles
- Fix diagonal movement speed (PR #113, thanks @dogtopus, closes #42)
- Toggle Sprint and Toggle Sneak can now be enabled separately just for controllers (closes #102)
- Added button binding profile support (closes #107)
- Fix button binding tooltips intersecting with chat on large GUI scales (closes #106)
- Add assets for non-licensed (numbered) PlayStation controllers (closes #110)
- Fix reacharound outline color
- Fix pixel error in legacy icons (closes #84)
- Fix creative flight being slow with Bedrockify installed (just disables the "disableFlyingMomentum" option on launch)
2022-10-16 15:53:03 +02:00
Martin Prokoph
cdafde01f3 Merge pull request #113 from dogtopus/preserve-speed-when-moving-diagonally
Preserve speed when moving diagonally
2022-10-13 15:26:53 +02:00
dogtopus
c07c4200f7 Clamp the speed to 1 so using dpad will not double the speed 2022-10-12 19:17:27 -03:00
dogtopus
c70da21df6 Preserve speed when moving diagonally
The original algorithm squares both X and Y separately, which cause the movement speed to drop by up to half when not moving perfectly along the axes. The new algorithm converts the XY speed vector into a speed and a moving angle vector and only square the speed instead. This prevents the slowdown issue present in the original algorithm.
2022-10-12 18:55:53 -03:00
Motschen
f5d5d93c19 Lowered value at which the HUD is considered as crammed 2022-09-23 21:06:21 +02:00
Motschen
429b4ca607 Add controller profiles, Fix HUD issues, Fix Reacharound Outline Color
Addresses #107 and #106
2022-09-23 20:48:32 +02:00
Motschen
dd173836ff MidnightControls 1.6.0 - Stability, QoL, Cleanup & Compat
- Fixed camera choppiness (especially noticeable on low framerates, closes #38)
- Asset improvements kindly contributed by @spudpiggy
- Button tips now adjust properly to the scaled width of the window (closes #95)
- Make 'Back' binding configurable (closes #93)
- Add config option to disable the button in the controls screen (closes #97)
- Add compatibility with the Inventory Tabs mod (closes #100)
- Improve Emotecraft compatibility
- Add radial menu listing unbound keys (closes #101)
- Fix disabling the HUD not hiding the tips in container screens (closes #104)
- Fix 'Back' button not working correctly
- Fix recipe book not switching tab via shoulder buttons in Crafting Table and Furnace screens
- Support scrolling in Stonecutter
2022-09-21 20:58:27 +02:00
Motschen
203fd6cdb6 First 1.6.0 changes
Way too many changes & fixes to list here, still got some work to do, but this is coming along great already
2022-09-18 20:20:10 +02:00
Martin Prokoph
003f79d405 Merge pull request #98 from TrueHorse/feature/useBuildInScroll
Use build in scrollInHotbar
2022-09-06 17:03:23 +00:00
Martin Prokoph
f48527402a Merge pull request #83 from Madis0/patch-3
Update et_ee.json
2022-09-06 16:47:02 +00:00
Paul Roß
8c4b705e65 use build in scrollInHotbar 2022-09-04 14:17:36 +02:00
Madis Otenurm
1def693ae8 Update et_ee.json 2022-08-03 14:45:03 +03:00
Madis Otenurm
cfd05bb7b6 Update et_ee.json 2022-08-03 14:44:32 +03:00
Motschen
2e861470d8 MidnightControls 1.5.0 - Hints, Legacy Icons, LibGUI
- Add hints when controller is available, but not enabled (Closes #81)
- Add optional Legacy controller icon pack (thanks @Ivanoks)
- Add LibGUI compatibility
- Fix #75 (Swift Sneak enchantment not working, thanks @andrewaramsay)
- Fix crawling being too fast
- Minify assets by @Madis0 and @RaptaG
2022-08-03 12:19:33 +02:00
Motschen
e87ed53485 Push 1.4.2 progress to GitHub (not finished yet) 2022-07-23 13:47:57 +02:00
Martin Prokoph
8847c7f499 Merge pull request #78 from RaptaG/fixed-png-name
Fix wrong name on `controller-buttons.png`
2022-07-22 14:24:10 +00:00
RaptaG
da2773b1e9 Fix wrong name (you're welcome @Madis0) 2022-07-22 14:22:52 +03:00
Martin Prokoph
3650e756c3 Merge pull request #76 from Madis0/compress
Minified images
2022-07-22 09:27:54 +00:00
Madis
6b885beede Minified images 2022-07-20 22:15:41 +03:00
Martin Prokoph
abb3d1de3c Merge pull request #62 from RaptaG/patch-1
Improve README and update the screenshots
2022-07-18 08:41:16 +00:00
Martin Prokoph
a8cdfeeba9 Merge pull request #67 from Ivanoks/1.19
Updated to 1.4.0 format!
2022-07-18 08:40:27 +00:00
Ivan
ed4d310565 Update ru_ru.json 2022-07-09 21:29:11 +06:00
Ivan
ac73c99506 1.4.0 2022-07-09 21:23:11 +06:00
Ivan
d45eeac6dc 1.4.0 new update format. 2022-07-09 20:57:47 +06:00
RaptaG
77ff589544 Actually update screenshots 2022-07-07 16:35:58 +03:00
RaptaG
ce5c0b22db Delete controller_options.png 2022-07-07 13:34:53 +00:00
RaptaG
98af13fd0b Delete 2022-07-07_14.35.12.png 2022-07-07 13:34:11 +00:00
RaptaG
2387444d3a Delete 2022-07-07_14.34.52.png 2022-07-07 13:34:04 +00:00
RaptaG
57860490c8 Updated screenshots 2022-07-07 16:33:35 +03:00
RaptaG
f46aa175a4 Delete controller_controls.png 2022-07-07 13:32:29 +00:00
RaptaG
78390ca02f Modrinth downloads and improve CF downloads 2022-07-07 13:31:57 +00:00
RaptaG
31821b4833 Add the icon 2022-07-07 12:37:01 +00:00
RaptaG
e34ba6025a More improvements 2022-07-07 12:34:57 +00:00
Motschen
9891cd2977 MidnightControls 1.4.1 - Fix tooltips getting displaced
Fixes tooltips in inventories getting displaced when having the GUI scale set to something above 4.
2022-07-06 14:14:25 +02:00
RaptaG
8566e859e3 Improve README 2022-07-06 09:25:51 +00:00
Motschen
735b9e8718 MidnightControls 1.4.0 - Many Improvements and Fixes
- EMI compat! (Switch page keybinds & more)
- Expose more keybindings
- Fix Compatibility with Quilt Creative Extension
- Improve Auto Switch mode (Automatically switch gamepad on connection changes)
- Fix triggers not working on some (slightly broken) controllers
- Fix #57 (Broken stack pickup)
- Fix #56 (Unused language strings)
- Fix #52 (Rebound perspective button blocking actions)
- Fix #46 (Button overlap with Crawl mod)
- Fix #59 (D-Pad can switch EMI buttons when in Inventories)
2022-07-05 21:15:31 +02:00
Martin Prokoph
71ee3d8e0a Merge pull request #55 from Madis0/patch-2
Estonian translation
2022-07-04 18:24:31 +00:00
Martin Prokoph
11f102759c Merge pull request #54 from Madis0/patch-1
Fix missing tooltip
2022-07-04 18:23:47 +00:00
Martin Prokoph
02dd543027 Merge pull request #53 from Ivanoks/1.19
Added Russian Language.
2022-07-04 18:22:39 +00:00
KiskaUWU
c247e51d00 Update ru_ru.json 2022-07-03 00:58:28 +10:00
KiskaUWU
e3052343d3 Update ru_ru.json 2022-07-03 00:57:17 +10:00
KiskaUWU
9e879f9230 Update ru_ru.json 2022-07-03 00:50:56 +10:00
Ivan
bda436d863 Update ru_ru.json
Fix the 128 ",".
2022-07-02 20:42:13 +06:00
KiskaUWU
98d2cdae63 Update ru_ru.json 2022-07-03 00:39:28 +10:00
Ivan
8e0e444d15 Update ru_ru.json
Changed the word format in line 99.
2022-07-02 20:07:07 +06:00
Madis Otenurm
f586647e07 Update et_ee.json 2022-07-02 17:02:47 +03:00
Ivan
73ab8456e7 Update ru_ru.json
Added subtitle about double-tap for run.
+ fix the extra characters in line 165.
2022-07-02 20:00:45 +06:00
Madis Otenurm
1a3d7ce225 Create et_ee.json 2022-07-02 16:42:40 +03:00
Madis Otenurm
965ab57159 Oops 2022-07-02 16:12:47 +03:00
Madis Otenurm
c8dba43b90 Update en_us.json 2022-07-02 12:44:08 +03:00
Ivan
dd8e62c73e Update ru_ru.json 2022-07-02 03:03:52 +06:00
Ivan
b24a158b9b Add files via upload 2022-07-02 02:12:07 +06:00
Motschen
df7c7bbdad MidnightControls 1.3.0 - Fixes and Improvements
- Merge #48 (Split rotation speed in X and Y, thanks to @ronniedude)
- Merge #47 (Korean translations by @gyular)
- Fix #50 (Stack pick-up problems in survival mode)
- Add some compatibility measures for EMI (Will likely be improved further in the future)
- Remove all REI-related code (not working anyway, EMI is better)
- Possibly fix #41 (Random crashes when changing keybinds)
2022-06-30 21:29:59 +02:00
Martin Prokoph
3ddae57eab Merge pull request #47 from gyular/ko_kr
Added Korean Translation
2022-06-30 19:20:55 +00:00
Martin Prokoph
a0701f55f6 Merge pull request #48 from ronniedude/1.19
Split rotationspeed option to allow for separate horizontal and vertical speeds (controller)
2022-06-30 15:03:02 +00:00
ronniedude
b15766dfdb Split rotationspeed option to allow for separate horizontal and vertical speed configurations (controller) 2022-06-29 16:55:15 -04:00
gyular
19ed068da9 Added Korean Translation 2022-06-28 01:53:56 +09:00
Motschen
d2e21f8723 MidnightControls 1.2.2 - Important Bugfix
Fix #45
Fix #44
2022-06-27 14:10:03 +02:00
Motschen
b3f7350de9 MidnightControls 1.2.1 - Fix log spam 2022-06-25 22:21:51 +02:00
Motschen
34408d7a2a MidnightControls 1.2.0 - Touchscreen, Modded Keybinds, Bugfixes
- Added #40 (Modded keybind support)
- Added #20 (Touchscreen support)
- Improved #13 (Sodium screen controller support)
- Attempt to fix #31 & #38 (Jittery input on low FPS)
- Fixed #35 (Front placing being broken)
- Fixed #32 (Option to disable double tap to sprint)
- Fixed #27 (Auto-adapt controller icons)
- Fixed #19 (HUD-scaling on big scales)
- Fixed #36 (Crash on game load)
- Fixed reset option
- Fixed scrolling in trading screens
- Disable features that might be considered as cheats (install MidnightControlsExtra to enable)
2022-06-25 21:23:25 +02:00
113 changed files with 4455 additions and 1759 deletions

View File

@@ -1,29 +1,29 @@
<div align="center">
<img src=https://github.com/TeamMidnightDust/MidnightControls/blob/1.19/src/main/resources/assets/midnightcontrols/icon.png>
# MidnightControls # MidnightControls
<!-- modrinth_exclude.start --> [![CurseForge](https://cf.way2muchnoise.eu/full_midnightcontrols_downloads%20on%20CurseForge.svg?badge_style=round)](https://www.curseforge.com/minecraft/mc-mods/midnightcontrols)
![Java 16](https://img.shields.io/badge/language-Java%2017-9B599A.svg?style=flat-square) <!-- modrinth_exclude.end --> [![Modrinth]](https://modrinth.com/mod/midnightcontrols)
[![GitHub license](https://img.shields.io/github/license/TeamMidnightDust/MidnightControls?style=flat-square)](https://raw.githubusercontent.com/TeamMidnightDust/MidnightControls/master/LICENSE) [![Version](https://img.shields.io/github/v/tag/TeamMidnightDust/MidnightControls?label=version&style=round)](https://github.com/TeamMidnightDust/MidnightControls/releases)
![Environment: Client](https://img.shields.io/badge/environment-client-1976d2?style=flat-square) ![Environment: Client](https://img.shields.io/badge/environment-client-1976d2?style=round)
[![Mod loader: Quilt/Fabric]][quilt] <!-- modrinth_exclude.start --> [![Mod loader: Quilt/Fabric]][Quilt]
[![Version](https://img.shields.io/github/v/tag/TeamMidnightDust/MidnightControls?label=version&style=flat-square)](https://github.com/TeamMidnightDust/MidnightControls/releases) [![Java 17](https://img.shields.io/badge/language-Java%2017-9B599A.svg?style=round)](https://www.oracle.com/java/technologies/downloads/#java17)
[![CurseForge](http://cf.way2muchnoise.eu/title/621768.svg)](https://www.curseforge.com/minecraft/mc-mods/midnightcontrols) [![GitHub license](https://img.shields.io/github/license/TeamMidnightDust/MidnightControls?style=round)](LICENSE)
<!-- modrinth_exclude.end -->
A Fabric Minecraft mod which adds better controls, reach-around and controller support. A Fabric Minecraft mod which adds better controls, reach-around and controller support.
Forked from [LambdaControls](https://github.com/LambdAurora/LambdaControls) by the amazing [LambdAurora](https://github.com/LambdAurora), which was sadly discontinued. Forked from [LambdaControls](https://github.com/LambdAurora/LambdaControls) by the amazing [LambdAurora](https://github.com/LambdAurora), which was sadly discontinued.
</div>
## What's this mod? ## What's this mod?
This mod adds better controls, reach-around features, etc. MidnightControls is a mod which provides controller and touchscreen support in Minecraft: Java Edition.<br />It also includes some Bedrock Edition parity and reach-around features!
Haven't you dreamed to travel in your modded Minecraft world with your controller? Yes? Then this mod is made for you! ## Features:
This mod also adds controller support.
## ✅ Features:
- Controller support - Controller support
- Touchscreen support (very experimental and buggy). - Touchscreen support
- Keyboard controls to look around. - Keyboard controls to look around.
- Toggleable on screen button indicator (like in Bedrock Edition). - Toggleable on screen button indicator (like in Bedrock Edition).
- Vertical reach-around. - Vertical reach-around.
@@ -32,29 +32,38 @@ This mod also adds controller support.
- Front block placing (be careful with this one) - Front block placing (be careful with this one)
- New controls settings! - New controls settings!
- Many options in config to change to your liking. - Many options in config to change to your liking.
- Many controllers supported and in a simply way your own controller mappings. - Many controllers supported and in a simple way your own controller mappings.
- An easy API for developers to add their own button bindings. - An easy API for developers to add their own button bindings.
## 🎮 Supported Controllers: ## 🎮 Supported Controllers:
- Dualshock controllers - DualShock controllers
- Dualsense controllers - DualSense controllers
- Xbox controllers - Xbox controllers
- Switch Pro controllers - Switch Pro controllers
- Joycons - Joy-Cons
- Steam controller and Steam Deck (WIP) - Steam controller and Steam Deck (WIP)
- And many more! - And many more!
## Screenshots ## Screenshots
![controller_controls](images/controller_controls.png) ![Controller_Controls](images/controller_controls.png)
![controller_options](images/controller_options.png) ![Controller_Options](images/controller_options.png)
<!-- modrinth_exclude.start -->
## Build ## Build
Just do `./gradlew build` and everything should build just fine! Clone the repo with:
<!-- modrinth_exclude.end --> ```
git clone https://github.com/TeamMidnightDust/MidnightControls
```
Enter the folder created and run:
```
./gradlew build
```
After this is done, everything should be built just fine!
[Quilt]: https://quiltmc.org
[quilt]: https://quiltmc.org
[Mod loader: Quilt/Fabric]: https://img.shields.io/badge/modloader-Quilt%2FFabric-blueviolet?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAADGAAAAxgGwdJvFAAAFU0lEQVR4nO1bwW7bOBCdCHtP+wUNxIvhS7yA7kkPOjf9AKPam4/OF2zzB96bblXhH0jPPkS5G1jnIvgib/IFtX/ALoYZemmKtEWRRe3aDzAsURbJGQ6HM4/02Wq1gmNGcNTSnxQA8IdakDK4AOCfJpj3SpiI98r2rAMAbxrWNWFFOMeL1nCJdXQa1gPTbpCbnm34ABIeBThv2hgAfOyVcF+2ZwkAfHGo54kVIRe6NVxiny4d6vpn2g36ugfqFLhwFB6kkUoc67k0XLv0qYKj9wEnBXiqZwEAf/ZKOOuV8BkLWBFesyI8A4C/LOt6AoC39C7HtBvg9Vt65hUnC/BUDzrOf1MGq5S9WkDZnuVle7ZqsBKgw/tO73K0hku8/u64EmhxsoA96MMvxdEroBIKO+CWoshnqqJPYTAGRJ8sql3QO3Op7D19D3z7AV8KeAGArFf+32lWhDwnKNuzuaUCclaE93KBiOU9hMQV+FLAOxz9lPHRR0VkZXs2oBDUNon5ULZnKOgcYwl4FTwna/K+CtRRwIK+dTnCCwkP9I0fkXmh4FcN+6UKqqtHblvtb+18po4TvKaPilsS8qVuYx5havsbJXS1I0ZVAXP1B5jfyzm+hAnN+We1XPluioX03kJtY9oNtG1T+b1aburDxhRAQVMGHw3z9k65F41nktmjUnjjrAj7ZXv27ECIyEKgBd7saBuka7lsPu0GA1MjR0+KVpwgMTlrMkN4YoztlZ/2camTvD0QjcWZF6KxMgcLyKbdAN+HKOb1y6PYH49gEsUwUKw1G48gi2KQZcApkYxH1eldUQBxeKbkRfXEQjDZ21+h2bMiHJDwH2wk1rSX0XWueHZd2yCZ/oVSnilTaA3VAiqjRRahQ0JBjuov3ijfPqAua0kUg67tmyjWCmvsS504wGQRnywjPJ8wtY3xw3827fjMBXziUalL3DcNrIzYRwXcTbvBZ7lgPHoNxKKYky1/+2xsHxXQbw2X/EIoggQHyjC9Yh8VcC6NshDc66jLOHpC5KSAPejDL8U+KuArboTQZgjHeARn+MFnvhvbRyfYaQ2XfNkTVFgUr/mIxlvkJuyjAjCae6BrYQUPW37vhDpT4MnAsCyIgbHBnYbcADJt7/t+deBCiSWsCG8sOv5IgU2FnJh2g+RnBDl1oCpgogqEx1TEURUFokx+tpCYnEzzjg1kh+fq/Ix9OXpG6OjjgI1VIGWcOMhlXh4PPdAz1VTe90rIU8Z/L9JUnALXSK4SjSUzOY+Y1ekyOlzjaamTvf3X8cjunBH1v6OeVtsG1QI66qYEVkoVmyA/O5fYmIHjgSsrskUavAc6q1BLeXXiANMZu0HKwGav7opGv+LticZqHOToLBeZrJRxC97qjOsowCTgZYO9OlNa25haMwgvsFMJPp3gLW1ji8b6dO89fhfYIbzAl23T4adtjyNvD6/mbbs9Xgs1hRcwWoIvCxDb47nQNm5aRDHvoPGcblNYCi+gtQSfU+AdLYfioLXYtHA9eruBhsILVJRwUIGQo/ACG0o4GAV4El5grQSffMA3SqbEnBdb1zeunfYsvAB3jL4UwE92KauA2NnNbLerNKhEqJ6Q+FIAOjpcATAVzjFHoC3qC9OurCW0W9s+6vXpAy4p0hPkSUL3ziNHiY3tqfNdQN4jORgnSEGMLyU8Udbq1QIEdEyRF3hSwlp4vKkwQimrHDuxAR6S4tleFIPzERnhSFXQEtbkD1kbwiMOlhJroISK8IiDpcQsp4NWeMRBc4I1lWAUHnHwpOgOJWwVHvFbsMIGJewUHvFb7QuQYxR/ttgIzbUAgB9KOM3uc+PN7QAAAABJRU5ErkJggg== [Mod loader: Quilt/Fabric]: https://img.shields.io/badge/modloader-Quilt%2FFabric-blueviolet?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAADGAAAAxgGwdJvFAAAFU0lEQVR4nO1bwW7bOBCdCHtP+wUNxIvhS7yA7kkPOjf9AKPam4/OF2zzB96bblXhH0jPPkS5G1jnIvgib/IFtX/ALoYZemmKtEWRRe3aDzAsURbJGQ6HM4/02Wq1gmNGcNTSnxQA8IdakDK4AOCfJpj3SpiI98r2rAMAbxrWNWFFOMeL1nCJdXQa1gPTbpCbnm34ABIeBThv2hgAfOyVcF+2ZwkAfHGo54kVIRe6NVxiny4d6vpn2g36ugfqFLhwFB6kkUoc67k0XLv0qYKj9wEnBXiqZwEAf/ZKOOuV8BkLWBFesyI8A4C/LOt6AoC39C7HtBvg9Vt65hUnC/BUDzrOf1MGq5S9WkDZnuVle7ZqsBKgw/tO73K0hku8/u64EmhxsoA96MMvxdEroBIKO+CWoshnqqJPYTAGRJ8sql3QO3Op7D19D3z7AV8KeAGArFf+32lWhDwnKNuzuaUCclaE93KBiOU9hMQV+FLAOxz9lPHRR0VkZXs2oBDUNon5ULZnKOgcYwl4FTwna/K+CtRRwIK+dTnCCwkP9I0fkXmh4FcN+6UKqqtHblvtb+18po4TvKaPilsS8qVuYx5havsbJXS1I0ZVAXP1B5jfyzm+hAnN+We1XPluioX03kJtY9oNtG1T+b1aburDxhRAQVMGHw3z9k65F41nktmjUnjjrAj7ZXv27ECIyEKgBd7saBuka7lsPu0GA1MjR0+KVpwgMTlrMkN4YoztlZ/2camTvD0QjcWZF6KxMgcLyKbdAN+HKOb1y6PYH49gEsUwUKw1G48gi2KQZcApkYxH1eldUQBxeKbkRfXEQjDZ21+h2bMiHJDwH2wk1rSX0XWueHZd2yCZ/oVSnilTaA3VAiqjRRahQ0JBjuov3ijfPqAua0kUg67tmyjWCmvsS504wGQRnywjPJ8wtY3xw3827fjMBXziUalL3DcNrIzYRwXcTbvBZ7lgPHoNxKKYky1/+2xsHxXQbw2X/EIoggQHyjC9Yh8VcC6NshDc66jLOHpC5KSAPejDL8U+KuArboTQZgjHeARn+MFnvhvbRyfYaQ2XfNkTVFgUr/mIxlvkJuyjAjCae6BrYQUPW37vhDpT4MnAsCyIgbHBnYbcADJt7/t+deBCiSWsCG8sOv5IgU2FnJh2g+RnBDl1oCpgogqEx1TEURUFokx+tpCYnEzzjg1kh+fq/Ix9OXpG6OjjgI1VIGWcOMhlXh4PPdAz1VTe90rIU8Z/L9JUnALXSK4SjSUzOY+Y1ekyOlzjaamTvf3X8cjunBH1v6OeVtsG1QI66qYEVkoVmyA/O5fYmIHjgSsrskUavAc6q1BLeXXiANMZu0HKwGav7opGv+LticZqHOToLBeZrJRxC97qjOsowCTgZYO9OlNa25haMwgvsFMJPp3gLW1ji8b6dO89fhfYIbzAl23T4adtjyNvD6/mbbs9Xgs1hRcwWoIvCxDb47nQNm5aRDHvoPGcblNYCi+gtQSfU+AdLYfioLXYtHA9eruBhsILVJRwUIGQo/ACG0o4GAV4El5grQSffMA3SqbEnBdb1zeunfYsvAB3jL4UwE92KauA2NnNbLerNKhEqJ6Q+FIAOjpcATAVzjFHoC3qC9OurCW0W9s+6vXpAy4p0hPkSUL3ziNHiY3tqfNdQN4jORgnSEGMLyU8Udbq1QIEdEyRF3hSwlp4vKkwQimrHDuxAR6S4tleFIPzERnhSFXQEtbkD1kbwiMOlhJroISK8IiDpcQsp4NWeMRBc4I1lWAUHnHwpOgOJWwVHvFbsMIGJewUHvFb7QuQYxR/ttgIzbUAgB9KOM3uc+PN7QAAAABJRU5ErkJggg==
[Modrinth]: https://img.shields.io/modrinth/dt/bXX9h73M?logoColor=white&logo=data:image/svg%2bxml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNTEyIDUxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTUwMy4xNiAzMjMuNTZDNTE0LjU1IDI4MS40NyA1MTUuMzIgMjM1LjkxIDUwMy4yIDE5MC43NkM0NjYuNTcgNTQuMjI5OSAzMjYuMDQgLTI2LjgwMDEgMTg5LjMzIDkuNzc5OTFDODMuODEwMSAzOC4wMTk5IDExLjM4OTkgMTI4LjA3IDAuNjg5OTQxIDIzMC40N0g0My45OUM1NC4yOSAxNDcuMzMgMTEzLjc0IDc0LjcyOTggMTk5Ljc1IDUxLjcwOThDMzA2LjA1IDIzLjI1OTggNDE1LjEzIDgwLjY2OTkgNDUzLjE3IDE4MS4zOEw0MTEuMDMgMTkyLjY1QzM5MS42NCAxNDUuOCAzNTIuNTcgMTExLjQ1IDMwNi4zIDk2LjgxOThMMjk4LjU2IDE0MC42NkMzMzUuMDkgMTU0LjEzIDM2NC43MiAxODQuNSAzNzUuNTYgMjI0LjkxQzM5MS4zNiAyODMuOCAzNjEuOTQgMzQ0LjE0IDMwOC41NiAzNjkuMTdMMzIwLjA5IDQxMi4xNkMzOTAuMjUgMzgzLjIxIDQzMi40IDMxMC4zIDQyMi40MyAyMzUuMTRMNDY0LjQxIDIyMy45MUM0NjguOTEgMjUyLjYyIDQ2Ny4zNSAyODEuMTYgNDYwLjU1IDMwOC4wN0w1MDMuMTYgMzIzLjU2WiIgZmlsbD0iIzMwYjI3YiIvPgogIDxwYXRoIGQ9Ik0zMjEuOTkgNTA0LjIyQzE4NS4yNyA1NDAuOCA0NC43NTAxIDQ1OS43NyA4LjExMDExIDMyMy4yNEMzLjg0MDExIDMwNy4zMSAxLjE3IDI5MS4zMyAwIDI3NS40Nkg0My4yN0M0NC4zNiAyODcuMzcgNDYuNDY5OSAyOTkuMzUgNDkuNjc5OSAzMTEuMjlDNTMuMDM5OSAzMjMuOCA1Ny40NSAzMzUuNzUgNjIuNzkgMzQ3LjA3TDEwMS4zOCAzMjMuOTJDOTguMTI5OSAzMTYuNDIgOTUuMzkgMzA4LjYgOTMuMjEgMzAwLjQ3QzY5LjE3IDIxMC44NyAxMjIuNDEgMTE4Ljc3IDIxMi4xMyA5NC43NjAxQzIyOS4xMyA5MC4yMTAxIDI0Ni4yMyA4OC40NDAxIDI2Mi45MyA4OS4xNTAxTDI1NS4xOSAxMzNDMjQ0LjczIDEzMy4wNSAyMzQuMTEgMTM0LjQyIDIyMy41MyAxMzcuMjVDMTU3LjMxIDE1NC45OCAxMTguMDEgMjIyLjk1IDEzNS43NSAyODkuMDlDMTM2Ljg1IDI5My4xNiAxMzguMTMgMjk3LjEzIDEzOS41OSAzMDAuOTlMMTg4Ljk0IDI3MS4zOEwxNzQuMDcgMjMxLjk1TDIyMC42NyAxODQuMDhMMjc5LjU3IDE3MS4zOUwyOTYuNjIgMTkyLjM4TDI2OS40NyAyMTkuODhMMjQ1Ljc5IDIyNy4zM0wyMjguODcgMjQ0LjcyTDIzNy4xNiAyNjcuNzlDMjM3LjE2IDI2Ny43OSAyNTMuOTUgMjg1LjYzIDI1My45OCAyODUuNjRMMjc3LjcgMjc5LjMzTDI5NC41OCAyNjAuNzlMMzMxLjQ0IDI0OS4xMkwzNDIuNDIgMjczLjgyTDMwNC4zOSAzMjAuNDVMMjQwLjY2IDM0MC42M0wyMTIuMDggMzA4LjgxTDE2Mi4yNiAzMzguN0MxODcuOCAzNjcuNzggMjI2LjIgMzgzLjkzIDI2Ni4wMSAzODAuNTZMMjc3LjU0IDQyMy41NUMyMTguMTMgNDMxLjQxIDE2MC4xIDQwNi44MiAxMjQuMDUgMzYxLjY0TDg1LjYzOTkgMzg0LjY4QzEzNi4yNSA0NTEuMTcgMjIzLjg0IDQ4NC4xMSAzMDkuNjEgNDYxLjE2QzM3MS4zNSA0NDQuNjQgNDE5LjQgNDAyLjU2IDQ0NS40MiAzNDkuMzhMNDg4LjA2IDM2NC44OEM0NTcuMTcgNDMxLjE2IDM5OC4yMiA0ODMuODIgMzIxLjk5IDUwNC4yMloiIGZpbGw9IiMzMGIyN2IiLz4KPC9zdmc+

View File

@@ -1,5 +1,5 @@
plugins { plugins {
id 'fabric-loom' version '0.11-SNAPSHOT' id 'fabric-loom' version '1.1-SNAPSHOT'
id 'java-library' id 'java-library'
id 'maven-publish' id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '7.0.0' id 'com.github.johnrengelman.shadow' version '7.0.0'
@@ -32,7 +32,7 @@ boolean isMCVersionNonRelease() {
} }
String getMCVersionString() { String getMCVersionString() {
if (isMCVersionNonRelease()) { if (isMCVersionNonRelease() || project.minecraft_version == "1.20.2") {
return project.minecraft_version return project.minecraft_version
} }
def version = project.minecraft_version.split('\\.') def version = project.minecraft_version.split('\\.')
@@ -68,11 +68,12 @@ repositories {
url 'https://maven.gegy.dev' url 'https://maven.gegy.dev'
} }
maven { maven {
name 'CottonMC' name = "CottonMC"
url 'https://server.bbkr.space/artifactory/libs-snapshot' url = "https://server.bbkr.space/artifactory/libs-release"
} }
maven { url "https://maven.terraformersmc.com/releases/" } maven { url "https://maven.terraformersmc.com/releases/" }
maven { url 'https://maven.kosmx.dev' } maven { url 'https://maven.kosmx.dev' }
maven { url 'https://maven.isxander.dev/releases' }
maven { url 'https://maven.shedaniel.me/' } maven { url 'https://maven.shedaniel.me/' }
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
maven { url "https://api.modrinth.com/maven" } maven { url "https://api.modrinth.com/maven" }
@@ -93,7 +94,9 @@ dependencies {
// Fabric API. This is technically optional, but you probably want it anyway. // Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "dev.lambdaurora:spruceui:${project.spruceui_version}" modImplementation ("dev.lambdaurora:spruceui:${project.spruceui_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
include "dev.lambdaurora:spruceui:${project.spruceui_version}" include "dev.lambdaurora:spruceui:${project.spruceui_version}"
api('org.aperlambda:lambdajcommon:1.8.1') { api('org.aperlambda:lambdajcommon:1.8.1') {
exclude group: 'com.google.code.gson' exclude group: 'com.google.code.gson'
@@ -101,7 +104,9 @@ dependencies {
} }
include 'org.aperlambda:lambdajcommon:1.8.1' include 'org.aperlambda:lambdajcommon:1.8.1'
modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}" modCompileOnlyApi ("com.terraformersmc:modmenu:${project.modmenu_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
// Compatibility mods // Compatibility mods
@@ -109,17 +114,26 @@ dependencies {
// modImplementation("maven.modrinth:ok-zoomer:${project.ok_zoomer_version}") // modImplementation("maven.modrinth:ok-zoomer:${project.ok_zoomer_version}")
// modImplementation "io.github.ennuil:LibZoomer:${project.libzoomer_version}" // modImplementation "io.github.ennuil:LibZoomer:${project.libzoomer_version}"
modImplementation "org.quiltmc:quilt-json5:1.0.0" modCompileOnlyApi "io.github.cottonmc:LibGui:${project.libgui_version}"
//modImplementation "maven.modrinth:sodium:${project.sodium_version}" modCompileOnlyApi "org.quiltmc:quilt-json5:1.0.0"
//modImplementation("maven.modrinth:emi:${project.emi_version}") modCompileOnly "maven.modrinth:sodium:${project.sodium_version}"
modImplementation "maven.modrinth:emotecraft:${project.emotecraft_version}" modCompileOnlyApi "maven.modrinth:emi:${project.emi_version}"
modImplementation "io.github.kosmx:bendy-lib:${project.bendylib_version}" modCompileOnlyApi "maven.modrinth:emotecraft:${project.emotecraft_version}"
modCompileOnlyApi "io.github.kosmx:bendy-lib:${project.bendylib_version}"
modCompileOnlyApi "dev.isxander:yet-another-config-lib:${project.yacl_version}"
modCompileOnlyApi "maven.modrinth:inventory-tabs-updated:${project.inventorytabs_version}"
modCompileOnlyApi "maven.modrinth:bedrockify:${project.bedrockify_version}"
// Required for Inventory Tabs
modCompileOnlyApi("me.shedaniel.cloth:cloth-config-fabric:${project.clothconfig_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}" modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"
include "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:core:3.6.3'
shadow 'com.electronwill.night-config:toml:3.6.3' shadow 'com.electronwill.night-config:toml:3.6.3'
apply plugin: 'java-library'
} }
loom { loom {
accessWidenerPath = file("src/main/resources/midnightcontrols.accesswidener") accessWidenerPath = file("src/main/resources/midnightcontrols.accesswidener")

View File

@@ -3,26 +3,31 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/use # check these on https://fabricmc.net/use
minecraft_version=1.19 minecraft_version=1.20.2
yarn_mappings=1.19+build.1 yarn_mappings=1.20.2+build.1
loader_version=0.14.7 loader_version=0.14.22
# Mod Properties # Mod Properties
mod_version = 1.1.0 mod_version = 1.9.0
maven_group = eu.midnightdust maven_group = eu.midnightdust
archives_base_name = midnightcontrols archives_base_name = midnightcontrols
modrinth_id=bXX9h73M modrinth_id=bXX9h73M
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.55.2+1.19 fabric_version=0.89.2+1.20.2
sodium_version=mc1.19-0.4.1 sodium_version=mc1.19.2-0.4.4
spruceui_version=4.0.0+1.19 spruceui_version=5.0.3+1.20.2
midnightlib_version=0.5.2 midnightlib_version=1.5.0-fabric
modmenu_version=4.0.0 modmenu_version=7.0.0
emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric
bendylib_version=2.0.+ bendylib_version=2.0.+
emi_version=0.1.1+1.18.2 emi_version=0.5.0+1.19.3
libgui_version=6.0.0+1.19
inventorytabs_version=inventorytabs-0.9.beta-1.19.x
clothconfig_version=7.0.72
yacl_version=2.2.0
bedrockify_version=1.9+mc1.20
# Ok Zoomer and LibZoomer are temporarily disabled for the time being, as we are currently using Reflection at runtime instead in OkZoomerCompat due to there being two major, completely incompatible API versions. # Ok Zoomer and LibZoomer are temporarily disabled for the time being, as we are currently using Reflection at runtime instead in OkZoomerCompat due to there being two major, completely incompatible API versions.
# ok_zoomer_version=5.0.0-beta.3+1.17.1 # ok_zoomer_version=5.0.0-beta.3+1.17.1

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 184 KiB

View File

@@ -24,7 +24,8 @@ import java.util.Optional;
*/ */
public enum ControlsMode implements Nameable { public enum ControlsMode implements Nameable {
DEFAULT, DEFAULT,
CONTROLLER; CONTROLLER,
TOUCHSCREEN;
/** /**
* Returns the next controls mode available. * Returns the next controls mode available.

View File

@@ -9,6 +9,7 @@
package eu.midnightdust.midnightcontrols; package eu.midnightdust.midnightcontrols;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback; import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
@@ -16,7 +17,6 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -37,14 +37,14 @@ public class MidnightControls implements ModInitializer {
public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString()); public static final Identifier 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 FEATURE_CHANNEL = new Identifier(MidnightControlsConstants.FEATURE_CHANNEL.toString());
public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString()); public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString());
public static boolean isExtrasLoaded;
public static final Text NOT_BOUND_TEXT = Text.translatable("midnightcontrols.not_bound");
public final Logger logger = LogManager.getLogger("MidnightControls"); public final Logger logger = LogManager.getLogger("MidnightControls");
@Override @Override
public void onInitialize() { public void onInitialize() {
INSTANCE = this; INSTANCE = this;
isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra");
this.log("Initializing MidnightControls..."); this.log("Initializing MidnightControls...");
ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> { ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> {

View File

@@ -61,7 +61,7 @@ public class MidnightControlsFeature implements Nameable {
* @return {@code true} if this feature is allowed, else {@code false} * @return {@code true} if this feature is allowed, else {@code false}
*/ */
public boolean isAllowed() { public boolean isAllowed() {
return this.allowed; return MidnightControls.isExtrasLoaded && this.allowed;
} }
/** /**

View File

@@ -24,15 +24,16 @@ import java.util.Optional;
* @since 1.0.0 * @since 1.0.0
*/ */
public enum ControllerType implements Nameable { public enum ControllerType implements Nameable {
DEFAULT(0, Text.of("Default")), DEFAULT(0),
DUALSHOCK(1, Text.of("Dualshock")), DUALSHOCK(1),
DUALSENSE(2, Text.of("Dualsense")), DUALSENSE(2),
SWITCH(3, Text.of("Switch")), SWITCH(3),
XBOX_360(4, Text.of("Xbox 360")), XBOX_360(4),
XBOX(5, Text.of("Xbox")), XBOX(5),
STEAM_DECK(6, Text.of("Steam Deck")), STEAM_DECK(6),
STEAM_CONTROLLER(7, Text.of("Steam Controller")), STEAM_CONTROLLER(7),
OUYA(8, Text.of("Ouya")); OUYA(8),
NUMBERED(9);
private final int id; private final int id;
private final Text text; private final Text text;

View File

@@ -10,19 +10,24 @@
package eu.midnightdust.midnightcontrols.client; package eu.midnightdust.midnightcontrols.client;
import dev.lambdaurora.spruceui.event.OpenScreenCallback; import dev.lambdaurora.spruceui.event.OpenScreenCallback;
import eu.midnightdust.lib.util.PlatformFunctions;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants; import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.MidnightControlsFeature; import eu.midnightdust.midnightcontrols.MidnightControlsFeature;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory;
import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.Controller;
import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsHud; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsHud;
import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import eu.midnightdust.midnightcontrols.client.ring.KeyBindingRingAction; import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingIDAccessor;
import eu.midnightdust.midnightcontrols.client.ring.ButtonBindingRingAction;
import eu.midnightdust.midnightcontrols.client.ring.MidnightRing; import eu.midnightdust.midnightcontrols.client.ring.MidnightRing;
import dev.lambdaurora.spruceui.hud.HudManager; import dev.lambdaurora.spruceui.hud.HudManager;
import eu.midnightdust.midnightcontrols.client.util.RainbowColor;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
@@ -42,6 +47,9 @@ import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.io.File; import java.io.File;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
/** /**
* Represents the midnightcontrols client mod. * Represents the midnightcontrols client mod.
@@ -51,6 +59,7 @@ import java.io.File;
* @since 1.1.0 * @since 1.1.0
*/ */
public class MidnightControlsClient extends MidnightControls implements ClientModInitializer { public class MidnightControlsClient extends MidnightControls implements ClientModInitializer {
public static boolean lateInitDone = false;
private static MidnightControlsClient INSTANCE; private static MidnightControlsClient INSTANCE;
public static final KeyBinding BINDING_LOOK_UP = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_up"), 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"); InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_8, "key.categories.movement");
@@ -60,8 +69,8 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement"); InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement");
public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_left"), 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"); InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement");
/*public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(midnightcontrolsConstants.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");*/ InputUtil.Type.KEYSYM, InputUtil.UNKNOWN_KEY.getCode(), "key.categories.misc");
public static final Identifier CONTROLLER_BUTTONS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_buttons.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_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 CONTROLLER_AXIS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_axis.png");
@@ -80,13 +89,12 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
KeyBindingHelper.registerKeyBinding(BINDING_LOOK_RIGHT); KeyBindingHelper.registerKeyBinding(BINDING_LOOK_RIGHT);
KeyBindingHelper.registerKeyBinding(BINDING_LOOK_DOWN); KeyBindingHelper.registerKeyBinding(BINDING_LOOK_DOWN);
KeyBindingHelper.registerKeyBinding(BINDING_LOOK_LEFT); KeyBindingHelper.registerKeyBinding(BINDING_LOOK_LEFT);
//KeyBindingHelper.registerKeyBinding(BINDING_RING); KeyBindingHelper.registerKeyBinding(BINDING_RING);
this.ring.registerAction("keybinding", KeyBindingRingAction.FACTORY); this.ring.registerAction("buttonbinding", ButtonBindingRingAction.FACTORY);
ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) -> { ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) ->
responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)); responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)));
});
ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> { ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> {
int features = buf.readVarInt(); int features = buf.readVarInt();
for (int i = 0; i < features; i++) { for (int i = 0; i < features; i++) {
@@ -102,22 +110,32 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave); ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave);
ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick); ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick);
ClientTickEvents.END_CLIENT_TICK.register(this::onTick); ClientTickEvents.START_CLIENT_TICK.register(this::onTick);
OpenScreenCallback.EVENT.register((client, screen) -> { OpenScreenCallback.EVENT.register((client, screen) -> {
// if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) { if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) {
// screen = new TouchscreenOverlay(this); screen = new TouchscreenOverlay(this);
// screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
// client.skipGameRender = false; client.skipGameRender = false;
// client.currentScreen = screen; client.currentScreen = screen;
// } else if (screen != null) { } else if (screen != null) {
this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight()); this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight());
//} }
}); });
final MinecraftClient client = MinecraftClient.getInstance();
int delay = 0; // delay for 0 sec.
int period = 1; // repeat every 0.001 sec. (100 times a second)
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
input.updateCamera(client);
}
}, delay, period);
HudManager.register(this.hud = new MidnightControlsHud(this)); HudManager.register(this.hud = new MidnightControlsHud(this));
FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> { FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> {
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL); ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL);
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","legacy"), modContainer, ResourcePackActivationType.NORMAL);
}); });
} }
@@ -127,8 +145,17 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
public void onMcInit(@NotNull MinecraftClient client) { public void onMcInit(@NotNull MinecraftClient client) {
ButtonBinding.init(client.options); ButtonBinding.init(client.options);
MidnightControlsConfig.load(); MidnightControlsConfig.load();
if (MidnightControlsConfig.configVersion < 2) {
MidnightControlsConfig.mouseScreens.remove("me.jellysquid.mods.sodium.client.gui");
MidnightControlsConfig.mouseScreens.remove("net.coderbot.iris.gui");
MidnightControlsConfig.mouseScreens.remove("net.minecraft.class_5375");
MidnightControlsConfig.mouseScreens.remove("net.minecraft.client.gui.screen.pack.PackScreen");
MidnightControlsConfig.configVersion = 2;
MidnightControlsConfig.write("midnightcontrols");
}
this.hud.setVisible(MidnightControlsConfig.hudEnable); this.hud.setVisible(MidnightControlsConfig.hudEnable);
Controller.updateMappings(); Controller.updateMappings();
try {
GLFW.glfwSetJoystickCallback((jid, event) -> { GLFW.glfwSetJoystickCallback((jid, event) -> {
if (event == GLFW.GLFW_CONNECTED) { if (event == GLFW.GLFW_CONNECTED) {
var controller = Controller.byId(jid); var controller = Controller.byId(jid);
@@ -141,9 +168,43 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
this.switchControlsMode(); this.switchControlsMode();
}); });
} catch (Exception e) {e.printStackTrace();}
MidnightControlsCompat.init(this); MidnightControlsCompat.init(this);
} }
ButtonCategory category;
/**
* This method is called to initialize keybindings
*/
public void initKeybindings() {
if (lateInitDone) return;
if (KeyBindingIDAccessor.getKEYS_BY_ID() == null || KeyBindingIDAccessor.getKEYS_BY_ID().isEmpty()) return;
if (PlatformFunctions.isModLoaded("voxelmap") && !KeyBindingIDAccessor.getKEYS_BY_ID().containsKey("key.minimap.toggleingamewaypoints")) return;
if (PlatformFunctions.isModLoaded("wynntils") && KeyBindingIDAccessor.getKEYS_BY_ID().entrySet().stream().noneMatch(b -> Objects.equals(b.getValue().getCategory(), "Wynntils"))) return;
for (int i = 0; i < KeyBindingIDAccessor.getKEYS_BY_ID().size(); ++i) {
KeyBinding keyBinding = KeyBindingIDAccessor.getKEYS_BY_ID().entrySet().stream().toList().get(i).getValue();
if (MidnightControlsConfig.excludedKeybindings.stream().noneMatch(excluded -> keyBinding.getTranslationKey().startsWith(excluded))) {
if (!keyBinding.getTranslationKey().contains("midnightcontrols") && !keyBinding.getTranslationKey().contains("ok_zoomer") && !keyBinding.getTranslationKey().contains("okzoomer")) {
category = null;
InputManager.streamCategories().forEach(buttonCategory -> {
if (buttonCategory.getIdentifier().equals(new org.aperlambda.lambdacommon.Identifier("minecraft", keyBinding.getCategory())))
category = buttonCategory;
});
if (category == null) {
category = new ButtonCategory(new org.aperlambda.lambdacommon.Identifier("minecraft", keyBinding.getCategory()));
InputManager.registerCategory(category);
}
ButtonBinding buttonBinding = new ButtonBinding.Builder(keyBinding.getTranslationKey()).category(category).linkKeybind(keyBinding).register();
if (MidnightControlsConfig.debug) {
logger.info(keyBinding.getTranslationKey());
logger.info(buttonBinding);
}
}
}
}
InputManager.loadButtonBindings();
lateInitDone = true;
}
/** /**
* This method is called every Minecraft tick. * This method is called every Minecraft tick.
@@ -151,17 +212,23 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
* @param client the client instance * @param client the client instance
*/ */
public void onTick(@NotNull MinecraftClient client) { public void onTick(@NotNull MinecraftClient client) {
this.initKeybindings();
this.input.tick(client); this.input.tick(client);
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput)) if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput))
this.input.tickController(client); this.input.tickController(client);
/*if (BINDING_RING.wasPressed()) { if (BINDING_RING.wasPressed()) {
client.openScreen(new RingScreen()); ring.loadFromUnbound();
}*/ client.setScreen(new RingScreen());
} }
if (client.world != null && MidnightControlsConfig.enableHints && !MidnightControlsConfig.autoSwitchMode && MidnightControlsConfig.controlsMode == ControlsMode.DEFAULT && MidnightControlsConfig.getController().isGamepad()) {
public void onRender(MinecraftClient client) { client.getToastManager().add(SystemToast.create(client, SystemToast.Type.PERIODIC_NOTIFICATION, Text.translatable("midnightcontrols.controller.tutorial.title"),
this.input.onRender(client.getTickDelta(), client); Text.translatable("midnightcontrols.controller.tutorial.description", Text.translatable("options.title"), Text.translatable("controls.title"),
Text.translatable("midnightcontrols.menu.title.controller"))));
MidnightControlsConfig.enableHints = false;
MidnightControlsConfig.save();
}
RainbowColor.tick();
} }
/** /**

View File

@@ -9,12 +9,20 @@
package eu.midnightdust.midnightcontrols.client; package eu.midnightdust.midnightcontrols.client;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.blaze3d.platform.GlDebugInfo;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.MidnightControlsFeature; import eu.midnightdust.midnightcontrols.MidnightControlsFeature;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.Controller;
import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
import eu.midnightdust.midnightcontrols.client.touch.TouchMode;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@@ -22,48 +30,88 @@ import org.lwjgl.glfw.GLFW;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_X; import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y;
/** /**
* Represents MidnightControls configuration. * Represents MidnightControls configuration.
*/ */
public class MidnightControlsConfig extends MidnightConfig { public class MidnightControlsConfig extends MidnightConfig {
public static boolean isEditing = false;
@Hidden @Entry public static int configVersion = 2;
// General // General
@Entry public static ControlsMode controlsMode = ControlsMode.DEFAULT; @Entry(category = "controller", name = "midnightcontrols.menu.controls_mode") public static ControlsMode controlsMode = ControlsMode.DEFAULT;
@Entry public static boolean autoSwitchMode = true; @Entry(category = "controller", name = "midnightcontrols.menu.auto_switch_mode") public static boolean autoSwitchMode = true;
@Entry public static boolean debug = false; @Entry(category = "misc", name = "Debug") public static boolean debug = false;
// HUD // HUD
@Entry public static boolean hudEnable = true; @Entry(category = "visual", name = "midnightcontrols.menu.hud_enable") public static boolean hudEnable = true;
@Entry public static HudSide hudSide = HudSide.LEFT; @Entry(category = "visual", name = "midnightcontrols.menu.hud_side") public static HudSide hudSide = HudSide.LEFT;
@Entry(category = "screens", name = "midnightcontrols.menu.move_chat") public static boolean moveChat = false;
// Gameplay // Gameplay
@Entry public static boolean analogMovement = true; @Entry(category = "gameplay", name = "midnightcontrols.menu.analog_movement") public static boolean analogMovement = true;
@Entry public static boolean fastBlockPlacing = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers. @Entry(category = "gameplay", name = "midnightcontrols.menu.double_tap_to_sprint") public static boolean doubleTapToSprint = true;
@Entry public static boolean flyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers. It can also conflict with some other mods. @Entry(category = "gameplay", name = "midnightcontrols.menu.controller_toggle_sneak") public static boolean controllerToggleSneak = MinecraftClient.getInstance().options.getSneakToggled().getValue();
@Entry public static boolean verticalFlyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers. @Entry(category = "gameplay", name = "midnightcontrols.menu.controller_toggle_sprint") public static boolean controllerToggleSprint = MinecraftClient.getInstance().options.getSprintToggled().getValue();
@Entry public static boolean horizontalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers. @Entry(category = "gameplay", name = "midnightcontrols.menu.fast_block_placing") public static boolean fastBlockPlacing = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry public static boolean verticalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers. @Entry(category = "gameplay", name = "midnightcontrols.menu.fly_drifting") public static boolean flyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers. It can also conflict with some other mods.
@Entry public static boolean shouldRenderReacharoundOutline = true; @Entry(category = "gameplay", name = "midnightcontrols.menu.fly_drifting_vertical") public static boolean verticalFlyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers.
@Entry public static int[] reacharoundOutlineColor = new int[]{255, 255, 255, 102}; @Entry(category = "gameplay", name = "midnightcontrols.menu.reacharound.horizontal") public static boolean horizontalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
// Controller @Entry(category = "gameplay", name = "midnightcontrols.menu.reacharound.vertical") public static boolean verticalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry public static ControllerType controllerType = ControllerType.DEFAULT; @Entry(category = "visual", name = "Reacharound Outline") public static boolean shouldRenderReacharoundOutline = true;
@Entry public static double rightDeadZone = 0.25; @Entry(category = "visual", name = "Reacharound Outline Color", isColor = true) public static String reacharoundOutlineColorHex = "#ffffff";
@Entry public static double leftDeadZone = 0.25; @Entry(category = "visual", name = "Reacharound Outline Alpha", isSlider = true, min = 0, max = 255) public static int reacharoundOutlineColorAlpha = 102;
@Entry public static boolean invertRightYAxis = false; @Entry(category = "controller", name = "midnightcontrols.menu.right_dead_zone", isSlider = true, min = 0.05, max = 1) public static double rightDeadZone = 0.25;
@Entry public static boolean invertRightXAxis = false; @Entry(category = "controller", name = "midnightcontrols.menu.left_dead_zone", isSlider = true, min = 0.05, max = 1) public static double leftDeadZone = 0.25;
@Entry public static double DEFAULT_MAX_VALUE = 1; @Entry(category = "controller", name = "midnightcontrols.menu.invert_right_y_axis") public static boolean invertRightYAxis = false;
@Entry public static double rotationSpeed = 40.0; @Entry(category = "controller", name = "midnightcontrols.menu.invert_right_x_axis") public static boolean invertRightXAxis = false;
@Entry public static double mouseSpeed = 25.0; @Entry(category = "controller", name = "midnightcontrols.menu.rotation_speed", isSlider = true, min = 0, max = 100, precision = 10) public static double rotationSpeed = 35.0; //used for x-axis, name kept for compatibility
@Entry public static boolean unfocusedInput = false; @Entry(category = "controller", name = "midnightcontrols.menu.y_axis_rotation_speed", isSlider = true, min = 0, max = 100, precision = 10) public static double yAxisRotationSpeed = rotationSpeed;
@Entry public static boolean virtualMouse = false; @Entry(category = "screens", name = "midnightcontrols.menu.mouse_speed", isSlider = true, min = 0, max = 150, precision = 10) public static double mouseSpeed = 25.0;
@Entry public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT; @Entry(category = "screens", name = "midnightcontrols.menu.joystick_as_mouse") public static boolean joystickAsMouse = false;
@Entry public static Object controllerID = 0; @Entry(category = "screens", name = "midnightcontrols.menu.eye_tracker_as_mouse") public static boolean eyeTrackerAsMouse = false;
@Entry public static Object secondControllerID = -1; @Entry(category = "screens", name = "midnightcontrols.menu.eye_tracker_deadzone", isSlider = true, min = 0, max = 0.4) public static double eyeTrackerDeadzone = 0.05;
@Entry public static List<String> mouseScreens = List.of("me.jellysquid.mods.sodium.client.gui","net.coderbot.iris.gui","net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui"); @Entry(category = "controller", name = "midnightcontrols.menu.unfocused_input") public static boolean unfocusedInput = false;
@Entry public static Map<String, String> BINDINGS = Map.of(); @Entry(category = "screens", name = "midnightcontrols.menu.virtual_mouse") public static boolean virtualMouse = false;
@Entry(category = "screens", name = "midnightcontrols.menu.virtual_mouse.skin") public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT;
@Entry(category = "screens", name = "midnightcontrols.menu.hide_cursor") public static boolean hideNormalMouse = false;
@Entry(category = "controller", name = "Controller ID") @Hidden public static Object controllerID = 0;
@Entry(category = "controller", name = "2nd Controller ID") @Hidden public static Object secondControllerID = -1;
@Entry(category = "visual", name = "midnightcontrols.menu.controller_type") public static ControllerType controllerType = ControllerType.DEFAULT;
@Entry(category = "screens", name = "Mouse screens") public static List<String> mouseScreens = Lists.newArrayList("net.minecraft.client.gui.screen.advancement",
"net.minecraft.class_457", "net.minecraft.class_408", "net.minecraft.class_3872", "me.flashyreese.mods.reeses_sodium_options.client.gui", "dev.emi.emi.screen",
"hardcorequesting.client.interfaces.GuiQuestBook", "hardcorequesting.client.interfaces.GuiReward", "hardcorequesting.client.interfaces.EditTrackerScreen",
"me.shedaniel.clothconfig2.gui.ClothConfigScreen", "com.mamiyaotaru.voxelmap.gui.GuiWaypoints", "com.mamiyaotaru.voxelmap.gui.GuiPersistentMap");
@Entry(category = "screens", name = "Arrow screens") public static List<String> arrowScreens = Lists.newArrayList(ChatScreen.class.getCanonicalName());
@Entry(category = "screens", name = "WASD screens") public static List<String> wasdScreens = Lists.newArrayList("com.ultreon.devices.core.Laptop");
@Entry(category = "touch", name = "Screens with close button") public static List<String> closeButtonScreens = Lists.newArrayList(ChatScreen.class.getCanonicalName(), AdvancementsScreen.class.getCanonicalName(), RingScreen.class.getCanonicalName());
@Entry(category = "touch", name = "midnightcontrols.menu.touch_speed", isSlider = true, min = 0, max = 150, precision = 10) public static double touchSpeed = 50.0;
@Entry(category = "touch", name = "midnightcontrols.menu.invert_touch") public static boolean invertTouch = false;
@Entry(category = "touch", name = "midnightcontrols.menu.touch_mode") public static TouchMode touchMode = TouchMode.CROSSHAIR;
@Entry(category = "touch", name = "midnightcontrols.menu.touch_break_delay", isSlider = true, min = 50, max = 500) public static int touchBreakDelay = 120;
@Entry(category = "touch", name = "midnightcontrols.menu.touch_transparency", isSlider = true, min = 0, max = 100) public static int touchTransparency = 75;
@Entry(category = "touch", name = "Touch Outline Color", isColor = true) public static String touchOutlineColorHex = "#ffffff";
@Entry(category = "touch", name = "Touch Outline Alpha", isSlider = true, min = 0, max = 255) public static int touchOutlineColorAlpha = 150;
@Entry(category = "touch", name = "Left Touch button bindings") public static List<String> leftTouchBinds = Lists.newArrayList("debug_screen", "screenshot","toggle_perspective");
@Entry(category = "touch", name = "Right Touch button bindings") public static List<String> rightTouchBinds = Lists.newArrayList("screenshot","toggle_perspective", "use");
@Entry @Hidden public static Map<String, String> BINDING = new HashMap<>();
private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?"); private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?");
@Entry public static double[] maxAnalogValues = new double[]{DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE}; @Deprecated @Hidden @Entry public static double[] maxAnalogValues = new double[]{1, 1, 1, 1};
@Entry(category = "controller", name = "Max analog value: Left X", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueLeftX = maxAnalogValues[0];
@Entry(category = "controller", name = "Max analog value: Left Y", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueLeftY = maxAnalogValues[1];
@Entry(category = "controller", name = "Max analog value: Right X", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueRightX = maxAnalogValues[2];
@Entry(category = "controller", name = "Max analog value: Right Y", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueRightY = maxAnalogValues[3];
@Entry(category = "controller", name = "Trigger button fix") public static boolean triggerFix = false;
@Entry(category = "controller", name = "Excluded Keybindings") public static List<String> excludedKeybindings = Lists.newArrayList("key.forward", "key.left", "key.back", "key.right", "key.jump", "key.sneak", "key.sprint", "key.inventory",
"key.swapOffhand", "key.drop", "key.use", "key.attack", "key.chat", "key.playerlist", "key.screenshot", "key.togglePerspective", "key.smoothCamera", "key.fullscreen", "key.saveToolbarActivator", "key.loadToolbarActivator",
"key.pickItem", "key.hotbar.1", "key.hotbar.2", "key.hotbar.3", "key.hotbar.4", "key.hotbar.5", "key.hotbar.6", "key.hotbar.7", "key.hotbar.8", "key.hotbar.9");
@Entry(category = "gameplay", name = "Enable Hints") public static boolean enableHints = true;
@Entry(category = "screens", name = "Enable Shortcut in Controls Options") public static boolean shortcutInControls = true;
@Entry(category = "misc", name = "Ring Bindings (WIP)") public static List<String> ringBindings = new ArrayList<>();
@Entry(category = "misc", name = "Ignored Unbound Keys") public static List<String> ignoredUnboundKeys = Lists.newArrayList("inventorytabs.key.next_tab");
@Entry @Hidden public static Map<String, Map<String, String>> controllerBindingProfiles = new HashMap<>();
private static Map<String, String> currentBindingProfile = new HashMap<>();
private static Controller prevController;
/** /**
* Loads the configuration * Loads the configuration
@@ -73,7 +121,6 @@ public class MidnightControlsConfig extends MidnightConfig {
MidnightControlsClient.get().log("Configuration loaded."); MidnightControlsClient.get().log("Configuration loaded.");
// Controller controls. // Controller controls.
InputManager.loadButtonBindings(); InputManager.loadButtonBindings();
//this.mod.ring.load(this.config);
} }
/** /**
@@ -84,6 +131,15 @@ public class MidnightControlsConfig extends MidnightConfig {
MidnightControlsClient.get().log("Configuration saved."); MidnightControlsClient.get().log("Configuration saved.");
MidnightControlsFeature.refreshEnabled(); MidnightControlsFeature.refreshEnabled();
} }
public static void updateBindingsForController(Controller controller) {
if (controller.isConnected() && controller.isGamepad() && controllerBindingProfiles.containsKey(controller.getGuid()))
currentBindingProfile = controllerBindingProfiles.get(controller.getGuid());
else currentBindingProfile = Maps.newHashMap(BINDING);
InputManager.loadButtonBindings();
}
public static Map<String, String> getBindingsForController() {
return currentBindingProfile;
}
/** /**
* Gets the used controller. * Gets the used controller.
* *
@@ -91,12 +147,25 @@ public class MidnightControlsConfig extends MidnightConfig {
*/ */
public static Controller getController() { public static Controller getController() {
var raw = MidnightControlsConfig.controllerID; var raw = MidnightControlsConfig.controllerID;
Controller controller = Controller.byId(GLFW.GLFW_JOYSTICK_1);
if (raw instanceof Number) { if (raw instanceof Number) {
return Controller.byId(((Number) raw).intValue()); controller = Controller.byId(((Number) raw).intValue());
} else if (raw instanceof String) { } else if (raw instanceof String) {
return Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1)); controller = Controller.byGuid((String) raw).orElse(Controller.byId(GLFW.GLFW_JOYSTICK_1));
} }
return Controller.byId(GLFW.GLFW_JOYSTICK_1); if ((!controller.isConnected() || !controller.isGamepad()) && MidnightControlsConfig.autoSwitchMode && !isEditing) {
for (int i = 0; i < GLFW.GLFW_JOYSTICK_LAST; ++i) {
Controller gamepad = Controller.byId(i);
if (gamepad.isConnected() && gamepad.isGamepad()) {
controller = gamepad;
i = GLFW_JOYSTICK_LAST;
}
}
}
if (controller.isConnected() && controller.isGamepad() && MidnightControlsConfig.autoSwitchMode && !isEditing) MidnightControlsConfig.controlsMode = ControlsMode.CONTROLLER;
if (prevController != controller) updateBindingsForController(controller);
prevController = controller;
return controller;
} }
/** /**
@@ -153,14 +222,21 @@ public class MidnightControlsConfig extends MidnightConfig {
} }
public static double getAxisMaxValue(int axis) { public static double getAxisMaxValue(int axis) {
if (axis >= MidnightControlsConfig.maxAnalogValues.length) return switch (axis) {
return DEFAULT_MAX_VALUE; case GLFW_GAMEPAD_AXIS_LEFT_X -> MidnightControlsConfig.maxAnalogValueLeftX;
return MidnightControlsConfig.maxAnalogValues[axis]; case GLFW_GAMEPAD_AXIS_LEFT_Y -> MidnightControlsConfig.maxAnalogValueLeftY;
case GLFW_GAMEPAD_AXIS_RIGHT_X -> MidnightControlsConfig.maxAnalogValueRightX;
default -> MidnightControlsConfig.maxAnalogValueRightY;
};
} }
public static void setAxisMaxValue(int axis, double value) { public static void setAxisMaxValue(int axis, double value) {
if (axis < MidnightControlsConfig.maxAnalogValues.length) switch (axis) {
MidnightControlsConfig.maxAnalogValues[axis] = value; case GLFW_GAMEPAD_AXIS_LEFT_X -> MidnightControlsConfig.maxAnalogValueLeftX = value;
case GLFW_GAMEPAD_AXIS_LEFT_Y -> MidnightControlsConfig.maxAnalogValueLeftY = value;
case GLFW_GAMEPAD_AXIS_RIGHT_X -> MidnightControlsConfig.maxAnalogValueRightX = value;
default -> MidnightControlsConfig.maxAnalogValueRightY = value;
};
} }
/** /**
@@ -170,7 +246,7 @@ public class MidnightControlsConfig extends MidnightConfig {
*/ */
public static void loadButtonBinding(@NotNull ButtonBinding button) { public static void loadButtonBinding(@NotNull ButtonBinding button) {
button.setButton(button.getDefaultButton()); button.setButton(button.getDefaultButton());
var code = MidnightControlsConfig.BINDINGS.getOrDefault("controller.controls." + button.getName(), button.getButtonCode()); var code = getBindingsForController().getOrDefault("controller.controls." + button.getName(), button.getButtonCode());
var matcher = BUTTON_BINDING_PATTERN.matcher(code); var matcher = BUTTON_BINDING_PATTERN.matcher(code);
@@ -194,14 +270,14 @@ public class MidnightControlsConfig extends MidnightConfig {
button.setButton(buttons); button.setButton(buttons);
} catch (Exception e) { } catch (Exception e) {
MidnightControlsClient.get().warn("Malformed config value \"" + code + "\" for binding \"" + button.getName() + "\"."); MidnightControlsClient.get().warn("Malformed config value \"" + code + "\" for binding \"" + button.getName() + "\".");
MidnightControlsConfig.BINDINGS.put("controller.controls." + button.getName(), button.getButtonCode()); setButtonBinding(button, button.getButton());
} }
} }
private static boolean checkValidity(@NotNull ButtonBinding binding, @NotNull String input, String group) { private static boolean checkValidity(@NotNull ButtonBinding binding, @NotNull String input, String group) {
if (group == null) { if (group == null) {
MidnightControlsClient.get().warn("Malformed config value \"" + input + "\" for binding \"" + binding.getName() + "\"."); MidnightControlsClient.get().warn("Malformed config value \"" + input + "\" for binding \"" + binding.getName() + "\".");
MidnightControlsConfig.BINDINGS.put("controller.controls." + binding.getName(), binding.getButtonCode()); setButtonBinding(binding, binding.getButton());
return false; return false;
} }
return true; return true;
@@ -215,7 +291,9 @@ public class MidnightControlsConfig extends MidnightConfig {
*/ */
public static void setButtonBinding(@NotNull ButtonBinding binding, int[] button) { public static void setButtonBinding(@NotNull ButtonBinding binding, int[] button) {
binding.setButton(button); binding.setButton(button);
MidnightControlsConfig.BINDINGS.put("controller.controls." + binding.getName(), binding.getButtonCode()); getBindingsForController().put("controller.controls." + binding.getName(), binding.getButtonCode());
if (controllerBindingProfiles.containsKey(getController().getGuid())) controllerBindingProfiles.get(getController().getGuid()).put("controller.controls." + binding.getName(), binding.getButtonCode());
else BINDING.put("controller.controls." + binding.getName(), binding.getButtonCode());
} }
public static boolean isBackButton(int btn, boolean isBtn, int state) { public static boolean isBackButton(int btn, boolean isBtn, int state) {
@@ -251,4 +329,67 @@ public class MidnightControlsConfig extends MidnightConfig {
public static boolean isMovementAxis(int axis) { public static boolean isMovementAxis(int axis) {
return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X; return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X;
} }
public static void reset() {
controlsMode = ControlsMode.DEFAULT;
autoSwitchMode = true;
debug = false;
hudEnable = true;
hudSide = HudSide.LEFT;
analogMovement = true;
doubleTapToSprint = true;
controllerToggleSneak = MinecraftClient.getInstance().options.getSneakToggled().getValue();
controllerToggleSprint = MinecraftClient.getInstance().options.getSprintToggled().getValue();
fastBlockPlacing = false;
flyDrifting = true;
verticalFlyDrifting = true;
horizontalReacharound = false;
verticalReacharound = false;
shouldRenderReacharoundOutline = true;
reacharoundOutlineColorHex = "#ffffff";
reacharoundOutlineColorAlpha = 102;
rightDeadZone = 0.25;
leftDeadZone = 0.25;
invertRightYAxis = false;
invertRightXAxis = false;
rotationSpeed = 40.0;
yAxisRotationSpeed = rotationSpeed;
mouseSpeed = 25.0;
unfocusedInput = false;
virtualMouse = false;
virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT;
controllerID = 0;
secondControllerID = -1;
controllerType = ControllerType.DEFAULT;
mouseScreens = Lists.newArrayList("net.minecraft.client.gui.screen.advancement", "net.minecraft.class_457", "net.minecraft.class_408", "net.minecraft.class_3872", "me.flashyreese.mods.reeses_sodium_options.client.gui", "dev.emi.emi.screen", "me.shedaniel.clothconfig2.gui.ClothConfigScreen", "com.mamiyaotaru.voxelmap.gui.GuiWaypoints", "com.mamiyaotaru.voxelmap.gui.GuiPersistentMap");
BINDING = new HashMap<>();
maxAnalogValueLeftX = 1;
maxAnalogValueLeftY = 1;
maxAnalogValueRightX = 1;
maxAnalogValueRightY = 1;
triggerFix = true;
enableHints = true;
shortcutInControls = true;
ringBindings = new ArrayList<>();
ignoredUnboundKeys = Lists.newArrayList("inventorytabs.key.next_tab");
controllerBindingProfiles = new HashMap<>();
}
/**
* Gets the controller type from the controller's identifier.
*
* @return the controller name matches a type, else empty
*/
public static @NotNull ControllerType matchControllerToType() {
String controller = getController().getName().toLowerCase();
if (controller.contains("xbox 360")) return ControllerType.XBOX_360;
else if (controller.contains("xbox") || controller.contains("afterglow")) return ControllerType.XBOX;
else if (controller.contains("steam") && GlDebugInfo.getCpuInfo().contains("AMD Custom APU")) return ControllerType.STEAM_DECK;
else if (controller.contains("steam")) return ControllerType.STEAM_CONTROLLER;
else if (controller.contains("dualsense") || controller.contains("ps5")) return ControllerType.DUALSENSE;
else if (controller.contains("dualshock") || controller.contains("ps4") || controller.contains("sony")) return ControllerType.DUALSHOCK;
else if (controller.contains("switch") || controller.contains("joy-con") || controller.contains("wii") || controller.contains("nintendo")) return ControllerType.SWITCH;
else if (controller.contains("ouya")) return ControllerType.OUYA;
else return ControllerType.DEFAULT;
}
} }

View File

@@ -10,16 +10,20 @@
package eu.midnightdust.midnightcontrols.client; package eu.midnightdust.midnightcontrols.client;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.compat.*;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.Controller;
import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget; import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget;
import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor; import eu.midnightdust.midnightcontrols.client.mixin.*;
import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor; import eu.midnightdust.midnightcontrols.client.ring.RingPage;
import eu.midnightdust.midnightcontrols.client.mixin.EntryListWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
import eu.midnightdust.midnightcontrols.client.util.MouseAccessor; import eu.midnightdust.midnightcontrols.client.util.MouseAccessor;
import dev.lambdaurora.spruceui.navigation.NavigationDirection; import dev.lambdaurora.spruceui.navigation.NavigationDirection;
import dev.lambdaurora.spruceui.screen.SpruceScreen; import dev.lambdaurora.spruceui.screen.SpruceScreen;
@@ -27,26 +31,23 @@ import dev.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget;
import dev.lambdaurora.spruceui.widget.SpruceElement; import dev.lambdaurora.spruceui.widget.SpruceElement;
import dev.lambdaurora.spruceui.widget.SpruceLabelWidget; import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget; import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import net.fabricmc.fabric.impl.item.group.CreativeGuiExtensions; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement; import net.minecraft.client.gui.ParentElement;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.gui.screen.advancement.AdvancementTab; import net.minecraft.client.gui.screen.advancement.AdvancementTab;
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.MerchantScreen;
import net.minecraft.client.gui.screen.ingame.StonecutterScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget; import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.gui.screen.world.WorldListWidget; import net.minecraft.client.gui.screen.world.WorldListWidget;
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; import net.minecraft.client.gui.widget.*;
import net.minecraft.client.gui.widget.EntryListWidget;
import net.minecraft.client.gui.widget.PressableWidget;
import net.minecraft.client.gui.widget.SliderWidget;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType; import net.minecraft.text.TranslatableTextContent;
import net.minecraft.text.Text;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.aperlambda.lambdacommon.utils.Pair; import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -69,7 +70,9 @@ public class MidnightInput {
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>(); private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
// Cooldowns // Cooldowns
public int actionGuiCooldown = 0; public int actionGuiCooldown = 0;
public int joystickCooldown = 0;
public boolean ignoreNextARelease = false; public boolean ignoreNextARelease = false;
public boolean ignoreNextXRelease = false;
private double targetYaw = 0.0; private double targetYaw = 0.0;
private double targetPitch = 0.0; private double targetPitch = 0.0;
private float prevXAxis = 0.f; private float prevXAxis = 0.f;
@@ -79,6 +82,7 @@ public class MidnightInput {
private float mouseSpeedX = 0.f; private float mouseSpeedX = 0.f;
private float mouseSpeedY = 0.f; private float mouseSpeedY = 0.f;
public int inventoryInteractionCooldown = 0; public int inventoryInteractionCooldown = 0;
public int screenCloseCooldown = 0;
private ControllerControlsWidget controlsInput = null; private ControllerControlsWidget controlsInput = null;
@@ -119,10 +123,15 @@ public class MidnightInput {
// Decreases the cooldown for GUI actions. // Decreases the cooldown for GUI actions.
if (this.actionGuiCooldown > 0) if (this.actionGuiCooldown > 0)
--this.actionGuiCooldown; --this.actionGuiCooldown;
if (this.screenCloseCooldown > 0)
--this.screenCloseCooldown;
if (this.joystickCooldown > 0)
--this.joystickCooldown;
InputManager.updateStates(); InputManager.updateStates();
var controller = MidnightControlsConfig.getController(); var controller = MidnightControlsConfig.getController();
if (controller.isConnected()) { if (controller.isConnected()) {
var state = controller.getState(); var state = controller.getState();
this.fetchButtonInput(client, state, false); this.fetchButtonInput(client, state, false);
@@ -135,10 +144,7 @@ public class MidnightInput {
this.fetchAxeInput(client, state, true); this.fetchAxeInput(client, state, true);
}); });
boolean allowInput = true; boolean allowInput = this.controlsInput == null || this.controlsInput.focusedBinding == null;
if (this.controlsInput != null && this.controlsInput.focusedBinding != null)
allowInput = false;
if (allowInput) if (allowInput)
InputManager.updateBindings(client); InputManager.updateBindings(client);
@@ -171,11 +177,11 @@ public class MidnightInput {
} }
/** /**
* This method is called when Minecraft renders. * This method is called to update the camera
* *
* @param client the client instance * @param client the client instance
*/ */
public void onRender(float tickDelta, @NotNull MinecraftClient client) { public void updateCamera(@NotNull MinecraftClient client) {
if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay)) if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay))
return; return;
@@ -184,14 +190,17 @@ public class MidnightInput {
return; return;
if (this.targetYaw != 0.f || this.targetPitch != 0.f) { if (this.targetYaw != 0.f || this.targetPitch != 0.f) {
float rotationYaw = (float) (player.prevYaw + (this.targetYaw / 0.10) * tickDelta); float rotationYaw = (float) (client.player.prevYaw + (this.targetYaw * 0.175));
float rotationPitch = (float) (player.prevPitch + (this.targetPitch / 0.10) * tickDelta); float rotationPitch = (float) (client.player.prevPitch + (this.targetPitch * 0.175));
client.player.prevYaw = rotationYaw;
client.player.prevPitch = MathHelper.clamp(rotationPitch, -90.f, 90.f);
client.player.setYaw(rotationYaw); client.player.setYaw(rotationYaw);
client.player.setPitch(MathHelper.clamp(rotationPitch, -90.f, 90.f)); client.player.setPitch(MathHelper.clamp(rotationPitch, -90.f, 90.f));
if (client.player.isRiding()) { if (client.player.isRiding() && client.player.getVehicle() != null) {
client.player.getVehicle().onPassengerLookAround(client.player); client.player.getVehicle().onPassengerLookAround(client.player);
} }
client.getTutorialManager().onUpdateMouse(this.targetPitch, this.targetYaw); client.getTutorialManager().onUpdateMouse(this.targetPitch, this.targetYaw);
MidnightControlsCompat.HANDLERS.forEach(handler -> handler.handleCamera(client, targetYaw, targetPitch));
} }
} }
@@ -245,23 +254,69 @@ public class MidnightInput {
InputManager.STATES.put(btn, state); InputManager.STATES.put(btn, state);
} }
} }
MathUtil.PolarUtil polarLeft = new MathUtil.PolarUtil();
MathUtil.PolarUtil polarRight = new MathUtil.PolarUtil();
private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) { private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
var buffer = gamepadState.axes(); var buffer = gamepadState.axes();
polarLeft.calculate(buffer.get(GLFW_GAMEPAD_AXIS_LEFT_X), buffer.get(GLFW_GAMEPAD_AXIS_LEFT_Y), 1, MidnightControlsConfig.leftDeadZone);
float leftX = polarLeft.polarX;
float leftY = polarLeft.polarY;
polarRight.calculate(buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_X), buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_Y), 1, MidnightControlsConfig.rightDeadZone);
float rightX = polarRight.polarX;
float rightY = polarRight.polarY;
for (int i = 0; i < buffer.limit(); i++) { for (int i = 0; i < buffer.limit(); i++) {
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i; int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
float value = buffer.get(); float value = buffer.get();
if (MidnightControlsConfig.analogMovement) {
switch (i) {
case GLFW_GAMEPAD_AXIS_LEFT_X -> value = leftX;
case GLFW_GAMEPAD_AXIS_LEFT_Y -> value = leftY;
}
}
switch (i) {
case GLFW_GAMEPAD_AXIS_RIGHT_X -> value = rightX;
case GLFW_GAMEPAD_AXIS_RIGHT_Y -> value = rightY;
}
float absValue = Math.abs(value); float absValue = Math.abs(value);
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y) if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
value *= -1.0F; value *= -1.0F;
int state = value > MidnightControlsConfig.rightDeadZone ? 1 : (value < -MidnightControlsConfig.rightDeadZone ? 2 : 0); int state = value > MidnightControlsConfig.rightDeadZone ? 1 : (value < -MidnightControlsConfig.rightDeadZone ? 2 : 0);
this.handleAxe(client, axis, value, absValue, state); if (!(client.currentScreen instanceof RingScreen || (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)))) this.handleAxe(client, axis, value, absValue, state);
}
if (client.currentScreen instanceof RingScreen || (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen))) {
float x = leftX;
float y = leftY;
if (x == 0 && y == 0) {
x = rightX;
y = rightY;
}
int index = -1;
float border = 0.3f;
if (x < -border) {
index = 3;
if (y < -border) index = 0;
else if (y > border) index = 5;
} else if (x > border) {
index = 4;
if (y < -border) index = 2;
else if (y > border) index = 7;
} else {
if (y < -border) index = 1;
else if (y > border) index = 6;
}
if (client.currentScreen instanceof RingScreen && index > -1) RingPage.selected = index;
if (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)) EmotecraftCompat.handleEmoteSelector(index);
} }
} }
private void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state) { public void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state) {
if (this.controlsInput != null && this.controlsInput.focusedBinding != null) { if (this.controlsInput != null && this.controlsInput.focusedBinding != null) {
if (action == 0 && !this.controlsInput.currentButtons.contains(button)) { if (action == 0 && !this.controlsInput.currentButtons.contains(button)) {
this.controlsInput.currentButtons.add(button); this.controlsInput.currentButtons.add(button);
@@ -276,16 +331,30 @@ public class MidnightInput {
return; return;
} }
if (action == 0 || action == 2) { if (client.currentScreen != null && (action == 0 || action == 2) && button == GLFW_GAMEPAD_BUTTON_Y &&
if (client.currentScreen != null && isScreenInteractive(client.currentScreen) MidnightControlsConfig.arrowScreens.contains(client.currentScreen.getClass().getCanonicalName())) {
pressKeyboardKey(client, GLFW.GLFW_KEY_ENTER);
this.screenCloseCooldown = 5;
}
else if (action == 0 || action == 2) {
if (client.currentScreen != null
&& (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN && (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN
|| button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)) { || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)) {
if (this.actionGuiCooldown == 0) { if (this.actionGuiCooldown == 0) {
if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP) { switch (button) {
this.changeFocus(client.currentScreen, NavigationDirection.UP); case GLFW_GAMEPAD_BUTTON_DPAD_UP -> this.changeFocus(client.currentScreen, NavigationDirection.UP);
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) { case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
this.changeFocus(client.currentScreen, NavigationDirection.DOWN); case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> this.handleLeftRight(client.currentScreen, false);
} else this.handleLeftRight(client.currentScreen, button != GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT); case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> this.handleLeftRight(client.currentScreen, true);
}
if (MidnightControlsConfig.wasdScreens.contains(client.currentScreen.getClass().getCanonicalName())) {
switch (button) {
case GLFW_GAMEPAD_BUTTON_DPAD_UP -> pressKeyboardKey(client, GLFW.GLFW_KEY_W);
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> pressKeyboardKey(client, GLFW.GLFW_KEY_S);
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> pressKeyboardKey(client, GLFW.GLFW_KEY_A);
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> pressKeyboardKey(client, GLFW.GLFW_KEY_D);
}
}
} }
return; return;
} }
@@ -301,105 +370,73 @@ public class MidnightInput {
return; return;
} }
} }
} else if (FabricLoader.getInstance().isModLoaded("libgui")) LibGuiCompat.handlePress(client.currentScreen);
}
if (this.handleInventory(client, button)) {
this.ignoreNextARelease = true;
return;
}
if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
if (client.currentScreen != null && client.currentScreen.getClass() != TitleScreen.class) {
if (!MidnightControlsCompat.handleMenuBack(client, client.currentScreen))
if (!this.tryGoBack(client.currentScreen))
client.currentScreen.close();
return;
} }
} }
} }
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen) if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen)
&& this.actionGuiCooldown == 0) { && this.actionGuiCooldown == 0) {
if (client.currentScreen instanceof CreativeInventoryScreen creativeScreen && ((HandledScreenAccessor) creativeScreen).midnightcontrols$getSlotAt( if (client.currentScreen instanceof HandledScreen<?> handledScreen && ((HandledScreenAccessor) handledScreen).midnightcontrols$getSlotAt(
client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(), client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(),
client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()) != null) return; client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()) != null) return;
if (!this.ignoreNextARelease) { if (!this.ignoreNextARelease) {
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
if (action == 0) { if (action == 0) {
Screen.wrapScreenError(() -> client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1), Screen.wrapScreenError(() -> {
((MouseAccessor) client.mouse).setLeftButtonClicked(false);
client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1);
},
"mouseClicked event handler", client.currentScreen.getClass().getCanonicalName()); "mouseClicked event handler", client.currentScreen.getClass().getCanonicalName());
} else if (action == 1) { } else if (action == 1) {
Screen.wrapScreenError(() -> client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1), Screen.wrapScreenError(() -> {
((MouseAccessor) client.mouse).setLeftButtonClicked(false);
client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1);
},
"mouseReleased event handler", client.currentScreen.getClass().getCanonicalName()); "mouseReleased event handler", client.currentScreen.getClass().getCanonicalName());
} else if (action == 2) {
Screen.wrapScreenError(() -> {
client.currentScreen.setDragging(true);
((MouseAccessor) client.mouse).setLeftButtonClicked(true);
((MouseAccessor) client.mouse).midnightcontrols$onCursorPos(client.getWindow().getHandle(), client.mouse.getX(), client.mouse.getY());
client.currentScreen.setDragging(false);
},
"mouseClicked event handler", client.currentScreen.getClass().getCanonicalName());
} }
this.actionGuiCooldown = 5; this.screenCloseCooldown = 5;
} else { } else {
this.ignoreNextARelease = false; this.ignoreNextARelease = false;
} }
} }
else if (button == GLFW.GLFW_GAMEPAD_BUTTON_X && client.currentScreen != null && !isScreenInteractive(client.currentScreen)
&& this.actionGuiCooldown == 0) {
if (client.currentScreen instanceof HandledScreen<?> handledScreen && ((HandledScreenAccessor) handledScreen).midnightcontrols$getSlotAt(
client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(),
client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()) != null) return;
if (!this.ignoreNextXRelease) {
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
if (action == 0) {
Screen.wrapScreenError(() -> client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_2),
"mouseClicked event handler", client.currentScreen.getClass().getCanonicalName());
} else if (action == 1) {
Screen.wrapScreenError(() -> client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_2),
"mouseReleased event handler", client.currentScreen.getClass().getCanonicalName());
}
this.screenCloseCooldown = 5;
} else {
this.ignoreNextXRelease = false;
}
}
}
public void pressKeyboardKey(MinecraftClient client, int key) {
client.keyboard.onKey(client.getWindow().getHandle(), key, 0, 1, 0);
}
public void pressKeyboardKey(Screen screen, int key) {
screen.keyPressed(key, 0, 1);
} }
/** /**
* Handles inventory interaction.
*
* @param client the client instance
* @param button the button pressed
* @return {@code true} if an inventory interaction was done
*/
private boolean handleInventory(@NotNull MinecraftClient client, int button) {
// if (!(client.currentScreen instanceof HandledScreen screen))
// return false;
//
// if (client.interactionManager == null || client.player == null)
// return false;
//
// if (this.inventoryInteractionCooldown > 0)
// return true;
//
// if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
// client.player.closeHandledScreen();
// return true;
// }
//
// double x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
// double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
//
// var accessor = (HandledScreenAccessor) screen;
// Slot slot = ((HandledScreenAccessor) client.currentScreen).midnightcontrols$getSlotAt(x, y);
//
// int slotId;
// if (slot == null) {
// if (client.player.currentScreenHandler.getCursorStack().isEmpty())
// return false;
// slotId = accessor.midnightcontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1;
// } else {
// slotId = slot.id;
// }
//
// var actionType = SlotActionType.PICKUP;
// int clickData = GLFW.GLFW_MOUSE_BUTTON_1;
// switch (button) {
// case GLFW_GAMEPAD_BUTTON_A:
// if (screen instanceof CreativeInventoryScreen)
// if (((CreativeInventoryScreenAccessor) screen).midnightcontrols$isCreativeInventorySlot(slot))
// actionType = SlotActionType.CLONE;
// if (slot != null && MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot)))
// actionType = SlotActionType.CLONE;
// break;
// case GLFW.GLFW_GAMEPAD_BUTTON_X:
// clickData = GLFW_MOUSE_BUTTON_2;
// break;
// case GLFW.GLFW_GAMEPAD_BUTTON_Y:
// actionType = SlotActionType.QUICK_MOVE;
// break;
// default:
// return false;
// }
//
// accessor.midnightcontrols$onMouseClick(slot, slotId, clickData, actionType);
return false;
}
/** /**
* Tries to go back. * Tries to go back.
@@ -409,14 +446,17 @@ public class MidnightInput {
*/ */
public boolean tryGoBack(@NotNull Screen screen) { public boolean tryGoBack(@NotNull Screen screen) {
var set = ImmutableSet.of("gui.back", "gui.done", "gui.cancel", "gui.toTitle", "gui.toMenu"); var set = ImmutableSet.of("gui.back", "gui.done", "gui.cancel", "gui.toTitle", "gui.toMenu");
return screen.children().stream().filter(element -> element instanceof PressableWidget) return screen.children().stream().filter(element -> element instanceof PressableWidget)
.map(element -> (PressableWidget) element) .map(element -> (PressableWidget) element)
.filter(element -> element.getMessage() != null && element.getMessage().getContent() != null) .filter(element -> element.getMessage() != null && element.getMessage().getContent() != null)
.anyMatch(element -> { .anyMatch(element -> {
if (set.stream().anyMatch(key -> element.getMessage().getContent().toString().equals(key))) { if (element.getMessage().getContent() instanceof TranslatableTextContent translatableText) {
if (set.stream().anyMatch(key -> translatableText.getKey().equals(key))) {
element.onPress(); element.onPress();
return true; return true;
} }
}
return false; return false;
}); });
} }
@@ -431,13 +471,29 @@ public class MidnightInput {
if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) || axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER)
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) || axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
if (asButtonState == 2) if (asButtonState == 2) {
asButtonState = 0; asButtonState = 0;
}
else {
// Fixes Triggers not working correctly on some controllers
if (MidnightControlsConfig.triggerFix) {
value = 1.0f;
absValue = 1.0f;
state = 1;
asButtonState = 1;
}
if (MidnightControlsConfig.debug) System.out.println(axis + " "+ value + " " + absValue + " " + state);
}
}
{ {
boolean currentPlusState = asButtonState == 1; boolean currentPlusState = value > getDeadZoneValue(axis);
boolean currentMinusState = asButtonState == 2; boolean currentMinusState = value < -getDeadZoneValue(axis);
if (!MidnightControlsConfig.analogMovement && (axis == GLFW_GAMEPAD_AXIS_LEFT_X || axis == GLFW_GAMEPAD_AXIS_LEFT_Y)) {
currentPlusState = asButtonState == 1;
currentMinusState = asButtonState == 2;
}
var previousPlusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, true), ButtonState.NONE); var previousPlusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, true), ButtonState.NONE);
var previousMinusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, false), ButtonState.NONE); var previousMinusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, false), ButtonState.NONE);
@@ -463,9 +519,13 @@ public class MidnightInput {
} }
} }
float axisValue = absValue;
if (!MidnightControlsConfig.analogMovement) {
double deadZone = this.getDeadZoneValue(axis); double deadZone = this.getDeadZoneValue(axis);
float axisValue = absValue < deadZone ? 0.f : (float) (absValue - deadZone); axisValue = (float) (absValue - deadZone);
axisValue /= (1.0 - deadZone); axisValue /= (1.0 - deadZone);
axisValue *= deadZone;
}
axisValue = (float) Math.min(axisValue / MidnightControlsConfig.getAxisMaxValue(axis), 1); axisValue = (float) Math.min(axisValue / MidnightControlsConfig.getAxisMaxValue(axis), 1);
if (currentPlusState) if (currentPlusState)
@@ -498,7 +558,23 @@ public class MidnightInput {
var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen; var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen;
// @TODO allow rebinding to left stick // @TODO allow rebinding to left stick
if (accessor.midnightcontrols$hasScrollbar() && absValue >= deadZone) { if (accessor.midnightcontrols$hasScrollbar() && absValue >= deadZone) {
creativeInventoryScreen.mouseScrolled(0.0, 0.0, -value); creativeInventoryScreen.mouseScrolled(0.0, 0.0, 0, -value);
}
return;
}
} else if (client.currentScreen instanceof MerchantScreen merchantScreen) {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
// @TODO allow rebinding to left stick
if (absValue >= deadZone) {
merchantScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f));
}
return;
}
} else if (client.currentScreen instanceof StonecutterScreen stonecutterScreen) {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
// @TODO allow rebinding to left stick
if (absValue >= deadZone) {
stonecutterScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f));
} }
return; return;
} }
@@ -512,20 +588,43 @@ public class MidnightInput {
return; return;
} }
} else if (client.currentScreen != null) { } else if (client.currentScreen != null) {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y && absValue >= deadZone) { float finalValue = value;
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y && absValue >= deadZone && client.currentScreen.children().stream().filter(element -> element instanceof SpruceEntryListWidget)
.map(element -> (SpruceEntryListWidget<?>) element)
.filter(AbstractSpruceWidget::isFocusedOrHovered)
.noneMatch(element -> {
element.mouseScrolled(0.0, 0.0, 0, -finalValue);
return true;
})
&&
client.currentScreen.children().stream().filter(element -> element instanceof EntryListWidget) client.currentScreen.children().stream().filter(element -> element instanceof EntryListWidget)
.map(element -> (EntryListWidget<?>) element) .map(element -> (EntryListWidget<?>) element)
.filter(element -> element.getType().isFocused()) .filter(element -> element.getType().isFocused())
.anyMatch(element -> { .noneMatch(element -> {
element.mouseScrolled(0.0, 0.0, -value); element.mouseScrolled(0.0, 0.0, 0, -finalValue);
return true; return true;
}); }))
{
client.currentScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f));
}
else if (isScreenInteractive(client.currentScreen) && absValue >= deadZone) {
if (value > 0 && joystickCooldown == 0) {
switch (axis) {
case GLFW_GAMEPAD_AXIS_LEFT_Y -> this.changeFocus(client.currentScreen, NavigationDirection.UP);
case GLFW_GAMEPAD_AXIS_LEFT_X -> this.handleLeftRight(client.currentScreen, true);
}
if (axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X) joystickCooldown = 4;
} else if (value < 0 && joystickCooldown == 0) {
switch (axis) {
case GLFW_GAMEPAD_AXIS_LEFT_Y -> this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
case GLFW_GAMEPAD_AXIS_LEFT_X -> this.handleLeftRight(client.currentScreen, false);
}
if (axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X) joystickCooldown = 4;
}
return; return;
} }
} }
absValue -= deadZone;
absValue /= (1.0 - deadZone);
absValue = (float) MathHelper.clamp(absValue / MidnightControlsConfig.getAxisMaxValue(axis), 0.f, 1.f); absValue = (float) MathHelper.clamp(absValue / MidnightControlsConfig.getAxisMaxValue(axis), 0.f, 1.f);
if (client.currentScreen == null) { if (client.currentScreen == null) {
// Handles the look direction. // Handles the look direction.
@@ -591,7 +690,7 @@ public class MidnightInput {
} }
} }
private boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) { public boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) {
if (focused instanceof PressableWidget widget) { if (focused instanceof PressableWidget widget) {
widget.playDownSound(MinecraftClient.getInstance().getSoundManager()); widget.playDownSound(MinecraftClient.getInstance().getSoundManager());
widget.onPress(); widget.onPress();
@@ -620,7 +719,10 @@ public class MidnightInput {
var childFocused = widget.getFocused(); var childFocused = widget.getFocused();
if (childFocused != null) if (childFocused != null)
return this.handleAButton(screen, childFocused); return this.handleAButton(screen, childFocused);
} else if (FabricLoader.getInstance().isModLoaded("yet-another-config-lib") && YACLCompat.handleAButton(screen, focused)) {
return true;
} }
else pressKeyboardKey(screen, GLFW_KEY_ENTER);
return false; return false;
} }
@@ -636,6 +738,10 @@ public class MidnightInput {
this.actionGuiCooldown = 5; this.actionGuiCooldown = 5;
return false; return false;
} }
if (FabricLoader.getInstance().isModLoaded("yet-another-config-lib") && YACLCompat.handleLeftRight(screen, right)) {
this.actionGuiCooldown = 5;
return false;
}
var focused = screen.getFocused(); var focused = screen.getFocused();
if (focused != null) if (focused != null)
if (this.handleRightLeftElement(focused, right)) if (this.handleRightLeftElement(focused, right))
@@ -650,11 +756,13 @@ public class MidnightInput {
return !spruceElement.onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false); return !spruceElement.onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
} }
if (element instanceof SliderWidget slider) { if (element instanceof SliderWidget slider) {
if (slider.active) {
slider.keyPressed(right ? 262 : 263, 0, 0); slider.keyPressed(right ? 262 : 263, 0, 0);
this.actionGuiCooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. this.actionGuiCooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks.
return false; return true;
}
} else if (element instanceof AlwaysSelectedEntryListWidget) { } else if (element instanceof AlwaysSelectedEntryListWidget) {
((EntryListWidgetAccessor) element).midnightcontrols$moveSelection(right ? EntryListWidget.MoveDirection.UP : EntryListWidget.MoveDirection.DOWN); //TODO((EntryListWidgetAccessor) element).midnightcontrols$moveSelection(right ? EntryListWidget.MoveDirection.DOWN : EntryListWidget.MoveDirection.UP);
return false; return false;
} else if (element instanceof ParentElement entryList) { } else if (element instanceof ParentElement entryList) {
var focused = entryList.getFocused(); var focused = entryList.getFocused();
@@ -664,6 +772,10 @@ public class MidnightInput {
} }
return true; return true;
} }
private double prevX = 0;
private double prevY = 0;
private double xValue;
private int xState;
/** /**
* Handles the look direction input. * Handles the look direction input.
@@ -675,46 +787,64 @@ public class MidnightInput {
*/ */
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) { public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) {
// Handles the look direction. // Handles the look direction.
if (client.player != null) {
double powValue = Math.pow(value, 2.0);
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
if (state == 2) {
this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
} else if (state == 1) {
this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
}
}
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
xValue = value;
xState = state;
return;
}
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y && client.player != null) {
double yStep = (MidnightControlsConfig.yAxisRotationSpeed / 100) * 0.6000000238418579 + 0.20000000298023224;
double xStep = (MidnightControlsConfig.rotationSpeed / 100) * 0.6000000238418579 + 0.20000000298023224;
double cursorDeltaX = 2 * xValue - this.prevX;
double cursorDeltaY = 2 * value - this.prevY;
boolean slowdown = client.options.getPerspective().isFirstPerson() && client.player.isUsingSpyglass();
double x = cursorDeltaX * xStep * (slowdown ? xStep : 1);
double y = cursorDeltaY * yStep * (slowdown ? yStep : 1);
double powXValue = Math.pow(x, 2.0);
double powYValue = Math.pow(y, 2.0);
if (state == 2) { if (state == 2) {
this.targetYaw = -MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D; this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powYValue) * 0.11D;
} else if (state == 1) { } else if (state == 1) {
this.targetYaw = MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D; this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powYValue) * 0.11D;
} }
if (xState == 2) {
this.targetYaw = -MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powXValue) * 0.11D;
} else if (xState == 1) {
this.targetYaw = MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powXValue) * 0.11D;
} }
this.prevY = value;
this.prevX = xValue;
} }
} }
private boolean changeFocus(@NotNull Screen screen, NavigationDirection direction) { private boolean changeFocus(@NotNull Screen screen, NavigationDirection direction) {
if (!isScreenInteractive(screen) && !screen.getClass().getCanonicalName().contains("me.jellysquid.mods.sodium.client.gui")) return false;
try {
if (screen instanceof SpruceScreen spruceScreen) { if (screen instanceof SpruceScreen spruceScreen) {
if (spruceScreen.onNavigation(direction, false)) { if (spruceScreen.onNavigation(direction, false)) {
this.actionGuiCooldown = 5; this.actionGuiCooldown = 5;
} }
return false; return false;
} }
if (!screen.changeFocus(direction.isLookingForward())) { switch (direction) {
if (screen.changeFocus(direction.isLookingForward())) { case UP -> pressKeyboardKey(screen, GLFW.GLFW_KEY_UP);
case DOWN -> pressKeyboardKey(screen, GLFW.GLFW_KEY_DOWN);
case LEFT -> pressKeyboardKey(screen, GLFW.GLFW_KEY_LEFT);
case RIGHT -> pressKeyboardKey(screen, GLFW.GLFW_KEY_RIGHT);
}
this.actionGuiCooldown = 5; this.actionGuiCooldown = 5;
return false; return false;
} } catch (Exception exception) {MidnightControls.get().warn("Unknown exception encountered while trying to change focus: "+exception);}
return true;
} else {
this.actionGuiCooldown = 5;
return false; return false;
} }
}
public static boolean isScreenInteractive(@NotNull Screen screen) { public static boolean isScreenInteractive(@NotNull Screen screen) {
return !(screen instanceof HandledScreen || MidnightControlsConfig.mouseScreens.stream().anyMatch(a -> screen.getClass().toString().contains(a)) return !(screen instanceof HandledScreen || MidnightControlsConfig.joystickAsMouse || MidnightControlsConfig.mouseScreens.stream().anyMatch(a -> screen.getClass().toString().contains(a))
|| (screen instanceof SpruceScreen && ((SpruceScreen) screen).requiresCursor()) || (screen instanceof SpruceScreen && ((SpruceScreen) screen).requiresCursor())
|| MidnightControlsCompat.requireMouseOnScreen(screen)); || MidnightControlsCompat.requireMouseOnScreen(screen));
} }

View File

@@ -73,7 +73,7 @@ public class MidnightReacharound {
return MidnightControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || MidnightControlsFeature.VERTICAL_REACHAROUND.isAvailable(); return MidnightControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || MidnightControlsFeature.VERTICAL_REACHAROUND.isAvailable();
} }
private float getPlayerRange(@NotNull MinecraftClient client) { public static float getPlayerRange(@NotNull MinecraftClient client) {
return client.interactionManager != null ? client.interactionManager.getReachDistance() : 0.f; return client.interactionManager != null ? client.interactionManager.getReachDistance() : 0.f;
} }
@@ -101,7 +101,7 @@ public class MidnightReacharound {
BlockPos blockPos = result.getBlockPos().down(); BlockPos blockPos = result.getBlockPos().down();
BlockState state = client.world.getBlockState(blockPos); BlockState state = client.world.getBlockState(blockPos);
if (client.player.getBlockPos().getY() - blockPos.getY() > 1 && (client.world.isAir(blockPos) || state.getMaterial().isReplaceable())) { if (client.player.getBlockPos().getY() - blockPos.getY() > 1 && (client.world.isAir(blockPos) || state.isReplaceable())) {
return new BlockHitResult(result.getPos(), Direction.DOWN, blockPos, false); return new BlockHitResult(result.getPos(), Direction.DOWN, blockPos, false);
} }
} }
@@ -120,31 +120,39 @@ public class MidnightReacharound {
return null; return null;
if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS
&& client.player.isOnGround() && client.player.getPitch(0.f) > 35.f) { && client.player.isOnGround() && client.player.getPitch(0.f) >= 35.f) {
if (client.player.isRiding()) if (client.player.isRiding())
return null; return null;
var playerPos = client.player.getBlockPos().down(); // Temporary pos, do not use
Vec3d playerPosi = client.player.getPos();
// Imitates var playerPos = client.player.getBlockPos().down();
Vec3d playerPos = new Vec3d(playerPosi.getX(), playerPosi.getY() - 1.0, playerPosi.getZ());
if (client.player.getY() - playerPos.getY() - 1.0 >= 0.25) { if (client.player.getY() - playerPos.getY() - 1.0 >= 0.25) {
playerPos = playerPos.up(); // Imitates playerPos = playerPos.up();
playerPos = playerPosi;
this.onSlab = true; this.onSlab = true;
} else { } else {
this.onSlab = false; this.onSlab = false;
} }
var targetPos = new BlockPos(client.crosshairTarget.getPos()).subtract(playerPos); var targetPos = new Vec3d(client.crosshairTarget.getPos().getX(), client.crosshairTarget.getPos().getY(), client.crosshairTarget.getPos().getZ()).subtract(playerPos);
var vector = new BlockPos.Mutable(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1)); var vector = new Vec3d(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1));
var blockPos = playerPos.add(vector); var blockPos = playerPos.add(vector);
// Some functions still need BlockPos, so this is here to let that happen
var blockyPos = BlockPos.ofFloored(blockPos);
var direction = client.player.getHorizontalFacing(); var direction = client.player.getHorizontalFacing();
var state = client.world.getBlockState(blockPos); var state = client.world.getBlockState(blockyPos);
if (!state.isAir()) if (!state.isAir())
return null; return null;
var adjacentBlockState = client.world.getBlockState(blockPos.offset(direction.getOpposite())); var adjacentBlockState = client.world.getBlockState(blockyPos.offset(direction.getOpposite()));
if (adjacentBlockState.isAir() || adjacentBlockState.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) { if (adjacentBlockState.isAir() || adjacentBlockState.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) {
return null; return null;
} }
return new BlockHitResult(client.crosshairTarget.getPos(), direction, blockPos, false); return new BlockHitResult(blockPos, direction, blockyPos, false);
} }
return null; return null;
} }

View File

@@ -0,0 +1,34 @@
/*
* Copyright © 2022 Motschen <motschen@midnightdust.eu>
*
* 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 me.juancarloscp52.bedrockify.client.BedrockifyClient;
import me.juancarloscp52.bedrockify.client.BedrockifyClientSettings;
import net.minecraft.client.gui.screen.Screen;
import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
/**
* Represents HQM compatibility handler.
*
* @author Motschen
* @version 1.7.0
* @since 1.7.0
*/
public class BedrockifyCompat implements CompatHandler {
@Override
public void handle(@NotNull MidnightControlsClient mod) {
BedrockifyClient.getInstance().settings.disableFlyingMomentum = false;
}
}

View File

@@ -33,6 +33,13 @@ public interface CompatHandler {
*/ */
void handle(@NotNull MidnightControlsClient mod); void handle(@NotNull MidnightControlsClient mod);
/**
* Handles custom camera updates
*
* @param client the Minecraft client instance
*/
default void handleCamera(@NotNull MinecraftClient client, double targetYaw, double targetPitch) {};
/** /**
* Returns whether the mouse is required on the specified screen. * Returns whether the mouse is required on the specified screen.
* *

View File

@@ -0,0 +1,48 @@
package eu.midnightdust.midnightcontrols.client.compat;
import dev.emi.emi.config.EmiConfig;
import dev.emi.emi.screen.EmiScreen;
import dev.emi.emi.screen.EmiScreenManager;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory;
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import org.aperlambda.lambdacommon.Identifier;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
public class EMICompat implements CompatHandler {
public static boolean handleTabs(boolean direction) {
if (isEMIEnabled() && MidnightControlsClient.get().input.actionGuiCooldown == 0 && EmiScreenManager.getSearchPanel() != null && EmiScreenManager.getSearchPanel().pageLeft != null && EmiScreenManager.getSearchPanel().pageRight != null) {
if (direction) EmiScreenManager.getSearchPanel().pageRight.onPress();
else EmiScreenManager.getSearchPanel().pageLeft.onPress();
MidnightControlsClient.get().input.actionGuiCooldown = 5;
return true;
}
return false;
}
@Override
public void handle(@NotNull MidnightControlsClient mod) {
ButtonCategory category = new ButtonCategory(new Identifier("midnightcontrols","category.emi"));
InputManager.registerCategory(category);
new ButtonBinding.Builder("emi_page_left")
.buttons(GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, ButtonBinding.axisAsButton(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true))
.category(category)
.action((client,action,value,buttonState)->handleTabs(false)).cooldown()
.filter(((client, buttonBinding) -> client.currentScreen instanceof HandledScreen<?> || client.currentScreen instanceof EmiScreen))
.register();
new ButtonBinding.Builder("emi_page_right")
.buttons(GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, ButtonBinding.axisAsButton(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true))
.category(category)
.action((client,action,value,buttonState)->handleTabs(true)).cooldown()
.filter(((client, buttonBinding) -> client.currentScreen instanceof HandledScreen<?> || client.currentScreen instanceof EmiScreen))
.register();
}
public static boolean isEMIEnabled() {
return EmiConfig.enabled;
}
public static boolean isSearchBarCentered() {
return EmiConfig.centerSearchBar;
}
}

View File

@@ -1,49 +1,34 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat; package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import io.github.kosmx.emotes.arch.gui.EmoteMenuImpl;
import io.github.kosmx.emotes.arch.gui.screen.ingame.FastChosseScreen; import io.github.kosmx.emotes.arch.gui.screen.ingame.FastChosseScreen;
import io.github.kosmx.emotes.main.network.ClientEmotePlay; import net.minecraft.client.MinecraftClient;
import org.jetbrains.annotations.NotNull; import net.minecraft.client.gui.screen.Screen;
/** public class EmotecraftCompat {
* Represents a compatibility handler for Emotecraft. private static final MinecraftClient client = MinecraftClient.getInstance();
* public static void openEmotecraftScreen(Screen parent) {
* @author Motschen client.setScreen(new EmoteMenuImpl(parent));
* @version 1.4.3 }
* @since 1.0.0 public static boolean isEmotecraftScreen(Screen screen) {
*/ return screen instanceof FastChosseScreen;
public class EmotecraftCompat implements CompatHandler { }
@Override public static void handleEmoteSelector(int index) {
public void handle(@NotNull MidnightControlsClient mod) {
new ButtonBinding.Builder("key.emotecraft.fastchoose") if (client.currentScreen instanceof FastChosseScreen) {
.buttons(16) int x = client.getWindow().getWidth() / 2;
.onlyInGame() int y = client.getWindow().getHeight() / 2;
.cooldown(true) if (index == 0) InputManager.queueMousePosition(x-200, y-200);
.category(ButtonBinding.MISC_CATEGORY) if (index == 1) InputManager.queueMousePosition(x, y-200);
.action((client, button, value, action) -> { if (index == 2) InputManager.queueMousePosition(x+200, y-200);
client.setScreen(new FastChosseScreen(null)); if (index == 3) InputManager.queueMousePosition(x-200, y);
return true; if (index == 4) InputManager.queueMousePosition(x+200, y);
}) if (index == 5) InputManager.queueMousePosition(x-200, y+200);
.register(); if (index == 6) InputManager.queueMousePosition(x, y+200);
new ButtonBinding.Builder("key.emotecraft.stop") if (index == 7) InputManager.queueMousePosition(x+200, y+200);
.buttons(17)
.onlyInGame() InputManager.INPUT_MANAGER.updateMousePosition(client);
.cooldown(true) }
.category(ButtonBinding.MISC_CATEGORY)
.action((client, button, value, action) -> {
ClientEmotePlay.clientStopLocalEmote();
return true;
})
.register();
} }
} }

View File

@@ -0,0 +1,33 @@
package eu.midnightdust.midnightcontrols.client.compat;
import com.kqp.inventorytabs.tabs.TabManager;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
public class InventoryTabsCompat {
public static void handleInventoryTabs(Screen screen, boolean next) {
if (screen instanceof HandledScreen<?> && !(screen instanceof CreativeInventoryScreen)) {
TabManager tabManager = TabManager.getInstance();
int tabIndex = tabManager.tabs.indexOf(tabManager.currentTab);
if (next) {
if (tabIndex < tabManager.tabs.size() - 1) tabManager.onTabClick(tabManager.tabs.get(tabIndex + 1));
else tabManager.onTabClick(tabManager.tabs.get(0));
} else {
if (tabIndex > 0) tabManager.onTabClick(tabManager.tabs.get(tabIndex - 1));
else tabManager.onTabClick(tabManager.tabs.get(tabManager.tabs.size() - 1));
}
}
}
public static void handleInventoryPage(Screen screen, boolean next) {
if (screen instanceof HandledScreen<?> && !(screen instanceof CreativeInventoryScreen)) {
TabManager tabManager = TabManager.getInstance();
if (next) {
if (tabManager.canGoForwardAPage()) tabManager.setCurrentPage(tabManager.currentPage + 1);
} else {
if (tabManager.canGoBackAPage()) tabManager.setCurrentPage(tabManager.currentPage - 1);
}
}
}
}

View File

@@ -0,0 +1,25 @@
package eu.midnightdust.midnightcontrols.client.compat;
import io.github.cottonmc.cotton.gui.impl.client.CottonScreenImpl;
import io.github.cottonmc.cotton.gui.widget.WButton;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.sound.SoundEvents;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("UnstableApiUsage")
public class LibGuiCompat {
public static boolean handlePress(@NotNull Screen screen) {
if (screen instanceof CottonScreenImpl cottonScreen) {
if (cottonScreen.getDescription() != null && cottonScreen.getDescription().getFocus() != null) {
if (cottonScreen.getDescription().getFocus() instanceof WButton button && button.getOnClick() != null) {
button.getOnClick().run();
MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
return true;
}
}
}
return false;
}
}

View File

@@ -45,17 +45,17 @@ public class MidnightControlsCompat {
mod.log("Adding Ok Zoomer compatibility..."); mod.log("Adding Ok Zoomer compatibility...");
HANDLERS.add(new OkZoomerCompat()); HANDLERS.add(new OkZoomerCompat());
} }
/*if (isReiPresent()) { if (isEMIPresent()) {
mod.log("Adding REI compatiblity..."); mod.log("Adding EMI compatibility...");
HANDLERS.add(new ReiCompat()); HANDLERS.add(new EMICompat());
}*/ }
if (FabricLoader.getInstance().isModLoaded("hardcorequesting") && LambdaReflection.doesClassExist(HQMCompat.GUI_BASE_CLASS_PATH)) { if (FabricLoader.getInstance().isModLoaded("hardcorequesting") && LambdaReflection.doesClassExist(HQMCompat.GUI_BASE_CLASS_PATH)) {
mod.log("Adding HQM compatibility..."); mod.log("Adding HQM compatibility...");
HANDLERS.add(new HQMCompat()); HANDLERS.add(new HQMCompat());
} }
if (FabricLoader.getInstance().isModLoaded("emotecraft")) { if (FabricLoader.getInstance().isModLoaded("bedrockify")) {
mod.log("Adding Emotecraft compatibility..."); mod.log("Adding Bedrockify compatibility...");
HANDLERS.add(new EmotecraftCompat()); HANDLERS.add(new BedrockifyCompat());
} }
HANDLERS.forEach(handler -> handler.handle(mod)); HANDLERS.forEach(handler -> handler.handle(mod));
InputManager.loadButtonBindings(); InputManager.loadButtonBindings();
@@ -163,4 +163,28 @@ public class MidnightControlsCompat {
public static boolean isReiPresent() { public static boolean isReiPresent() {
return FabricLoader.getInstance().isModLoaded("roughlyenoughitems"); return FabricLoader.getInstance().isModLoaded("roughlyenoughitems");
} }
/**
* Returns whether EMI is present.
*
* @return true if EMI is present, else false
*/
public static boolean isEMIPresent() {
return FabricLoader.getInstance().isModLoaded("emi");
}
/**
* Returns whether InventoryTabs is present.
*
* @return true if InventoryTabs is present, else false
*/
public static boolean isInventoryTabsPresent() {
return FabricLoader.getInstance().isModLoaded("inventorytabs");
}
/**
* Returns whether Emotecraft is present.
*
* @return true if Emotecraft is present, else false
*/
public static boolean isEmotecraftPresent() {
return FabricLoader.getInstance().isModLoaded("emotecraft");
}
} }

View File

@@ -9,6 +9,7 @@
package eu.midnightdust.midnightcontrols.client.compat; package eu.midnightdust.midnightcontrols.client.compat;
import net.fabricmc.loader.api.FabricLoader;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
@@ -29,10 +30,7 @@ public class MidnightControlsMixinPlugin implements IMixinConfigPlugin {
private final HashMap<String, Boolean> conditionalMixins = new HashMap<>(); private final HashMap<String, Boolean> conditionalMixins = new HashMap<>();
public MidnightControlsMixinPlugin() { public MidnightControlsMixinPlugin() {
this.putConditionalMixin("EntryListWidgetAccessor", MidnightControlsCompat.isReiPresent()); //this.putConditionalMixin("SodiumOptionsGUIAccessor", FabricLoader.getInstance().isModLoaded("sodium"));
this.putConditionalMixin("EntryWidgetAccessor", MidnightControlsCompat.isReiPresent());
this.putConditionalMixin("RecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent());
this.putConditionalMixin("VillagerRecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent());
} }
private void putConditionalMixin(@NotNull String path, boolean condition) { private void putConditionalMixin(@NotNull String path, boolean condition) {

View File

@@ -1,355 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* 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.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.compat.mixin.EntryListWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.compat.mixin.EntryWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.InputHandlers;
import eu.midnightdust.midnightcontrols.client.controller.PressAction;
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.EntryListWidget;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Optional;
import static eu.midnightdust.midnightcontrols.client.compat.CompatHandler.SlotPos.INVALID_SLOT;
import static org.lwjgl.glfw.GLFW.*;
/**
* Represents a compatibility handler for REI.
*
* @author LambdAurora
* @version 1.7.0
* @since 1.2.0
*/
public class ReiCompat implements CompatHandler {
private static EntryListWidget ENTRY_LIST_WIDGET;
@Override
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))
.action(handleTab(false))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "category_next"))
.buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleTab(true))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "page_back"))
.buttons(ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_X, false))
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handlePage(false))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "page_next"))
.buttons(ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_X, true))
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handlePage(true))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "recipe_back"))
.buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleRecipe(false))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "recipe_next"))
.buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleRecipe(true))
.cooldown(true)
.register();
// For some reasons this is broken.
ButtonBinding.builder(new Identifier("rei", "show_usage"))
.buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handleShowRecipeUsage(true))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "show_recipe"))
.buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB)
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handleShowRecipeUsage(false))
.cooldown(true)
.register();
*/
}
/*
@Override
public boolean requireMouseOnScreen(Screen screen) {
return isViewingScreen(screen);
}
@Override
public @Nullable CompatHandler.SlotPos getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
ScreenOverlayImpl overlay = ScreenOverlayImpl.getInstance();
if (overlay.isInside(mouseX, mouseY)) {
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return null;
return this.getSlotAt(widget, mouseX, mouseY, false);
} else if (isViewingScreen(screen)) {
for (Element element : screen.children()) {
var slot = this.getSlotAt(element, mouseX, mouseY, true);
if (slot != null)
return slot;
}
}
return null;
}
private @Nullable CompatHandler.SlotPos getSlotAt(@NotNull Element element, int mouseX, int mouseY, boolean allowEmpty) {
if (element instanceof EntryWidget) {
EntryWidget entry = (EntryWidget) element;
if (entry.containsMouse(mouseX, mouseY)) {
if (!allowEmpty && entry.getEntries().isEmpty())
return INVALID_SLOT;
return new SlotPos(entry.getBounds().getX() + 1, entry.getBounds().getY() + 1);
}
} else if (element instanceof EntryListWidget) {
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries();
for (EntryListEntryWidget entry : entries) {
var slot = this.getSlotAt(entry, mouseX, mouseY, allowEmpty);
if (slot != null && slot != INVALID_SLOT)
return slot;
}
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds widgetWithBounds) {
for (var child : widgetWithBounds.children()) {
var slot = this.getSlotAt(child, mouseX, mouseY, allowEmpty);
if (slot != null && slot != INVALID_SLOT)
return slot;
}
}
return null;
}
private static boolean isViewingScreen(Screen screen) {
return screen instanceof DefaultDisplayViewingScreen || screen instanceof CompositeDisplayViewingScreen;
}
@Override
public boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) {
if (!isViewingScreen(screen))
return false;
MinecraftClient.getInstance().setScreen(REIRuntimeImpl.getInstance().getPreviousContainerScreen());
REIRuntimeImpl.getInstance().getLastOverlay().init();
return true;
}
private static EntryListWidget getEntryListWidget() {
if (ENTRY_LIST_WIDGET == null) {
ENTRY_LIST_WIDGET = LambdaReflection.getFirstFieldOfType(ContainerScreenOverlay.class, EntryListWidget.class)
.map(field -> (EntryListWidget) LambdaReflection.getFieldValue(null, field))
.orElse(null);
}
return ENTRY_LIST_WIDGET;
}
private static @Nullable AbstractEntryStack getCurrentStack(@NotNull MinecraftClient client) {
double x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
if (isViewingScreen(client.currentScreen)) {
for (Element element : client.currentScreen.children()) {
EntryStack stack = getCurrentStack(element, x, y);
if (stack != null)
return stack;
}
}
Optional<ContainerScreenOverlay> overlay = REIRuntimeImpl.getInstance().getOverlay(false,false);
if (!overlay.isPresent())
return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return ScreenOverlayImpl.getInstance().getInstance().getOverlayMenu()..getScreenFocusedStack(client.currentScreen);
return getCurrentStack(widget, x, y);
}
private static @Nullable EntryStack getCurrentStack(@NotNull Element element, double mouseX, double mouseY) {
if (element instanceof EntryWidget) {
EntryWidget entry = (EntryWidget) element;
if (entry.containsMouse(mouseX, mouseY))
return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry();
} else if (element instanceof EntryListWidget) {
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries();
for (EntryListEntryWidget entry : entries) {
if (entry.containsMouse(mouseX, mouseY)) {
return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry();
}
}
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds) {
for (Element child : ((WidgetWithBounds) element).children()) {
EntryStack stack = getCurrentStack(child, mouseX, mouseY);
if (stack != null)
return stack;
}
}
return null;
}
private static PressAction handleShowRecipeUsage(boolean usage) {
return (client, button, value, action) -> {
if (action.isUnpressed())
return false;
EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
if (stack == null) {
stack = getCurrentStack(client);
}
if (stack != null && !stack.isEmpty()) {
stack = stack.copy();
if (usage) {
return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addUsagesFor(stack).setInputNotice(stack).fillPreferredOpenedCategory());
} else {
return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory());
}
}
return false;
};
}
private static PressAction handlePage(boolean next) {
return (client, button, value, action) -> {
if (action == ButtonState.RELEASE)
return false;
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent())
return false;
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return false;
if (next)
widget.nextPage();
else
widget.previousPage();
widget.updateEntriesPosition();
return true;
};
}
/**
* Returns the handler for category tabs buttons.
*
* @param next True if the action is to switch to the next tab.
* @return The handler.
*/
/*
private static PressAction handleTab(boolean next) {
return (client, button, value, action) -> {
if (action != ButtonState.RELEASE)
return false;
if (client.currentScreen instanceof RecipeViewingScreen) {
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
if (next)
screen.getCategoryNext().onClick();
else
screen.getCategoryBack().onClick();
return true;
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) {
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex();
screen.setSelectedCategoryIndex(getNextIndex(currentTab, categories.size(), next));
screen.setSelectedRecipeIndex(0);
screen.lambdacontrols_init();
return true;
}
return false;
};
}
private static PressAction handleRecipe(boolean next) {
return (client, button, value, action) -> {
if (action.isUnpressed())
return false;
if (client.currentScreen instanceof RecipeViewingScreen) {
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
if (next)
screen.getRecipeNext().onClick();
else
screen.getRecipeBack().onClick();
return true;
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) {
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex();
List<RecipeDisplay> recipes = screen.getCategoryMap().get(categories.get(currentTab));
if (recipes.size() == 0)
return true;
int currentRecipe = screen.getSelectedRecipeIndex();
int nextRecipe = getNextIndex(currentRecipe, recipes.size(), next);
if (nextRecipe == 0) {
screen.getScrolling().scrollTo(0.0, true);
} else if (nextRecipe == recipes.size() - 1) {
screen.getScrolling().scrollTo(screen.getScrolling().getMaxScroll(), true);
} else {
double scrollAmount = screen.getScrolling().getMaxScroll() / (float) recipes.size();
screen.getScrolling().offset(next ? scrollAmount : -scrollAmount, true);
}
screen.setSelectedRecipeIndex(nextRecipe);
screen.lambdacontrols_init();
return true;
}
return false;
};
}
private static int getNextIndex(int currentIndex, int size, boolean next) {
int nextIndex = currentIndex + (next ? 1 : -1);
if (nextIndex < 0)
nextIndex = size - 1;
else if (nextIndex >= size)
nextIndex = 0;
return nextIndex;
}
*/
}

View File

@@ -0,0 +1,20 @@
package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.compat.mixin.SodiumOptionsGUIAccessor;
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
import net.minecraft.client.gui.screen.Screen;
public class SodiumCompat {
public static void handleTabs(Screen screen, boolean direction) {
if (screen instanceof SodiumOptionsGUI optionsGUI) {
SodiumOptionsGUIAccessor accessor = (SodiumOptionsGUIAccessor) optionsGUI;
final int max = accessor.getPages().size()-1;
int i = accessor.getPages().indexOf(accessor.getCurrentPage());
i = (direction ? ((max > i) ? ++i : 0) : (i > 0 ? --i : max));
if (MidnightControlsConfig.debug) MidnightControls.get().log(""+i);
optionsGUI.setPage(accessor.getPages().get(i));
}
}
}

View File

@@ -0,0 +1,56 @@
package eu.midnightdust.midnightcontrols.client.compat;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.OptionListWidget;
import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.gui.controllers.ControllerWidget;
import dev.isxander.yacl.gui.controllers.slider.SliderControllerElement;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen;
import org.lwjgl.glfw.GLFW;
public class YACLCompat {
public static boolean handleAButton(Screen screen, Element element) {
if (element instanceof AbstractWidget abstractWidget) {
// imitate ender key press
return abstractWidget.keyPressed(GLFW.GLFW_KEY_ENTER, 0, 0);
}
return false;
}
public static boolean handleLeftRight(Screen screen, boolean direction) {
if (screen instanceof YACLScreen yaclScreen) {
SliderControllerElement focusedSlider = yaclScreen.optionList.children().stream()
.filter(OptionListWidget.OptionEntry.class::isInstance)
.map(entry -> ((OptionListWidget.OptionEntry) entry).widget)
.filter(ControllerWidget.class::isInstance)
.map(ControllerWidget.class::cast)
.filter(SliderControllerElement.class::isInstance)
.map(SliderControllerElement.class::cast)
.filter(ControllerWidget::isHovered)
.findFirst()
.orElse(null);
if (focusedSlider == null)
return false;
focusedSlider.incrementValue(direction ? 1 : -1);
return true;
}
return false;
}
public static boolean handleCategories(Screen screen, boolean direction) {
if (screen instanceof YACLScreen yaclScreen) {
int categoryIdx = yaclScreen.getCurrentCategoryIdx();
if (direction) categoryIdx++; else categoryIdx--;
if (categoryIdx < 0) categoryIdx = yaclScreen.config.categories().size() - 1;
if (categoryIdx >= yaclScreen.config.categories().size()) categoryIdx = 0;
yaclScreen.changeCategory(categoryIdx);
return true;
}
return false;
}
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.widget.EntryListWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
/**
* Represents an accessor to REI's EntryListWidget.
*
* @author LambdAurora
* @version 1.5.0
* @since 1.5.0
*/
@Mixin(value = EntryListWidget.class, remap = false)
public interface EntryListWidgetAccessor {
@Accessor(value = "children")
List<Element> getEntries();
}

View File

@@ -1,23 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
/**
* Represents an accessor to REI's EntryWidget.
*
* @author LambdAurora
* @version 1.5.0
* @since 1.5.0
*/
//@Mixin(value = EntryWidget.class, remap = false)
public interface EntryWidgetAccessor {
/*@Invoker("getCurrentEntry")
EntryStack midnightcontrols_getCurrentEntry();*/
}

View File

@@ -1,32 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
/**
* Represents an accessor to REI's RecipeViewingScreen.
*
* @author LambdAurora
* @version 1.7.0
* @since 1.2.0
*/
//@Mixin(value = DefaultDisplayViewingScreen.class, remap = false)
public interface RecipeViewingScreenAccessor {
/*@Accessor("categoryBack")
Button getCategoryBack();
@Accessor("categoryNext")
Button getCategoryNext();
@Accessor("recipeBack")
Button getRecipeBack();
@Accessor("recipeNext")
Button getRecipeNext();*/
}

View File

@@ -0,0 +1,19 @@
package eu.midnightdust.midnightcontrols.client.compat.mixin;
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
import me.jellysquid.mods.sodium.client.gui.options.OptionPage;
import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(value = SodiumOptionsGUI.class, remap = false)
public interface SodiumOptionsGUIAccessor {
@Accessor
List<ControlElement<?>> getControls();
@Accessor
List<OptionPage> getPages();
@Accessor
OptionPage getCurrentPage();
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
/**
* Represents an accessor to REI's VillagerRecipeViewingScreen.
*
* @author LambdAurora
* @version 1.7.0
* @since 1.2.0
*/
//@Mixin(CompositeDisplayViewingScreen.class)
public interface VillagerRecipeViewingScreenAccessor {
/*@Accessor(value = "categoryMap", remap = false)
Map<DisplayCategory<?>, List<Display>> getCategoryMap();
@Accessor(value = "categories", remap = false)
List<DisplayCategory<?>> getCategories();
@Accessor(value = "selectedCategoryIndex", remap = false)
int getSelectedCategoryIndex();
@Accessor(value = "selectedCategoryIndex", remap = false)
void setSelectedCategoryIndex(int selectedCategoryIndex);
@Accessor(value = "selectedRecipeIndex", remap = false)
int getSelectedRecipeIndex();
@Accessor(value = "selectedRecipeIndex", remap = false)
void setSelectedRecipeIndex(int selectedRecipeIndex);
@Accessor(value = "scrolling", remap = false)
ScrollingContainer getScrolling();
@Invoker("init")
void midnightcontrols_init();*/
}

View File

@@ -10,9 +10,14 @@
package eu.midnightdust.midnightcontrols.client.controller; package eu.midnightdust.midnightcontrols.client.controller;
import eu.midnightdust.midnightcontrols.client.ButtonState; import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.aperlambda.lambdacommon.utils.function.PairPredicate; import org.aperlambda.lambdacommon.utils.function.PairPredicate;
@@ -43,6 +48,15 @@ public class ButtonBinding {
public static final ButtonBinding BACK = new Builder("back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false)) public static final ButtonBinding BACK = new Builder("back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false))
.action(MovementHandler.HANDLER).onlyInGame().register(); .action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding CHAT = new Builder("chat").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT).onlyInGame().cooldown().register(); public static final ButtonBinding CHAT = new Builder("chat").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT).onlyInGame().cooldown().register();
public static final ButtonBinding CONTROLS_RING = new Builder("controls_ring").buttons(GLFW_GAMEPAD_BUTTON_GUIDE).onlyInGame().cooldown()
.action((client, button1, value, action) -> {
if (action.isPressed()) {
MidnightControlsClient.get().ring.loadFromUnbound();
client.setScreen(new RingScreen());
}
if (action.isUnpressed() && client.currentScreen != null) client.currentScreen.close();
return true;
}).register();
public static final ButtonBinding DROP_ITEM = new Builder("drop_item").buttons(GLFW_GAMEPAD_BUTTON_B).onlyInGame().cooldown().register(); public static final ButtonBinding DROP_ITEM = new Builder("drop_item").buttons(GLFW_GAMEPAD_BUTTON_B).onlyInGame().cooldown().register();
public static final ButtonBinding FORWARD = new Builder("forward").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true)) public static final ButtonBinding FORWARD = new Builder("forward").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true))
.action(MovementHandler.HANDLER).onlyInGame().register(); .action(MovementHandler.HANDLER).onlyInGame().register();
@@ -51,6 +65,8 @@ public class ButtonBinding {
public static final ButtonBinding HOTBAR_RIGHT = new Builder("hotbar_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) public static final ButtonBinding HOTBAR_RIGHT = new Builder("hotbar_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.action(InputHandlers.handleHotbar(true)).onlyInGame().cooldown().register(); .action(InputHandlers.handleHotbar(true)).onlyInGame().cooldown().register();
public static final ButtonBinding INVENTORY = new Builder("inventory").buttons(GLFW_GAMEPAD_BUTTON_Y).onlyInGame().cooldown().register(); public static final ButtonBinding INVENTORY = new Builder("inventory").buttons(GLFW_GAMEPAD_BUTTON_Y).onlyInGame().cooldown().register();
public static final ButtonBinding EXIT = new Builder("exit").buttons(GLFW_GAMEPAD_BUTTON_B).filter((client, buttonBinding) -> client.currentScreen != null && buttonBinding.cooldown == 0 && INVENTORY.cooldown == 0)
.action(InputHandlers.handleExit()).cooldown().register();
public static final ButtonBinding JUMP = new Builder("jump").buttons(GLFW_GAMEPAD_BUTTON_A).onlyInGame().register(); public static final ButtonBinding JUMP = new Builder("jump").buttons(GLFW_GAMEPAD_BUTTON_A).onlyInGame().register();
public static final ButtonBinding LEFT = new Builder("left").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false)) public static final ButtonBinding LEFT = new Builder("left").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false))
.action(MovementHandler.HANDLER).onlyInGame().register(); .action(MovementHandler.HANDLER).onlyInGame().register();
@@ -61,6 +77,8 @@ public class ButtonBinding {
.action(MovementHandler.HANDLER).onlyInGame().register(); .action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A) public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A)
.action(InputHandlers::handleScreenshot).cooldown().register(); .action(InputHandlers::handleScreenshot).cooldown().register();
public static final ButtonBinding DEBUG_SCREEN = new Builder("debug_screen").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_B)
.action((client,binding,value,action) -> {if (action == ButtonState.PRESS) client.inGameHud.getDebugHud().toggleDebugHud(); return true;}).cooldown().register();
public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN) public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
.action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register(); .action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT) public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)
@@ -69,26 +87,26 @@ public class ButtonBinding {
.action(InputHandlers.handleInventorySlotPad(2)).onlyInInventory().cooldown().register(); .action(InputHandlers.handleInventorySlotPad(2)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_UP = new Builder("slot_up").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP) public static final ButtonBinding SLOT_UP = new Builder("slot_up").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP)
.action(InputHandlers.handleInventorySlotPad(0)).onlyInInventory().cooldown().register(); .action(InputHandlers.handleInventorySlotPad(0)).onlyInInventory().cooldown().register();
public static final ButtonBinding SMOOTH_CAMERA = new Builder("toggle_smooth_camera").onlyInGame().cooldown().register();
public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB) public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register(); .actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register();
public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).onlyInGame().register(); public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB)
.actions(InputHandlers::handleToggleSprint).onlyInGame().register();
public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register(); public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register();
public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register(); .action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null)).cooldown().register();
public static final ButtonBinding TAB_RIGHT = new Builder("tab_next").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) public static final ButtonBinding TAB_RIGHT = new Builder("tab_next").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register(); .action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null)).cooldown().register();
public static final ButtonBinding PAGE_LEFT = new Builder("page_back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)) public static final ButtonBinding PAGE_LEFT = new Builder("page_back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true))
.action(InputHandlers.handlePage(false)).filter(InputHandlers::inInventory).cooldown().register(); .action(InputHandlers.handlePage(false)).filter(InputHandlers::inInventory).cooldown(30).register();
public static final ButtonBinding PAGE_RIGHT = new Builder("page_next").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)) public static final ButtonBinding PAGE_RIGHT = new Builder("page_next").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true))
.action(InputHandlers.handlePage(true)).filter(InputHandlers::inInventory).cooldown().register(); .action(InputHandlers.handlePage(true)).filter(InputHandlers::inInventory).cooldown(30).register();
public static final ButtonBinding TAKE = new Builder("take").buttons(GLFW_GAMEPAD_BUTTON_X) public static final ButtonBinding TAKE = new Builder("take").buttons(GLFW_GAMEPAD_BUTTON_X)
.action(InputHandlers.handleActions()).filter(InputHandlers::inInventory).cooldown().register(); .action(InputHandlers.handleActions()).filter(InputHandlers::inInventory).cooldown().register();
public static final ButtonBinding TAKE_ALL = new Builder("take_all").buttons(GLFW_GAMEPAD_BUTTON_A) public static final ButtonBinding TAKE_ALL = new Builder("take_all").buttons(GLFW_GAMEPAD_BUTTON_A)
.action(InputHandlers.handleActions()).filter(InputHandlers::inInventory).cooldown().register(); .action(InputHandlers.handleActions()).filter(InputHandlers::inInventory).cooldown().register();
public static final ButtonBinding QUICK_MOVE = new Builder("quick_move").buttons(GLFW_GAMEPAD_BUTTON_Y) public static final ButtonBinding QUICK_MOVE = new Builder("quick_move").buttons(GLFW_GAMEPAD_BUTTON_Y)
.action(InputHandlers.handleActions()).filter(InputHandlers::inInventory).cooldown().register(); .action(InputHandlers.handleActions()).filter(InputHandlers::inInventory).cooldown().register();
public static final ButtonBinding TOGGLE_PERSPECTIVE = new Builder("toggle_perspective").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_Y).cooldown().register(); public static final ButtonBinding TOGGLE_PERSPECTIVE = new Builder("toggle_perspective").filter(InputHandlers::inGame).buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_Y).cooldown().register();
public static final ButtonBinding USE = new Builder("use").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)).register(); public static final ButtonBinding USE = new Builder("use").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)).register();
private int[] button; private int[] button;
@@ -99,6 +117,7 @@ public class ButtonBinding {
protected PairPredicate<MinecraftClient, ButtonBinding> filter; protected PairPredicate<MinecraftClient, ButtonBinding> filter;
private final List<PressAction> actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION)); private final List<PressAction> actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION));
private boolean hasCooldown; private boolean hasCooldown;
private int cooldownLength = 5;
private int cooldown = 0; private int cooldown = 0;
boolean pressed = false; boolean pressed = false;
@@ -110,10 +129,22 @@ public class ButtonBinding {
this.actions.addAll(actions); this.actions.addAll(actions);
this.hasCooldown = hasCooldown; this.hasCooldown = hasCooldown;
} }
public ButtonBinding(String key, int[] defaultButton, List<PressAction> actions, PairPredicate<MinecraftClient, ButtonBinding> filter, boolean hasCooldown, int cooldownLength) {
this.setButton(this.defaultButton = defaultButton);
this.key = key;
this.text = Text.translatable(this.key);
this.filter = filter;
this.actions.addAll(actions);
this.hasCooldown = hasCooldown;
this.cooldownLength = cooldownLength;
}
public ButtonBinding(String key, int[] defaultButton, boolean hasCooldown) { public ButtonBinding(String key, int[] defaultButton, boolean hasCooldown) {
this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown); this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown);
} }
public ButtonBinding(String key, int[] defaultButton, boolean hasCooldown, int cooldownLength) {
this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown, cooldownLength);
}
/** /**
* Returns the button bound. * Returns the button bound.
@@ -230,7 +261,7 @@ public class ButtonBinding {
if (state == ButtonState.REPEAT && this.hasCooldown && this.cooldown != 0) if (state == ButtonState.REPEAT && this.hasCooldown && this.cooldown != 0)
return; return;
if (this.hasCooldown && state.isPressed()) { if (this.hasCooldown && state.isPressed()) {
this.cooldown = 5; this.cooldown = cooldownLength;
} }
for (int i = this.actions.size() - 1; i >= 0; i--) { for (int i = this.actions.size() - 1; i >= 0; i--) {
if (this.actions.get(i).press(client, this, value, state)) if (this.actions.get(i).press(client, this, value, state))
@@ -248,7 +279,7 @@ public class ButtonBinding {
* @return the translation key * @return the translation key
*/ */
public @NotNull String getTranslationKey() { public @NotNull String getTranslationKey() {
return "midnightcontrols.action." + this.getName(); return I18n.hasTranslation("midnightcontrols.action." + this.getName()) ? "midnightcontrols.action." + this.getName() : this.getName();
} }
public @NotNull Text getText() { public @NotNull Text getText() {
@@ -316,7 +347,6 @@ public class ButtonBinding {
PLAYER_LIST.mcKeyBinding = options.playerListKey; PLAYER_LIST.mcKeyBinding = options.playerListKey;
RIGHT.mcKeyBinding = options.rightKey; RIGHT.mcKeyBinding = options.rightKey;
SCREENSHOT.mcKeyBinding = options.screenshotKey; SCREENSHOT.mcKeyBinding = options.screenshotKey;
SMOOTH_CAMERA.mcKeyBinding = options.smoothCameraKey;
SNEAK.mcKeyBinding = options.sneakKey; SNEAK.mcKeyBinding = options.sneakKey;
SPRINT.mcKeyBinding = options.sprintKey; SPRINT.mcKeyBinding = options.sprintKey;
SWAP_HANDS.mcKeyBinding = options.swapHandsKey; SWAP_HANDS.mcKeyBinding = options.swapHandsKey;
@@ -381,23 +411,33 @@ public class ButtonBinding {
ButtonBinding.USE ButtonBinding.USE
)); ));
INVENTORY_CATEGORY = InputManager.registerDefaultCategory("key.categories.inventory", category -> category.registerAllBindings( INVENTORY_CATEGORY = InputManager.registerDefaultCategory("key.categories.inventory", category -> category.registerAllBindings(
ButtonBinding.EXIT,
ButtonBinding.DROP_ITEM, ButtonBinding.DROP_ITEM,
ButtonBinding.HOTBAR_LEFT, ButtonBinding.HOTBAR_LEFT,
ButtonBinding.HOTBAR_RIGHT, ButtonBinding.HOTBAR_RIGHT,
ButtonBinding.INVENTORY, ButtonBinding.INVENTORY,
ButtonBinding.SWAP_HANDS, ButtonBinding.SWAP_HANDS,
ButtonBinding.TAB_LEFT,
ButtonBinding.TAB_RIGHT,
ButtonBinding.PAGE_LEFT, ButtonBinding.PAGE_LEFT,
ButtonBinding.PAGE_RIGHT, ButtonBinding.PAGE_RIGHT,
ButtonBinding.TAKE, ButtonBinding.TAKE,
ButtonBinding.TAKE_ALL, ButtonBinding.TAKE_ALL,
ButtonBinding.QUICK_MOVE ButtonBinding.QUICK_MOVE,
ButtonBinding.SLOT_UP,
ButtonBinding.SLOT_DOWN,
ButtonBinding.SLOT_LEFT,
ButtonBinding.SLOT_RIGHT
)); ));
MULTIPLAYER_CATEGORY = InputManager.registerDefaultCategory("key.categories.multiplayer", MULTIPLAYER_CATEGORY = InputManager.registerDefaultCategory("key.categories.multiplayer",
category -> category.registerAllBindings(ButtonBinding.CHAT, ButtonBinding.PLAYER_LIST)); category -> category.registerAllBindings(ButtonBinding.CHAT, ButtonBinding.PLAYER_LIST));
MISC_CATEGORY = InputManager.registerDefaultCategory("key.categories.misc", category -> category.registerAllBindings( MISC_CATEGORY = InputManager.registerDefaultCategory("key.categories.misc", category -> category.registerAllBindings(
ButtonBinding.SCREENSHOT, ButtonBinding.SCREENSHOT,
ButtonBinding.TOGGLE_PERSPECTIVE,
ButtonBinding.PAUSE_GAME,
//SMOOTH_CAMERA, //SMOOTH_CAMERA,
ButtonBinding.TOGGLE_PERSPECTIVE ButtonBinding.DEBUG_SCREEN,
ButtonBinding.CONTROLS_RING
)); ));
} }
@@ -426,6 +466,7 @@ public class ButtonBinding {
private final List<PressAction> actions = new ArrayList<>(); private final List<PressAction> actions = new ArrayList<>();
private PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue(); private PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue();
private boolean cooldown = false; private boolean cooldown = false;
private int cooldownLength = 5;
private ButtonCategory category = null; private ButtonCategory category = null;
private KeyBinding mcBinding = null; private KeyBinding mcBinding = null;
@@ -440,7 +481,7 @@ public class ButtonBinding {
} }
public Builder(@NotNull Identifier identifier) { public Builder(@NotNull Identifier identifier) {
this(identifier.getNamespace() + "." + identifier.getNamespace()); this(identifier.getNamespace() + "." + identifier.getPath());
} }
/** /**
@@ -528,6 +569,17 @@ public class ButtonBinding {
this.cooldown = cooldown; this.cooldown = cooldown;
return this; return this;
} }
/**
* Sets the cooldown enabled with a custom duration for {@link ButtonBinding}.
*
* @param cooldownLength duration of {@link ButtonBinding} cooldown
* @return the builder instance
*/
public Builder cooldown(int cooldownLength) {
this.cooldownLength = cooldownLength;
this.cooldown = true;
return this;
}
/** /**
* Puts a cooldown on the {@link ButtonBinding}. * Puts a cooldown on the {@link ButtonBinding}.
@@ -567,7 +619,7 @@ public class ButtonBinding {
* @return the built {@link ButtonBinding} * @return the built {@link ButtonBinding}
*/ */
public ButtonBinding build() { public ButtonBinding build() {
var binding = new ButtonBinding(this.key, this.buttons, this.actions, this.filter, this.cooldown); var binding = new ButtonBinding(this.key, this.buttons, this.actions, this.filter, this.cooldown, this.cooldownLength);
if (this.category != null) if (this.category != null)
this.category.registerBinding(binding); this.category.registerBinding(binding);
if (this.mcBinding != null) if (this.mcBinding != null)

View File

@@ -13,6 +13,7 @@ import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.toast.SystemToast; import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.aperlambda.lambdacommon.utils.Nameable; import org.aperlambda.lambdacommon.utils.Nameable;
@@ -31,6 +32,7 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static org.lwjgl.BufferUtils.createByteBuffer; import static org.lwjgl.BufferUtils.createByteBuffer;
@@ -78,7 +80,7 @@ public record Controller(int id) implements Nameable {
* @return the controller's name * @return the controller's name
*/ */
@Override @Override
public String getName() { public @NotNull String getName() {
var name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id); var name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id);
return name == null ? String.valueOf(this.id()) : name; return name == null ? String.valueOf(this.id()) : name;
} }
@@ -136,7 +138,7 @@ public record Controller(int id) implements Nameable {
} }
} }
buffer.flip(); // Force Java 8 >.< if (buffer != null) buffer.flip(); // Force Java 8 >.<
return buffer; return buffer;
} }
@@ -144,12 +146,14 @@ public record Controller(int id) implements Nameable {
* Updates the controller mappings. * Updates the controller mappings.
*/ */
public static void updateMappings() { public static void updateMappings() {
CompletableFuture.supplyAsync(Controller::updateMappingsSync);
}
private static boolean updateMappingsSync() {
try { try {
MidnightControlsClient.get().log("Updating controller mappings..."); MidnightControlsClient.get().log("Updating controller mappings...");
File databaseFile = new File("config/gamecontrollerdatabase.txt"); File databaseFile = new File("config/gamecontrollerdatabase.txt");
try { try {
BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream()); BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile)); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile));
byte[] dataBuffer = new byte[1024]; byte[] dataBuffer = new byte[1024];
int bytesRead; int bytesRead;
@@ -159,11 +163,11 @@ public record Controller(int id) implements Nameable {
out.close(); out.close();
} catch (Exception ignored) {/* Just continue when internet connection is not available */} } catch (Exception ignored) {/* Just continue when internet connection is not available */}
var database = ioResourceToBuffer(databaseFile.getPath(), 1024); var database = ioResourceToBuffer(databaseFile.getPath(), 1024);
GLFW.glfwUpdateGamepadMappings(database); if (database != null) GLFW.glfwUpdateGamepadMappings(database);
if (!MidnightControlsClient.MAPPINGS_FILE.exists()) if (!MidnightControlsClient.MAPPINGS_FILE.exists())
return; return false;
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024); var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
GLFW.glfwUpdateGamepadMappings(buffer); if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -178,6 +182,7 @@ public record Controller(int id) implements Nameable {
if (client != null) { if (client != null) {
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT, client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT,
Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string))); Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string)));
MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string);
} }
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -198,5 +203,6 @@ public record Controller(int id) implements Nameable {
controller.isGamepad())); controller.isGamepad()));
} }
} }
return true;
} }
} }

View File

@@ -9,33 +9,49 @@
package eu.midnightdust.midnightcontrols.client.controller; package eu.midnightdust.midnightcontrols.client.controller;
import com.google.common.collect.Lists;
import eu.midnightdust.lib.util.PlatformFunctions;
import eu.midnightdust.midnightcontrols.client.ButtonState; import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.MidnightInput; import eu.midnightdust.midnightcontrols.client.MidnightInput;
import eu.midnightdust.midnightcontrols.client.compat.InventoryTabsCompat;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.compat.SodiumCompat;
import eu.midnightdust.midnightcontrols.client.compat.YACLCompat;
import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor; import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor;
import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor; import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor;
import eu.midnightdust.midnightcontrols.client.mixin.RecipeBookWidgetAccessor; import eu.midnightdust.midnightcontrols.client.mixin.RecipeBookWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.mixin.TabNavigationWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import net.fabricmc.fabric.impl.item.group.CreativeGuiExtensions; import eu.midnightdust.midnightcontrols.client.util.MouseAccessor;
import net.fabricmc.fabric.impl.client.itemgroup.CreativeGuiExtensions;
import net.fabricmc.fabric.impl.client.itemgroup.FabricCreativeGuiComponents;
import net.fabricmc.fabric.impl.itemgroup.FabricItemGroup;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.Framebuffer; import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.*;
import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.widget.PressableWidget;
import net.minecraft.client.gui.widget.TabNavigationWidget;
import net.minecraft.client.util.ScreenshotRecorder; import net.minecraft.client.util.ScreenshotRecorder;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType; import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.util.math.MathHelper;
import org.aperlambda.lambdacommon.utils.Pair; import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_2; import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_2;
@@ -47,49 +63,94 @@ import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_2;
* @version 1.7.0 * @version 1.7.0
* @since 1.1.0 * @since 1.1.0
*/ */
@SuppressWarnings("UnstableApiUsage")
public class InputHandlers { public class InputHandlers {
private InputHandlers() { private InputHandlers() {
} }
private static List<ItemGroup> getVisibleGroups(CreativeInventoryScreen screen) {
return ItemGroups.getGroups().stream()
.filter(itemGroup -> {
if (FabricCreativeGuiComponents.COMMON_GROUPS.contains(itemGroup)) return true;
return ((CreativeGuiExtensions)screen).fabric_currentPage() == ((FabricItemGroup)itemGroup).getPage() && itemGroup.shouldDisplay();
}).toList();
}
public static PressAction handleHotbar(boolean next) { public static PressAction handleHotbar(boolean next) {
return (client, button, value, action) -> { return (client, button, value, action) -> {
if (action == ButtonState.RELEASE) if (action == ButtonState.RELEASE)
return false; return false;
// When ingame // When in-game
if (client.currentScreen == null && client.player != null) { if (client.currentScreen == null && client.player != null) {
if (!client.player.isSpectator()) {
if (next) if (next)
client.player.getInventory().selectedSlot = client.player.getInventory().selectedSlot == 8 ? 0 : client.player.getInventory().selectedSlot + 1; client.player.getInventory().scrollInHotbar(-1.0);
else else
client.player.getInventory().selectedSlot = client.player.getInventory().selectedSlot == 0 ? 8 : client.player.getInventory().selectedSlot - 1; client.player.getInventory().scrollInHotbar(1.0);
}
else {
if (client.inGameHud.getSpectatorHud().isOpen()) {
client.inGameHud.getSpectatorHud().cycleSlot(next ? -1 : 1);
} else {
float g = MathHelper.clamp(client.player.getAbilities().getFlySpeed() + (next ? 1 : -1) * 0.005F, 0.0F, 0.2F);
client.player.getAbilities().setFlySpeed(g);
}
}
return true; return true;
} else if (client.currentScreen instanceof RingScreen) {
MidnightControlsClient.get().ring.cyclePage(next);
} else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) { } else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) {
int currentTab = inventory.getSelectedTab(); if (PlatformFunctions.isModLoaded("connectormod")) return true;
int nextTab = currentTab + (next ? 1 : -1); ItemGroup currentTab = CreativeInventoryScreenAccessor.getSelectedTab();
if (nextTab < 0) int currentColumn = currentTab.getColumn();
nextTab = ItemGroup.GROUPS.length - 1; ItemGroup.Row currentRow = currentTab.getRow();
else if (nextTab >= ItemGroup.GROUPS.length) ItemGroup newTab = null;
nextTab = 0; List<ItemGroup> visibleTabs = getVisibleGroups((CreativeInventoryScreen) client.currentScreen);
inventory.midnightcontrols$setSelectedTab(ItemGroup.GROUPS[nextTab]); for (ItemGroup tab : visibleTabs) {
if (tab.getRow().equals(currentRow) && ((newTab == null && ((next && tab.getColumn() > currentColumn) ||
(!next && tab.getColumn() < currentColumn))) || (newTab != null && ((next && tab.getColumn() > currentColumn && tab.getColumn() < newTab.getColumn()) ||
(!next && tab.getColumn() < currentColumn && tab.getColumn() > newTab.getColumn())))))
newTab = tab;
}
if (newTab == null)
for (ItemGroup tab : visibleTabs) {
if ((tab.getRow().compareTo(currentRow)) != 0 && ((next && newTab == null || next && newTab.getColumn() > tab.getColumn()) || (!next && newTab == null) || (!next && newTab.getColumn() < tab.getColumn())))
newTab = tab;
}
if (newTab == null) {
for (ItemGroup tab : visibleTabs) {
if ((next && tab.getRow() == ItemGroup.Row.TOP && tab.getColumn() == 0) ||
!next && tab.getRow() == ItemGroup.Row.BOTTOM && (newTab == null || tab.getColumn() > newTab.getColumn()))
newTab = tab;
}
}
if (newTab == null || newTab.equals(currentTab)) newTab = ItemGroups.getDefaultTab();
inventory.midnightcontrols$setSelectedTab(newTab);
return true; return true;
} else if (client.currentScreen instanceof InventoryScreen inventoryScreen) { } else if (client.currentScreen instanceof InventoryScreen || client.currentScreen instanceof CraftingScreen || client.currentScreen instanceof AbstractFurnaceScreen<?>) {
var recipeBook = (RecipeBookWidgetAccessor) inventoryScreen.getRecipeBookWidget(); RecipeBookWidget recipeBook;
var tabs = recipeBook.getTabButtons(); if (client.currentScreen instanceof InventoryScreen inventoryScreen) recipeBook = inventoryScreen.getRecipeBookWidget();
var currentTab = recipeBook.getCurrentTab(); else if (client.currentScreen instanceof CraftingScreen craftingScreen) recipeBook = craftingScreen.getRecipeBookWidget();
if (currentTab == null) else recipeBook = ((AbstractFurnaceScreen<?>)client.currentScreen).getRecipeBookWidget();
var recipeBookAccessor = (RecipeBookWidgetAccessor) recipeBook;
var tabs = recipeBookAccessor.getTabButtons();
var currentTab = recipeBookAccessor.getCurrentTab();
if (currentTab == null || !recipeBook.isOpen()) {
if (MidnightControlsCompat.isInventoryTabsPresent()) InventoryTabsCompat.handleInventoryTabs(client.currentScreen, next);
return false; return false;
}
int nextTab = tabs.indexOf(currentTab) + (next ? 1 : -1); int nextTab = tabs.indexOf(currentTab) + (next ? 1 : -1);
if (nextTab < 0) if (nextTab < 0)
nextTab = tabs.size() - 1; nextTab = tabs.size() - 1;
else if (nextTab >= tabs.size()) else if (nextTab >= tabs.size())
nextTab = 0; nextTab = 0;
currentTab.setToggled(false); currentTab.setToggled(false);
recipeBook.setCurrentTab(currentTab = tabs.get(nextTab)); recipeBookAccessor.setCurrentTab(currentTab = tabs.get(nextTab));
currentTab.setToggled(true); currentTab.setToggled(true);
recipeBook.midnightcontrols$refreshResults(true); recipeBookAccessor.midnightcontrols$refreshResults(true);
return true; return true;
} else if (client.currentScreen instanceof AdvancementsScreenAccessor screen) { } else if (client.currentScreen instanceof AdvancementsScreenAccessor screen) {
var tabs = screen.getTabs().values().stream().distinct().collect(Collectors.toList()); var tabs = screen.getTabs().values().stream().distinct().toList();
var tab = screen.getSelectedTab(); var tab = screen.getSelectedTab();
if (tab == null) if (tab == null)
return false; return false;
@@ -100,27 +161,68 @@ public class InputHandlers {
nextTab = tabs.size() - 1; nextTab = tabs.size() - 1;
else if (nextTab >= tabs.size()) else if (nextTab >= tabs.size())
nextTab = 0; nextTab = 0;
screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot(), true); screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot().getAdvancementEntry(), true);
break; break;
} }
} }
return true; return true;
} else if (client.currentScreen != null && client.currentScreen.children().stream().anyMatch(e -> e instanceof TabNavigationWidget)) {
return Lists.newCopyOnWriteArrayList(client.currentScreen.children()).stream().anyMatch(e -> {
if (e instanceof TabNavigationWidget tabs) {
TabNavigationWidgetAccessor accessor = (TabNavigationWidgetAccessor) tabs;
int tabIndex = accessor.getTabs().indexOf(accessor.getTabManager().getCurrentTab());
if (next ? tabIndex+1 < accessor.getTabs().size() : tabIndex > 0) {
if (next) tabs.selectTab(tabIndex + 1, true);
else tabs.selectTab(tabIndex - 1, true);
return true;
} }
}
return false;
});
} else {
if (FabricLoader.getInstance().isModLoaded("sodium"))
SodiumCompat.handleTabs(client.currentScreen, next);
if (FabricLoader.getInstance().isModLoaded("yet-another-config-lib") && YACLCompat.handleCategories(client.currentScreen, next))
return true;
}
if (MidnightControlsCompat.isInventoryTabsPresent()) InventoryTabsCompat.handleInventoryTabs(client.currentScreen, next);
return false; return false;
}; };
} }
public static PressAction handlePage(boolean next) { public static PressAction handlePage(boolean next) {
return (client, button, value, action) -> { return (client, button, value, action) -> {
if (action == ButtonState.RELEASE)
return false;
if (client.currentScreen instanceof CreativeInventoryScreen) { if (client.currentScreen instanceof CreativeInventoryScreen) {
var screen = (HandledScreenAccessor) client.currentScreen;
try { try {
if (next) { return client.currentScreen.children().stream().filter(element -> element instanceof PressableWidget)
((CreativeGuiExtensions) screen).fabric_nextPage(); .map(element -> (PressableWidget) element)
} else { .filter(element -> element.getMessage() != null && element.getMessage().getContent() != null)
((CreativeGuiExtensions) screen).fabric_previousPage(); .anyMatch(element -> {
if (next && element.getMessage().getString().equals(">")) {
element.onPress();
return true;
} else if (element.getMessage().getString().equals("<")) {
element.onPress();
return true;
} }
return false;
});
} catch (Exception ignored) {} } catch (Exception ignored) {}
} }
if (MidnightControlsCompat.isInventoryTabsPresent()) InventoryTabsCompat.handleInventoryPage(client.currentScreen, next);
return false;
};
}
public static PressAction handleExit() {
return (client, button, value, action) -> {
if (client.currentScreen != null && client.currentScreen.getClass() != TitleScreen.class) {
if (!MidnightControlsCompat.handleMenuBack(client, client.currentScreen))
if (!MidnightControlsClient.get().input.tryGoBack(client.currentScreen))
client.currentScreen.close();
return true;
}
return false; return false;
}; };
} }
@@ -140,32 +242,35 @@ public class InputHandlers {
int slotId; int slotId;
if (slot == null) { if (slot == null) {
if (client.player.currentScreenHandler.getCursorStack().isEmpty()) if (button.getName().equals("take_all")) {
((MouseAccessor) client.mouse).setLeftButtonClicked(true);
return false; return false;
}
slotId = accessor.midnightcontrols$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 { } else {
slotId = slot.id; slotId = slot.id;
} }
var actionType = SlotActionType.PICKUP; var actionType = SlotActionType.PICKUP;
int clickData = GLFW.GLFW_MOUSE_BUTTON_1; int clickData = GLFW.GLFW_MOUSE_BUTTON_1;
MidnightControlsClient.get().input.inventoryInteractionCooldown = 5; MidnightControlsClient.get().input.inventoryInteractionCooldown = 5;
switch (button.getName()) { switch (button.getName()) {
case "take_all": case "take_all" -> {
if (accessor instanceof CreativeInventoryScreen) if (screen instanceof CreativeInventoryScreen) {
if (((CreativeInventoryScreenAccessor) accessor).midnightcontrols$isCreativeInventorySlot(slot)) if (slot != null && (((CreativeInventoryScreenAccessor) accessor).midnightcontrols$isCreativeInventorySlot(slot) || MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot))))
actionType = SlotActionType.CLONE; actionType = SlotActionType.CLONE;
if (slot != null && MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot))) }
actionType = SlotActionType.CLONE; }
break; case "take" -> {
case "take":
clickData = GLFW_MOUSE_BUTTON_2; clickData = GLFW_MOUSE_BUTTON_2;
break; }
case "quick_move": case "quick_move" -> {
actionType = SlotActionType.QUICK_MOVE; actionType = SlotActionType.QUICK_MOVE;
break; }
default: default -> {
return false; return false;
} }
}
accessor.midnightcontrols$onMouseClick(slot, slotId, clickData, actionType); accessor.midnightcontrols$onMouseClick(slot, slotId, clickData, actionType);
return true; return true;
}; };
@@ -174,8 +279,8 @@ public class InputHandlers {
public static boolean handlePauseGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, float value, @NotNull ButtonState action) { public static boolean handlePauseGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, float value, @NotNull ButtonState action) {
if (action == ButtonState.PRESS) { if (action == ButtonState.PRESS) {
// If in game, then pause the game. // If in game, then pause the game.
if (client.currentScreen == null) if (client.currentScreen == null || client.currentScreen instanceof RingScreen)
client.openPauseMenu(false); client.openGameMenu(false);
else if (client.currentScreen instanceof HandledScreen && client.player != null) // If the current screen is a container then close it. else if (client.currentScreen instanceof HandledScreen && client.player != null) // If the current screen is a container then close it.
client.player.closeHandledScreen(); client.player.closeHandledScreen();
else // Else just close the current screen. else // Else just close the current screen.
@@ -204,9 +309,28 @@ public class InputHandlers {
boolean sneakToggled = client.options.getSneakToggled().getValue(); boolean sneakToggled = client.options.getSneakToggled().getValue();
if (client.player.getAbilities().flying && sneakToggled) if (client.player.getAbilities().flying && sneakToggled)
client.options.getSneakToggled().setValue(false); client.options.getSneakToggled().setValue(false);
else if (MidnightControlsConfig.controllerToggleSneak != sneakToggled)
client.options.getSneakToggled().setValue(!sneakToggled);
binding.setPressed(button.pressed); binding.setPressed(button.pressed);
if (client.player.getAbilities().flying && sneakToggled) if (client.player.getAbilities().flying && sneakToggled)
client.options.getSneakToggled().setValue(true); client.options.getSneakToggled().setValue(true);
else if (MidnightControlsConfig.controllerToggleSneak != sneakToggled)
client.options.getSneakToggled().setValue(sneakToggled);
});
return true;
}
public static boolean handleToggleSprint(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action) {
button.asKeyBinding().ifPresent(binding -> {
boolean sprintToggled = client.options.getSprintToggled().getValue();
if (client.player.getAbilities().flying && sprintToggled)
client.options.getSprintToggled().setValue(false);
else if (MidnightControlsConfig.controllerToggleSneak != sprintToggled)
client.options.getSprintToggled().setValue(!sprintToggled);
binding.setPressed(button.pressed);
if (client.player.getAbilities().flying && sprintToggled)
client.options.getSprintToggled().setValue(true);
else if (MidnightControlsConfig.controllerToggleSneak != sprintToggled)
client.options.getSprintToggled().setValue(sprintToggled);
}); });
return true; return true;
} }
@@ -297,7 +421,7 @@ public class InputHandlers {
* @return true if the client is in game, else false * @return true if the client is in game, else false
*/ */
public static boolean inGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { public static boolean inGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
return client.currentScreen == null; return (client.currentScreen == null && MidnightControlsClient.get().input.screenCloseCooldown <= 0) || client.currentScreen instanceof TouchscreenOverlay || client.currentScreen instanceof RingScreen;
} }
/** /**

View File

@@ -17,6 +17,7 @@ import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.InputUtil; import net.minecraft.client.util.InputUtil;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.aperlambda.lambdacommon.Identifier; import org.aperlambda.lambdacommon.Identifier;
@@ -42,15 +43,19 @@ public class InputManager {
private static final List<ButtonCategory> CATEGORIES = new ArrayList<>(); private static final List<ButtonCategory> CATEGORIES = new ArrayList<>();
public static final Int2ObjectMap<ButtonState> STATES = new Int2ObjectOpenHashMap<>(); public static final Int2ObjectMap<ButtonState> STATES = new Int2ObjectOpenHashMap<>();
public static final Int2FloatMap BUTTON_VALUES = new Int2FloatOpenHashMap(); public static final Int2FloatMap BUTTON_VALUES = new Int2FloatOpenHashMap();
private int prevTargetMouseX = 0; public int prevTargetMouseX = 0;
private int prevTargetMouseY = 0; public int prevTargetMouseY = 0;
private int targetMouseX = 0; public int targetMouseX = 0;
private int targetMouseY = 0; public int targetMouseY = 0;
protected InputManager() { protected InputManager() {
} }
public void tick(@NotNull MinecraftClient client) { public void tick(@NotNull MinecraftClient client) {
if (MidnightControlsConfig.autoSwitchMode && !MidnightControlsConfig.isEditing && MidnightControlsConfig.controlsMode != ControlsMode.TOUCHSCREEN)
if (MidnightControlsConfig.getController().isConnected() && MidnightControlsConfig.getController().isGamepad())
MidnightControlsConfig.controlsMode = ControlsMode.CONTROLLER;
else MidnightControlsConfig.controlsMode = ControlsMode.DEFAULT;
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) { if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) {
this.controllerTick(client); this.controllerTick(client);
} }
@@ -124,6 +129,29 @@ public class InputManager {
public static boolean hasBinding(@NotNull Identifier identifier) { public static boolean hasBinding(@NotNull Identifier identifier) {
return hasBinding(identifier.getNamespace() + "." + identifier.getName()); return hasBinding(identifier.getNamespace() + "." + identifier.getName());
} }
private static ButtonBinding tempBinding;
/**
* Returns the binding matching the given string.
*
* @param name the name of the binding to get
* @return true if the binding is registered, else false
*/
public static ButtonBinding getBinding(@NotNull String name) {
if (BINDINGS.parallelStream().map(ButtonBinding::getName).anyMatch(binding -> binding.equalsIgnoreCase(name)))
BINDINGS.forEach(binding -> {
if (binding.getName().equalsIgnoreCase(name)) InputManager.tempBinding = binding;
});
return tempBinding;
}
private static List<ButtonBinding> unboundBindings;
public static List<ButtonBinding> getUnboundBindings() {
unboundBindings = new ArrayList<>();
BINDINGS.forEach(binding -> {
if (binding.isNotBound() && !MidnightControlsConfig.ignoredUnboundKeys.contains(binding.getTranslationKey())) unboundBindings.add(binding);
});
unboundBindings.sort(Comparator.comparing(s -> I18n.translate(s.getTranslationKey())));
return unboundBindings;
}
/** /**
* Registers a button binding. * Registers a button binding.

View File

@@ -12,8 +12,19 @@ package eu.midnightdust.midnightcontrols.client.controller;
import eu.midnightdust.midnightcontrols.client.ButtonState; import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.input.Input;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.tutorial.MovementTutorialStepHandler;
import net.minecraft.client.util.InputUtil;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.enchantment.SoulSpeedEnchantment;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.scanner.SimpleNbtScanner;
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@@ -30,8 +41,10 @@ public final class MovementHandler implements PressAction {
private boolean pressingBack = false; private boolean pressingBack = false;
private boolean pressingLeft = false; private boolean pressingLeft = false;
private boolean pressingRight = false; private boolean pressingRight = false;
private float slowdownFactor = 1.f;
private float movementForward = 0.f; private float movementForward = 0.f;
private float movementSideways = 0.f; private float movementSideways = 0.f;
private MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil();
private MovementHandler() { private MovementHandler() {
} }
@@ -48,8 +61,11 @@ public final class MovementHandler implements PressAction {
player.input.pressingBack = this.pressingBack; player.input.pressingBack = this.pressingBack;
player.input.pressingLeft = this.pressingLeft; player.input.pressingLeft = this.pressingLeft;
player.input.pressingRight = this.pressingRight; player.input.pressingRight = this.pressingRight;
player.input.movementForward = this.movementForward;
player.input.movementSideways = this.movementSideways; polarUtil.calculate(this.movementSideways, this.movementForward, this.slowdownFactor);
player.input.movementForward = polarUtil.polarY;
player.input.movementSideways = polarUtil.polarX;
this.shouldOverrideMovement = false; this.shouldOverrideMovement = false;
} }
@@ -69,28 +85,26 @@ public final class MovementHandler implements PressAction {
this.shouldOverrideMovement = direction != 0; this.shouldOverrideMovement = direction != 0;
if (MidnightControlsConfig.analogMovement) { if (!MidnightControlsConfig.analogMovement) {
value = (float) Math.pow(value, 2); value = 1.f;
} else value = 1.f; }
this.slowdownFactor = client.player.shouldSlowDown() ? (MathHelper.clamp(
0.3F + EnchantmentHelper.getSwiftSneakSpeedBoost(client.player),
0.0F,
1.0F
)) : 1.f;
if (button == ButtonBinding.FORWARD || button == ButtonBinding.BACK) { if (button == ButtonBinding.FORWARD || button == ButtonBinding.BACK) {
// Handle forward movement. // Handle forward movement.
this.pressingForward = direction > 0; this.pressingForward = direction > 0;
this.pressingBack = direction < 0; this.pressingBack = direction < 0;
this.movementForward = direction * value; this.movementForward = direction * value;
// Slowing down if sneaking.
if (client.player.input.sneaking)
this.movementForward *= 0.3D;
} else { } else {
// Handle sideways movement. // Handle sideways movement.
this.pressingLeft = direction > 0; this.pressingLeft = direction > 0;
this.pressingRight = direction < 0; this.pressingRight = direction < 0;
this.movementSideways = direction * value; this.movementSideways = direction * value;
// Slowing down if sneaking.
if (client.player.input.sneaking)
this.movementSideways *= 0.3D;
} }
return this.shouldOverrideMovement; return this.shouldOverrideMovement;

View File

@@ -14,11 +14,11 @@ import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.HudSide; import eu.midnightdust.midnightcontrols.client.HudSide;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.MidnightInput;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import dev.lambdaurora.spruceui.hud.Hud; import dev.lambdaurora.spruceui.hud.Hud;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
@@ -38,7 +38,7 @@ import org.jetbrains.annotations.Nullable;
*/ */
public class MidnightControlsHud extends Hud { public class MidnightControlsHud extends Hud {
private final MidnightControlsClient mod; private final MidnightControlsClient mod;
private MinecraftClient client; private final MinecraftClient client = MinecraftClient.getInstance();
private int attackWidth = 0; private int attackWidth = 0;
private int attackButtonWidth = 0; private int attackButtonWidth = 0;
private int dropItemWidth = 0; private int dropItemWidth = 0;
@@ -47,12 +47,14 @@ public class MidnightControlsHud extends Hud {
private int inventoryButtonWidth = 0; private int inventoryButtonWidth = 0;
private int swapHandsWidth = 0; private int swapHandsWidth = 0;
private int swapHandsButtonWidth = 0; private int swapHandsButtonWidth = 0;
private boolean showSwapHandsAction = false;
private int useWidth = 0; private int useWidth = 0;
private int useButtonWidth = 0; private int useButtonWidth = 0;
private BlockHitResult placeHitResult; private BlockHitResult placeHitResult;
private String attackAction = ""; private String attackAction = "";
private String placeAction = ""; private String placeAction = "";
private int ticksDisplayedCrosshair = 0; private int ticksDisplayedCrosshair = 0;
private static boolean isCrammed = false;
public MidnightControlsHud(@NotNull MidnightControlsClient mod) { public MidnightControlsHud(@NotNull MidnightControlsClient mod) {
super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator")); super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator"));
@@ -62,7 +64,6 @@ public class MidnightControlsHud extends Hud {
@Override @Override
public void init(@NotNull MinecraftClient client, int screenWidth, int screenHeight) { public void init(@NotNull MinecraftClient client, int screenWidth, int screenHeight) {
super.init(client, screenWidth, screenHeight); super.init(client, screenWidth, screenHeight);
this.client = client;
this.inventoryWidth = this.width(ButtonBinding.INVENTORY); this.inventoryWidth = this.width(ButtonBinding.INVENTORY);
this.inventoryButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.INVENTORY); this.inventoryButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.INVENTORY);
this.swapHandsWidth = this.width(ButtonBinding.SWAP_HANDS); this.swapHandsWidth = this.width(ButtonBinding.SWAP_HANDS);
@@ -73,17 +74,23 @@ public class MidnightControlsHud extends Hud {
this.useButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.USE); this.useButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.USE);
} }
/** /**
* Renders the midnightcontrols' HUD. * Renders the MidnightControls HUD.
*/ */
@Override @Override
public void render(MatrixStack matrices, float tickDelta) { public void render(DrawContext context, float tickDelta) {
if (this.client == null) return;
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && this.client.currentScreen == null) { if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && this.client.currentScreen == null) {
isCrammed = client.getWindow().getScaledWidth() < 520;
int y = bottom(2); int y = bottom(2);
this.renderFirstIcons(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); MatrixStack matrices = context.getMatrices();
this.renderSecondIcons(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); matrices.push();
this.renderFirstSection(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y); this.renderFirstIcons(context, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y);
this.renderSecondSection(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y); this.renderSecondIcons(context, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y);
this.renderFirstSection(context, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y);
this.renderSecondSection(context, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y);
matrices.pop();
} }
if (this.mod.reacharound.isLastReacharoundVertical()) { if (this.mod.reacharound.isLastReacharoundVertical()) {
@@ -95,86 +102,102 @@ public class MidnightControlsHud extends Hud {
scale *= scale; scale *= scale;
int opacity = ((int) (255 * scale)) << 24; int opacity = ((int) (255 * scale)) << 24;
this.client.textRenderer.draw(matrices, text, window.getScaledWidth() / 2.f - this.client.textRenderer.getWidth(text) / 2.f, context.drawText(client.textRenderer, text, (int) (window.getScaledWidth() / 2.f - this.client.textRenderer.getWidth(text) / 2.f),
window.getScaledHeight() / 2.f - 4, 0xCCCCCC | opacity); (int) (window.getScaledHeight() / 2.f - 4), 0xCCCCCC | opacity, false);
} }
} }
public void renderFirstIcons(MatrixStack matrices, int x, int y) { public void renderFirstIcons(DrawContext context, int x, int y) {
int offset = 2 + this.inventoryWidth + this.inventoryButtonWidth + 4; int offset = 2 + this.inventoryWidth + this.inventoryButtonWidth + 4;
int currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.inventoryButtonWidth; int currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.inventoryButtonWidth;
this.drawButton(matrices, currentX, y, ButtonBinding.INVENTORY, true); if (!ButtonBinding.INVENTORY.isNotBound()) this.drawButton(context, currentX, y, ButtonBinding.INVENTORY, true);
this.drawButton(matrices, currentX += (MidnightControlsConfig.hudSide == HudSide.LEFT ? offset : -offset), y, ButtonBinding.SWAP_HANDS, true); if (!ButtonBinding.SWAP_HANDS.isNotBound() && !isCrammed && showSwapHandsAction) this.drawButton(context, currentX += (MidnightControlsConfig.hudSide == HudSide.LEFT ? offset : -offset), y, ButtonBinding.SWAP_HANDS, true);
offset = 2 + this.swapHandsWidth + this.dropItemButtonWidth + 4; offset = 2 + this.swapHandsWidth + this.dropItemButtonWidth + 4;
if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.RIGHT) { if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.RIGHT) {
currentX += -offset; currentX += -offset;
} else { } else {
currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.dropItemButtonWidth; currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.dropItemButtonWidth;
y -= 24; y -= 20;
} }
this.drawButton(matrices, currentX, y, ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty()); if (!ButtonBinding.DROP_ITEM.isNotBound()) this.drawButton(context, currentX, y, ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty());
} }
public void renderSecondIcons(MatrixStack matrices, int x, int y) { public void renderSecondIcons(DrawContext context, int x, int y) {
int offset; int offset;
int currentX = x; int currentX = x;
if (!this.placeAction.isEmpty()) { if (isCrammed && showSwapHandsAction && !this.client.options.getShowSubtitles().getValue() && !ButtonBinding.SWAP_HANDS.isNotBound()) {
if (MidnightControlsConfig.hudSide == HudSide.LEFT) if (MidnightControlsConfig.hudSide == HudSide.LEFT)
currentX -= this.useButtonWidth; currentX -= this.useButtonWidth;
this.drawButton(matrices, currentX, y, ButtonBinding.USE, true); this.drawButton(context, currentX, y, ButtonBinding.SWAP_HANDS, true);
currentX = x;
y -= 20;
}
if (!this.placeAction.isEmpty() && (!ButtonBinding.USE.isNotBound()) ) {
if (MidnightControlsConfig.hudSide == HudSide.LEFT)
currentX -= this.useButtonWidth;
this.drawButton(context, currentX, y, ButtonBinding.USE, true);
offset = 2 + this.useWidth + 4; offset = 2 + this.useWidth + 4;
if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.LEFT) { if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.LEFT) {
currentX -= offset; currentX -= offset;
} else { } else {
currentX = x; currentX = x;
y -= 24; y -= 20;
} }
} }
if (MidnightControlsConfig.hudSide == HudSide.LEFT) if (MidnightControlsConfig.hudSide == HudSide.LEFT)
currentX -= this.attackButtonWidth; currentX -= this.attackButtonWidth;
this.drawButton(matrices, currentX, y, ButtonBinding.ATTACK, this.attackWidth != 0); if (!ButtonBinding.ATTACK.isNotBound()) this.drawButton(context, currentX, y, ButtonBinding.ATTACK, this.attackWidth != 0);
} }
public void renderFirstSection(MatrixStack matrices, int x, int y) { public void renderFirstSection(DrawContext context, int x, int y) {
int currentX = MidnightControlsConfig.hudSide == 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); if (!ButtonBinding.INVENTORY.isNotBound()) this.drawTip(context, currentX, y, ButtonBinding.INVENTORY, true);
currentX += MidnightControlsConfig.hudSide == 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.swapHandsWidth - 2 - this.swapHandsButtonWidth - 4;
this.drawTip(matrices, currentX, y, ButtonBinding.SWAP_HANDS, true); if (!ButtonBinding.SWAP_HANDS.isNotBound() && !isCrammed && showSwapHandsAction) this.drawTip(context, currentX, y, ButtonBinding.SWAP_HANDS, true);
if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.RIGHT) { if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.RIGHT) {
currentX += -this.dropItemWidth - 2 - this.dropItemButtonWidth - 4; currentX += -this.dropItemWidth - 2 - this.dropItemButtonWidth - 4;
} else { } else {
y -= 24; y -= 20;
currentX = MidnightControlsConfig.hudSide == 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()); if (!ButtonBinding.DROP_ITEM.isNotBound()) this.drawTip(context, currentX, y, ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty());
} }
public void renderSecondSection(MatrixStack matrices, int x, int y) { public void renderSecondSection(DrawContext context, int x, int y) {
int currentX = x; int currentX = x;
if (isCrammed && showSwapHandsAction && !this.client.options.getShowSubtitles().getValue() && !ButtonBinding.SWAP_HANDS.isNotBound()) {
currentX += MidnightControlsConfig.hudSide == HudSide.RIGHT ? this.swapHandsButtonWidth + 2 : -this.swapHandsButtonWidth - 2 - this.swapHandsWidth;
this.drawTip(context, currentX, y, ButtonBinding.SWAP_HANDS, true);
currentX = x;
y -= 20;
}
if (!this.placeAction.isEmpty()) { if (!this.placeAction.isEmpty()) {
currentX += MidnightControlsConfig.hudSide == 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); this.drawTip(context, currentX, y, this.placeAction, true);
if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.LEFT) { if (this.client.options.getShowSubtitles().getValue() && MidnightControlsConfig.hudSide == HudSide.LEFT) {
currentX -= 4; currentX -= 4;
} else { } else {
currentX = x; currentX = x;
y -= 24; y -= 20;
} }
} }
currentX += MidnightControlsConfig.hudSide == 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); if (!ButtonBinding.ATTACK.isNotBound()) this.drawTip(context, currentX, y, this.attackAction, this.attackWidth != 0);
} }
@Override @Override
public void tick() { public void tick() {
if (this.client == null) return;
super.tick(); super.tick();
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) { if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) {
if (this.client.crosshairTarget == null) if (this.client.crosshairTarget == null)
@@ -231,6 +254,7 @@ public class MidnightControlsHud extends Hud {
placeAction = customUseAction; placeAction = customUseAction;
this.placeAction = placeAction; this.placeAction = placeAction;
this.showSwapHandsAction = !this.client.player.getMainHandStack().isEmpty() || !this.client.player.getOffHandStack().isEmpty();
// Cache the "Use" tip width. // Cache the "Use" tip width.
if (this.placeAction.isEmpty()) if (this.placeAction.isEmpty())
@@ -246,7 +270,7 @@ public class MidnightControlsHud extends Hud {
} }
private int bottom(int y) { private int bottom(int y) {
return this.client.getWindow().getScaledHeight() - y - MidnightControlsRenderer.ICON_SIZE; return (this.client.getWindow().getScaledHeight() - y - MidnightControlsRenderer.ICON_SIZE);
} }
private int width(@NotNull ButtonBinding binding) { private int width(@NotNull ButtonBinding binding) {
@@ -259,20 +283,20 @@ public class MidnightControlsHud extends Hud {
return this.client.textRenderer.getWidth(I18n.translate(text)); return this.client.textRenderer.getWidth(I18n.translate(text));
} }
private void drawButton(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display) { private void drawButton(DrawContext context, int x, int y, @NotNull ButtonBinding button, boolean display) {
if (display) if (display)
MidnightControlsRenderer.drawButton(matrices, x, y, button, this.client); MidnightControlsRenderer.drawButton(context, x, y, button, this.client);
} }
private void drawTip(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display) { private void drawTip(DrawContext context, int x, int y, @NotNull ButtonBinding button, boolean display) {
this.drawTip(matrices, x, y, button.getTranslationKey(), display); this.drawTip(context, x, y, button.getTranslationKey(), display);
} }
private void drawTip(MatrixStack matrices, int x, int y, @NotNull String action, boolean display) { private void drawTip(DrawContext context, int x, int y, @NotNull String action, boolean display) {
if (!display) if (!display)
return; return;
var translatedAction = I18n.translate(action); var translatedAction = I18n.translate(action);
int textY = (MidnightControlsRenderer.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); context.drawText(this.client.textRenderer, translatedAction, x, (y + textY), 14737632, false);
} }
} }

View File

@@ -10,6 +10,7 @@
package eu.midnightdust.midnightcontrols.client.gui; package eu.midnightdust.midnightcontrols.client.gui;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import eu.midnightdust.midnightcontrols.client.ControllerType;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.MidnightInput; import eu.midnightdust.midnightcontrols.client.MidnightInput;
@@ -18,9 +19,8 @@ import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@@ -75,17 +75,17 @@ public class MidnightControlsRenderer {
return width; return width;
} }
public static ButtonSize drawButton(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) { public static ButtonSize drawButton(DrawContext context, int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) {
return drawButton(matrices, x, y, button.getButton(), client); return drawButton(context, x, y, button.getButton(), client);
} }
public static ButtonSize drawButton(MatrixStack matrices, int x, int y, int[] buttons, @NotNull MinecraftClient client) { public static ButtonSize drawButton(DrawContext context, int x, int y, int[] buttons, @NotNull MinecraftClient client) {
int height = 0; int height = 0;
int length = 0; int length = 0;
int currentX = x; int currentX = x;
for (int i = 0; i < buttons.length; i++) { for (int i = 0; i < buttons.length; i++) {
int btn = buttons[i]; int btn = buttons[i];
int size = drawButton(matrices, currentX, y, btn, client); int size = drawButton(context, currentX, y, btn, client);
if (size > height) if (size > height)
height = size; height = size;
length += size; length += size;
@@ -97,7 +97,7 @@ public class MidnightControlsRenderer {
return new ButtonSize(length, height); return new ButtonSize(length, height);
} }
public static int drawButton(MatrixStack matrices, int x, int y, int button, @NotNull MinecraftClient client) { public static int drawButton(DrawContext context, int x, int y, int button, @NotNull MinecraftClient client) {
boolean second = false; boolean second = false;
if (button == -1) if (button == -1)
return 0; return 0;
@@ -106,7 +106,7 @@ public class MidnightControlsRenderer {
second = true; second = true;
} }
int controllerType = MidnightControlsConfig.controllerType.getId(); int controllerType = MidnightControlsConfig.controllerType == ControllerType.DEFAULT ? MidnightControlsConfig.matchControllerToType().getId() : MidnightControlsConfig.controllerType.getId();
boolean axis = false; boolean axis = false;
int buttonOffset = button * 15; int buttonOffset = button * 15;
switch (button) { switch (button) {
@@ -157,13 +157,13 @@ public class MidnightControlsRenderer {
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200 -> buttonOffset = 10 * 15; case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200 -> buttonOffset = 10 * 15;
} }
RenderSystem.setShaderTexture(0, axis ? MidnightControlsClient.CONTROLLER_AXIS : button >= 15 && button <= 19 ? MidnightControlsClient.CONTROLLER_EXPANDED :MidnightControlsClient.CONTROLLER_BUTTONS);
RenderSystem.disableDepthTest(); RenderSystem.disableDepthTest();
int assetSize = axis || (button >= 15 && button <= 18) ? 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); 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), context.drawTexture(axis ? MidnightControlsClient.CONTROLLER_AXIS : button >= 15 && button <= 19 ? MidnightControlsClient.CONTROLLER_EXPANDED :MidnightControlsClient.CONTROLLER_BUTTONS
, x + (ICON_SIZE / 2 - assetSize / 2), y + (ICON_SIZE / 2 - assetSize / 2),
(float) buttonOffset, (float) (controllerType * assetSize), (float) buttonOffset, (float) (controllerType * assetSize),
assetSize, assetSize, assetSize, assetSize,
256, 256); 256, 256);
@@ -172,18 +172,18 @@ public class MidnightControlsRenderer {
return ICON_SIZE; return ICON_SIZE;
} }
public static int drawButtonTip(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client) { public static int drawButtonTip(DrawContext context, int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client) {
return drawButtonTip(matrices, x, y, button.getButton(), button.getTranslationKey(), display, client); return drawButtonTip(context, x, y, button.getButton(), button.getTranslationKey(), display, client);
} }
public static int drawButtonTip(MatrixStack matrices, int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client) { public static int drawButtonTip(DrawContext context, int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client) {
if (display) { if (display) {
int buttonWidth = drawButton(matrices, x, y, button, client).length(); int buttonWidth = drawButton(context, x, y, button, client).length();
var translatedAction = I18n.translate(action); var translatedAction = I18n.translate(action);
int textY = (MidnightControlsRenderer.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); return context.drawTextWithShadow(client.textRenderer, translatedAction, (x + buttonWidth + 2), (y + textY), 14737632);
} }
return -10; return -10;
@@ -193,7 +193,7 @@ public class MidnightControlsRenderer {
return 15 + 5 + textRenderer.getWidth(action); return 15 + 5 + textRenderer.getWidth(action);
} }
public static void renderVirtualCursor(@NotNull MatrixStack matrices, @NotNull MinecraftClient client) { public static void renderVirtualCursor(@NotNull DrawContext context, @NotNull MinecraftClient client) {
if (!MidnightControlsConfig.virtualMouse || (client.currentScreen == null if (!MidnightControlsConfig.virtualMouse || (client.currentScreen == null
|| MidnightInput.isScreenInteractive(client.currentScreen))) || MidnightInput.isScreenInteractive(client.currentScreen)))
return; return;
@@ -231,27 +231,32 @@ public class MidnightControlsRenderer {
mouseY -= 8; mouseY -= 8;
} }
drawCursor(matrices, mouseX, mouseY, hoverSlot, client); //context.getMatrices().push();
context.getMatrices().translate(0f, 0f, 999f);
drawCursor(context, mouseX, mouseY, hoverSlot, client);
//context.getMatrices().pop();
} }
/** /**
* Draws the virtual cursor. * Draws the virtual cursor.
* *
* @param matrices the matrix stack * @param context the context
* @param x x coordinate * @param x x coordinate
* @param y y coordinate * @param y y coordinate
* @param hoverSlot true if hovering a slot, else false * @param hoverSlot true if hovering a slot, else false
* @param client the client instance * @param client the client instance
*/ */
public static void drawCursor(@NotNull MatrixStack matrices, int x, int y, boolean hoverSlot, @NotNull MinecraftClient client) { public static void drawCursor(@NotNull DrawContext context, int x, int y, boolean hoverSlot, @NotNull MinecraftClient client) {
RenderSystem.disableDepthTest(); //RenderSystem.disableDepthTest();
//RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f); //RenderSystem.disableBlend();
RenderSystem.setShaderTexture(0, MidnightControlsClient.CURSOR_TEXTURE); //RenderSystem.setShaderTexture(0, MidnightControlsClient.CURSOR_TEXTURE);
DrawableHelper.drawTexture(matrices, x, y, context.drawTexture(MidnightControlsClient.CURSOR_TEXTURE, x, y,
hoverSlot ? 16.f : 0.f, MidnightControlsConfig.virtualMouseSkin.ordinal() * 16.f, hoverSlot ? 16.f : 0.f, MidnightControlsConfig.virtualMouseSkin.ordinal() * 16.f,
16, 16, 32, 64); 16, 16, 32, 64);
RenderSystem.enableDepthTest(); context.fill(1, 1, x, y, 0xFFFFFF);
context.draw();
//RenderSystem.enableDepthTest();
} }
public record ButtonSize(int length, int height) { public record ButtonSize(int length, int height) {

View File

@@ -29,6 +29,7 @@ import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget; import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
@@ -38,7 +39,7 @@ import net.minecraft.text.MutableText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.util.math.Matrix4f; import org.joml.Matrix4f;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.awt.*; import java.awt.*;
@@ -55,12 +56,21 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
private final SpruceOption inputModeOption; private final SpruceOption inputModeOption;
private final SpruceOption autoSwitchModeOption; private final SpruceOption autoSwitchModeOption;
private final SpruceOption rotationSpeedOption; private final SpruceOption rotationSpeedOption;
private final SpruceOption yAxisRotationSpeedOption;
private final SpruceOption mouseSpeedOption; private final SpruceOption mouseSpeedOption;
private final SpruceOption joystickAsMouseOption;
private final SpruceOption eyeTrackingAsMouseOption;
private final SpruceOption eyeTrackingDeadzone;
private final SpruceOption virtualMouseOption; private final SpruceOption virtualMouseOption;
private final SpruceOption hideCursorOption;
private final SpruceOption resetOption; private final SpruceOption resetOption;
private final SpruceOption advancedConfigOption;
// Gameplay options // Gameplay options
private final SpruceOption analogMovementOption; private final SpruceOption analogMovementOption;
private final SpruceOption doubleTapToSprintOption;
private final SpruceOption autoJumpOption; private final SpruceOption autoJumpOption;
private final SpruceOption controllerToggleSneakOption;
private final SpruceOption controllerToggleSprintOption;
private final SpruceOption fastBlockPlacingOption; private final SpruceOption fastBlockPlacingOption;
private final SpruceOption frontBlockPlacingOption; private final SpruceOption frontBlockPlacingOption;
private final SpruceOption verticalReacharoundOption; private final SpruceOption verticalReacharoundOption;
@@ -71,6 +81,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
private final SpruceOption virtualMouseSkinOption; private final SpruceOption virtualMouseSkinOption;
private final SpruceOption hudEnableOption; private final SpruceOption hudEnableOption;
private final SpruceOption hudSideOption; private final SpruceOption hudSideOption;
private final SpruceOption moveChatOption;
// Controller options // Controller options
private final SpruceOption controllerOption = private final SpruceOption controllerOption =
new SpruceCyclingOption("midnightcontrols.menu.controller", new SpruceCyclingOption("midnightcontrols.menu.controller",
@@ -110,10 +121,11 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
else else
return option.getDisplayText(Text.literal(controllerName)); return option.getDisplayText(Text.literal(controllerName));
}).orElse(option.getDisplayText(SpruceTexts.OPTIONS_OFF.copyContentOnly().formatted(Formatting.RED))), }).orElse(option.getDisplayText(SpruceTexts.OPTIONS_OFF.copyContentOnly().formatted(Formatting.RED))),
Text.translatable("midnightcontrols.tooltip.controller2")); Text.translatable("midnightcontrols.menu.controller2.tooltip"));
private final SpruceOption unfocusedInputOption; private final SpruceOption unfocusedInputOption;
private final SpruceOption invertsRightXAxis; private final SpruceOption invertsRightXAxis;
private final SpruceOption invertsRightYAxis; private final SpruceOption invertsRightYAxis;
private final SpruceOption toggleControllerProfileOption;
private final SpruceOption rightDeadZoneOption; private final SpruceOption rightDeadZoneOption;
private final SpruceOption leftDeadZoneOption; private final SpruceOption leftDeadZoneOption;
private final SpruceOption[] maxAnalogValueOptions = new SpruceOption[]{ private final SpruceOption[] maxAnalogValueOptions = new SpruceOption[]{
@@ -128,9 +140,15 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
() -> MidnightControlsConfig.getAxisMaxValue(axis), () -> MidnightControlsConfig.getAxisMaxValue(axis),
newValue -> MidnightControlsConfig.setAxisMaxValue(axis, newValue), newValue -> MidnightControlsConfig.setAxisMaxValue(axis, newValue),
option -> option.getDisplayText(Text.literal(String.format("%.2f", option.get()))), option -> option.getDisplayText(Text.literal(String.format("%.2f", option.get()))),
Text.translatable(key.replace("menu", "tooltip")) Text.translatable(key.concat(".tooltip"))
); );
} }
// Touch options
private final SpruceOption touchSpeedOption;
private final SpruceOption touchBreakDelayOption;
private final SpruceOption invertTouchOption;
private final SpruceOption touchTransparencyOption;
private final SpruceOption touchModeOption;
private final MutableText controllerMappingsUrlText = Text.literal("(") private final MutableText controllerMappingsUrlText = Text.literal("(")
.append(Text.literal(GAMEPAD_TOOL_URL).formatted(Formatting.GOLD)) .append(Text.literal(GAMEPAD_TOOL_URL).formatted(Formatting.GOLD))
@@ -152,6 +170,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
public MidnightControlsSettingsScreen(Screen parent, boolean hideControls) { public MidnightControlsSettingsScreen(Screen parent, boolean hideControls) {
super(Text.translatable("midnightcontrols.title.settings")); super(Text.translatable("midnightcontrols.title.settings"));
MidnightControlsConfig.isEditing = true;
this.parent = parent; this.parent = parent;
// General options // General options
this.inputModeOption = new SpruceCyclingOption("midnightcontrols.menu.controls_mode", this.inputModeOption = new SpruceCyclingOption("midnightcontrols.menu.controls_mode",
@@ -160,91 +179,148 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
MidnightControlsConfig.controlsMode = next; MidnightControlsConfig.controlsMode = next;
MidnightControlsConfig.save(); MidnightControlsConfig.save();
if (this.client.player != null) { if (this.client != null && this.client.player != null) {
ClientPlayNetworking.getSender().sendPacket(MidnightControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next)); ClientPlayNetworking.getSender().sendPacket(MidnightControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next));
} }
}, option -> option.getDisplayText(Text.translatable(MidnightControlsConfig.controlsMode.getTranslationKey())), }, option -> option.getDisplayText(Text.translatable(MidnightControlsConfig.controlsMode.getTranslationKey())),
Text.translatable("midnightcontrols.tooltip.controls_mode")); Text.translatable("midnightcontrols.menu.controls_mode.tooltip"));
this.autoSwitchModeOption = new SpruceToggleBooleanOption("midnightcontrols.menu.auto_switch_mode", () -> MidnightControlsConfig.autoSwitchMode, this.autoSwitchModeOption = new SpruceToggleBooleanOption("midnightcontrols.menu.auto_switch_mode", () -> MidnightControlsConfig.autoSwitchMode,
value -> MidnightControlsConfig.autoSwitchMode = value, Text.translatable("midnightcontrols.tooltip.auto_switch_mode")); value -> MidnightControlsConfig.autoSwitchMode = value, Text.translatable("midnightcontrols.menu.auto_switch_mode.tooltip"));
this.rotationSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.rotation_speed", 0.0, 100.0, .5f, this.rotationSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.rotation_speed", 0.0, 100.0, .5f,
() -> MidnightControlsConfig.rotationSpeed, () -> MidnightControlsConfig.rotationSpeed,
value -> MidnightControlsConfig.rotationSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))), value -> MidnightControlsConfig.rotationSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.tooltip.rotation_speed")); Text.translatable("midnightcontrols.menu.rotation_speed.tooltip"));
this.yAxisRotationSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.y_axis_rotation_speed", 0.0, 100.0, .5f,
() -> MidnightControlsConfig.yAxisRotationSpeed,
value -> MidnightControlsConfig.yAxisRotationSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.menu.y_axis_rotation_speed.tooltip"));
this.mouseSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.mouse_speed", 0.0, 150.0, .5f, this.mouseSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.mouse_speed", 0.0, 150.0, .5f,
() -> MidnightControlsConfig.mouseSpeed, () -> MidnightControlsConfig.mouseSpeed,
value -> MidnightControlsConfig.mouseSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))), value -> MidnightControlsConfig.mouseSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.tooltip.mouse_speed")); Text.translatable("midnightcontrols.menu.mouse_speed.tooltip"));
this.joystickAsMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.joystick_as_mouse",
() -> MidnightControlsConfig.joystickAsMouse, value -> MidnightControlsConfig.joystickAsMouse = value,
Text.translatable("midnightcontrols.menu.joystick_as_mouse.tooltip"));
this.eyeTrackingAsMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.eye_tracker_as_mouse",
() -> MidnightControlsConfig.eyeTrackerAsMouse, value -> MidnightControlsConfig.eyeTrackerAsMouse = value,
Text.translatable("midnightcontrols.menu.eye_tracker_as_mouse.tooltip"));
this.eyeTrackingDeadzone = new SpruceDoubleInputOption("midnightcontrols.menu.eye_tracker_deadzone",
() -> MidnightControlsConfig.eyeTrackerDeadzone, value -> MidnightControlsConfig.eyeTrackerDeadzone = value,
Text.translatable("midnightcontrols.menu.eye_tracker_deadzone.tooltip"));
this.resetOption = SpruceSimpleActionOption.reset(btn -> { this.resetOption = SpruceSimpleActionOption.reset(btn -> {
// TODO MidnightControlsConfig.reset();
MidnightControlsConfig.init("midnightcontrols", MidnightControlsConfig.class);
var client = MinecraftClient.getInstance(); var client = MinecraftClient.getInstance();
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
}); });
this.advancedConfigOption = SpruceSimpleActionOption.of("midnightcontrols.midnightconfig.title", button -> client.setScreen(MidnightControlsConfig.getScreen(this, "midnightcontrols")));
// Gameplay options // Gameplay options
this.analogMovementOption = new SpruceToggleBooleanOption("midnightcontrols.menu.analog_movement", this.analogMovementOption = new SpruceToggleBooleanOption("midnightcontrols.menu.analog_movement",
() -> MidnightControlsConfig.analogMovement, value -> MidnightControlsConfig.analogMovement = value, () -> MidnightControlsConfig.analogMovement, value -> MidnightControlsConfig.analogMovement = value,
Text.translatable("midnightcontrols.tooltip.analog_movement")); Text.translatable("midnightcontrols.menu.analog_movement.tooltip"));
this.doubleTapToSprintOption = new SpruceToggleBooleanOption("midnightcontrols.menu.double_tap_to_sprint",
() -> MidnightControlsConfig.doubleTapToSprint, value -> MidnightControlsConfig.doubleTapToSprint = value,
Text.translatable("midnightcontrols.menu.double_tap_to_sprint.tooltip"));
this.autoJumpOption = new SpruceToggleBooleanOption("options.autoJump", this.autoJumpOption = new SpruceToggleBooleanOption("options.autoJump",
() -> this.client.options.getAutoJump().getValue(), () -> this.client.options.getAutoJump().getValue(),
newValue -> this.client.options.getAutoJump().setValue(newValue), newValue -> this.client.options.getAutoJump().setValue(newValue),
null); null);
this.controllerToggleSneakOption = new SpruceToggleBooleanOption("midnightcontrols.menu.controller_toggle_sneak",
() -> MidnightControlsConfig.controllerToggleSneak, value -> MidnightControlsConfig.controllerToggleSneak = value,
null);
this.controllerToggleSprintOption = new SpruceToggleBooleanOption("midnightcontrols.menu.controller_toggle_sprint",
() -> MidnightControlsConfig.controllerToggleSprint, value -> MidnightControlsConfig.controllerToggleSprint = value,
null);
this.fastBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fast_block_placing", () -> MidnightControlsConfig.fastBlockPlacing, this.fastBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fast_block_placing", () -> MidnightControlsConfig.fastBlockPlacing,
value -> MidnightControlsConfig.fastBlockPlacing = value, Text.translatable("midnightcontrols.tooltip.fast_block_placing")); value -> MidnightControlsConfig.fastBlockPlacing = value, Text.translatable("midnightcontrols.menu.fast_block_placing.tooltip"));
this.frontBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.horizontal", () -> MidnightControlsConfig.horizontalReacharound, this.frontBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.horizontal", () -> MidnightControlsConfig.horizontalReacharound,
value -> MidnightControlsConfig.horizontalReacharound = value, Text.translatable("midnightcontrols.tooltip.reacharound.horizontal")); value -> MidnightControlsConfig.horizontalReacharound = value, Text.translatable("midnightcontrols.menu.reacharound.horizontal.tooltip"));
this.verticalReacharoundOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.vertical", () -> MidnightControlsConfig.verticalReacharound, this.verticalReacharoundOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.vertical", () -> MidnightControlsConfig.verticalReacharound,
value -> MidnightControlsConfig.verticalReacharound = value, Text.translatable("midnightcontrols.tooltip.reacharound.vertical")); value -> MidnightControlsConfig.verticalReacharound = value, Text.translatable("midnightcontrols.menu.reacharound.vertical.tooltip"));
this.flyDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting", () -> MidnightControlsConfig.flyDrifting, this.flyDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting", () -> MidnightControlsConfig.flyDrifting,
value -> MidnightControlsConfig.flyDrifting = value, Text.translatable("midnightcontrols.tooltip.fly_drifting")); value -> MidnightControlsConfig.flyDrifting = value, Text.translatable("midnightcontrols.menu.fly_drifting.tooltip"));
this.flyVerticalDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting_vertical", () -> MidnightControlsConfig.verticalFlyDrifting, this.flyVerticalDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting_vertical", () -> MidnightControlsConfig.verticalFlyDrifting,
value -> MidnightControlsConfig.verticalFlyDrifting = value, Text.translatable("midnightcontrols.tooltip.fly_drifting_vertical")); value -> MidnightControlsConfig.verticalFlyDrifting = value, Text.translatable("midnightcontrols.menu.fly_drifting_vertical.tooltip"));
// Appearance options // Appearance options
this.controllerTypeOption = new SpruceCyclingOption("midnightcontrols.menu.controller_type", this.controllerTypeOption = new SpruceCyclingOption("midnightcontrols.menu.controller_type",
amount -> MidnightControlsConfig.controllerType = MidnightControlsConfig.controllerType.next(), amount -> MidnightControlsConfig.controllerType = MidnightControlsConfig.controllerType.next(),
option -> option.getDisplayText(MidnightControlsConfig.controllerType.getTranslatedText()), option -> option.getDisplayText(MidnightControlsConfig.controllerType.getTranslatedText()),
Text.translatable("midnightcontrols.tooltip.controller_type")); Text.translatable("midnightcontrols.menu.controller_type.tooltip"));
this.virtualMouseSkinOption = new SpruceCyclingOption("midnightcontrols.menu.virtual_mouse.skin", this.virtualMouseSkinOption = new SpruceCyclingOption("midnightcontrols.menu.virtual_mouse.skin",
amount -> MidnightControlsConfig.virtualMouseSkin = MidnightControlsConfig.virtualMouseSkin.next(), amount -> MidnightControlsConfig.virtualMouseSkin = MidnightControlsConfig.virtualMouseSkin.next(),
option -> option.getDisplayText(MidnightControlsConfig.virtualMouseSkin.getTranslatedText()), option -> option.getDisplayText(MidnightControlsConfig.virtualMouseSkin.getTranslatedText()),
null); null);
this.hudEnableOption = new SpruceToggleBooleanOption("midnightcontrols.menu.hud_enable", () -> MidnightControlsConfig.hudEnable, this.hudEnableOption = new SpruceToggleBooleanOption("midnightcontrols.menu.hud_enable", () -> MidnightControlsConfig.hudEnable,
this.mod::setHudEnabled, Text.translatable("midnightcontrols.tooltip.hud_enable")); this.mod::setHudEnabled, Text.translatable("midnightcontrols.menu.hud_enable.tooltip"));
this.hudSideOption = new SpruceCyclingOption("midnightcontrols.menu.hud_side", this.hudSideOption = new SpruceCyclingOption("midnightcontrols.menu.hud_side",
amount -> MidnightControlsConfig.hudSide = MidnightControlsConfig.hudSide.next(), amount -> MidnightControlsConfig.hudSide = MidnightControlsConfig.hudSide.next(),
option -> option.getDisplayText(MidnightControlsConfig.hudSide.getTranslatedText()), option -> option.getDisplayText(MidnightControlsConfig.hudSide.getTranslatedText()),
Text.translatable("midnightcontrols.tooltip.hud_side")); Text.translatable("midnightcontrols.menu.hud_side.tooltip"));
this.moveChatOption = new SpruceToggleBooleanOption("midnightcontrols.menu.move_chat", () -> MidnightControlsConfig.moveChat,
value -> MidnightControlsConfig.moveChat = value, Text.translatable("midnightcontrols.menu.move_chat.tooltip"));
// Controller options // Controller options
this.toggleControllerProfileOption = new SpruceToggleBooleanOption("midnightcontrols.menu.separate_controller_profile", () -> MidnightControlsConfig.controllerBindingProfiles.containsKey(MidnightControlsConfig.getController().getGuid()), value -> {
if (value) {
MidnightControlsConfig.controllerBindingProfiles.put(MidnightControlsConfig.getController().getGuid(), MidnightControlsConfig.getBindingsForController());
MidnightControlsConfig.updateBindingsForController(MidnightControlsConfig.getController());
} else {
MidnightControlsConfig.controllerBindingProfiles.remove(MidnightControlsConfig.getController().getGuid());
MidnightControlsConfig.updateBindingsForController(MidnightControlsConfig.getController());
}
}, Text.translatable(""));
this.rightDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.right_dead_zone", 0.05, 1.0, .05f, this.rightDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.right_dead_zone", 0.05, 1.0, .05f,
() -> MidnightControlsConfig.rightDeadZone, () -> MidnightControlsConfig.rightDeadZone,
value -> MidnightControlsConfig.rightDeadZone = value, option -> { value -> MidnightControlsConfig.rightDeadZone = value, option -> {
var value = String.valueOf(option.get()); var value = String.valueOf(option.get());
return option.getDisplayText(Text.literal(value.substring(0, Math.min(value.length(), 5)))); return option.getDisplayText(Text.literal(value.substring(0, Math.min(value.length(), 5))));
}, Text.translatable("midnightcontrols.tooltip.right_dead_zone")); }, Text.translatable("midnightcontrols.menu.right_dead_zone.tooltip"));
this.leftDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.left_dead_zone", 0.05, 1.0, .05f, this.leftDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.left_dead_zone", 0.05, 1.0, .05f,
() -> MidnightControlsConfig.leftDeadZone, () -> MidnightControlsConfig.leftDeadZone,
value -> MidnightControlsConfig.leftDeadZone = value, option -> { value -> MidnightControlsConfig.leftDeadZone = value, option -> {
var value = String.valueOf(option.get()); var value = String.valueOf(option.get());
return option.getDisplayText(Text.literal(value.substring(0, Math.min(value.length(), 5)))); return option.getDisplayText(Text.literal(value.substring(0, Math.min(value.length(), 5))));
}, Text.translatable("midnightcontrols.tooltip.left_dead_zone")); }, Text.translatable("midnightcontrols.menu.left_dead_zone.tooltip"));
this.invertsRightXAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_x_axis", () -> MidnightControlsConfig.invertRightXAxis, this.invertsRightXAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_x_axis", () -> MidnightControlsConfig.invertRightXAxis,
value -> MidnightControlsConfig.invertRightXAxis = value, null); value -> MidnightControlsConfig.invertRightXAxis = value, null);
this.invertsRightYAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_y_axis", () -> MidnightControlsConfig.invertRightYAxis, this.invertsRightYAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_y_axis", () -> MidnightControlsConfig.invertRightYAxis,
value -> MidnightControlsConfig.invertRightYAxis = value, null); value -> MidnightControlsConfig.invertRightYAxis = value, null);
this.unfocusedInputOption = new SpruceToggleBooleanOption("midnightcontrols.menu.unfocused_input", () -> MidnightControlsConfig.unfocusedInput, this.unfocusedInputOption = new SpruceToggleBooleanOption("midnightcontrols.menu.unfocused_input", () -> MidnightControlsConfig.unfocusedInput,
value -> MidnightControlsConfig.unfocusedInput = value, Text.translatable("midnightcontrols.tooltip.unfocused_input")); value -> MidnightControlsConfig.unfocusedInput = value, Text.translatable("midnightcontrols.menu.unfocused_input.tooltip"));
this.virtualMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.virtual_mouse", () -> MidnightControlsConfig.virtualMouse, this.virtualMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.virtual_mouse", () -> MidnightControlsConfig.virtualMouse,
value -> MidnightControlsConfig.virtualMouse = value, Text.translatable("midnightcontrols.tooltip.virtual_mouse")); value -> MidnightControlsConfig.virtualMouse = value, Text.translatable("midnightcontrols.menu.virtual_mouse.tooltip"));
this.hideCursorOption = new SpruceToggleBooleanOption("midnightcontrols.menu.hide_cursor", () -> MidnightControlsConfig.hideNormalMouse,
value -> MidnightControlsConfig.hideNormalMouse = value, Text.translatable("midnightcontrols.menu.hide_cursor.tooltip"));
// Touch options
this.touchModeOption = new SpruceCyclingOption("midnightcontrols.menu.touch_mode",
amount -> MidnightControlsConfig.touchMode = MidnightControlsConfig.touchMode.next(),
option -> option.getDisplayText(MidnightControlsConfig.touchMode.getTranslatedText()),
Text.translatable("midnightcontrols.menu.touch_mode.tooltip"));
this.touchSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.touch_speed", 0.0, 150.0, .5f,
() -> MidnightControlsConfig.touchSpeed,
value -> MidnightControlsConfig.touchSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.menu.touch_speed.tooltip"));
this.touchBreakDelayOption = new SpruceDoubleOption("midnightcontrols.menu.touch_break_delay", 50, 500, 1f,
() -> (double) MidnightControlsConfig.touchBreakDelay,
value -> MidnightControlsConfig.touchBreakDelay = value.intValue(), option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.menu.touch_break_delay.tooltip"));
this.touchTransparencyOption = new SpruceDoubleOption("midnightcontrols.menu.touch_transparency", 0, 100, 1f,
() -> (double) MidnightControlsConfig.touchTransparency,
value -> MidnightControlsConfig.touchTransparency = value.intValue(), option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.menu.touch_break_delay.tooltip"));
this.invertTouchOption = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_touch", () -> MidnightControlsConfig.invertTouch,
value -> MidnightControlsConfig.invertTouch = value, Text.translatable("midnightcontrols.menu.invert_touch.tooltip"));
} }
@Override @Override
public void removed() { public void removed() {
MidnightControlsConfig.isEditing = false;
MidnightControlsConfig.save(); MidnightControlsConfig.save();
super.removed(); super.removed();
} }
@Override @Override
public void close() { public void close() {
MidnightControlsConfig.isEditing = false;
MidnightControlsConfig.save(); MidnightControlsConfig.save();
super.close(); super.close();
} }
@@ -260,8 +336,8 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
this.buildTabs(); this.buildTabs();
this.addDrawableChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150)); 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, this.addDrawableChild(ButtonWidget.builder(SpruceTexts.GUI_DONE, btn -> this.client.setScreen(this.parent))
btn -> this.client.setScreen(this.parent))); .dimensions(this.width / 2 - 155 + 160, this.height - 29, 150, 20).build());
} }
public void buildTabs() { public void buildTabs() {
@@ -286,39 +362,53 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
tabs.addSeparatorEntry(Text.translatable("midnightcontrols.menu.separator.controller")); tabs.addSeparatorEntry(Text.translatable("midnightcontrols.menu.separator.controller"));
tabs.addTabEntry(Text.translatable("midnightcontrols.menu.title.controller"), null, tabs.addTabEntry(Text.translatable("midnightcontrols.menu.title.controller"), null,
this::buildControllerTab); this::buildControllerTab);
tabs.addTabEntry(Text.translatable("midnightcontrols.menu.title.touch"), null,
this::buildTouchTab);
tabs.addTabEntry(Text.translatable("midnightcontrols.menu.title.mappings.string"), null, tabs.addTabEntry(Text.translatable("midnightcontrols.menu.title.mappings.string"), null,
this::buildMappingsStringEditorTab); this::buildMappingsStringEditorTab);
} }
public SpruceOptionListWidget buildGeneralTab(int width, int height) { public SpruceOptionListWidget buildGeneralTab(int width, int height) {
var list = new SpruceOptionListWidget(Position.origin(), width, height); var list = new SpruceOptionListWidget(Position.origin(), width, height);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.inputModeOption); list.addSingleOptionEntry(this.inputModeOption);
list.addSingleOptionEntry(this.autoSwitchModeOption); list.addSingleOptionEntry(this.autoSwitchModeOption);
list.addSingleOptionEntry(this.rotationSpeedOption); list.addSingleOptionEntry(this.rotationSpeedOption);
list.addSingleOptionEntry(this.yAxisRotationSpeedOption);
list.addSingleOptionEntry(this.mouseSpeedOption); list.addSingleOptionEntry(this.mouseSpeedOption);
list.addSingleOptionEntry(this.virtualMouseOption); list.addSingleOptionEntry(this.virtualMouseOption);
list.addSingleOptionEntry(this.hideCursorOption);
list.addSingleOptionEntry(this.joystickAsMouseOption);
list.addSingleOptionEntry(this.eyeTrackingAsMouseOption);
list.addSingleOptionEntry(this.advancedConfigOption);
return list; return list;
} }
public SpruceOptionListWidget buildGameplayTab(int width, int height) { public SpruceOptionListWidget buildGameplayTab(int width, int height) {
var list = new SpruceOptionListWidget(Position.origin(), width, height); var list = new SpruceOptionListWidget(Position.origin(), width, height);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.analogMovementOption); list.addSingleOptionEntry(this.analogMovementOption);
list.addSingleOptionEntry(this.fastBlockPlacingOption); list.addSingleOptionEntry(this.doubleTapToSprintOption);
list.addSingleOptionEntry(this.frontBlockPlacingOption); list.addSingleOptionEntry(this.controllerToggleSneakOption);
list.addSingleOptionEntry(this.verticalReacharoundOption); list.addSingleOptionEntry(this.controllerToggleSprintOption);
list.addSingleOptionEntry(this.flyDriftingOption); if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.fastBlockPlacingOption);
list.addSingleOptionEntry(this.flyVerticalDriftingOption); if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.frontBlockPlacingOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.verticalReacharoundOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.flyDriftingOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.flyVerticalDriftingOption);
list.addSingleOptionEntry(this.autoJumpOption); list.addSingleOptionEntry(this.autoJumpOption);
return list; return list;
} }
public SpruceOptionListWidget buildVisualTab(int width, int height) { public SpruceOptionListWidget buildVisualTab(int width, int height) {
var list = new SpruceOptionListWidget(Position.origin(), width, height); var list = new SpruceOptionListWidget(Position.origin(), width, height);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.controllerTypeOption); list.addSingleOptionEntry(this.controllerTypeOption);
list.addSingleOptionEntry(this.virtualMouseSkinOption); list.addSingleOptionEntry(this.virtualMouseSkinOption);
list.addSingleOptionEntry(new SpruceSeparatorOption("midnightcontrols.menu.title.hud", true, null)); list.addSingleOptionEntry(new SpruceSeparatorOption("midnightcontrols.menu.title.hud", true, null));
list.addSingleOptionEntry(this.hudEnableOption); list.addSingleOptionEntry(this.hudEnableOption);
list.addSingleOptionEntry(this.hudSideOption); list.addSingleOptionEntry(this.hudSideOption);
list.addSingleOptionEntry(this.moveChatOption);
return list; return list;
} }
@@ -352,8 +442,10 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
labels.addChild(aboutMappings3); labels.addChild(aboutMappings3);
var list = new SpruceOptionListWidget(Position.origin(), width, listHeight); var list = new SpruceOptionListWidget(Position.origin(), width, listHeight);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.controllerOption); list.addSingleOptionEntry(this.controllerOption);
list.addSingleOptionEntry(this.secondControllerOption); list.addSingleOptionEntry(this.secondControllerOption);
list.addSingleOptionEntry(this.toggleControllerProfileOption);
list.addSingleOptionEntry(this.unfocusedInputOption); list.addSingleOptionEntry(this.unfocusedInputOption);
list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis); list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis);
list.addSingleOptionEntry(this.rightDeadZoneOption); list.addSingleOptionEntry(this.rightDeadZoneOption);
@@ -366,41 +458,55 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
root.addChild(labels); root.addChild(labels);
return root; return root;
} }
public SpruceOptionListWidget buildTouchTab(int width, int height) {
var list = new SpruceOptionListWidget(Position.origin(), width, height);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.touchSpeedOption);
list.addSingleOptionEntry(this.invertTouchOption);
list.addSingleOptionEntry(new SpruceSeparatorOption("midnightcontrols.menu.title.hud", true, null));
list.addSingleOptionEntry(this.touchModeOption);
list.addSingleOptionEntry(this.touchBreakDelayOption);
list.addSingleOptionEntry(this.touchTransparencyOption);
return list;
}
public SpruceContainerWidget buildMappingsStringEditorTab(int width, int height) { public SpruceContainerWidget buildMappingsStringEditorTab(int width, int height) {
return new MappingsStringInputWidget(Position.origin(), width, height); return new MappingsStringInputWidget(Position.origin(), width, height);
} }
@Override @Override
public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void renderTitle(DrawContext context, int mouseX, int mouseY, float delta) {
drawCenteredText(matrices, this.textRenderer, I18n.translate("midnightcontrols.menu.title"), this.width / 2, 8, 16777215); context.drawCenteredTextWithShadow(this.textRenderer, I18n.translate("midnightcontrols.menu.title"), this.width / 2, 8, 16777215);
} }
public static class MidnightControlsBackground implements Background { public static class MidnightControlsBackground implements Background {
@Override private static int transparency = 160;
public void render(MatrixStack matrixStack, SpruceWidget widget, int vOffset, int mouseX, int mouseY, float delta) { public MidnightControlsBackground() {}
fill(matrixStack, widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight(), MidnightColorUtil.hex2Rgb("#000000")); public MidnightControlsBackground(int transparency) {
MidnightControlsBackground.transparency = transparency;
} }
private void fill(MatrixStack matrixStack, int x2, int y2, int x1, int y1, Color color) { @Override
public void render(DrawContext context, SpruceWidget widget, int vOffset, int mouseX, int mouseY, float delta) {
fill(context.getMatrices(), widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight(), MidnightColorUtil.hex2Rgb("#000000"));
}
private static void fill(MatrixStack matrixStack, int x2, int y2, int x1, int y1, Color color) {
matrixStack.push(); matrixStack.push();
Matrix4f matrix = matrixStack.peek().getPositionMatrix(); Matrix4f matrix = matrixStack.peek().getPositionMatrix();
float r = (float)(color.getRed()) / 255.0F; float r = (float)(color.getRed()) / 255.0F;
float g = (float)(color.getGreen()) / 255.0F; float g = (float)(color.getGreen()) / 255.0F;
float b = (float)(color.getBlue()) / 255.0F; float b = (float)(color.getBlue()) / 255.0F;
float t = (float)(160) / 255.0F; float t = (float)(transparency) / 255.0F;
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer(); BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
RenderSystem.disableTexture();
RenderSystem.defaultBlendFunc(); RenderSystem.defaultBlendFunc();
RenderSystem.setShader(GameRenderer::getPositionColorShader); RenderSystem.setShader(GameRenderer::getPositionColorProgram);
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
bufferBuilder.vertex(matrix, (float)x1, (float)y2, 0.0F).color(r, g, b, t).next(); bufferBuilder.vertex(matrix, (float)x1, (float)y2, 0.0F).color(r, g, b, t).next();
bufferBuilder.vertex(matrix, (float)x2, (float)y2, 0.0F).color(r, g, b, t).next(); bufferBuilder.vertex(matrix, (float)x2, (float)y2, 0.0F).color(r, g, b, t).next();
bufferBuilder.vertex(matrix, (float)x2, (float)y1, 0.0F).color(r, g, b, t).next(); bufferBuilder.vertex(matrix, (float)x2, (float)y1, 0.0F).color(r, g, b, t).next();
bufferBuilder.vertex(matrix, (float)x1, (float)y1, 0.0F).color(r, g, b, t).next(); bufferBuilder.vertex(matrix, (float)x1, (float)y1, 0.0F).color(r, g, b, t).next();
BufferRenderer.drawWithShader(bufferBuilder.end()); BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
RenderSystem.enableTexture();
RenderSystem.disableBlend(); RenderSystem.disableBlend();
matrixStack.pop(); matrixStack.pop();
} }

View File

@@ -10,9 +10,11 @@
package eu.midnightdust.midnightcontrols.client.gui; package eu.midnightdust.midnightcontrols.client.gui;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.ring.RingButtonMode;
import eu.midnightdust.midnightcontrols.client.ring.RingPage; import eu.midnightdust.midnightcontrols.client.ring.RingPage;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
/** /**
@@ -30,26 +32,58 @@ public class RingScreen extends Screen {
this.mod = MidnightControlsClient.get(); this.mod = MidnightControlsClient.get();
} }
@Override
protected void init() {
super.init();
if (mod.ring.getMaxPages() > 1) {
this.addDrawableChild(ButtonWidget.builder(Text.of(""), button -> this.mod.ring.cyclePage(false)).dimensions(5, 5, 20, 20).build());
this.addDrawableChild(ButtonWidget.builder(Text.of(""), button -> this.mod.ring.cyclePage(true)).dimensions(width - 25, 5, 20, 20).build());
}
}
@Override @Override
public boolean shouldPause() { public boolean shouldPause() {
return false; return false;
} }
@Override @Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(matrices, mouseX, mouseY, delta); super.render(context, mouseX, mouseY, delta);
RingPage page = this.mod.ring.getCurrentPage(); RingPage page = this.mod.ring.getCurrentPage();
page.render(context, this.textRenderer, this.width, this.height, mouseX, mouseY, delta);
page.render(matrices, this.textRenderer, this.width, this.height, mouseX, mouseY, delta);
} }
@Override
public void close() {
super.close();
assert client != null;
client.currentScreen = null;
RingPage page = this.mod.ring.getCurrentPage();
if (RingPage.selected >= 0 && page.actions[RingPage.selected] != null)
page.actions[RingPage.selected].activate(RingButtonMode.PRESS);
RingPage.selected = -1;
this.removed();
}
// @Override
// public boolean changeFocus(boolean lookForwards) {
// if (lookForwards) {
// if (RingPage.selected < 7) ++RingPage.selected;
// else RingPage.selected = -1;
// }
// else {
// if (RingPage.selected > -1) --RingPage.selected;
// else RingPage.selected = 7;
// }
// return true;
// }
@Override @Override
public boolean mouseReleased(double mouseX, double mouseY, int button) { public boolean mouseReleased(double mouseX, double mouseY, int button) {
/*if (midnightcontrolsClient.BINDING_RING.matchesMouse(button)) { if (mod.ring.getCurrentPage().onClick(width, height, (int) mouseX, (int) mouseY)) {
this.onClose(); this.close();
return true; return true;
}*/ }
return false; return false;
} }
} }

View File

@@ -9,27 +9,45 @@
package eu.midnightdust.midnightcontrols.client.gui; package eu.midnightdust.midnightcontrols.client.gui;
import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget; import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import eu.midnightdust.lib.util.PlatformFunctions;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.HudSide; import eu.midnightdust.midnightcontrols.client.HudSide;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.compat.EmotecraftCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import eu.midnightdust.midnightcontrols.client.touch.gui.ItemUseButtonWidget;
import eu.midnightdust.midnightcontrols.client.touch.gui.SilentTexturedButtonWidget;
import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor;
import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.block.BlockState;
import net.minecraft.client.gui.screen.GameMenuScreen; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.*;
import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.TextIconButtonWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.texture.MissingSprite;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.InputUtil;
import net.minecraft.item.*;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Arm; import net.minecraft.util.*;
import net.minecraft.util.Identifier; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.List;
import java.util.Objects;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X; import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y; import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
@@ -38,264 +56,435 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
*/ */
public class TouchscreenOverlay extends Screen { public class TouchscreenOverlay extends Screen {
public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png"); public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png");
private MidnightControlsClient mod; private final MidnightControlsClient mod;
private SpruceTexturedButtonWidget jumpButton; private SilentTexturedButtonWidget inventoryButton;
private SpruceTexturedButtonWidget flyButton; private SilentTexturedButtonWidget swapHandsButton;
private SpruceTexturedButtonWidget flyUpButton; private SilentTexturedButtonWidget dropButton;
private SpruceTexturedButtonWidget flyDownButton; private ItemUseButtonWidget useButton;
private SilentTexturedButtonWidget jumpButton;
private SilentTexturedButtonWidget flyButton;
private SilentTexturedButtonWidget flyUpButton;
private SilentTexturedButtonWidget flyDownButton;
private SilentTexturedButtonWidget forwardButton;
private SilentTexturedButtonWidget forwardLeftButton;
private SilentTexturedButtonWidget forwardRightButton;
private SilentTexturedButtonWidget leftButton;
private SilentTexturedButtonWidget rightButton;
private SilentTexturedButtonWidget backButton;
private SilentTexturedButtonWidget startSneakButton;
private SilentTexturedButtonWidget endSneakButton;
private int flyButtonEnableTicks = 0; private int flyButtonEnableTicks = 0;
private int forwardButtonTick = 0; private int forwardButtonTick = 0;
private SpruceTexturedButtonWidget forwardLeftButton; public long clickStartTime;
private SpruceTexturedButtonWidget forwardRightButton; public HitResult firstHitResult = null;
private SpruceTexturedButtonWidget startSneakButton; public static TouchscreenOverlay instance;
private SpruceTexturedButtonWidget endSneakButton;
public TouchscreenOverlay(@NotNull MidnightControlsClient mod) public TouchscreenOverlay(@NotNull MidnightControlsClient mod) {
{
super(Text.literal("Touchscreen overlay")); super(Text.literal("Touchscreen overlay"));
this.mod = mod; this.mod = mod;
this.passEvents = true;
} }
// @Override @Override
// public boolean shouldPause() public boolean shouldPause() {
// { return false;
// return false; }
// }
// @Override
// @Override public void renderInGameBackground(DrawContext context) {}
// public boolean keyPressed(int keyCode, int scanCode, int modifiers)
// { private void pauseGame() {
// super.keyPressed(keyCode,scanCode,modifiers); assert this.client != null;
// //return false; this.client.setScreen(new GameMenuScreen(true));
// return true; if (this.client.isIntegratedServerRunning() && !Objects.requireNonNull(this.client.getServer()).isRemote()) {
// } this.client.getSoundManager().pauseAll();
// }
// private void pauseGame(boolean bl) }
// {
// if (this.client == null) /**
// return; * Updates the forward button ticks cooldown.
// boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote(); *
// if (bl2) { * @param state The button state.
// this.client.setScreen(new GameMenuScreen(!bl)); *
// this.client.getSoundManager().pauseAll(); */
// } else { private void updateForwardButtonsState(boolean state) {
// this.client.setScreen(new GameMenuScreen(true)); this.forwardButtonTick = state ? -1 : 20;
// } }
// }
// /**
// /** * Updates the jump buttons.
// * Updates the forward button ticks cooldown. */
// * private void updateJumpButtons() {
// * @param state The button state. assert this.client != null;
// * assert this.client.player != null;
// */ float transparency = MidnightControlsConfig.touchTransparency / 100f;
// private void updateForwardButtonsState(boolean state)
// { if (this.client.player.getAbilities().flying) {
// if (state) boolean oldStateFly = this.flyButton.isVisible();
// this.forwardButtonTick = -1; this.jumpButton.setVisible(false);
// else this.flyButton.setVisible(true);
// this.forwardButtonTick = 20; this.flyUpButton.setVisible(true);
// } this.flyDownButton.setVisible(true);
// this.flyButton.setAlpha(transparency);
// /** this.flyUpButton.setAlpha(transparency);
// * Updates the jump buttons. this.flyDownButton.setAlpha(transparency);
// */ if (oldStateFly != this.flyButton.isVisible()) {
// private void updateJumpButtons() this.flyButtonEnableTicks = 5;
// { this.setJump(false);
// if (this.client == null) } else if (this.flyButtonEnableTicks > 0)
// return; this.flyButtonEnableTicks--;
// if (!this.client.interactionManager.isFlyingLocked()) { } else {
// boolean oldStateFly = this.flyButton.visible; this.jumpButton.setVisible(true);
// this.jumpButton.visible = false; this.flyButton.setVisible(false);
// this.flyButton.visible = true; this.flyUpButton.setVisible(false);
// this.flyUpButton.visible = true; this.flyDownButton.setVisible(false);
// this.flyDownButton.visible = true; this.jumpButton.setAlpha(transparency);
// if (oldStateFly != this.flyButton.visible) { }
// this.flyButtonEnableTicks = 5; }
// this.handleJump(null, false);
// } else if (this.flyButtonEnableTicks > 0) /**
// this.flyButtonEnableTicks--; * Handles the jump button.
// } else { *
// this.jumpButton.visible = true; * @param btn The pressed button.
// this.flyButton.visible = false; */
// this.flyUpButton.visible = false; private void handleJump(SpruceButtonWidget btn) {
// this.flyDownButton.visible = false; assert this.client != null;
// } ((KeyBindingAccessor) this.client.options.jumpKey).midnightcontrols$handlePressState(btn.isActive());
// } }
// /**
// /** * Handles the jump button.
// * Handles the jump button. *
// * * @param state The state.
// * @param btn The pressed button. */
// * @param state The state of the jump button. private void setJump(boolean state) {
// */ assert this.client != null;
// private void handleJump(ButtonWidget btn, boolean state) ((KeyBindingAccessor) this.client.options.jumpKey).midnightcontrols$handlePressState(state);
// { }
// ((KeyBindingAccessor) this.client.options.keyJump).midnightcontrols$handlePressState(state);
// } @Override
// protected void init() {
// @Override super.init();
// public void tick() assert this.client != null;
// { assert this.client.player != null;
// if (this.forwardButtonTick > 0) { assert this.client.interactionManager != null;
// this.forwardButtonTick--; int scaledWidth = this.client.getWindow().getScaledWidth();
// } else if (this.forwardButtonTick == 0) { int scaledHeight = this.client.getWindow().getScaledHeight();
// if (this.forwardLeftButton.visible) int emoteOffset = 0;
// this.forwardLeftButton.visible = false; if (PlatformFunctions.isModLoaded("emotecraft")) {
// if (this.forwardRightButton.visible) emoteOffset = 10;
// this.forwardRightButton.visible = false; TextIconButtonWidget emoteButton = TextIconButtonWidget.builder(Text.empty(), btn -> EmotecraftCompat.openEmotecraftScreen(this), true).width(20).texture(new Identifier(MidnightControlsConstants.NAMESPACE, "touch/emote"), 20, 20).build();
// } emoteButton.setPosition(scaledWidth / 2 - 30, 0);
// this.updateJumpButtons(); this.addDrawableChild(emoteButton);
// } }
//
// @Override TextIconButtonWidget chatButton = TextIconButtonWidget.builder(Text.empty(), btn -> this.client.setScreen(new ChatScreen("")), true).width(20).texture(new Identifier(MidnightControlsConstants.NAMESPACE, "touch/chat"), 20, 20).build();
// protected void init() chatButton.setPosition(scaledWidth / 2 - 20 + emoteOffset, 0);
// { this.addDrawableChild(chatButton);
// super.init(); TextIconButtonWidget pauseButton = TextIconButtonWidget.builder(Text.empty(), btn -> this.pauseGame(), true).width(20).texture(new Identifier(MidnightControlsConstants.NAMESPACE, "touch/pause"), 20, 20).build();
// int scaledWidth = this.client.getWindow().getScaledWidth(); pauseButton.setPosition(scaledWidth / 2 + emoteOffset, 0);
// int scaledHeight = this.client.getWindow().getScaledHeight(); this.addDrawableChild(pauseButton);
// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256, // Inventory buttons.
// btn -> this.client.setScreen(new ChatScreen("")), LiteralText.EMPTY)); int inventoryButtonX = scaledWidth / 2;
// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, int inventoryButtonY = scaledHeight - 16 - 5;
// btn -> this.pauseGame(false))); if (this.client.options.getMainArm().getValue() == Arm.LEFT) {
// // Inventory buttons. inventoryButtonX = inventoryButtonX - 91 - 24;
// int inventoryButtonX = scaledWidth / 2; } else {
// int inventoryButtonY = scaledHeight - 16 - 5; inventoryButtonX = inventoryButtonX + 91 + 4;
// if (this.client.options.mainArm == Arm.LEFT) { }
// inventoryButtonX = inventoryButtonX - 91 - 24; this.addDrawableChild(this.inventoryButton = new SilentTexturedButtonWidget(Position.of(inventoryButtonX, inventoryButtonY), 20, 20, Text.empty(), btn -> {
// } else { if (this.client.interactionManager.hasRidingInventory()) {
// inventoryButtonX = inventoryButtonX + 91 + 4; this.client.player.openRidingInventory();
// } } else {
// this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, this.client.getTutorialManager().onInventoryOpened();
// btn -> { this.client.setScreen(new InventoryScreen(this.client.player));
// if (this.client.interactionManager.hasRidingInventory()) { }
// this.client.player.openRidingInventory(); }, 20, 0, 20, WIDGETS_LOCATION, 256, 256));
// } else { ;
// this.client.getTutorialManager().onInventoryOpened(); int jumpButtonX, swapHandsX, sneakButtonX;
// this.client.openScreen(new InventoryScreen(this.client.player)); int sneakButtonY = scaledHeight - 10 - 40 - 5;
// } if (MidnightControlsConfig.hudSide == HudSide.LEFT) {
// })); jumpButtonX = scaledWidth - 20 - 20;
// int jumpButtonX, swapHandsX, sneakButtonX; swapHandsX = jumpButtonX - 5 - 40;
// int sneakButtonY = scaledHeight - 10 - 40 - 5; sneakButtonX = 10 + 20 + 5;
// if (MidnightControlsConfig.hudSide == HudSide.LEFT) { } else {
// jumpButtonX = scaledWidth - 20 - 20; jumpButtonX = 20;
// swapHandsX = jumpButtonX - 5 - 40; swapHandsX = jumpButtonX + 5 + 40;
// sneakButtonX = 10 + 20 + 5; sneakButtonX = scaledWidth - 10 - 40 - 5;
// } else { }
// jumpButtonX = 20; // Swap items hand.
// swapHandsX = jumpButtonX + 5 + 40; this.addDrawableChild(this.swapHandsButton = new SilentTexturedButtonWidget(Position.of(swapHandsX, sneakButtonY), 20, 20, Text.empty(),
// sneakButtonX = scaledWidth - 10 - 40 - 5; button -> {
// } if (button.isActive()) {
// // Swap items hand. if (!this.client.player.isSpectator()) {
// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY, 20, 20, 0, 160, 20, WIDGETS_LOCATION, Objects.requireNonNull(this.client.getNetworkHandler()).sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN));
// (btn, state) -> { }
// if (state) { }
// if (!this.client.player.isSpectator()) { },0, 160, 20, WIDGETS_LOCATION));
// this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN)); // Drop
// } this.addDrawableChild(this.dropButton = new SilentTexturedButtonWidget(Position.of(swapHandsX, sneakButtonY + 5 + 20), 20, 20, Text.empty(), btn -> {
// } if (btn.isActive() && !client.player.isSpectator() && client.player.dropSelectedItem(false)) {
// })); client.player.swingHand(Hand.MAIN_HAND);
// // Drop }
// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION, }, 20, 160, 20, WIDGETS_LOCATION));
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyDrop).midnightcontrols$handlePressState(state))); // Use
// // Jump keys this.addDrawableChild(this.useButton = new ItemUseButtonWidget(Position.of(width/2-25, height - 70), 50, 17, Text.translatable(MidnightControlsConstants.NAMESPACE+".action.eat"), btn ->
// this.addDrawableChild(this.jumpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 0, 40, 20, WIDGETS_LOCATION, client.interactionManager.interactItem(client.player, client.player.getActiveHand())));
// this::handleJump)); // Jump keys
// this.addDrawableChild(this.flyButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 20, 40, 20, WIDGETS_LOCATION, this.addDrawableChild(this.jumpButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(), this::handleJump, 0, 40, 20, WIDGETS_LOCATION));
// (btn, state) -> { this.addDrawableChild(this.flyButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(),btn -> {
// if (this.flyButtonEnableTicks == 0) this.client..abilities.flying = false; if (this.flyButtonEnableTicks == 0) this.client.player.getAbilities().flying = false;
// })); }, 20, 40, 20, WIDGETS_LOCATION)
// this.addDrawableChild(this.flyUpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION, );
// this::handleJump)); this.addDrawableChild(this.flyUpButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY - 5 - 20), 20, 20,Text.empty(),
// this.addDrawableChild(this.flyDownButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION, this::handleJump, 40, 40, 20, WIDGETS_LOCATION
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(state))); ));
// this.updateJumpButtons(); this.addDrawableChild(this.flyDownButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY + 20 + 5), 20, 20, Text.empty(),
// // Movements keys btn -> ((KeyBindingAccessor) this.client.options.sneakKey).midnightcontrols$handlePressState(btn.isActive()), 60, 40, 20, WIDGETS_LOCATION
// this.addDrawableChild((this.startSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 0, 120, 20, WIDGETS_LOCATION, ));
// (btn, state) -> { this.updateJumpButtons();
// if (state) { // Movements keys
// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(true); this.addDrawableChild((this.startSneakButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY), 20, 20, Text.empty(), btn -> {
// this.startSneakButton.setVisible(false); if (btn.isActive()) {
// this.endSneakButton.setVisible(true); ((KeyBindingAccessor) this.client.options.sneakKey).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) -> { }, 0, 120, 20, WIDGETS_LOCATION))
// if (state) { );
// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(false); this.addDrawableChild((this.endSneakButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY), 20, 20, Text.empty(), btn -> {
// this.endSneakButton.setVisible(false); if (btn.isActive()) {
// this.startSneakButton.setVisible(true); ((KeyBindingAccessor) this.client.options.sneakKey).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, }, 20, 120, 20, WIDGETS_LOCATION)));
// (btn, state) -> { this.addDrawableChild(this.forwardLeftButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> {
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); ((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive());
// ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state); ((KeyBindingAccessor) this.client.options.leftKey).midnightcontrols$handlePressState(btn.isActive());
// this.updateForwardButtonsState(state); this.updateForwardButtonsState(btn.isActive());
// })); }, 80, 80, 20, WIDGETS_LOCATION
// this.forwardLeftButton.setVisible(false); ));
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION, this.addDrawableChild(this.forwardButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> {
// (btn, state) -> { ((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive());
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); this.updateForwardButtonsState(btn.isActive());
// this.updateForwardButtonsState(state); this.forwardLeftButton.setVisible(true);
// this.forwardLeftButton.setVisible(true); this.forwardRightButton.setVisible(true);
// this.forwardRightButton.setVisible(true); }, 0, 80, 20, WIDGETS_LOCATION
// })); ));
// this.addDrawableChild(this.forwardRightButton = new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION, this.addDrawableChild(this.forwardRightButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> {
// (btn, state) -> { ((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive());
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state); ((KeyBindingAccessor) this.client.options.rightKey).midnightcontrols$handlePressState(btn.isActive());
// ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state); this.updateForwardButtonsState(btn.isActive());
// this.updateForwardButtonsState(state); }, 100, 80, 20, WIDGETS_LOCATION
// })); ));
// this.forwardRightButton.setVisible(true);
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY, 20, 20, 20, 80, 20, WIDGETS_LOCATION, this.addDrawableChild(this.rightButton =new SilentTexturedButtonWidget(Position.of(sneakButtonX + 20 + 5, sneakButtonY), 20, 20, Text.empty(),
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state))); btn -> ((KeyBindingAccessor) this.client.options.rightKey).midnightcontrols$handlePressState(btn.isActive()), 20, 80, 20, WIDGETS_LOCATION
// 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(this.backButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY + 20 + 5), 20, 20, Text.empty(),
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY, 20, 20, 60, 80, 20, WIDGETS_LOCATION, btn -> ((KeyBindingAccessor) this.client.options.backKey).midnightcontrols$handlePressState(btn.isActive()), 40, 80, 20, WIDGETS_LOCATION
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state))); ));
// this.addDrawableChild(this.leftButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX - 20 - 5, sneakButtonY), 20, 20, Text.empty(),
// this.children().forEach(button -> { btn -> ((KeyBindingAccessor) this.client.options.leftKey).midnightcontrols$handlePressState(btn.isActive()), 60, 80, 20, WIDGETS_LOCATION
// if (button instanceof SpruceTexturedButtonWidget) { ));
// ((SpruceTexturedButtonWidget) button).setSilent(true); initCustomButtons(true);
// } initCustomButtons(false);
// });
// } this.setButtonProperties(MidnightControlsConfig.touchTransparency / 100f);
// TouchscreenOverlay.instance = this;
// @Override }
// public boolean mouseClicked(double mouseX, double mouseY, int button) private void initCustomButtons(boolean left) {
// { assert client != null;
// if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) { Identifier emptySprite = new Identifier(MidnightControlsConstants.NAMESPACE, "touch/empty");
// int centerX = this.width / 2; List<String> list = left ? MidnightControlsConfig.leftTouchBinds : MidnightControlsConfig.rightTouchBinds;
// if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { Sprite missingSprite = client.getGuiAtlasManager().getSprite(MissingSprite.getMissingSpriteId());
// for (int slot = 0; slot < 9; ++slot) { for (int i = 0; i < list.size(); i++) {
// int slotX = centerX - 90 + slot * 20 + 2; String bindName = list.get(i);
// if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { ButtonBinding binding = InputManager.getBinding(bindName);
// this.client.player.getInventory().selectedSlot = slot; if (binding == null) continue;
// return true; boolean hasTexture = client.getGuiAtlasManager().getSprite(new Identifier(MidnightControlsConstants.NAMESPACE, "binding/"+bindName)) != missingSprite;
// } if (MidnightControlsConfig.debug) System.out.println(left +" "+new Identifier(MidnightControlsConstants.NAMESPACE, "binding/"+bindName)+" "+ hasTexture);
// } var button = TextIconButtonWidget.builder(Text.translatable("binding.getTranslationKey()"), b -> binding.handle(client, 1, ButtonState.PRESS), hasTexture)
// } .texture(hasTexture ? new Identifier(MidnightControlsConstants.NAMESPACE, "binding/"+bindName) : emptySprite, 20, 20).dimension(20, 20).build();
// } button.setPosition(left ? (3+(i*23)) : this.width-(23+(i*23)), 3);
// return super.mouseClicked(mouseX, mouseY, button); button.setAlpha(MidnightControlsConfig.touchTransparency / 100f);
// } this.addDrawableChild(button);
// }
// @Override }
// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) private void setButtonProperties(float transparency) {
// { this.inventoryButton.setAlpha(transparency);
// if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) { this.dropButton.setAlpha(transparency);
// if (deltaY > 0.01) this.swapHandsButton.setAlpha(transparency);
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2); this.jumpButton.setAlpha(transparency);
// else if (deltaY < 0.01) this.flyButton.setAlpha(transparency);
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1); this.flyUpButton.setAlpha(transparency);this.useButton.setAlpha(Math.min(transparency+0.1f, 1.0f));
// this.flyDownButton.setAlpha(transparency);
// if (deltaX > 0.01) this.startSneakButton.setAlpha(transparency);
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2); this.endSneakButton.setAlpha(transparency);
// else if (deltaX < 0.01) this.forwardButton.setAlpha(transparency);
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1); this.forwardLeftButton.setAlpha(Math.max(0.05f, transparency-0.1f));
// } this.forwardRightButton.setAlpha(Math.max(0.05f, transparency-0.1f));
// return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); this.leftButton.setAlpha(transparency);
// } this.rightButton.setAlpha(transparency);
this.backButton.setAlpha(transparency);
this.useButton.setAlpha(Math.min(transparency+0.1f, 1.0f));
this.endSneakButton.setVisible(false);
this.forwardLeftButton.setVisible(false);
this.forwardRightButton.setVisible(false);
}
@Override
public void tick() {
assert this.client != null;
assert this.client.interactionManager != null;
assert this.client.player != null;
if (this.forwardButtonTick > 0) {
--this.forwardButtonTick;
} else {
this.forwardLeftButton.setVisible(false);
this.forwardRightButton.setVisible(false);
}
this.useButton.setVisible(client.player.getMainHandStack() != null && (client.player.getMainHandStack().getUseAction() != UseAction.NONE || client.player.getMainHandStack().getItem() instanceof ArmorItem) && !TouchUtils.hasInWorldUseAction(client.player.getMainHandStack()));
this.updateJumpButtons();
double scaleFactor = client.getWindow().getScaleFactor();
if (clickStartTime > 0 && System.currentTimeMillis() - clickStartTime >= MidnightControlsConfig.touchBreakDelay) this.mouseHeldDown(client.mouse.getX() / scaleFactor, client.mouse.getY() / scaleFactor);
else client.interactionManager.cancelBlockBreaking();
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
int centerX = this.width / 2;
if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null && 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;
}
}
} else {
clickStartTime = System.currentTimeMillis();
boolean bl = super.mouseClicked(mouseX, mouseY, button);
if (!bl) firstHitResult = TouchUtils.getTargettedObject(mouseX, mouseY);
return bl;
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
firstHitResult = null;
if (!super.mouseReleased(mouseX, mouseY, button) && System.currentTimeMillis() - clickStartTime < 200) {
assert client != null;
assert client.player != null;
assert client.world != null;
assert client.interactionManager != null;
clickStartTime = -1;
if (client.player.getMainHandStack() != null && TouchUtils.hasInWorldUseAction(client.player.getMainHandStack())) {
client.interactionManager.stopUsingItem(client.player);
return true;
}
HitResult result = TouchUtils.getTargettedObject(mouseX, mouseY);
if (result == null) return false;
if (result instanceof BlockHitResult blockHit) {
BlockPos blockPos = blockHit.getBlockPos().offset(blockHit.getSide());
BlockState state = client.world.getBlockState(blockPos);
if (client.world.isAir(blockPos) || state.isReplaceable()) {
ItemStack stackInHand = client.player.getMainHandStack();
int previousStackCount = stackInHand.getCount();
var interaction = client.interactionManager.interactBlock(client.player, client.player.getActiveHand(), blockHit);
if (interaction.isAccepted()) {
if (interaction.shouldSwingHand()) {
client.player.swingHand(client.player.preferredHand);
if (!stackInHand.isEmpty() && (stackInHand.getCount() != previousStackCount || client.interactionManager.hasCreativeInventory())) {
client.gameRenderer.firstPersonRenderer.resetEquipProgress(client.player.preferredHand);
}
}
return true;
}
}
}
if (result instanceof EntityHitResult entityHit) {
client.interactionManager.attackEntity(client.player, entityHit.getEntity());
client.player.swingHand(Hand.MAIN_HAND);
}
}
clickStartTime = -1;
return false;
}
public void mouseHeldDown(double mouseX, double mouseY) {
assert client != null;
assert client.player != null;
assert client.interactionManager != null;
if (!isDragging()) {
if (client.player.getMainHandStack() != null && TouchUtils.hasInWorldUseAction(client.player.getMainHandStack())) {
client.interactionManager.interactItem(client.player, client.player.getActiveHand());
return;
}
HitResult result = TouchUtils.getTargettedObject(mouseX, mouseY);
if (result == null || firstHitResult == null) return;
if (result instanceof BlockHitResult blockHit && firstHitResult instanceof BlockHitResult firstBlock && blockHit.getBlockPos().equals(firstBlock.getBlockPos())) {
if (MidnightControlsConfig.debug) System.out.println(blockHit.getBlockPos().toString());
if (client.interactionManager.updateBlockBreakingProgress(blockHit.getBlockPos(), blockHit.getSide())) {
client.particleManager.addBlockBreakingParticles(blockHit.getBlockPos(), blockHit.getSide());
client.player.swingHand(Hand.MAIN_HAND);
} else client.interactionManager.cancelBlockBreaking();
firstHitResult = TouchUtils.getTargettedObject(mouseX, mouseY);
}
else if (result instanceof EntityHitResult entityHit && firstHitResult instanceof EntityHitResult firstEntity && entityHit.getEntity().getUuid().compareTo(firstEntity.getEntity().getUuid()) == 0) {
if (client.interactionManager.interactEntity(client.player, entityHit.getEntity(), client.player.getActiveHand()) == ActionResult.SUCCESS) {
client.player.swingHand(Hand.MAIN_HAND);
}
firstHitResult = TouchUtils.getTargettedObject(mouseX, mouseY);
}
}
}
@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 (!MidnightControlsConfig.invertTouch) {
deltaX = -deltaX;
deltaY = -deltaY;
}
if (deltaY > 0.01)
this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs((deltaY / 3.0)*MidnightControlsConfig.touchSpeed/100), 2);
else this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs((deltaY / 3.0)*MidnightControlsConfig.touchSpeed/100), 1);
if (deltaX > 0.01)
this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs((deltaX / 3.0)*MidnightControlsConfig.touchSpeed/100), 2);
else this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs((deltaX / 3.0)*MidnightControlsConfig.touchSpeed/100), 1);
HitResult result = TouchUtils.getTargettedObject(mouseX, mouseY);
if (result != null && firstHitResult != null) {
if (result instanceof BlockHitResult blockHit && firstHitResult instanceof BlockHitResult firstBlock && !blockHit.getBlockPos().equals(firstBlock.getBlockPos())) {
firstHitResult = null;
} else if (result instanceof EntityHitResult entityHit && firstHitResult instanceof EntityHitResult firstEntity && entityHit.getEntity().getUuid().compareTo(firstEntity.getEntity().getUuid()) != 0) {
firstHitResult = null;
}
}
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
//client.currentScreen = null;
KeyBinding.onKeyPressed(InputUtil.fromKeyCode(keyCode, scanCode));
super.keyPressed(keyCode,scanCode,modifiers);
return true;
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
context.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
context.fill(mouseX-10, mouseY-10, mouseX+10, mouseY+10, 0xFFFFFF);
}
} }

View File

@@ -15,7 +15,7 @@ import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget; import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -45,12 +45,12 @@ public class ControllerButtonWidget extends AbstractSpruceIconButtonWidget {
} }
@Override @Override
protected int renderIcon(MatrixStack matrices, int mouseX, int mouseY, float delta) { protected int renderIcon(DrawContext context, int mouseX, int mouseY, float delta) {
int x = this.getX(); int x = this.getX();
if (this.binding.getButton().length > 1) { if (this.binding.getButton().length > 1) {
x += (this.width / 2 - this.iconWidth / 2) - 4; x += (this.width / 2 - this.iconWidth / 2) - 4;
} }
var size = MidnightControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance()); var size = MidnightControlsRenderer.drawButton(context, x, this.getY(), this.binding, MinecraftClient.getInstance());
this.iconWidth = size.length(); this.iconWidth = size.length();
return size.height(); return size.height();
} }

View File

@@ -17,8 +17,9 @@ import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.aperlambda.lambdacommon.utils.function.Predicates; import org.aperlambda.lambdacommon.utils.function.Predicates;
@@ -49,6 +50,7 @@ public class ControllerControlsWidget extends SpruceContainerWidget {
Text.translatable("midnightcontrols.menu.keyboard_controls"), Text.translatable("midnightcontrols.menu.keyboard_controls"),
btn -> this.client.setScreen(new ControlsOptionsScreen(null, this.client.options)))); btn -> this.client.setScreen(new ControlsOptionsScreen(null, this.client.options))));
this.bindingsListWidget = new ControlsListWidget(Position.of(this, 0, 43), this.width, this.height - 43 - 35, this); this.bindingsListWidget = new ControlsListWidget(Position.of(this, 0, 43), this.width, this.height - 43 - 35, this);
this.bindingsListWidget.setBackground(new MidnightControlsSettingsScreen.MidnightControlsBackground(130));
this.addChild(this.bindingsListWidget); this.addChild(this.bindingsListWidget);
this.addChild(this.resetButton = new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150, 20, this.addChild(this.resetButton = new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150, 20,
SpruceTexts.CONTROLS_RESET_ALL, SpruceTexts.CONTROLS_RESET_ALL,
@@ -56,11 +58,11 @@ public class ControllerControlsWidget extends SpruceContainerWidget {
} }
@Override @Override
public void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
drawCenteredText(matrices, this.client.textRenderer, Text.translatable("midnightcontrols.menu.title.controller_controls"), context.drawCenteredTextWithShadow(this.client.textRenderer, Text.translatable("midnightcontrols.menu.title.controller_controls"),
this.getX() + this.width / 2, this.getY() + 4, 16777215); this.getX() + this.width / 2, this.getY() + 4, 16777215);
this.resetButton.setActive(InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault))); this.resetButton.setActive(InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault)));
super.renderWidget(matrices, mouseX, mouseY, delta); super.renderWidget(context, mouseX, mouseY, delta);
} }
public void finishBindingEdit(int... buttons) { public void finishBindingEdit(int... buttons) {

View File

@@ -25,6 +25,7 @@ import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget; import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@@ -226,14 +227,14 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
/* Rendering */ /* Rendering */
@Override @Override
protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) { protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
boolean focused = gui.focusedBinding == this.binding; boolean focused = gui.focusedBinding == this.binding;
var textRenderer = ControlsListWidget.this.client.textRenderer; var textRenderer = ControlsListWidget.this.client.textRenderer;
int height = this.getHeight(); int height = this.getHeight();
//float textX = (float) (this.getX() + 70 - ControlsListWidget.this.maxTextLength); //float textX = (float) (this.getX() + 70 - ControlsListWidget.this.maxTextLength);
int textY = this.getY() + height / 2; int textY = this.getY() + height / 2;
textRenderer.draw(matrices, this.bindingName, this.getX(), (float) (textY - 9 / 2), 16777215); context.drawText(textRenderer, this.bindingName, this.getX(), (textY - 9 / 2), 16777215, true);
this.resetButton.setVisible(!focused); this.resetButton.setVisible(!focused);
this.unbindButton.setVisible(focused); this.unbindButton.setVisible(focused);
@@ -252,7 +253,7 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
this.editButton.setMessage(text.formatted(Formatting.GOLD)); this.editButton.setMessage(text.formatted(Formatting.GOLD));
} }
this.children.forEach(widget -> widget.render(matrices, mouseX, mouseY, delta)); this.children.forEach(widget -> widget.render(context, mouseX, mouseY, delta));
} }
} }
@@ -289,8 +290,8 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
/* Rendering */ /* Rendering */
@Override @Override
protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) { protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
this.separatorWidget.render(matrices, mouseX, mouseY, delta); this.separatorWidget.render(context, mouseX, mouseY, delta);
} }
@Override @Override

View File

@@ -0,0 +1,35 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ChatScreen.class)
public abstract class ChatScreenMixin extends Screen {
@Shadow protected TextFieldWidget chatField;
protected ChatScreenMixin(Text title) {
super(title);
}
@Inject(at = @At("TAIL"), method = "init")
private void midnightcontrols$moveInputField(CallbackInfo ci) {
if (MidnightControlsConfig.moveChat) chatField.setY(4);
}
@Inject(method = "render", at = @At("HEAD"))
private void midnightcontrols$moveInputFieldBackground(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (MidnightControlsConfig.moveChat) context.getMatrices().translate(0f, -this.height + 16, 0f);
}
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;render(Lnet/minecraft/client/gui/DrawContext;IIF)V", shift = At.Shift.BEFORE))
private void midnightcontrols$dontMoveOtherStuff(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (MidnightControlsConfig.moveChat) context.getMatrices().translate(0f, this.height - 16, 0f);
}
}

View File

@@ -17,4 +17,6 @@ import org.spongepowered.asm.mixin.gen.Accessor;
public interface ClickableWidgetAccessor { public interface ClickableWidgetAccessor {
@Accessor("height") @Accessor("height")
int getHeight(); int getHeight();
@Accessor("focused")
void setFocused(boolean value);
} }

View File

@@ -10,6 +10,7 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.controller.MovementHandler; import eu.midnightdust.midnightcontrols.client.controller.MovementHandler;
@@ -27,6 +28,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/** /**
@@ -36,8 +38,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity { public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity {
private boolean midnightcontrols$driftingPrevented = false; private boolean midnightcontrols$driftingPrevented = false;
public ClientPlayerEntityMixin(ClientWorld world, GameProfile profile, @Nullable PlayerPublicKey publicKey) { public ClientPlayerEntityMixin(ClientWorld world, GameProfile profile) {
super(world, profile, publicKey); super(world, profile);
} }
@Shadow @Shadow
@@ -53,10 +55,13 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
@Shadow @Shadow
protected abstract boolean isCamera(); protected abstract boolean isCamera();
@Shadow protected int ticksLeftToDoubleTapSprint;
@Inject(method = "move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V")) @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) { public void onMove(MovementType type, Vec3d movement, CallbackInfo ci) {
var mod = MidnightControlsClient.get(); if (!MidnightControlsConfig.doubleTapToSprint) ticksLeftToDoubleTapSprint = 0;
if (!MidnightControls.isExtrasLoaded) return;
if (type == MovementType.SELF) { if (type == MovementType.SELF) {
if (this.getAbilities().flying && (!MidnightControlsConfig.flyDrifting || !MidnightControlsConfig.verticalFlyDrifting)) { if (this.getAbilities().flying && (!MidnightControlsConfig.flyDrifting || !MidnightControlsConfig.verticalFlyDrifting)) {
if (!this.hasMovementInput()) { if (!this.hasMovementInput()) {
@@ -79,7 +84,7 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
@Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z")) @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z"))
public void onTickMovement(CallbackInfo ci) { public void onTickMovement(CallbackInfo ci) {
if (this.getAbilities().flying && this.isCamera()) { if (this.getAbilities().flying && this.isCamera()) {
if (MidnightControlsConfig.verticalFlyDrifting) if (MidnightControlsConfig.verticalFlyDrifting || !MidnightControls.isExtrasLoaded)
return; return;
int moving = 0; int moving = 0;
if (this.input.sneaking) { if (this.input.sneaking) {

View File

@@ -13,9 +13,10 @@ import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScree
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
import net.minecraft.client.gui.screen.option.GameOptionsScreen; import net.minecraft.client.gui.screen.option.GameOptionsScreen;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.TextIconButtonWidget;
import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.GameOptions;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@@ -29,13 +30,11 @@ public abstract class ControlsOptionsScreenMixin extends GameOptionsScreen {
public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) { public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) {
super(parent, gameOptions, 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;")) @Inject(method = "init", at = @At(value = "INVOKE", ordinal = 1, 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) { private void addControllerButton(CallbackInfo ci) {
int i = this.width / 2 - 155; TextIconButtonWidget iconWidget = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
int j = i + 160; .dimension(20,20).texture(new Identifier("midnightcontrols", "icon/controller"), 20, 20).build();
int k = this.height / 6 - 12 + 48;; iconWidget.setPosition(this.width / 2 + 158, this.height / 6 - 12);
this.addDrawableChild(new ButtonWidget(j, k, 150, 20, Text.translatable("midnightcontrols.menu.title.controller").append("..."), (button) -> { this.addDrawableChild(iconWidget);
this.client.setScreen(new MidnightControlsSettingsScreen(this, false));
}));
} }
} }

View File

@@ -11,6 +11,7 @@ package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -29,7 +30,9 @@ public interface CreativeInventoryScreenAccessor {
* @return the selected tab index * @return the selected tab index
*/ */
@Accessor("selectedTab") @Accessor("selectedTab")
int getSelectedTab(); static ItemGroup getSelectedTab() {
return ItemGroups.getDefaultTab();
}
/** /**
* Sets the selected tab. * Sets the selected tab.

View File

@@ -1,20 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* 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 net.minecraft.client.gui.widget.EntryListWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(EntryListWidget.class)
public interface EntryListWidgetAccessor {
@Invoker("moveSelection")
void midnightcontrols$moveSelection(EntryListWidget.MoveDirection direction);
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* 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 net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.SimpleOption;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* Represents a mixin to GameOptions.
* <p>
* Sets the default of the Auto-Jump option to false.
*/
@Mixin(GameOptions.class)
public abstract class GameOptionsMixin {
@Shadow public abstract SimpleOption<Boolean> getAutoJump();
@Inject(method = "load", at = @At("HEAD"))
public void onInit(CallbackInfo ci) {
// Set default value of the Auto-Jump option to false.
getAutoJump().setValue(false);
}
}

View File

@@ -9,27 +9,44 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import com.mojang.blaze3d.systems.RenderSystem;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer;
import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(GameRenderer.class) @Mixin(GameRenderer.class)
public class GameRendererMixin { public abstract class GameRendererMixin {
@Shadow @Shadow
@Final @Final
private MinecraftClient client; MinecraftClient client;
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Mouse;getX()D")) @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Mouse;getX()D", shift = At.Shift.BEFORE))
private void onRender(float tickDelta, long startTime, boolean fullRender, CallbackInfo ci) { private void onRender(float tickDelta, long startTime, boolean fullRender, CallbackInfo ci) {
if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER)
MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen); MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen);
} }
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILSOFT)
private void renderVirtualCursor(float tickDelta, long startTime, boolean tick, CallbackInfo ci, boolean bl, MatrixStack matrixStack, DrawContext drawContext) {
MidnightControlsRenderer.renderVirtualCursor(drawContext, client);
drawContext.draw();
}
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z", ordinal = 0), method = "renderWorld")
private void postWorldRender(float tickDelta, long limitTime, MatrixStack matrix, CallbackInfo ci) {
TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix());
TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix());
TouchUtils.lastWorldSpaceMatrix.set(matrix.peek().getPositionMatrix());
}
} }

View File

@@ -12,17 +12,22 @@ package eu.midnightdust.midnightcontrols.client.mixin;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.MidnightInput; import eu.midnightdust.midnightcontrols.client.MidnightInput;
import eu.midnightdust.midnightcontrols.client.compat.EMICompat;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType; import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.gen.Invoker;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -34,7 +39,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
*/ */
@Mixin(HandledScreen.class) @Mixin(HandledScreen.class)
public abstract class HandledScreenMixin implements HandledScreenAccessor { public abstract class HandledScreenMixin implements HandledScreenAccessor {
@Accessor("x") @Accessor("x")
public abstract int getX(); public abstract int getX();
@@ -52,19 +56,26 @@ public abstract class HandledScreenMixin implements HandledScreenAccessor {
public abstract void midnightcontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType); public abstract void midnightcontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType);
@Inject(method = "render", at = @At("RETURN")) @Inject(method = "render", at = @At("RETURN"))
public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { public void onRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) { if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.hudEnable) {
var client = MinecraftClient.getInstance(); var client = MinecraftClient.getInstance();
int x = 2, y = client.getWindow().getScaledHeight() - 2 - MidnightControlsRenderer.ICON_SIZE; int x = 2, y = client.getWindow().getScaledHeight() - 2 - MidnightControlsRenderer.ICON_SIZE;
if (MidnightControlsCompat.isEMIPresent() && EMICompat.isEMIEnabled()) {
x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "midnightcontrols.action.pickup_all", true, client) + 2; x += 42;
x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "midnightcontrols.action.exit", true, client) + 2; }
if (!ButtonBinding.TAKE_ALL.isNotBound()) x = MidnightControlsRenderer.drawButtonTip(context, x, y, ButtonBinding.TAKE_ALL,true, client) + 2;
if (!ButtonBinding.EXIT.isNotBound()) x = MidnightControlsRenderer.drawButtonTip(context, x, y, ButtonBinding.EXIT, true, client) + 2;
if (MidnightControlsCompat.isReiPresent()) { if (MidnightControlsCompat.isReiPresent()) {
x = 2; x = 2;
y -= 24; y -= 24;
} }
x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "midnightcontrols.action.pickup", true, client) + 2; if (MidnightControlsCompat.isEMIPresent() && EMICompat.isEMIEnabled() && EMICompat.isSearchBarCentered()) {
MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, "midnightcontrols.action.quick_move", true, client); x = client.getWindow().getScaledWidth() - 55 - client.textRenderer.getWidth(Text.translatable("midnightcontrols.action.pickup"))
- client.textRenderer.getWidth(Text.translatable("midnightcontrols.action.quick_move"))
- MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.TAKE) - MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.QUICK_MOVE);
}
if (!ButtonBinding.TAKE.isNotBound()) x = MidnightControlsRenderer.drawButtonTip(context, x, y, ButtonBinding.TAKE, true, client);
if (!ButtonBinding.QUICK_MOVE.isNotBound()) MidnightControlsRenderer.drawButtonTip(context, x, y, ButtonBinding.QUICK_MOVE, true, client);
} }
} }
} }

View File

@@ -0,0 +1,24 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.client.util.InputUtil;
import org.spongepowered.asm.mixin.Mixin;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(InputUtil.class)
public abstract class InputUtilMixin {
/**
* @author kabliz
* @reason This method is static, and there is a terrible UX issue if raw input is turned on at the same time as
* eye tracking. Raw input only tracks literal mice and not other devices, leading to the game appearing to be
* unresponsive and the player not understanding why. This overwrite preserves the user's mouse preferences,
* while not interfering with eye tracking, and the two modes can be switched between during a play session.
*/
@Inject(method = "isRawMouseMotionSupported", at = @At("HEAD"), cancellable = true)
private static void setRawMouseMotionSupported(CallbackInfoReturnable<Boolean> cir) {
if (MidnightControlsConfig.eyeTrackerAsMouse) cir.setReturnValue(false);
}
}

View File

@@ -0,0 +1,14 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.client.option.KeyBinding;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Map;
@Mixin(KeyBinding.class)
public interface KeyBindingIDAccessor {
@Accessor @Final
static Map<String, KeyBinding> getKEYS_BY_ID() {return null;};
}

View File

@@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@Mixin(KeyBinding.class) @Mixin(KeyBinding.class)
public class KeyBindingMixin implements KeyBindingAccessor { public abstract class KeyBindingMixin implements KeyBindingAccessor {
@Shadow @Shadow
private int timesPressed; private int timesPressed;
@@ -28,7 +28,7 @@ public class KeyBindingMixin implements KeyBindingAccessor {
if (!this.pressed) if (!this.pressed)
this.pressed = true; this.pressed = true;
++this.timesPressed; ++this.timesPressed;
return oldPressed != this.pressed; return !oldPressed;
} }
@Override @Override

View File

@@ -0,0 +1,18 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import net.minecraft.client.Keyboard;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(Keyboard.class)
public class KeyboardMixin {
@Redirect(method = "onKey", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;"))
private Screen midnightcontrols$ignoreTouchOverlay(MinecraftClient instance) {
if (instance.currentScreen instanceof TouchscreenOverlay) return null;
return instance.currentScreen;
}
}

View File

@@ -9,18 +9,15 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.MidnightControlsFeature; import eu.midnightdust.midnightcontrols.MidnightControlsFeature;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightInput; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.client.render.BufferBuilderStorage;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
@@ -31,7 +28,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.Opcodes; import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@@ -54,10 +51,6 @@ public abstract class MinecraftClientMixin {
@Nullable @Nullable
public ClientPlayerInteractionManager interactionManager; public ClientPlayerInteractionManager interactionManager;
@Shadow
@Nullable
public ClientWorld world;
@Shadow @Shadow
@Final @Final
public GameRenderer gameRenderer; public GameRenderer gameRenderer;
@@ -65,6 +58,8 @@ public abstract class MinecraftClientMixin {
@Shadow @Shadow
private int itemUseCooldown; private int itemUseCooldown;
@Shadow public abstract BufferBuilderStorage getBufferBuilders();
private BlockPos midnightcontrols$lastTargetPos; private BlockPos midnightcontrols$lastTargetPos;
private Vec3d midnightcontrols$lastPos; private Vec3d midnightcontrols$lastPos;
private Direction midnightcontrols$lastTargetSide; private Direction midnightcontrols$lastTargetSide;
@@ -104,24 +99,22 @@ public abstract class MinecraftClientMixin {
this.midnightcontrols$lastTargetSide = side; this.midnightcontrols$lastTargetSide = side;
} }
// Removed front placing sprinting as way too cheaty. // Removed front placing sprinting as way too cheaty.
/*else if (this.player.isSprinting()) { // else if (this.player.isSprinting()) {
hitResult = midnightcontrolsClient.get().reacharound.getLastReacharoundResult(); // hitResult = MidnightControlsClient.get().reacharound.getLastReacharoundResult();
if (hitResult != null) { // if (hitResult != null) {
if (cooldown > 0) // if (cooldown > 0)
this.itemUseCooldown = 0; // this.itemUseCooldown = 0;
} // }
}*/ // }
this.midnightcontrols$lastPos = this.player.getPos(); this.midnightcontrols$lastPos = this.player.getPos();
} }
@Inject(method = "render", at = @At("HEAD")) @Inject(at = @At("TAIL"), method = "setScreen")
private void onRender(boolean fullRender, CallbackInfo ci) { private void setScreen(Screen screen, CallbackInfo info) {
MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this)); if (MidnightControlsConfig.hideNormalMouse){
if (screen != null) GLFW.glfwSetInputMode(MinecraftClient.getInstance().getWindow().getHandle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_HIDDEN);
else GLFW.glfwSetInputMode(MinecraftClient.getInstance().getWindow().getHandle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED);
} }
@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) {
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) @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)
@@ -157,4 +150,10 @@ public abstract class MinecraftClientMixin {
} }
} }
} }
// This is always supposed to be located at before the line 'this.profiler.swap("Keybindings");'
// @Redirect(method = "tick", at = @At(value = "FIELD",target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;", ordinal = 6))
// private Screen midnightcontrols$ignoreTouchOverlay(MinecraftClient instance) {
// if (instance.currentScreen instanceof TouchscreenOverlay) return null;
// return instance.currentScreen;
// }
} }

View File

@@ -15,16 +15,23 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.util.MouseAccessor; import eu.midnightdust.midnightcontrols.client.util.MouseAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.Mouse; import net.minecraft.client.Mouse;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.GlfwUtil;
import net.minecraft.client.util.SmoothUtil;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.gen.Invoker;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import eu.midnightdust.midnightcontrols.client.mouse.EyeTrackerHandler;
import static org.lwjgl.glfw.GLFW.GLFW_CURSOR;
import static org.lwjgl.glfw.GLFW.GLFW_CURSOR_HIDDEN;
/** /**
* Adds extra access to the mouse. * Adds extra access to the mouse.
@@ -35,6 +42,40 @@ public abstract class MouseMixin implements MouseAccessor {
@Final @Final
private MinecraftClient client; private MinecraftClient client;
@Shadow
private double y;
@Shadow
private double cursorDeltaX;
@Shadow
private double cursorDeltaY;
@Shadow
private double x;
@Shadow
private boolean cursorLocked;
@Shadow
private boolean hasResolutionChanged;
@Shadow
private double lastMouseUpdateTime;
@Shadow
@Final
private SmoothUtil cursorXSmoother;
@Shadow
@Final
private SmoothUtil cursorYSmoother;
@Shadow private boolean leftButtonClicked;
@Accessor
public abstract void setLeftButtonClicked(boolean value);
@Invoker("onCursorPos") @Invoker("onCursorPos")
public abstract void midnightcontrols$onCursorPos(long window, double x, double y); public abstract void midnightcontrols$onCursorPos(long window, double x, double y);
@@ -51,7 +92,7 @@ public abstract class MouseMixin implements MouseAccessor {
private void isCursorLocked(CallbackInfoReturnable<Boolean> ci) { private void isCursorLocked(CallbackInfoReturnable<Boolean> ci) {
if (this.client.currentScreen == null) { if (this.client.currentScreen == null) {
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse) { if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse) {
ci.setReturnValue(true); //ci.setReturnValue(true);
ci.cancel(); ci.cancel();
} }
} }
@@ -59,8 +100,42 @@ public abstract class MouseMixin implements MouseAccessor {
@Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true) @Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true)
private void onCursorLocked(CallbackInfo ci) { private void onCursorLocked(CallbackInfo ci) {
if (/*config.getControlsMode() == ControlsMode.TOUCHSCREEN if ((MidnightControlsConfig.eyeTrackerAsMouse && client.isWindowFocused() && !this.cursorLocked)
||*/ (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse)) || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN
|| (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse))
ci.cancel(); ci.cancel();
} }
@Inject(method = "updateMouse", at = @At("HEAD"), cancellable = true)
private void updateMouse(CallbackInfo ci) {
if (MidnightControlsConfig.eyeTrackerAsMouse && cursorLocked && client.isWindowFocused()) {
//Eye Tracking is only for the camera controlling cursor, we need the normal cursor everywhere else.
if (!client.options.smoothCameraEnabled) {
cursorXSmoother.clear();
cursorYSmoother.clear();
}
EyeTrackerHandler.updateMouseWithEyeTracking(x + cursorDeltaX, y + cursorDeltaY, client,
lastMouseUpdateTime, leftButtonClicked, cursorXSmoother, cursorYSmoother);
lastMouseUpdateTime = GlfwUtil.getTime();
cursorDeltaX = 0.0;
cursorDeltaY = 0.0;
ci.cancel();
}
}
@Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true)
private void lockCursor(CallbackInfo ci) {
if (MidnightControlsConfig.eyeTrackerAsMouse && client.isWindowFocused() && !this.cursorLocked) {
if (!MinecraftClient.IS_SYSTEM_MAC) {
KeyBinding.updatePressedStates();
}
//In eye tracking mode, we cannot have the cursor locked to the center.
GLFW.glfwSetInputMode(client.getWindow().getHandle(), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
cursorLocked = true; //The game uses this flag for other gameplay checks
client.setScreen(null);
hasResolutionChanged = true;
ci.cancel();
}
}
} }

View File

@@ -0,0 +1,38 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import dev.lambdaurora.spruceui.Position;
import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.InputHandlers;
import eu.midnightdust.midnightcontrols.client.touch.gui.SilentTexturedButtonWidget;
import net.minecraft.client.MinecraftClient;
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.ingame.HandledScreen;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay.WIDGETS_LOCATION;
@Mixin(Screen.class)
public abstract class ScreenMixin {
@Shadow protected abstract <T extends Element & Drawable & Selectable> T addDrawableChild(T drawableElement);
@Shadow public int width;
@Inject(method = "init(Lnet/minecraft/client/MinecraftClient;II)V", at = @At("TAIL"))
public void midnightcontrols$addCloseButton(MinecraftClient client, int width, int height, CallbackInfo ci) {
if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && (MidnightControlsConfig.closeButtonScreens.stream().anyMatch(s -> this.getClass().getName().startsWith(s) || ((Object)this) instanceof HandledScreen<?>))) {
this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(this.width - 30, 10), 20, 20, Text.empty(), btn ->
InputHandlers.handleExit().press(client, ButtonBinding.BACK, 0f, ButtonState.PRESS), 20, 160, 20, WIDGETS_LOCATION));
}
}
}

View File

@@ -0,0 +1,16 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import com.google.common.collect.ImmutableList;
import net.minecraft.client.gui.tab.Tab;
import net.minecraft.client.gui.tab.TabManager;
import net.minecraft.client.gui.widget.TabNavigationWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(TabNavigationWidget.class)
public interface TabNavigationWidgetAccessor {
@Accessor
TabManager getTabManager();
@Accessor
ImmutableList<Tab> getTabs();
}

View File

@@ -9,8 +9,13 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import eu.midnightdust.midnightcontrols.client.touch.TouchMode;
import eu.midnightdust.midnightcontrols.client.util.RainbowColor;
import net.minecraft.block.ShapeContext; import net.minecraft.block.ShapeContext;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
@@ -20,16 +25,21 @@ import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemUsageContext; import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult; import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.awt.*;
/** /**
* Represents a mixin to WorldRenderer. * Represents a mixin to WorldRenderer.
* <p> * <p>
@@ -49,7 +59,14 @@ public abstract class WorldRendererMixin {
private BufferBuilderStorage bufferBuilders; private BufferBuilderStorage bufferBuilders;
@Shadow @Shadow
private static void drawShapeOutline(MatrixStack matrixStack, VertexConsumer vertexConsumer, VoxelShape voxelShape, double d, double e, double f, float g, float h, float i, float j) { private static void drawCuboidShapeOutline(MatrixStack matrices, VertexConsumer vertexConsumer, VoxelShape shape, double offsetX, double offsetY, double offsetZ, float red, float green, float blue, float alpha) {
}
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"))
private HitResult.Type dontRenderOutline(HitResult instance) {
if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
return HitResult.Type.MISS;
}
return instance.getType();
} }
@Inject( @Inject(
@@ -63,13 +80,38 @@ public abstract class WorldRendererMixin {
) )
private void onOutlineRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, private void onOutlineRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer,
LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) { LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS && TouchscreenOverlay.instance != null) {
this.renderFingerOutline(matrices, camera);
}
this.renderReacharoundOutline(matrices, camera);
}
@Unique
private void renderFingerOutline(MatrixStack matrices, Camera camera) {
if (TouchscreenOverlay.instance.firstHitResult == null || TouchscreenOverlay.instance.firstHitResult.getType() != HitResult.Type.BLOCK)
return;
BlockHitResult result = (BlockHitResult) TouchscreenOverlay.instance.firstHitResult;
var blockPos = result.getBlockPos();
if (this.world.getWorldBorder().contains(blockPos) && this.client.player != null) {
var outlineShape = this.world.getBlockState(blockPos).getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
Color rgb = MidnightColorUtil.hex2Rgb(MidnightControlsConfig.touchOutlineColorHex);
if (MidnightControlsConfig.touchOutlineColorHex.isEmpty()) rgb = RainbowColor.radialRainbow(1,1);
var pos = camera.getPos();
matrices.push();
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape, blockPos.getX() - pos.getX(), blockPos.getY() - pos.getY(), blockPos.getZ() - pos.getZ(),
rgb.getRed() / 255.f, rgb.getGreen() / 255.f, rgb.getBlue() / 255.f, MidnightControlsConfig.touchOutlineColorAlpha / 255.f);
matrices.pop();
}
}
@Unique
private void renderReacharoundOutline(MatrixStack matrices, Camera camera) {
if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !MidnightControlsConfig.shouldRenderReacharoundOutline) if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !MidnightControlsConfig.shouldRenderReacharoundOutline)
return; return;
var result = MidnightControlsClient.get().reacharound.getLastReacharoundResult(); var result = MidnightControlsClient.get().reacharound.getLastReacharoundResult();
if (result == null) if (result == null)
return; return;
var blockPos = result.getBlockPos(); var blockPos = result.getBlockPos();
if (this.world.getWorldBorder().contains(blockPos)) { if (this.world.getWorldBorder().contains(blockPos) && this.client.player != null) {
var stack = this.client.player.getStackInHand(Hand.MAIN_HAND); var stack = this.client.player.getStackInHand(Hand.MAIN_HAND);
if (stack == null || !(stack.getItem() instanceof BlockItem)) if (stack == null || !(stack.getItem() instanceof BlockItem))
return; return;
@@ -86,12 +128,14 @@ public abstract class WorldRendererMixin {
var pos = camera.getPos(); var pos = camera.getPos();
var outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity())); var outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
int[] color = MidnightControlsConfig.reacharoundOutlineColor; Color rgb = MidnightColorUtil.hex2Rgb(MidnightControlsConfig.reacharoundOutlineColorHex);
if (MidnightControlsConfig.reacharoundOutlineColorHex.isEmpty()) rgb = RainbowColor.radialRainbow(1,1);
matrices.push();
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines()); var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
drawShapeOutline(matrices, vertexConsumer, outlineShape, drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape,
(double) blockPos.getX() - pos.getX(), (double) blockPos.getY() - pos.getY(), (double) blockPos.getZ() - pos.getZ(), (double) blockPos.getX() - pos.getX(), (double) blockPos.getY() - pos.getY(), (double) blockPos.getZ() - pos.getZ(),
color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f); rgb.getRed() / 255.f, rgb.getGreen() / 255.f, rgb.getBlue() / 255.f, MidnightControlsConfig.reacharoundOutlineColorAlpha / 255.f);
matrices.pop();
} }
} }
} }

View File

@@ -0,0 +1,76 @@
package eu.midnightdust.midnightcontrols.client.mouse;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.GlfwUtil;
import net.minecraft.client.util.SmoothUtil;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
public class EyeTrackerHandler {
/**
* Based on the updateMouse method in the Mouse.class, this changes the mouse algorithm to suit eye tracking.
* This requires the cursor to not be locked, and the raw input setting to be turned off.
*/
public static void updateMouseWithEyeTracking(double mouseX, double mouseY,
MinecraftClient client,
double lastMouseUpdateTime,
boolean holdingLeftMouseButton,
SmoothUtil smoothX,
SmoothUtil smoothY
) {
// The player wants objects of interest to be moved under the crosshair that is always center of screen.
// Normal mouse controls operate with the delta values from the direction of mouse movement,
// but in eye tracking we want to use the cursor's actual x,y values (their point of gaze), relative to
// the screen center (where the crosshair is). This new eye tracking delta creates a vector that points
// from the crosshair to the gaze point. As the player keeps their eyes on the object of interest, we pull
// that object into the center until the object is underneath the crosshair.
double timestamp = GlfwUtil.getTime();
double deltaTime = timestamp - lastMouseUpdateTime;
// The center of screen is the new (0,0)
double centerX = client.getWindow().getWidth() / 2.0;
double centerY = client.getWindow().getHeight() / 2.0;
double gazeRawX = mouseX - centerX;
double gazeRawY = mouseY - centerY;
//This part follows the original mouse.java somewhat closely, with different constants
double feeling = 2.5;
double sensitivity = client.options.getMouseSensitivity().getValue() * feeling;
double spyglass = sensitivity * sensitivity * sensitivity;
double moveScalar = spyglass * 8.0;
double frameScalar;
if(client.options.getPerspective().isFirstPerson() && client.player.isUsingSpyglass()) {
frameScalar = spyglass;
} else {
frameScalar = moveScalar;
}
if(holdingLeftMouseButton){
frameScalar *= 0.5; //Don't move the camera so much while mining. It's annoying.
}
// The longest vector connects the center to the corner of the screen, so that is our maximum magnitude for
// normalization. We use normalized screen size vector for resolution independent control
double magnitudeMax = Math.sqrt(centerX*centerX + centerY*centerY);
double normalizedX = gazeRawX / magnitudeMax;
double normalizedY = gazeRawY / magnitudeMax;
double moveX = normalizedX * frameScalar;
double moveY = normalizedY * frameScalar;
if (client.options.smoothCameraEnabled) {
moveX = smoothX.smooth(moveX, moveScalar*deltaTime);
moveY = smoothY.smooth(moveY, moveScalar*deltaTime);
}
// The player entity's needs their facing rotated.
double invertY = 1.0;
double moveMagnitude = Math.sqrt(normalizedX*normalizedX + normalizedY*normalizedY);
if (client.options.getInvertYMouse().getValue()) {
invertY = -1.0;
}
if (client.player != null && moveMagnitude > MidnightControlsConfig.eyeTrackerDeadzone) {
client.player.changeLookDirection(moveX, moveY * invertY);
client.getTutorialManager().onUpdateMouse(moveX, moveY);
}
}
}

View File

@@ -10,23 +10,30 @@
package eu.midnightdust.midnightcontrols.client.ring; package eu.midnightdust.midnightcontrols.client.ring;
import com.electronwill.nightconfig.core.Config; import com.electronwill.nightconfig.core.Config;
import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.option.StickyKeyBinding;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
public class KeyBindingRingAction extends RingAction { public class ButtonBindingRingAction extends RingAction {
public static final Factory FACTORY = new Factory(); public static final Factory FACTORY = new Factory();
public final KeyBinding binding; public final ButtonBinding binding;
public KeyBindingRingAction(@NotNull Config config, @NotNull KeyBinding binding) { public ButtonBindingRingAction(@NotNull ButtonBinding binding) {
super(config); super();
this.binding = binding; this.binding = binding;
} }
@@ -37,19 +44,19 @@ public class KeyBindingRingAction extends RingAction {
@Override @Override
public void onAction(@NotNull RingButtonMode mode) { public void onAction(@NotNull RingButtonMode mode) {
KeyBindingAccessor accessor = (KeyBindingAccessor) this.binding; binding.handle(MinecraftClient.getInstance(), 1.0f, ButtonState.PRESS);
switch (mode) { if (binding.asKeyBinding().isPresent()) {
case PRESS, HOLD -> accessor.midnightcontrols$handlePressState(this.activated); binding.asKeyBinding().get().setPressed(true);
case TOGGLE -> { ((KeyBindingAccessor)binding.asKeyBinding().get()).midnightcontrols$press();
accessor.midnightcontrols$handlePressState(!this.binding.isPressed());
this.activated = !this.binding.isPressed();
}
} }
} }
@Override @Override
public void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered) { public void drawIcon(@NotNull DrawContext context, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered) {
drawCenteredText(matrices, textRenderer, Text.translatable(this.getName()), x + 25, y + 25 - textRenderer.fontHeight / 2, 0xffffff); List<OrderedText> lines = textRenderer.wrapLines(Text.translatable(this.getName()), MidnightRing.ELEMENT_SIZE);
for (int i = 0; i < lines.size(); ++i) {
context.drawCenteredTextWithShadow(textRenderer, lines.get(i), x + MidnightRing.ELEMENT_SIZE / 2, y + MidnightRing.ELEMENT_SIZE / 2 - textRenderer.fontHeight / 2 * (lines.size()-1) - textRenderer.fontHeight / 2 + textRenderer.fontHeight * i, 0xffffff);
}
} }
protected static class Factory implements RingAction.Factory { protected static class Factory implements RingAction.Factory {

View File

@@ -1,36 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.util.math.MatrixStack;
import org.jetbrains.annotations.NotNull;
public class DummyRingAction extends RingAction {
public DummyRingAction(@NotNull Config config) {
super(config);
}
@Override
public @NotNull String getName() {
return "dummy";
}
@Override
public void onAction(@NotNull RingButtonMode mode) {
}
@Override
public void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered) {
drawCenteredText(matrices, textRenderer, this.getName(), x + 25, y + 25 - textRenderer.fontHeight / 2, 0xffffff);
}
}

View File

@@ -9,10 +9,12 @@
package eu.midnightdust.midnightcontrols.client.ring; package eu.midnightdust.midnightcontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -28,7 +30,7 @@ import java.util.Map;
* @since 1.4.0 * @since 1.4.0
*/ */
public final class MidnightRing { public final class MidnightRing {
public static final int ELEMENT_SIZE = 50; public static final int ELEMENT_SIZE = 75;
private final Map<String, RingAction.Factory> actionFactories = new Object2ObjectOpenHashMap<>(); private final Map<String, RingAction.Factory> actionFactories = new Object2ObjectOpenHashMap<>();
private final List<RingPage> pages = new ArrayList<>(Collections.singletonList(RingPage.DEFAULT)); private final List<RingPage> pages = new ArrayList<>(Collections.singletonList(RingPage.DEFAULT));
@@ -41,7 +43,7 @@ public final class MidnightRing {
public void registerAction(@NotNull String name, @NotNull RingAction.Factory factory) { public void registerAction(@NotNull String name, @NotNull RingAction.Factory factory) {
if (this.actionFactories.containsKey(name)) { if (this.actionFactories.containsKey(name)) {
this.mod.warn("Tried to register twice a ring action: \"" + name + "\"."); this.mod.warn("Tried to register a ring action twice: \"" + name + "\".");
return; return;
} }
this.actionFactories.put(name, factory); this.actionFactories.put(name, factory);
@@ -50,17 +52,54 @@ public final class MidnightRing {
/** /**
* Loads the ring from configuration. * Loads the ring from configuration.
*/ */
public void load() { public void loadFromConfig() {
// List<Config> configPages = MidnightControlsConfig.ringPages; List<String> configBindings = MidnightControlsConfig.ringBindings;
// if (configPages != null) { if (configBindings != null) {
// this.pages.clear(); this.pages.clear();
// for (var configPage : configPages) { int bindingIndex = 0;
// RingPage.parseRingPage(configPage).ifPresent(this.pages::add); for (int i = 0; i < MathHelper.ceil(configBindings.size() / 8f); ++i) {
// } this.pages.add(new RingPage(i+1 + " / " + MathHelper.ceil(configBindings.size() / 8f)));
// } }
// if (this.pages.isEmpty()) {
// this.pages.add(RingPage.DEFAULT); for (String binding : configBindings) {
// } ButtonBinding buttonBinding = InputManager.getBinding(binding);
if (buttonBinding != null) {
RingPage page = this.pages.get(MathHelper.floor(bindingIndex / 8f));
page.actions[bindingIndex - 8 * (MathHelper.floor(bindingIndex / 8f))] = (new ButtonBindingRingAction(buttonBinding));
++bindingIndex;
}
}
}
if (this.pages.isEmpty()) {
this.pages.add(RingPage.DEFAULT);
}
}
/**
* Loads the ring from all unbound keys.
*/
public void loadFromUnbound() {
List<ButtonBinding> unboundBindings = InputManager.getUnboundBindings();
if (unboundBindings != null) {
this.pages.clear();
int bindingIndex = 0;
for (int i = 0; i < MathHelper.ceil(unboundBindings.size() / 8f); ++i) {
this.pages.add(new RingPage(i+1 + " / " + MathHelper.ceil(unboundBindings.size() / 8f)));
}
for (ButtonBinding buttonBinding : unboundBindings) {
if (buttonBinding != null) {
RingPage page = this.pages.get(MathHelper.floor(bindingIndex / 8f));
page.actions[bindingIndex - 8 * (MathHelper.floor(bindingIndex / 8f))] = (new ButtonBindingRingAction(buttonBinding));
++bindingIndex;
}
}
}
if (this.pages.isEmpty()) {
this.pages.add(RingPage.DEFAULT);
}
}
public int getMaxPages() {
return this.pages.size();
} }
public @NotNull RingPage getCurrentPage() { public @NotNull RingPage getCurrentPage() {
@@ -70,4 +109,13 @@ public final class MidnightRing {
this.currentPage = 0; this.currentPage = 0;
return this.pages.get(this.currentPage); return this.pages.get(this.currentPage);
} }
public void cyclePage(boolean forwards) {
if (forwards) {
if (currentPage < pages.size()-1) ++currentPage;
else currentPage = 0;
} else {
if (currentPage > 0) --currentPage;
else currentPage = pages.size();
}
}
} }

View File

@@ -11,9 +11,8 @@ package eu.midnightdust.midnightcontrols.client.ring;
import com.electronwill.nightconfig.core.Config; import com.electronwill.nightconfig.core.Config;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.aperlambda.lambdacommon.utils.Nameable; import org.aperlambda.lambdacommon.utils.Nameable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -28,12 +27,10 @@ import java.util.function.Supplier;
* @version 1.5.0 * @version 1.5.0
* @since 1.4.0 * @since 1.4.0
*/ */
public abstract class RingAction extends DrawableHelper implements Nameable { public abstract class RingAction implements Nameable {
protected Config config;
protected boolean activated = false; protected boolean activated = false;
public RingAction(@NotNull Config config) { public RingAction() {
this.config = config;
} }
/** /**
@@ -62,12 +59,12 @@ public abstract class RingAction extends DrawableHelper implements Nameable {
public abstract void onAction(@NotNull RingButtonMode mode); public abstract void onAction(@NotNull RingButtonMode mode);
public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered) { public void render(@NotNull DrawContext context, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered, int index) {
fill(matrices, x, y, x + MidnightRing.ELEMENT_SIZE, y + MidnightRing.ELEMENT_SIZE, hovered ? 0xbb777777 : 0xbb000000); context.fill(x, y, x + MidnightRing.ELEMENT_SIZE, y + MidnightRing.ELEMENT_SIZE, hovered || RingPage.selected == index ? 0xbb777777 : 0xbb000000);
drawIcon(matrices, textRenderer, x, y, hovered); drawIcon(context, textRenderer, x, y, hovered);
} }
public abstract void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered); public abstract void drawIcon(@NotNull DrawContext context, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered);
/** /**
* Represents a factory for {@link RingAction}. * Represents a factory for {@link RingAction}.

View File

@@ -9,15 +9,12 @@
package eu.midnightdust.midnightcontrols.client.ring; package eu.midnightdust.midnightcontrols.client.ring;
import com.electronwill.nightconfig.core.Config; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Optional;
/** /**
* Represents a ring page. * Represents a ring page.
* *
@@ -25,11 +22,12 @@ import java.util.Optional;
* @version 1.5.0 * @version 1.5.0
* @since 1.4.0 * @since 1.4.0
*/ */
public class RingPage extends DrawableHelper { public class RingPage {
public static final RingPage DEFAULT = new RingPage("Default"); public static final RingPage DEFAULT = new RingPage("Default");
public final String name; public final String name;
private RingAction[] actions = new RingAction[8]; public static int selected = -1;
public RingAction[] actions = new RingAction[8];
public RingPage(@NotNull String name) { public RingPage(@NotNull String name) {
this.name = name; this.name = name;
@@ -41,14 +39,58 @@ public class RingPage extends DrawableHelper {
/** /**
* Renders the ring page. * Renders the ring page.
* *
* @param matrices the matrices * @param context the context
* @param width the screen width * @param width the screen width
* @param height the screen height * @param height the screen height
* @param mouseX the mouse X-coordinate * @param mouseX the mouse X-coordinate
* @param mouseY the mouse Y-coordinate * @param mouseY the mouse Y-coordinate
* @param tickDelta the tick delta * @param tickDelta the tick delta
*/ */
public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int width, int height, int mouseX, int mouseY, float tickDelta) { public void render(@NotNull DrawContext context, @NotNull TextRenderer textRenderer, int width, int height, int mouseX, int mouseY, float tickDelta) {
int centerX = width / 2;
int centerY = height / 2;
if (MidnightControlsClient.get().ring.getMaxPages() > 1) context.drawCenteredTextWithShadow(textRenderer, name, centerX, 5, 0xffffff);
int offset = MidnightRing.ELEMENT_SIZE + (MidnightRing.ELEMENT_SIZE / 2) + 5;
int y = centerY - offset;
int x = centerX - offset;
for (int i = 0; i < 3; i++) {
var ringAction = this.actions[i];
if (ringAction != null)
ringAction.render(context, textRenderer, x, y, isHovered(x, y, mouseX, mouseY), i);
x += MidnightRing.ELEMENT_SIZE + 5;
}
y += MidnightRing.ELEMENT_SIZE + 5;
x = centerX - offset;
for (int i = 3; i < 5; i++) {
var ringAction = this.actions[i];
if (ringAction != null)
ringAction.render(context, textRenderer, x, y, isHovered(x, y, mouseX, mouseY), i);
x += (MidnightRing.ELEMENT_SIZE + 5) * 2;
}
y += MidnightRing.ELEMENT_SIZE + 5;
x = centerX - offset;
for (int i = 5; i < 8; i++) {
var ringAction = this.actions[i];
if (ringAction != null)
ringAction.render(context, textRenderer, x, y, isHovered(x, y, mouseX, mouseY), i);
x += MidnightRing.ELEMENT_SIZE + 5;
}
}
private static boolean isHovered(int x, int y, int mouseX, int mouseY) {
return mouseX >= x && mouseY >= y && mouseX <= x + MidnightRing.ELEMENT_SIZE && mouseY <= y + MidnightRing.ELEMENT_SIZE && selected < 0;
}
/**
* Renders the ring page.
*
* @param width the screen width
* @param height the screen height
* @param mouseX the mouse X-coordinate
* @param mouseY the mouse Y-coordinate
*/
public boolean onClick(int width, int height, int mouseX, int mouseY) {
int centerX = width / 2; int centerX = width / 2;
int centerY = height / 2; int centerY = height / 2;
@@ -58,48 +100,32 @@ public class RingPage extends DrawableHelper {
int x = centerX - offset; int x = centerX - offset;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
var ringAction = this.actions[i]; var ringAction = this.actions[i];
if (ringAction != null) if (ringAction != null && isHovered(x,y,mouseX,mouseY)) {
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY)); ringAction.activate(RingButtonMode.PRESS);
x += 55; return true;
} }
y += 55; x += MidnightRing.ELEMENT_SIZE + 5;
}
y += MidnightRing.ELEMENT_SIZE + 5;
x = centerX - offset; x = centerX - offset;
for (int i = 3; i < 5; i++) { for (int i = 3; i < 5; i++) {
var ringAction = this.actions[i]; var ringAction = this.actions[i];
if (ringAction != null) if (ringAction != null && isHovered(x,y,mouseX,mouseY)) {
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY)); ringAction.activate(RingButtonMode.PRESS);
x += 55 * 2; return true;
} }
y += 55; x += (MidnightRing.ELEMENT_SIZE + 5) * 2;
}
y += MidnightRing.ELEMENT_SIZE + 5;
x = centerX - offset; x = centerX - offset;
for (int i = 5; i < 8; i++) { for (int i = 5; i < 8; i++) {
var ringAction = this.actions[i]; var ringAction = this.actions[i];
if (ringAction != null) if (ringAction != null && isHovered(x,y,mouseX,mouseY)) {
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY)); ringAction.activate(RingButtonMode.PRESS);
x += 55; return true;
} }
x += MidnightRing.ELEMENT_SIZE + 5;
} }
return false;
private static boolean isHovered(int x, int y, int mouseX, int mouseY) {
return mouseX >= x && mouseY >= y && mouseX <= x + MidnightRing.ELEMENT_SIZE && mouseY <= y + MidnightRing.ELEMENT_SIZE;
}
/**
* Tries to parse a ring page configuration.
*
* @param config the configuration
* @return an optional ring page
*/
public static @NotNull Optional<RingPage> parseRingPage(@NotNull Config config) {
String name = config.get("name");
if (name == null)
return Optional.empty();
var page = new RingPage(name);
List<Config> actionConfigs = config.get("actions");
return Optional.of(page);
} }
} }

View File

@@ -0,0 +1,17 @@
package eu.midnightdust.midnightcontrols.client.touch;
import net.minecraft.text.Text;
import org.jetbrains.annotations.NotNull;
public enum TouchMode {
CROSSHAIR, FINGER_POS;
public Text getTranslatedText() {
return Text.translatable("midnightcontrols.midnightconfig.enum."+this.getClass().getSimpleName()+"."+this.name());
}
public @NotNull TouchMode next() {
var v = values();
if (v.length == this.ordinal() + 1)
return v[0];
return v[this.ordinal() + 1];
}
}

View File

@@ -0,0 +1,66 @@
package eu.midnightdust.midnightcontrols.client.touch;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera;
import net.minecraft.entity.projectile.ProjectileUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.util.UseAction;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL11;
import static eu.midnightdust.midnightcontrols.client.MidnightReacharound.getPlayerRange;
public class TouchUtils {
private static final MinecraftClient client = MinecraftClient.getInstance();
public static final Matrix4f lastWorldSpaceMatrix = new Matrix4f();
public static final Matrix4f lastProjMat = new Matrix4f();
public static final Matrix4f lastModMat = new Matrix4f();
public static HitResult getTargettedObject(double mouseX, double mouseY) {
if (MidnightControlsConfig.touchMode == TouchMode.CROSSHAIR) {
return client.crosshairTarget;
}
Vec3d near = screenSpaceToWorldSpace(mouseX, mouseY, 0);
Vec3d far = screenSpaceToWorldSpace(mouseX, mouseY, 1);
EntityHitResult entityCast = ProjectileUtil.raycast(client.player, near, far, Box.from(client.player.getPos()).expand(getPlayerRange(client)), entity -> (!entity.isSpectator() && entity.isAttackable()), getPlayerRange(client) * getPlayerRange(client));
if (entityCast != null && entityCast.getType() == HitResult.Type.ENTITY) return entityCast;
BlockHitResult result = client.world.raycast(new RaycastContext(near, far, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.ANY, client.player));
if (client.player.getPos().distanceTo(result.getPos()) > getPlayerRange(client)) return null;
return result;
}
/* Taken from https://github.com/0x3C50/Renderer/blob/master/src/main/java/me/x150/renderer/util/RendererUtils.java#L270
* Credits to 0x3C50 */
public static Vec3d screenSpaceToWorldSpace(double x, double y, double d) {
Camera camera = client.getEntityRenderDispatcher().camera;
int displayHeight = client.getWindow().getScaledHeight();
int displayWidth = client.getWindow().getScaledWidth();
int[] viewport = new int[4];
GL11.glGetIntegerv(GL11.GL_VIEWPORT, viewport);
Vector3f target = new Vector3f();
Matrix4f matrixProj = new Matrix4f(lastProjMat);
Matrix4f matrixModel = new Matrix4f(lastModMat);
matrixProj.mul(matrixModel)
.mul(lastWorldSpaceMatrix)
.unproject((float) x / displayWidth * viewport[2],
(float) (displayHeight - y) / displayHeight * viewport[3], (float) d, viewport, target);
return new Vec3d(target.x, target.y, target.z).add(camera.getPos());
}
public static boolean hasInWorldUseAction(ItemStack stack) {
UseAction action = stack.getUseAction();
return action == UseAction.BOW || action == UseAction.BRUSH || action == UseAction.SPEAR;
}
}

View File

@@ -0,0 +1,43 @@
package eu.midnightdust.midnightcontrols.client.touch.gui;
import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.PotionItem;
import net.minecraft.text.Text;
import net.minecraft.util.UseAction;
public class ItemUseButtonWidget extends SpruceButtonWidget {
public ItemUseButtonWidget(Position position, int width, int height, Text message, PressAction action) {
super(position, width, height, message, action);
}
@Override
protected void onRelease(double mouseX, double mouseY) {
assert client.player != null;
assert client.interactionManager != null;
UseAction action = client.player.getMainHandStack().getUseAction();
if (action == UseAction.SPYGLASS || action == UseAction.TOOT_HORN) client.interactionManager.stopUsingItem(client.player);
super.onRelease(mouseX, mouseY);
}
@Override
public void setVisible(boolean visible) {
if (visible && client.player != null && client.player.getMainHandStack() != null) {
UseAction action = client.player.getMainHandStack().getUseAction();
if (action == UseAction.EAT) {
this.setMessage(Text.translatable(MidnightControlsConstants.NAMESPACE+".action.eat"));
} else if (action == UseAction.DRINK) {
this.setMessage(Text.translatable(MidnightControlsConstants.NAMESPACE+".action.drink"));
} else if (client.player.getMainHandStack().getItem() instanceof ArmorItem) {
this.setMessage(Text.translatable(MidnightControlsConstants.NAMESPACE+".action.equip"));
} else if (!action.equals(UseAction.NONE)) {
this.setMessage(Text.translatable(MidnightControlsConstants.NAMESPACE+".action.use"));
}
}
this.setAlpha(MidnightControlsConfig.touchTransparency / 100f);
super.setVisible(visible);
}
}

View File

@@ -0,0 +1,39 @@
package eu.midnightdust.midnightcontrols.client.touch.gui;
import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
public class SilentTexturedButtonWidget extends SpruceTexturedButtonWidget {
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, PressAction action, int u, int v, int hoveredVOffset, Identifier texture) {
super(position, width, height, message, action, u, v, hoveredVOffset, texture);
}
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, boolean showMessage, PressAction action, int u, int v, int hoveredVOffset, Identifier texture) {
super(position, width, height, message, showMessage, action, u, v, hoveredVOffset, texture);
}
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, PressAction action, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight) {
super(position, width, height, message, action, u, v, hoveredVOffset, texture, textureWidth, textureHeight);
}
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, boolean showMessage, PressAction action, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight) {
super(position, width, height, message, showMessage, action, u, v, hoveredVOffset, texture, textureWidth, textureHeight);
}
@Override
public void playDownSound() {}
@Override
protected void onRelease(double mouseX, double mouseY) {
this.setActive(false);
super.onClick(mouseX, mouseY);
super.onRelease(mouseX, mouseY);
this.setActive(true);
}
@Override
public void onClick(double mouseX, double mouseY) {
this.setActive(true);
super.onClick(mouseX, mouseY);
this.setActive(false);
}
}

View File

@@ -0,0 +1,23 @@
package eu.midnightdust.midnightcontrols.client.util;
import net.minecraft.util.math.MathHelper;
public class MathUtil {
public static class PolarUtil {
public float polarX;
public float polarY;
public PolarUtil() {}
public void calculate(float x, float y, float speedFactor) {
calculate(x, y, speedFactor, 0);
}
public void calculate(float x, float y, float speedFactor, double deadZone) {
double inputR = Math.pow(x, 2) + Math.pow(y, 2);
inputR = (Math.abs(speedFactor * MathHelper.clamp(inputR,0.f,1.f)));
inputR = inputR < deadZone ? 0f : (inputR-deadZone) / (1f-deadZone);
double inputTheta = Math.atan2(y, x);
polarX = (float) (inputR *Math.cos(inputTheta));
polarY = (float) (inputR *Math.sin(inputTheta));
}
}
}

View File

@@ -14,4 +14,5 @@ package eu.midnightdust.midnightcontrols.client.util;
*/ */
public interface MouseAccessor { public interface MouseAccessor {
void midnightcontrols$onCursorPos(long window, double x, double y); void midnightcontrols$onCursorPos(long window, double x, double y);
void setLeftButtonClicked(boolean value);
} }

View File

@@ -0,0 +1,15 @@
package eu.midnightdust.midnightcontrols.client.util;
import java.awt.*;
public class RainbowColor {
public static float hue;
public static void tick() {
if (hue > 1) hue = 0f;
hue = hue + 0.01f;
}
public static Color radialRainbow(float saturation, float brightness) {
return Color.getHSBColor(hue, saturation, brightness);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -4,10 +4,11 @@
"key.midnightcontrols.look_left": "Nach links schauen", "key.midnightcontrols.look_left": "Nach links schauen",
"key.midnightcontrols.look_right": "Nach rechts schauen", "key.midnightcontrols.look_right": "Nach rechts schauen",
"key.midnightcontrols.look_up": "Nach oben schauen", "key.midnightcontrols.look_up": "Nach oben schauen",
"key.midnightcontrols.ring": "Zeige Steuerungsring", "key.midnightcontrols.ring": "Öffne Ring mit ungebundenen Aktionen",
"midnightcontrols.action.attack": "Angreifen", "midnightcontrols.action.attack": "Angreifen",
"midnightcontrols.action.back": "Zurück", "midnightcontrols.action.back": "Zurück",
"midnightcontrols.action.chat": "Chat öffnen", "midnightcontrols.action.chat": "Chat öffnen",
"midnightcontrols.action.controls_ring": "Öffne Ring mit ungebundenen Aktionen",
"midnightcontrols.action.drop_item": "Item droppen", "midnightcontrols.action.drop_item": "Item droppen",
"midnightcontrols.action.exit": "Schließen", "midnightcontrols.action.exit": "Schließen",
"midnightcontrols.action.forward": "Vorwärts", "midnightcontrols.action.forward": "Vorwärts",
@@ -40,8 +41,6 @@
"midnightcontrols.action.zoom_in": "Zoom erhöhen", "midnightcontrols.action.zoom_in": "Zoom erhöhen",
"midnightcontrols.action.zoom_out": "Zoom verringern", "midnightcontrols.action.zoom_out": "Zoom verringern",
"midnightcontrols.action.zoom_reset": "Zoom zurücksetzen", "midnightcontrols.action.zoom_reset": "Zoom zurücksetzen",
"midnightcontrols.action.key.emotecraft.fastchoose": "Emote Schnellauswahl",
"midnightcontrols.action.key.emotecraft.stop": "Emote stoppen",
"midnightcontrols.button.left_bumper": "Linke Schultertaste", "midnightcontrols.button.left_bumper": "Linke Schultertaste",
"midnightcontrols.button.right_bumper": "Rechte Schultertaste", "midnightcontrols.button.right_bumper": "Rechte Schultertaste",
"midnightcontrols.button.back": "Zurück", "midnightcontrols.button.back": "Zurück",
@@ -68,6 +67,8 @@
"midnightcontrols.axis.right_x-": "Rechts X-", "midnightcontrols.axis.right_x-": "Rechts X-",
"midnightcontrols.axis.right_y-": "Rechts Y-", "midnightcontrols.axis.right_y-": "Rechts Y-",
"midnightcontrols.button.unknown": "Unbekannt (%d)", "midnightcontrols.button.unknown": "Unbekannt (%d)",
"midnightcontrols.controller.tutorial.title": "Spiele Minecraft mit Controller!",
"midnightcontrols.controller.tutorial.description": "Gehe zu %s -> %s -> %s",
"midnightcontrols.controller.connected": "Controller %d verbunden.", "midnightcontrols.controller.connected": "Controller %d verbunden.",
"midnightcontrols.controller.disconnected": "Controller %d getrennt.", "midnightcontrols.controller.disconnected": "Controller %d getrennt.",
"midnightcontrols.controller.mappings.1": "Um die Controller-Mappings anzupassen, benutze %s", "midnightcontrols.controller.mappings.1": "Um die Controller-Mappings anzupassen, benutze %s",
@@ -76,80 +77,80 @@
"midnightcontrols.controller.mappings.error.write": "Fehler beim Schreiben der Controller Mappings.", "midnightcontrols.controller.mappings.error.write": "Fehler beim Schreiben der Controller Mappings.",
"midnightcontrols.controller.mappings.updated": "Mappings aktualisiert!", "midnightcontrols.controller.mappings.updated": "Mappings aktualisiert!",
"midnightcontrols.controller_type.default": "Standard", "midnightcontrols.controller_type.default": "Standard",
"midnightcontrols.controller_type.dualshock": "DualShock", "midnightcontrols.controller_type.numbered": "Nummerierter Controller",
"midnightcontrols.controller_type.switch": "Switch",
"midnightcontrols.controller_type.xbox": "Xbox",
"midnightcontrols.controller_type.steam": "Steam",
"midnightcontrols.controller_type.ouya": "OUYA",
"midnightcontrols.controls_mode.default": "Tastatur/Maus", "midnightcontrols.controls_mode.default": "Tastatur/Maus",
"midnightcontrols.controls_mode.controller": "Controller", "midnightcontrols.controls_mode.controller": "Controller",
"midnightcontrols.controls_mode.touchscreen": "Touchscreen", "midnightcontrols.controls_mode.touchscreen": "Touchscreen (In Arbeit)",
"midnightcontrols.hud_side.left": "links", "midnightcontrols.hud_side.left": "Links",
"midnightcontrols.hud_side.right": "rechts", "midnightcontrols.hud_side.right": "Rechts",
"midnightcontrols.menu.analog_movement": "Analoge Bewegung", "midnightcontrols.menu.analog_movement": "Analoge Bewegung",
"midnightcontrols.menu.analog_movement.tooltip": "Aktiviert analoge Bewegung, wenn möglich.",
"midnightcontrols.menu.auto_switch_mode": "Automatischer Wechsel", "midnightcontrols.menu.auto_switch_mode": "Automatischer Wechsel",
"midnightcontrols.menu.auto_switch_mode.tooltip": "Ob der Eingabemodus automatisch auf Controller eingestellt werden soll, wenn einer verbunden wird.",
"midnightcontrols.menu.controller": "Controller", "midnightcontrols.menu.controller": "Controller",
"midnightcontrols.menu.controller2": "Zweiter Controller", "midnightcontrols.menu.controller2": "Zweiter Controller",
"midnightcontrols.menu.controller2.tooltip": "Zweiter Controller, zum Beispiel für Joy-Cons.",
"midnightcontrols.menu.controller_type": "Controller-Typ", "midnightcontrols.menu.controller_type": "Controller-Typ",
"midnightcontrols.menu.controller_type.tooltip": "Der Controllertyp für den die Knöpfe angezeigt werden sollen.",
"midnightcontrols.menu.controls_mode": "Modus", "midnightcontrols.menu.controls_mode": "Modus",
"midnightcontrols.menu.controls_mode.tooltip": "Der Steuerungsmodus.",
"midnightcontrols.menu.double_tap_to_sprint": "Doppel-Tipp zum Sprinten",
"midnightcontrols.menu.fast_block_placing": "Schnelles Bauen", "midnightcontrols.menu.fast_block_placing": "Schnelles Bauen",
"midnightcontrols.menu.fast_block_placing.tooltip": "Während des Fliegens im Kreativmodus das schnelle Platzieren von Knöpfen aktivieren. §cWird von manchen Servern als cheaten eingestuft.",
"midnightcontrols.menu.fly_drifting": "Flug-Drifting", "midnightcontrols.menu.fly_drifting": "Flug-Drifting",
"midnightcontrols.menu.fly_drifting.tooltip": "Aktiviert das Flug-Drifting von Vanilla Minecraft.",
"midnightcontrols.menu.fly_drifting_vertical": "Vertikales Flug-Drifting", "midnightcontrols.menu.fly_drifting_vertical": "Vertikales Flug-Drifting",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "Aktiviert das vertikale Flug-Drifting von Vanilla Minecraft",
"midnightcontrols.menu.hud_enable": "HUD aktivieren", "midnightcontrols.menu.hud_enable": "HUD aktivieren",
"midnightcontrols.menu.hud_enable.tooltip": "(De-)Aktiviert die Knopfanzeige im Spiel",
"midnightcontrols.menu.hud_side": "HUD-Seite", "midnightcontrols.menu.hud_side": "HUD-Seite",
"midnightcontrols.menu.hud_side.tooltip": "Die Position der Knopfanzeige.",
"midnightcontrols.menu.invert_right_x_axis": "X rechts umkehren", "midnightcontrols.menu.invert_right_x_axis": "X rechts umkehren",
"midnightcontrols.menu.invert_right_y_axis": "Y rechts umkehren", "midnightcontrols.menu.invert_right_y_axis": "Y rechts umkehren",
"midnightcontrols.menu.keyboard_controls": "Tastatureinstellungen...", "midnightcontrols.menu.keyboard_controls": "Tastatureinstellungen...",
"midnightcontrols.menu.left_dead_zone": "Linke tote Zone", "midnightcontrols.menu.left_dead_zone": "Tote Zone des linken Sticks",
"midnightcontrols.menu.left_dead_zone.tooltip": "Die tote Zone für den linken Analogstick.",
"midnightcontrols.menu.mappings.open_input_str": "Öffne den Controller-Mapping Editor", "midnightcontrols.menu.mappings.open_input_str": "Öffne den Controller-Mapping Editor",
"midnightcontrols.menu.max_left_x_value": "Maximalwert Linke X-Achse", "midnightcontrols.menu.max_left_x_value": "Maximalwert Linke X-Achse",
"midnightcontrols.menu.max_left_x_value.tooltip": "Ändert den maximalen Wert der linken X-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.menu.max_left_y_value": "Maximalwert Linke Y-Achse", "midnightcontrols.menu.max_left_y_value": "Maximalwert Linke Y-Achse",
"midnightcontrols.menu.max_left_y_value.tooltip": "Ändert den maximalen Wert der linken Y-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.menu.max_right_x_value": "Maximalwert Rechte X-Achse", "midnightcontrols.menu.max_right_x_value": "Maximalwert Rechte X-Achse",
"midnightcontrols.menu.max_right_x_value.tooltip": "Ändert den maximalen Wert der rechten X-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.menu.max_right_y_value": "Maximalwert Rechte Y-Achse", "midnightcontrols.menu.max_right_y_value": "Maximalwert Rechte Y-Achse",
"midnightcontrols.menu.max_right_y_value.tooltip": "Ändert den maximalen Wert der rechten Y-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.menu.mouse_speed": "Mausgeschwindigkeit", "midnightcontrols.menu.mouse_speed": "Mausgeschwindigkeit",
"midnightcontrols.menu.mouse_speed.tooltip": "Die emulierte Mausgeschwindigkeit des Controllers.",
"midnightcontrols.menu.reacharound.horizontal": "Vorderes Blockplatzieren", "midnightcontrols.menu.reacharound.horizontal": "Vorderes Blockplatzieren",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Aktiviert vorderes Platzieren von Blöcken, §cwird von manchen Servern als cheaten eingestuft§r.",
"midnightcontrols.menu.reacharound.vertical": "Vertikales Umgreifen", "midnightcontrols.menu.reacharound.vertical": "Vertikales Umgreifen",
"midnightcontrols.menu.reacharound.vertical.tooltip": "Aktiviert vertikales Platzieren von Blöcken, §cwird von manchen Servern als cheaten eingestuft§r.",
"midnightcontrols.menu.reload_controller_mappings": "Controller-Mappings neuladen", "midnightcontrols.menu.reload_controller_mappings": "Controller-Mappings neuladen",
"midnightcontrols.menu.right_dead_zone": "Rechte tote Zone", "midnightcontrols.menu.reload_controller_mappings.tooltip": "Lädt die Controller-Mappings neu.",
"midnightcontrols.menu.rotation_speed": "Rotationsgeschwindigkeit", "midnightcontrols.menu.right_dead_zone": "Tote Zone des rechten Sticks",
"midnightcontrols.menu.right_dead_zone.tooltip": "Die tote Zone für den rechten Analogstick.",
"midnightcontrols.menu.rotation_speed": "Rotationsgeschwindigkeit (X-Achse)",
"midnightcontrols.menu.rotation_speed.tooltip": "Die Kamerarotationsgeschwindigkeit im Controllermodus. (X-Achse)",
"midnightcontrols.menu.y_axis_rotation_speed": "Rotationsgeschwindigkeit (Y-Achse)",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "Die Kamerarotationsgeschwindigkeit im Controllermodus. (Y-Achse)",
"midnightcontrols.menu.separate_controller_profile": "Separates Controller-Profil",
"midnightcontrols.menu.separator.controller": "Controller", "midnightcontrols.menu.separator.controller": "Controller",
"midnightcontrols.menu.separator.general": "Generell", "midnightcontrols.menu.separator.general": "Generell",
"midnightcontrols.menu.title": "MidnightControls - Einstellungen", "midnightcontrols.menu.title": "MidnightControls - Einstellungen",
"midnightcontrols.menu.title.controller": "Controlleroptionen", "midnightcontrols.menu.title.controller": "Controlleroptionen",
"midnightcontrols.menu.title.controller_controls": "Controller Steuerung", "midnightcontrols.menu.title.controller_controls": "Controller Aktionen",
"midnightcontrols.menu.title.gameplay": "Gameplay Optionen", "midnightcontrols.menu.title.gameplay": "Gameplay Optionen",
"midnightcontrols.menu.title.general": "Generelle Optionen", "midnightcontrols.menu.title.general": "Generelle Optionen",
"midnightcontrols.menu.title.hud": "HUD Optionen", "midnightcontrols.menu.title.hud": "HUD Optionen",
"midnightcontrols.menu.title.mappings.string": "Mapping-Datei Editor", "midnightcontrols.menu.title.mappings.string": "Mapping-Datei Editor",
"midnightcontrols.menu.title.visual": "Visuelle Optionen", "midnightcontrols.menu.title.visual": "Visuelle Optionen",
"midnightcontrols.menu.unfocused_input": "Unfokussierte Eingabe", "midnightcontrols.menu.unfocused_input": "Unfokussierte Eingabe",
"midnightcontrols.menu.unfocused_input.tooltip": "Erlaube Controllereingabe auch wenn das Fenster nicht fokussiert ist.",
"midnightcontrols.menu.virtual_mouse": "Virtuelle Maus", "midnightcontrols.menu.virtual_mouse": "Virtuelle Maus",
"midnightcontrols.menu.virtual_mouse.tooltip": "Aktiviere die virtuelle Maus.",
"midnightcontrols.menu.virtual_mouse.skin": "Aussehen der Virtuellen Maus", "midnightcontrols.menu.virtual_mouse.skin": "Aussehen der Virtuellen Maus",
"midnightcontrols.narrator.unbound": "%s entbunden", "midnightcontrols.narrator.unbound": "%s entbunden",
"midnightcontrols.not_bound": "Nicht zugewiesen", "midnightcontrols.not_bound": "Nicht zugewiesen",
"midnightcontrols.tooltip.analog_movement": "Aktiviert analoge Bewegung, wenn möglich.",
"midnightcontrols.tooltip.auto_switch_mode": "Ob der Eingabemodus automatisch auf Controller eingestellt werden soll, wenn einer verbunden wird.",
"midnightcontrols.tooltip.controller2": "Zweiter Controller, zum Beispiel für Joy-Cons.",
"midnightcontrols.tooltip.controller_type": "Der Controllertyp für den die Knöpfe angezeigt werden sollen.",
"midnightcontrols.tooltip.controls_mode": "Der Steuerungsmodus.",
"midnightcontrols.tooltip.fast_block_placing": "Während des Fliegens im Kreativmodus das schnelle Platzieren von Knöpfen aktivieren. §cWird von manchen Servern als cheaten eingestuft.",
"midnightcontrols.tooltip.fly_drifting": "Aktiviert das Flug-Drifting von Vanilla Minecraft.",
"midnightcontrols.tooltip.fly_drifting_vertical": "Aktiviert das vertikale Flug-Drifting von Vanilla Minecraft",
"midnightcontrols.tooltip.hud_enable": "(De-)Aktiviert die Knopfanzeige im Spiel",
"midnightcontrols.tooltip.hud_side": "Die Position der Knopfanzeige.",
"midnightcontrols.tooltip.left_dead_zone": "Die tote Zone für den linken Analogstick.",
"midnightcontrols.tooltip.max_left_x_value": "Ändert den maximalen Wert der linken X-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.tooltip.max_left_y_value": "Ändert den maximalen Wert der linken Y-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.tooltip.max_right_x_value": "Ändert den maximalen Wert der rechten X-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.tooltip.max_right_y_value": "Ändert den maximalen Wert der rechten Y-Achse. Nützlich, wenn deine Achse nicht bis zum Maximum geht.",
"midnightcontrols.tooltip.mouse_speed": "Die emulierte Mausgeschwindigkeit des Controllers.",
"midnightcontrols.tooltip.reacharound.horizontal": "Aktiviert vorderes Platzieren von Blöcken, §cwird von manchen Servern als cheaten eingestuft§r.",
"midnightcontrols.tooltip.reacharound.vertical": "Aktiviert vertikales Platzieren von Blöcken, §cwird von manchen Servern als cheaten eingestuft§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "Lädt die Controller-Mappings neu.",
"midnightcontrols.tooltip.right_dead_zone": "Die tote Zone für den rechten Analogstick.",
"midnightcontrols.tooltip.rotation_speed": "Die Kamerarotationsgeschwindigkeit im Controllermodus.",
"midnightcontrols.tooltip.unfocused_input": "Erlaube Controllereingabe auch wenn das Fenster nicht fokussiert ist.",
"midnightcontrols.tooltip.virtual_mouse": "Aktiviere die virtuelle Maus.",
"midnightcontrols.virtual_mouse.skin.default_light": "Standard Hell", "midnightcontrols.virtual_mouse.skin.default_light": "Standard Hell",
"midnightcontrols.virtual_mouse.skin.default_dark": "Standard Dunkel", "midnightcontrols.virtual_mouse.skin.default_dark": "Standard Dunkel",
"midnightcontrols.virtual_mouse.skin.second_light": "Alternativ Hell", "midnightcontrols.virtual_mouse.skin.second_light": "Alternativ Hell",

View File

@@ -1,15 +1,41 @@
{ {
"midnightcontrols.midnightconfig.title": "MidnightControls Advanced Config", "midnightcontrols.midnightconfig.title": "MidnightControls Advanced Config",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_LIGHT": "Default Light",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_DARK": "Default Dark",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_LIGHT": "Second Light",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_DARK": "Second Dark",
"midnightcontrols.midnightconfig.enum.ControllerType.DEFAULT": "Default",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSHOCK": "DualShock",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSENSE": "DualSense",
"midnightcontrols.midnightconfig.enum.ControllerType.SWITCH": "Switch/Wii Controller",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX": "Xbox One/Series Controller",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX_360": "Xbox 360 Controller",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_CONTROLLER": "Steam Controller",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_DECK": "Steam Deck",
"midnightcontrols.midnightconfig.enum.ControllerType.OUYA": "OUYA Controller",
"midnightcontrols.midnightconfig.enum.ControllerType.NUMBERED": "Numbered Controller",
"midnightcontrols.midnightconfig.enum.ControlsMode.DEFAULT": "Keyboard/Mouse",
"midnightcontrols.midnightconfig.enum.ControlsMode.CONTROLLER": "Controller",
"midnightcontrols.midnightconfig.enum.ControlsMode.TOUCHSCREEN": "Touchscreen (WIP)",
"midnightcontrols.midnightconfig.enum.HudSide.LEFT": "Left",
"midnightcontrols.midnightconfig.enum.HudSide.RIGHT": "Right",
"midnightcontrols.midnightconfig.enum.TouchMode.CROSSHAIR": "At Crosshair",
"midnightcontrols.midnightconfig.enum.TouchMode.FINGER_POS": "Finger Position",
"key.midnightcontrols.look_down": "Look down", "key.midnightcontrols.look_down": "Look down",
"key.midnightcontrols.look_left": "Look left", "key.midnightcontrols.look_left": "Look left",
"key.midnightcontrols.look_right": "Look right", "key.midnightcontrols.look_right": "Look right",
"key.midnightcontrols.look_up": "Look up", "key.midnightcontrols.look_up": "Look up",
"key.midnightcontrols.ring": "Show controls ring", "key.midnightcontrols.ring": "Open Unbound Keybind Ring",
"midnightcontrols.action.attack": "Attack", "midnightcontrols.action.attack": "Attack",
"midnightcontrols.action.back": "Back", "midnightcontrols.action.back": "Back",
"midnightcontrols.action.chat": "Open Chat", "midnightcontrols.action.chat": "Open Chat",
"midnightcontrols.action.controls_ring": "Open Unbound Keybind Ring",
"midnightcontrols.action.debug_screen": "Open Debug HUD (F3)",
"midnightcontrols.action.drop_item": "Drop Item", "midnightcontrols.action.drop_item": "Drop Item",
"midnightcontrols.action.exit": "Exit", "midnightcontrols.action.drink": "Drink",
"midnightcontrols.action.eat": "Eat",
"midnightcontrols.action.equip": "Equip",
"midnightcontrols.action.exit": "Exit Screen",
"midnightcontrols.action.forward": "Forward", "midnightcontrols.action.forward": "Forward",
"midnightcontrols.action.hit": "Hit", "midnightcontrols.action.hit": "Hit",
"midnightcontrols.action.hotbar_left": "Hotbar left", "midnightcontrols.action.hotbar_left": "Hotbar left",
@@ -26,6 +52,10 @@
"midnightcontrols.action.quick_move": "Quick move", "midnightcontrols.action.quick_move": "Quick move",
"midnightcontrols.action.right": "Right", "midnightcontrols.action.right": "Right",
"midnightcontrols.action.screenshot": "Take Screenshot", "midnightcontrols.action.screenshot": "Take Screenshot",
"midnightcontrols.action.slot_up": "Move Slot up",
"midnightcontrols.action.slot_down": "Move Slot down",
"midnightcontrols.action.slot_left": "Move Slot left",
"midnightcontrols.action.slot_right": "Move Slot right",
"midnightcontrols.action.sneak": "Sneak", "midnightcontrols.action.sneak": "Sneak",
"midnightcontrols.action.sprint": "Sprint", "midnightcontrols.action.sprint": "Sprint",
"midnightcontrols.action.swap_hands": "Swap Hands", "midnightcontrols.action.swap_hands": "Swap Hands",
@@ -33,6 +63,8 @@
"midnightcontrols.action.toggle_smooth_camera": "Toggle Cinematic Camera", "midnightcontrols.action.toggle_smooth_camera": "Toggle Cinematic Camera",
"midnightcontrols.action.page_back": "Previous Page", "midnightcontrols.action.page_back": "Previous Page",
"midnightcontrols.action.page_next": "Next Page", "midnightcontrols.action.page_next": "Next Page",
"midnightcontrols.action.tab_back": "Previous Tab",
"midnightcontrols.action.tab_next": "Next Tab",
"midnightcontrols.action.take": "Take Item", "midnightcontrols.action.take": "Take Item",
"midnightcontrols.action.take_all": "Take Stack", "midnightcontrols.action.take_all": "Take Stack",
"midnightcontrols.action.use": "Use", "midnightcontrols.action.use": "Use",
@@ -40,8 +72,9 @@
"midnightcontrols.action.zoom_in": "Increase Zoom", "midnightcontrols.action.zoom_in": "Increase Zoom",
"midnightcontrols.action.zoom_out": "Decrease Zoom", "midnightcontrols.action.zoom_out": "Decrease Zoom",
"midnightcontrols.action.zoom_reset": "Reset Zoom", "midnightcontrols.action.zoom_reset": "Reset Zoom",
"midnightcontrols.action.key.emotecraft.fastchoose": "Fast Choose Emote", "midnightcontrols.action.emi_page_left": "Previous Page",
"midnightcontrols.action.key.emotecraft.stop": "Stop Emote", "midnightcontrols.action.emi_page_right": "Next Page",
"midnightcontrols.category.emi": "EMI",
"midnightcontrols.button.a": "A", "midnightcontrols.button.a": "A",
"midnightcontrols.button.b": "B", "midnightcontrols.button.b": "B",
"midnightcontrols.button.x": "X", "midnightcontrols.button.x": "X",
@@ -72,6 +105,8 @@
"midnightcontrols.axis.right_x-": "Right X-", "midnightcontrols.axis.right_x-": "Right X-",
"midnightcontrols.axis.right_y-": "Right Y-", "midnightcontrols.axis.right_y-": "Right Y-",
"midnightcontrols.button.unknown": "Unknown (%d)", "midnightcontrols.button.unknown": "Unknown (%d)",
"midnightcontrols.controller.tutorial.title": "Play the game with a Controller!",
"midnightcontrols.controller.tutorial.description": "Go to %s -> %s -> %s",
"midnightcontrols.controller.connected": "Controller %d connected.", "midnightcontrols.controller.connected": "Controller %d connected.",
"midnightcontrols.controller.disconnected": "Controller %d disconnected.", "midnightcontrols.controller.disconnected": "Controller %d disconnected.",
"midnightcontrols.controller.mappings.1": "To configure the controller mappings, please use %s", "midnightcontrols.controller.mappings.1": "To configure the controller mappings, please use %s",
@@ -79,84 +114,117 @@
"midnightcontrols.controller.mappings.error": "Error while loading mappings.", "midnightcontrols.controller.mappings.error": "Error while loading mappings.",
"midnightcontrols.controller.mappings.error.write": "Error while writing mappings to file.", "midnightcontrols.controller.mappings.error.write": "Error while writing mappings to file.",
"midnightcontrols.controller.mappings.updated": "Updated mappings!", "midnightcontrols.controller.mappings.updated": "Updated mappings!",
"midnightcontrols.controller_type.default": "default", "midnightcontrols.controller_type.default": "Default",
"midnightcontrols.controller_type.dualshock": "DualShock", "midnightcontrols.controller_type.dualshock": "DualShock",
"midnightcontrols.controller_type.switch": "Switch", "midnightcontrols.controller_type.dualsense": "DualSense",
"midnightcontrols.controller_type.xbox": "Xbox", "midnightcontrols.controller_type.switch": "Switch/Wii Controller",
"midnightcontrols.controller_type.steam": "Steam", "midnightcontrols.controller_type.xbox": "Xbox One/Series Controller",
"midnightcontrols.controller_type.ouya": "OUYA", "midnightcontrols.controller_type.xbox_360": "Xbox 360 Controller",
"midnightcontrols.controller_type.steam_controller": "Steam Controller",
"midnightcontrols.controller_type.steam_deck": "Steam Deck",
"midnightcontrols.controller_type.ouya": "OUYA Controller",
"midnightcontrols.controller_type.numbered": "Numbered Controller",
"midnightcontrols.controls_mode.default": "Keyboard/Mouse", "midnightcontrols.controls_mode.default": "Keyboard/Mouse",
"midnightcontrols.controls_mode.controller": "Controller", "midnightcontrols.controls_mode.controller": "Controller",
"midnightcontrols.controls_mode.touchscreen": "Touchscreen", "midnightcontrols.controls_mode.touchscreen": "Touchscreen (WIP)",
"midnightcontrols.hud_side.left": "left", "midnightcontrols.hud_side.left": "Left",
"midnightcontrols.hud_side.right": "right", "midnightcontrols.hud_side.right": "Right",
"midnightcontrols.menu.analog_movement": "Analog Movement", "midnightcontrols.menu.analog_movement": "Analog Movement",
"midnightcontrols.menu.analog_movement.tooltip": "When possible, enables analog movement.",
"midnightcontrols.menu.auto_switch_mode": "Auto Switch Mode", "midnightcontrols.menu.auto_switch_mode": "Auto Switch Mode",
"midnightcontrols.menu.auto_switch_mode.tooltip": "Whether the controls mode should be switched to Controller automatically if one is connected.",
"midnightcontrols.menu.controller": "Controller", "midnightcontrols.menu.controller": "Controller",
"midnightcontrols.menu.controller2": "Second Controller", "midnightcontrols.menu.controller2": "Second Controller",
"midnightcontrols.menu.controller2.tooltip": "Second controller to use, which allows (for example) Joy-Cons support.",
"midnightcontrols.menu.controller_toggle_sneak": "Toggle Sneak on Controller",
"midnightcontrols.menu.controller_toggle_sprint": "Toggle Sprint on Controller",
"midnightcontrols.menu.controller_type": "Controller Type", "midnightcontrols.menu.controller_type": "Controller Type",
"midnightcontrols.menu.controller_type.tooltip": "The controller type you're using (needed to display the correct buttons)",
"midnightcontrols.menu.controls_mode": "Mode", "midnightcontrols.menu.controls_mode": "Mode",
"midnightcontrols.menu.controls_mode.tooltip": "The controls mode.",
"midnightcontrols.menu.double_tap_to_sprint": "Double-Tap to Sprint",
"midnightcontrols.menu.double_tap_to_sprint.tooltip": "Toggles whether the Walk Forwards key makes the player sprint when double-tapped quickly",
"midnightcontrols.menu.fast_block_placing": "Fast Block Placing", "midnightcontrols.menu.fast_block_placing": "Fast Block Placing",
"midnightcontrols.menu.fast_block_placing.tooltip": "While flying in creative mode, enables fast block placing depending on your speed. §cOn some servers this might be considered as cheating.",
"midnightcontrols.menu.fly_drifting": "Fly Drifting", "midnightcontrols.menu.fly_drifting": "Fly Drifting",
"midnightcontrols.menu.fly_drifting.tooltip": "While flying, enables Vanilla drifting/inertia.",
"midnightcontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting", "midnightcontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "While flying, enables Vanilla vertical drifting/intertia.",
"midnightcontrols.menu.hud_enable": "Enable HUD", "midnightcontrols.menu.hud_enable": "Enable HUD",
"midnightcontrols.menu.hud_enable.tooltip": "Toggles the on-screen controller button indicator.",
"midnightcontrols.menu.hud_side": "HUD Side", "midnightcontrols.menu.hud_side": "HUD Side",
"midnightcontrols.menu.hud_side.tooltip": "The position of the HUD.",
"midnightcontrols.menu.invert_right_x_axis": "Invert Right X", "midnightcontrols.menu.invert_right_x_axis": "Invert Right X",
"midnightcontrols.menu.invert_right_y_axis": "Invert Right Y", "midnightcontrols.menu.invert_right_y_axis": "Invert Right Y",
"midnightcontrols.menu.joystick_as_mouse": "Always use left stick as mouse",
"midnightcontrols.menu.joystick_as_mouse.tooltip": "Make the joystick behave like a mouse in every menu.",
"midnightcontrols.menu.eye_tracker_as_mouse": "Use Eye Tracker as Mouse",
"midnightcontrols.menu.eye_tracker_as_mouse.tooltip": "Replace the mouse with an eye tracking device, (for example) the Tobii 5.",
"midnightcontrols.menu.eye_tracker_deadzone": "Eye Tracker Deadzone Size",
"midnightcontrols.menu.eye_tracker_deadzone.tooltip": "Stops camera movement when looking near the cross hair",
"midnightcontrols.menu.keyboard_controls": "Keyboard Controls...", "midnightcontrols.menu.keyboard_controls": "Keyboard Controls...",
"midnightcontrols.menu.left_dead_zone": "Left Dead Zone", "midnightcontrols.menu.left_dead_zone": "Left Stick Dead Zone",
"midnightcontrols.menu.left_dead_zone.tooltip": "The dead zone for the controller's left analog stick.",
"midnightcontrols.menu.mappings.open_input_str": "Open Mappings File Editor", "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_x_value": "Left X Axis Max Value",
"midnightcontrols.menu.max_left_x_value.tooltip": "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.menu.max_left_y_value": "Left Y Axis Max Value", "midnightcontrols.menu.max_left_y_value": "Left Y Axis Max Value",
"midnightcontrols.menu.max_left_y_value.tooltip": "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.menu.max_right_x_value": "Right X Axis Max Value", "midnightcontrols.menu.max_right_x_value": "Right X Axis Max Value",
"midnightcontrols.menu.max_right_x_value.tooltip": "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.menu.max_right_y_value": "Right Y Axis Max Value", "midnightcontrols.menu.max_right_y_value": "Right Y Axis Max Value",
"midnightcontrols.menu.max_right_y_value.tooltip": "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.menu.mouse_speed": "Mouse Speed", "midnightcontrols.menu.mouse_speed": "Mouse Speed",
"midnightcontrols.menu.mouse_speed.tooltip": "The controller's emulated mouse speed.",
"midnightcontrols.menu.move_chat": "Move chat input box to top",
"midnightcontrols.menu.move_chat.tooltip": "Moves the chat input field to the top, for better input on devices with on-screen keyboards.",
"midnightcontrols.menu.reacharound.horizontal": "Front Block Placing", "midnightcontrols.menu.reacharound.horizontal": "Front Block Placing",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Enables front block placing, §cmight be considered cheating on some servers§r.",
"midnightcontrols.menu.reacharound.vertical": "Vertical Reacharound", "midnightcontrols.menu.reacharound.vertical": "Vertical Reacharound",
"midnightcontrols.menu.reacharound.vertical.tooltip": "Enables vertical reacharound, §cmight be considered cheating on some servers§r.",
"midnightcontrols.menu.reload_controller_mappings": "Reload Controller Mappings", "midnightcontrols.menu.reload_controller_mappings": "Reload Controller Mappings",
"midnightcontrols.menu.right_dead_zone": "Right Dead Zone", "midnightcontrols.menu.reload_controller_mappings.tooltip": "Reloads the controller mappings file.",
"midnightcontrols.menu.rotation_speed": "Rotation Speed", "midnightcontrols.menu.right_dead_zone": "Right Stick Dead Zone",
"midnightcontrols.menu.right_dead_zone.tooltip": "The dead zone for the controller's right analog stick.",
"midnightcontrols.menu.rotation_speed": "X Axis Rotation Speed",
"midnightcontrols.menu.rotation_speed.tooltip": "The camera's X Axis rotation speed in controller mode.",
"midnightcontrols.menu.y_axis_rotation_speed": "Y Axis Rotation Speed",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "The camera's Y Axis rotation speed in controller mode.",
"midnightcontrols.menu.separate_controller_profile": "Separate Controller Profile",
"midnightcontrols.menu.separator.controller": "Controller", "midnightcontrols.menu.separator.controller": "Controller",
"midnightcontrols.menu.separator.general": "General", "midnightcontrols.menu.separator.general": "General",
"midnightcontrols.menu.title": "MidnightControls - Settings", "midnightcontrols.menu.title": "MidnightControls - Settings",
"midnightcontrols.menu.title.controller": "Controller Options", "midnightcontrols.menu.title.controller": "Controller Options",
"midnightcontrols.menu.title.controller_controls": "Controller Controls", "midnightcontrols.menu.title.controller_controls": "Controller Bindings",
"midnightcontrols.menu.title.gameplay": "Gameplay Options", "midnightcontrols.menu.title.gameplay": "Gameplay Options",
"midnightcontrols.menu.title.general": "General Options", "midnightcontrols.menu.title.general": "General Options",
"midnightcontrols.menu.title.hud": "HUD Options", "midnightcontrols.menu.title.hud": "HUD Options",
"midnightcontrols.menu.title.mappings.string": "Mappings File Editor", "midnightcontrols.menu.title.mappings.string": "Mappings File Editor",
"midnightcontrols.menu.title.touch": "Touch Options",
"midnightcontrols.menu.title.visual": "Appearance Options", "midnightcontrols.menu.title.visual": "Appearance Options",
"midnightcontrols.menu.touch_break_delay": "Touch Break Delay",
"midnightcontrols.menu.touch_speed": "Touch Speed",
"midnightcontrols.menu.invert_touch": "Invert Touch Direction",
"midnightcontrols.menu.touch_mode": "Touch Interaction Mode",
"midnightcontrols.menu.touch_transparency": "Touch HUD Transparency",
"midnightcontrols.menu.unfocused_input": "Unfocused Input", "midnightcontrols.menu.unfocused_input": "Unfocused Input",
"midnightcontrols.menu.unfocused_input.tooltip": "Allows controller input when the window is not focused.",
"midnightcontrols.menu.virtual_mouse": "Virtual Mouse", "midnightcontrols.menu.virtual_mouse": "Virtual Mouse",
"midnightcontrols.menu.virtual_mouse.tooltip": "Enables the virtual mouse, which is useful during splitscreen.",
"midnightcontrols.menu.virtual_mouse.skin": "Virtual Mouse Skin", "midnightcontrols.menu.virtual_mouse.skin": "Virtual Mouse Skin",
"midnightcontrols.menu.hide_cursor": "Hide Normal Mouse Cursor",
"midnightcontrols.menu.hide_cursor.tooltip": "Hides the normal mouse cursor, leaving only the virtual mouse visible.",
"midnightcontrols.narrator.unbound": "Unbound %s", "midnightcontrols.narrator.unbound": "Unbound %s",
"midnightcontrols.not_bound": "Not bound", "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_light": "Default Light",
"midnightcontrols.virtual_mouse.skin.default_dark": "Default Dark", "midnightcontrols.virtual_mouse.skin.default_dark": "Default Dark",
"midnightcontrols.virtual_mouse.skin.second_light": "Second Light", "midnightcontrols.virtual_mouse.skin.second_light": "Second Light",
"midnightcontrols.virtual_mouse.skin.second_dark": "Second Dark", "midnightcontrols.virtual_mouse.skin.second_dark": "Second Dark",
"midnightcontrols.midnightconfig.category.controller": "Controller",
"midnightcontrols.midnightconfig.category.misc": "Miscellaneous",
"midnightcontrols.midnightconfig.category.screens": "Screens",
"midnightcontrols.midnightconfig.category.gameplay": "Gameplay",
"midnightcontrols.midnightconfig.category.touch": "Touch",
"midnightcontrols.midnightconfig.category.visual": "Visual",
"modmenu.descriptionTranslation.midnightcontrols": "Adds controller support and enhanced controls overall.\nForked from LambdaControls, which sadly got discontinued." "modmenu.descriptionTranslation.midnightcontrols": "Adds controller support and enhanced controls overall.\nForked from LambdaControls, which sadly got discontinued."
} }

View File

@@ -80,31 +80,54 @@
"midnightcontrols.hud_side.left": "izquierda", "midnightcontrols.hud_side.left": "izquierda",
"midnightcontrols.hud_side.right": "derecha", "midnightcontrols.hud_side.right": "derecha",
"midnightcontrols.menu.analog_movement": "Movimiento analógico", "midnightcontrols.menu.analog_movement": "Movimiento analógico",
"midnightcontrols.menu.analog_movement.tooltip": "Habilita el movimiento analógico cuando es posible.",
"midnightcontrols.menu.auto_switch_mode": "Cambio de modo automático", "midnightcontrols.menu.auto_switch_mode": "Cambio de modo automático",
"midnightcontrols.menu.auto_switch_mode.tooltip": "Si el modo de controles debe cambiarse a Controlador automáticamente si hay uno conectado.",
"midnightcontrols.menu.controller": "Controlador", "midnightcontrols.menu.controller": "Controlador",
"midnightcontrols.menu.controller2": "Segundo controlador", "midnightcontrols.menu.controller2": "Segundo controlador",
"midnightcontrols.menu.controller2.tooltip": "Segundo controlador a uso, que permite el soporte de Joy-Cons por ejemplo.",
"midnightcontrols.menu.controller_type": "Tipo de controlador", "midnightcontrols.menu.controller_type": "Tipo de controlador",
"midnightcontrols.menu.controller_type.tooltip": "El tipo de controlador para mostrar los botones correctos.",
"midnightcontrols.menu.controls_mode": "Modo", "midnightcontrols.menu.controls_mode": "Modo",
"midnightcontrols.menu.controls_mode.tooltip": "El modo de controles.",
"midnightcontrols.menu.fast_block_placing": "Colocación rápida de bloques", "midnightcontrols.menu.fast_block_placing": "Colocación rápida de bloques",
"midnightcontrols.menu.fast_block_placing.tooltip": "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.menu.fly_drifting": "Volar a la deriva", "midnightcontrols.menu.fly_drifting": "Volar a la deriva",
"midnightcontrols.menu.fly_drifting.tooltip": "Mientras vuela, habilita la deriva/inercia de vainilla.",
"midnightcontrols.menu.fly_drifting_vertical": "Volar a la deriva vertical", "midnightcontrols.menu.fly_drifting_vertical": "Volar a la deriva vertical",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "Mientras vuela, habilita la deriva/inercia vertical de vainilla.",
"midnightcontrols.menu.hud_enable": "Habilitar HUD", "midnightcontrols.menu.hud_enable": "Habilitar HUD",
"midnightcontrols.menu.hud_enable.tooltip": "Alterna el indicador del botón del controlador en pantalla.",
"midnightcontrols.menu.hud_side": "Lado de HUD", "midnightcontrols.menu.hud_side": "Lado de HUD",
"midnightcontrols.menu.hud_side.tooltip": "La posición del HUD.",
"midnightcontrols.menu.invert_right_x_axis": "Invertir derecha X", "midnightcontrols.menu.invert_right_x_axis": "Invertir derecha X",
"midnightcontrols.menu.invert_right_y_axis": "Invertir derecha Y", "midnightcontrols.menu.invert_right_y_axis": "Invertir derecha Y",
"midnightcontrols.menu.keyboard_controls": "Controles del teclado...", "midnightcontrols.menu.keyboard_controls": "Controles del teclado...",
"midnightcontrols.menu.left_dead_zone": "Zona muerta izquierda", "midnightcontrols.menu.left_dead_zone": "Zona muerta izquierda",
"midnightcontrols.menu.left_dead_zone.tooltip": "La zona muerta de la palanca analógica izquierda del controlador.",
"midnightcontrols.menu.mappings.open_input_str": "Abrir el editor de archivo de asignaciones", "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_x_value": "Valor máximo del eje X izquierdo",
"midnightcontrols.menu.max_left_x_value.tooltip": "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.menu.max_left_y_value": "Valor máximo del eje Y izquierdo", "midnightcontrols.menu.max_left_y_value": "Valor máximo del eje Y izquierdo",
"midnightcontrols.menu.max_left_y_value.tooltip": "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.menu.max_right_x_value": "Valor máximo del eje X derecho", "midnightcontrols.menu.max_right_x_value": "Valor máximo del eje X derecho",
"midnightcontrols.menu.max_right_x_value.tooltip": "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.menu.max_right_y_value": "Valor máximo del eje Y derecho", "midnightcontrols.menu.max_right_y_value": "Valor máximo del eje Y derecho",
"midnightcontrols.menu.max_right_y_value.tooltip": "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.menu.mouse_speed": "Velocidad del ratón", "midnightcontrols.menu.mouse_speed": "Velocidad del ratón",
"midnightcontrols.menu.mouse_speed.tooltip": "La velocidad del ratón emulada del controlador.",
"midnightcontrols.menu.reacharound.horizontal": "Colocación de bloque frontal", "midnightcontrols.menu.reacharound.horizontal": "Colocación de bloque frontal",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Habilita la colocación del bloque frontal, §cpodría considerarse trampa en algunos servidores§r.",
"midnightcontrols.menu.reacharound.vertical": "Alcance vertical", "midnightcontrols.menu.reacharound.vertical": "Alcance vertical",
"midnightcontrols.menu.reacharound.vertical.tooltip": "Habilita el alcance vertical, §cpodría considerarse trampa en algunos servidores§r.",
"midnightcontrols.menu.reload_controller_mappings": "Recargar asignaciones de controlador", "midnightcontrols.menu.reload_controller_mappings": "Recargar asignaciones de controlador",
"midnightcontrols.menu.reload_controller_mappings.tooltip": "Vuelve a cargar el archivo de asignaciones del controlador.",
"midnightcontrols.menu.right_dead_zone": "Zona muerta derecha", "midnightcontrols.menu.right_dead_zone": "Zona muerta derecha",
"midnightcontrols.menu.rotation_speed": "Velocidad de rotación", "midnightcontrols.menu.right_dead_zone.tooltip": "La zona muerta de la palanca analógica derecha del controlador.",
"midnightcontrols.menu.rotation_speed": "Velocidad de rotación (eje X)",
"midnightcontrols.menu.rotation_speed.tooltip": "La velocidad de rotación de la cámara en modo controlador. (eje X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Velocidad de rotación (eje Y)",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "La velocidad de rotación de la cámara en modo controlador. (eje Y)",
"midnightcontrols.menu.separator.controller": "Controlador", "midnightcontrols.menu.separator.controller": "Controlador",
"midnightcontrols.menu.separator.general": "General", "midnightcontrols.menu.separator.general": "General",
"midnightcontrols.menu.title": "midnightcontrols - Configuraciones", "midnightcontrols.menu.title": "midnightcontrols - Configuraciones",
@@ -116,33 +139,12 @@
"midnightcontrols.menu.title.mappings.string": "Editor de archivo de asignaciones", "midnightcontrols.menu.title.mappings.string": "Editor de archivo de asignaciones",
"midnightcontrols.menu.title.visual": "Opciones de apariencia", "midnightcontrols.menu.title.visual": "Opciones de apariencia",
"midnightcontrols.menu.unfocused_input": "Entrada desenfocada", "midnightcontrols.menu.unfocused_input": "Entrada desenfocada",
"midnightcontrols.menu.unfocused_input.tooltip": "Habilita entrada del controlador cuando la ventana no está enfocada.",
"midnightcontrols.menu.virtual_mouse": "Ratón virtual", "midnightcontrols.menu.virtual_mouse": "Ratón virtual",
"midnightcontrols.menu.virtual_mouse.tooltip": "Habilite el ratón virtual que es útil en el caso de una pantalla dividida.",
"midnightcontrols.menu.virtual_mouse.skin": "Piel de ratón virtual", "midnightcontrols.menu.virtual_mouse.skin": "Piel de ratón virtual",
"midnightcontrols.narrator.unbound": "Resetear %s", "midnightcontrols.narrator.unbound": "Resetear %s",
"midnightcontrols.not_bound": "No ligado", "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_light": "Ligera por defecto",
"midnightcontrols.virtual_mouse.skin.default_dark": "Oscura por defecto", "midnightcontrols.virtual_mouse.skin.default_dark": "Oscura por defecto",
"midnightcontrols.virtual_mouse.skin.second_light": "Ligera segundario", "midnightcontrols.virtual_mouse.skin.second_light": "Ligera segundario",

View File

@@ -0,0 +1,132 @@
{
"midnightcontrols.midnightconfig.title": "MidnightControls täpsem seadistus",
"key.midnightcontrols.look_down": "Vaata alla",
"key.midnightcontrols.look_left": "Vaata vasakule",
"key.midnightcontrols.look_right": "Vaata paremale",
"key.midnightcontrols.look_up": "Vaata üles",
"key.midnightcontrols.ring": "Kuva juhtnupuringi",
"midnightcontrols.action.attack": "Ründa",
"midnightcontrols.action.back": "Tagasi",
"midnightcontrols.action.chat": "Ava vestlus",
"midnightcontrols.action.drop_item": "Viska ese",
"midnightcontrols.action.exit": "Välju",
"midnightcontrols.action.forward": "Edasi",
"midnightcontrols.action.hit": "Löö",
"midnightcontrols.action.hotbar_left": "Plokiriba vasakule",
"midnightcontrols.action.hotbar_right": "Plokiriba paremale",
"midnightcontrols.action.inventory": "Seljakott",
"midnightcontrols.action.jump": "Hüppa",
"midnightcontrols.action.left": "Vasakule",
"midnightcontrols.action.pause_game": "Mäng pausile",
"midnightcontrols.action.pick_block": "Vali plokk",
"midnightcontrols.action.pickup": "Korja üles",
"midnightcontrols.action.pickup_all": "Korja kõik üles",
"midnightcontrols.action.place": "Aseta",
"midnightcontrols.action.player_list": "Mängijate loend",
"midnightcontrols.action.quick_move": "Kiirliigutus",
"midnightcontrols.action.right": "Paremale",
"midnightcontrols.action.screenshot": "Loo kuvatõmmis",
"midnightcontrols.action.sneak": "Hiili",
"midnightcontrols.action.sprint": "Jookse",
"midnightcontrols.action.swap_hands": "Vaheta käsi",
"midnightcontrols.action.toggle_perspective": "Lülita perspektiivi",
"midnightcontrols.action.toggle_smooth_camera": "Lülita kinemaatilist kaamerat",
"midnightcontrols.action.page_back": "Eelmine leht",
"midnightcontrols.action.page_next": "Järgmine leht",
"midnightcontrols.action.take": "Võta ese",
"midnightcontrols.action.take_all": "Võta kuhi",
"midnightcontrols.action.use": "Kasuta",
"midnightcontrols.action.zoom": "Suumi",
"midnightcontrols.action.zoom_in": "Suurenda suumi",
"midnightcontrols.action.zoom_out": "Vähenda suumi",
"midnightcontrols.action.zoom_reset": "Lähtesta suum",
"midnightcontrols.action.key.emotecraft.fastchoose": "Vali kiirelt liigutus",
"midnightcontrols.action.key.emotecraft.stop": "Peata liigutus",
"midnightcontrols.button.left_bumper": "Vasak külgnupp",
"midnightcontrols.button.right_bumper": "Parem külgnupp",
"midnightcontrols.button.left_thumb": "Vasak pöidlanupp",
"midnightcontrols.button.right_thumb": "Parem pöidlanupp",
"midnightcontrols.button.dpad_up": "DPAD üles",
"midnightcontrols.button.dpad_right": "DPAD paremale",
"midnightcontrols.button.dpad_down": "DPAD alla",
"midnightcontrols.button.dpad_left": "DPAD vasakule",
"midnightcontrols.axis.left_x+": "Vasak X+",
"midnightcontrols.axis.left_y+": "Vasak Y+",
"midnightcontrols.axis.right_x+": "Parem X+",
"midnightcontrols.axis.right_y+": "Parem Y+",
"midnightcontrols.axis.left_trigger": "Vasak käiviti",
"midnightcontrols.axis.right_trigger": "Parem käiviti",
"midnightcontrols.axis.left_x-": "Vasak X-",
"midnightcontrols.axis.left_y-": "Vasak Y-",
"midnightcontrols.axis.right_x-": "Parem X-",
"midnightcontrols.axis.right_y-": "Parem Y-",
"midnightcontrols.button.unknown": "Teadmata (%d)",
"midnightcontrols.controller.tutorial.title": "Mängi mängu oma juhtpuldiga!",
"midnightcontrols.controller.tutorial.description": "Mine %s -> %s -> %s",
"midnightcontrols.controller.connected": "Mängupult %d ühendatud.",
"midnightcontrols.controller.disconnected": "Mängupult %d lahti ühendatud.",
"midnightcontrols.controller.mappings.1": "Mängupuldi vastenduste seadistamiseks palun kasuta %s",
"midnightcontrols.controller.mappings.3": "ning aseta vastendus vastenduste failiredaktorisse.",
"midnightcontrols.controller.mappings.error": "Vastenduste laadimisel esines viga.",
"midnightcontrols.controller.mappings.error.write": "Vastenduste faili kirjutamisel esines viga.",
"midnightcontrols.controller.mappings.updated": "Vastendused uuendatud!",
"midnightcontrols.controller_type.default": "vaikimisi",
"midnightcontrols.controls_mode.default": "klaviatuur/hiir",
"midnightcontrols.controls_mode.controller": "mängupult",
"midnightcontrols.controls_mode.touchscreen": "puuteekraan (arenduses)",
"midnightcontrols.hud_side.left": "vasak",
"midnightcontrols.hud_side.right": "parem",
"midnightcontrols.menu.analog_movement": "Analoogliikumine",
"midnightcontrols.menu.auto_switch_mode": "Vaheta režiimi automaatselt",
"midnightcontrols.menu.controller": "Mängupult",
"midnightcontrols.menu.controller2": "Teine mängupult",
"midnightcontrols.menu.controller_type": "Mängupuldi tüüp",
"midnightcontrols.menu.controls_mode": "Režiim",
"midnightcontrols.menu.double_tap_to_sprint": "Jooksmiseks topeltkoputa",
"midnightcontrols.menu.fast_block_placing": "Kiire plokiasetus",
"midnightcontrols.menu.fly_drifting": "Lennutriivimine",
"midnightcontrols.menu.fly_drifting_vertical": "Vertikaalne lennutriivimine",
"midnightcontrols.menu.hud_enable": "Nähtav liides",
"midnightcontrols.menu.hud_side": "Liidese pool",
"midnightcontrols.menu.invert_right_x_axis": "Pööratud parem X",
"midnightcontrols.menu.invert_right_y_axis": "Pööratud parem Y",
"midnightcontrols.menu.keyboard_controls": "Klaviatuuri juhtnupud...",
"midnightcontrols.menu.left_dead_zone": "Vasak surnud tsoon",
"midnightcontrols.menu.mappings.open_input_str": "Ava vastenduste failiredaktor",
"midnightcontrols.menu.max_left_x_value": "Vasaku X-telje maks. väärtus",
"midnightcontrols.menu.max_left_y_value": "Vasaku Y-telje maks. väärtus",
"midnightcontrols.menu.max_right_x_value": "Parema X-telje maks. väärtus",
"midnightcontrols.menu.max_right_y_value": "Parema Y-telje maks. väärtus",
"midnightcontrols.menu.mouse_speed": "Hiire kiirus",
"midnightcontrols.menu.reacharound.horizontal": "Ploki etteasetus",
"midnightcontrols.menu.reacharound.vertical": "Vertikaalne ümberasetus",
"midnightcontrols.menu.reload_controller_mappings": "Laadi mängupuldi vastendused uuesti",
"midnightcontrols.menu.right_dead_zone": "Parem surnud tsoon",
"midnightcontrols.menu.rotation_speed": "X-telje pöördekiirus",
"midnightcontrols.menu.y_axis_rotation_speed": "Y-telje pöördekiirus",
"midnightcontrols.menu.separator.controller": "Mängupult",
"midnightcontrols.menu.separator.general": "Üldine",
"midnightcontrols.menu.title": "MidnightControls - seaded",
"midnightcontrols.menu.title.controller": "Mängupuldi valikud",
"midnightcontrols.menu.title.controller_controls": "Mängupuldi juhtnupud",
"midnightcontrols.menu.title.gameplay": "Mängukogemuse valikud",
"midnightcontrols.menu.title.general": "Üldised valikud",
"midnightcontrols.menu.title.hud": "Liidese valikud",
"midnightcontrols.menu.title.mappings.string": "Vastenduste failiredaktor",
"midnightcontrols.menu.title.visual": "Välimuse valikud",
"midnightcontrols.menu.unfocused_input": "Fookustamata sisend",
"midnightcontrols.menu.virtual_mouse": "Virtuaalne hiir",
"midnightcontrols.menu.virtual_mouse.skin": "Virtuaalse hiire välimus",
"midnightcontrols.narrator.unbound": "Määramata %s",
"midnightcontrols.not_bound": "määramata",
"midnightcontrols.virtual_mouse.skin.default_light": "vaikimisi hele",
"midnightcontrols.virtual_mouse.skin.default_dark": "vaikimisi tume",
"midnightcontrols.virtual_mouse.skin.second_light": "teine hele",
"midnightcontrols.virtual_mouse.skin.second_dark": "teine tume",
"modmenu.descriptionTranslation.midnightcontrols": "Lisab mängupuldi toe ning täiendab juhtnuppe üldiselt.\nFork loodud LambdaControls-ist, mille toetamine kahjuks lõpetati."
}

View File

@@ -104,7 +104,8 @@
"midnightcontrols.menu.reacharound.vertical": "Placement vertical", "midnightcontrols.menu.reacharound.vertical": "Placement vertical",
"midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes", "midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes",
"midnightcontrols.menu.right_dead_zone": "Zone morte axe droit", "midnightcontrols.menu.right_dead_zone": "Zone morte axe droit",
"midnightcontrols.menu.rotation_speed": "Vitesse de rotation", "midnightcontrols.menu.rotation_speed": "Vitesse de rotation (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Vitesse de rotation (Y)",
"midnightcontrols.menu.separator.general": "Général", "midnightcontrols.menu.separator.general": "Général",
"midnightcontrols.menu.separator.controller": "Manette", "midnightcontrols.menu.separator.controller": "Manette",
"midnightcontrols.menu.title": "midnightcontrols - Paramètres", "midnightcontrols.menu.title": "midnightcontrols - Paramètres",
@@ -120,29 +121,30 @@
"midnightcontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle", "midnightcontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle",
"midnightcontrols.narrator.unbound": "Délier %s", "midnightcontrols.narrator.unbound": "Délier %s",
"midnightcontrols.not_bound": "Non défini", "midnightcontrols.not_bound": "Non défini",
"midnightcontrols.tooltip.analog_movement": "Active le mouvement analogique si possible.", "midnightcontrols.menu.analog_movement.tooltip": "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.menu.auto_switch_mode.tooltip": "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.menu.controller2.tooltip": "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.menu.controller_type.tooltip": "Le type de contrôle n'influe que sur les boutons affichés.",
"midnightcontrols.tooltip.controls_mode": "Change le mode de contrôle.", "midnightcontrols.menu.controls_mode.tooltip": "Change le mode de contrôle.",
"midnightcontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.", "midnightcontrols.menu.fast_block_placing.tooltip": "Active le placement rapide de blocs en vol.",
"midnightcontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.", "midnightcontrols.menu.fly_drifting.tooltip": "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.menu.fly_drifting_vertical.tooltip": "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.menu.hud_enable.tooltip": "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.menu.hud_side.tooltip": "Change la position du HUD.",
"midnightcontrols.tooltip.left_dead_zone": "Zone morte de l'axe gauche de la manette.", "midnightcontrols.menu.left_dead_zone.tooltip": "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.menu.max_left_x_value.tooltip": "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.menu.max_left_y_value.tooltip": "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.menu.max_right_x_value.tooltip": "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.menu.max_right_y_value.tooltip": "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.menu.mouse_speed.tooltip": "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.menu.reacharound.horizontal.tooltip": "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.menu.reacharound.vertical.tooltip": "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.menu.reload_controller_mappings.tooltip": "Recharge le fichier de configuration des manettes.",
"midnightcontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.", "midnightcontrols.menu.right_dead_zone.tooltip": "Zone morte de l'axe droit de la manette.",
"midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.", "midnightcontrols.menu.rotation_speed.tooltip": "Change la vitesse de rotation de la caméra. (X)",
"midnightcontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.", "midnightcontrols.menu.y_axis_rotation_speed.tooltip": "Change la vitesse de rotation de la caméra. (Y)",
"midnightcontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.", "midnightcontrols.menu.unfocused_input.tooltip": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.",
"midnightcontrols.menu.virtual_mouse.tooltip": "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_light": "défaut clair",
"midnightcontrols.virtual_mouse.skin.default_dark": "défaut foncé", "midnightcontrols.virtual_mouse.skin.default_dark": "défaut foncé",
"midnightcontrols.virtual_mouse.skin.second_light": "second clair", "midnightcontrols.virtual_mouse.skin.second_light": "second clair",

View File

@@ -104,7 +104,8 @@
"midnightcontrols.menu.reacharound.vertical": "Placement vertical", "midnightcontrols.menu.reacharound.vertical": "Placement vertical",
"midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes", "midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes",
"midnightcontrols.menu.right_dead_zone": "Zone morte axe droit", "midnightcontrols.menu.right_dead_zone": "Zone morte axe droit",
"midnightcontrols.menu.rotation_speed": "Vitesse de rotation", "midnightcontrols.menu.rotation_speed": "Vitesse de rotation (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Vitesse de rotation (Y)",
"midnightcontrols.menu.separator.general": "Général", "midnightcontrols.menu.separator.general": "Général",
"midnightcontrols.menu.separator.controller": "Manette", "midnightcontrols.menu.separator.controller": "Manette",
"midnightcontrols.menu.title": "midnightcontrols - Paramètres", "midnightcontrols.menu.title": "midnightcontrols - Paramètres",
@@ -120,29 +121,30 @@
"midnightcontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle", "midnightcontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle",
"midnightcontrols.narrator.unbound": "Délier %s", "midnightcontrols.narrator.unbound": "Délier %s",
"midnightcontrols.not_bound": "Non défini", "midnightcontrols.not_bound": "Non défini",
"midnightcontrols.tooltip.analog_movement": "Active le mouvement analogique si possible.", "midnightcontrols.menu.analog_movement.tooltip": "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.menu.auto_switch_mode.tooltip": "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.menu.controller2.tooltip": "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.menu.controller_type.tooltip": "Le type de contrôle n'influe que sur les boutons affichés.",
"midnightcontrols.tooltip.controls_mode": "Change le mode de contrôle.", "midnightcontrols.menu.controls_mode.tooltip": "Change le mode de contrôle.",
"midnightcontrols.tooltip.fast_block_placing": "Active le placement rapide de blocs en vol.", "midnightcontrols.menu.fast_block_placing.tooltip": "Active le placement rapide de blocs en vol.",
"midnightcontrols.tooltip.fly_drifting": "Pendant que le joueur vole, active le glissement Vanilla.", "midnightcontrols.menu.fly_drifting.tooltip": "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.menu.fly_drifting_vertical.tooltip": "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.menu.hud_enable.tooltip": "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.menu.hud_side.tooltip": "Change la position du HUD.",
"midnightcontrols.tooltip.left_dead_zone": "Zone morte de l'axe gauche de la manette.", "midnightcontrols.menu.left_dead_zone.tooltip": "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.menu.max_left_x_value.tooltip": "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.menu.max_left_y_value.tooltip": "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.menu.max_right_x_value.tooltip": "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.menu.max_right_y_value.tooltip": "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.menu.mouse_speed.tooltip": "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.menu.reacharound.horizontal.tooltip": "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.menu.reacharound.vertical.tooltip": "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.menu.reload_controller_mappings.tooltip": "Recharge le fichier de configuration des manettes.",
"midnightcontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.", "midnightcontrols.menu.right_dead_zone.tooltip": "Zone morte de l'axe droit de la manette.",
"midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.", "midnightcontrols.menu.rotation_speed.tooltip": "Change la vitesse de rotation de la caméra. (X)",
"midnightcontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.", "midnightcontrols.menu.y_axis_rotation_speed.tooltip": "Change la vitesse de rotation de la caméra. (Y)",
"midnightcontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.", "midnightcontrols.menu.unfocused_input.tooltip": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.",
"midnightcontrols.menu.virtual_mouse.tooltip": "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_light": "défaut clair",
"midnightcontrols.virtual_mouse.skin.default_dark": "défaut foncé", "midnightcontrols.virtual_mouse.skin.default_dark": "défaut foncé",
"midnightcontrols.virtual_mouse.skin.second_light": "second clair", "midnightcontrols.virtual_mouse.skin.second_light": "second clair",

View File

@@ -0,0 +1,203 @@
{
"midnightcontrols.midnightconfig.title": "Configurazione Avanzata MidnightControls",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_LIGHT": "Default Chiaro",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_DARK": "Default Scuro",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_LIGHT": "Chiaro Secondario",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_DARK": "Scuro secondario",
"midnightcontrols.midnightconfig.enum.ControllerType.DEFAULT": "Default",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSHOCK": "DualShock",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSENSE": "DualSense",
"midnightcontrols.midnightconfig.enum.ControllerType.SWITCH": "Controller Switch/Wii",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX": "Controller Xbox One/Series",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX_360": "Controller Xbox 360",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_CONTROLLER": "Controller Steam",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_DECK": "Steam Deck",
"midnightcontrols.midnightconfig.enum.ControllerType.OUYA": "Controller OUYA",
"midnightcontrols.midnightconfig.enum.ControllerType.NUMBERED": "Controller Numerato",
"midnightcontrols.midnightconfig.enum.ControlsMode.DEFAULT": "Tastiera/Mouse",
"midnightcontrols.midnightconfig.enum.ControlsMode.CONTROLLER": "Controller",
"midnightcontrols.midnightconfig.enum.ControlsMode.TOUCHSCREEN": "Touchscreen (WIP)",
"midnightcontrols.midnightconfig.enum.HudSide.LEFT": "Sinistra",
"midnightcontrols.midnightconfig.enum.HudSide.RIGHT": "Destra",
"key.midnightcontrols.look_down": "Guarda in basso",
"key.midnightcontrols.look_left": "Guarda a sinistra",
"key.midnightcontrols.look_right": "Guarda a destra",
"key.midnightcontrols.look_up": "Guarda sopra",
"key.midnightcontrols.ring": "Apri Tasti non impostati",
"midnightcontrols.action.attack": "Attacca",
"midnightcontrols.action.back": "Indietro",
"midnightcontrols.action.chat": "Apri Chat",
"midnightcontrols.action.controls_ring": "Apri Tasti non impostati",
"midnightcontrols.action.debug_screen": "Apri HUD di Debug (F3)",
"midnightcontrols.action.drop_item": "Rilascia oggetto",
"midnightcontrols.action.exit": "Esci",
"midnightcontrols.action.forward": "Avanti",
"midnightcontrols.action.hit": "Colpisci",
"midnightcontrols.action.hotbar_left": "Hotbar sinistra",
"midnightcontrols.action.hotbar_right": "Hotbar destra",
"midnightcontrols.action.inventory": "Inventario",
"midnightcontrols.action.jump": "Salta",
"midnightcontrols.action.left": "Sinistra",
"midnightcontrols.action.pause_game": "Pausa il gioco",
"midnightcontrols.action.pick_block": "Prendi Blocco",
"midnightcontrols.action.pickup": "Raccogli",
"midnightcontrols.action.pickup_all": "Raccogli Tutto",
"midnightcontrols.action.place": "Piazza",
"midnightcontrols.action.player_list": "Lista Giocatori",
"midnightcontrols.action.quick_move": "Muovi veloce",
"midnightcontrols.action.right": "Destra",
"midnightcontrols.action.screenshot": "Fai uno Screenshot",
"midnightcontrols.action.slot_up": "Muovi slot sopra",
"midnightcontrols.action.slot_down": "Muovi slot sotto",
"midnightcontrols.action.slot_left": "Muovi slot a sinistra",
"midnightcontrols.action.slot_right": "Muovi slot a destra",
"midnightcontrols.action.sneak": "Accovaccia",
"midnightcontrols.action.sprint": "Corri",
"midnightcontrols.action.swap_hands": "Scambia le mani",
"midnightcontrols.action.toggle_perspective": "Cambia la prospettiva",
"midnightcontrols.action.toggle_smooth_camera": "Cambia Camera Cinematica",
"midnightcontrols.action.page_back": "Pagina precedente",
"midnightcontrols.action.page_next": "Pagina Successica",
"midnightcontrols.action.tab_back": "Tab Precedente",
"midnightcontrols.action.tab_next": "Tab Successiva",
"midnightcontrols.action.take": "Prendi Item",
"midnightcontrols.action.take_all": "Prendi Stack",
"midnightcontrols.action.use": "Usa",
"midnightcontrols.action.zoom": "Zoom",
"midnightcontrols.action.zoom_in": "Aumenta Zoom",
"midnightcontrols.action.zoom_out": "Diminuisci Zoom",
"midnightcontrols.action.zoom_reset": "Resetta Zoom",
"midnightcontrols.action.emi_page_left": "Pagina Precedente",
"midnightcontrols.action.emi_page_right": "Pagina Successiva",
"midnightcontrols.category.emi": "EMI",
"midnightcontrols.button.a": "A",
"midnightcontrols.button.b": "B",
"midnightcontrols.button.x": "X",
"midnightcontrols.button.y": "Y",
"midnightcontrols.button.left_bumper": "Bumper Destro",
"midnightcontrols.button.right_bumper": "Bumper Sinistro",
"midnightcontrols.button.back": "Indietro",
"midnightcontrols.button.start": "Avvia",
"midnightcontrols.button.guide": "Guida",
"midnightcontrols.button.left_thumb": "Pollice Sinistro",
"midnightcontrols.button.right_thumb": "Pollice Destro",
"midnightcontrols.button.dpad_up": "DPAD Sopra",
"midnightcontrols.button.dpad_right": "DPAD Destra",
"midnightcontrols.button.dpad_down": "DPAD Sotto",
"midnightcontrols.button.dpad_left": "DPAD Sinistra",
"midnightcontrols.button.l4": "L4",
"midnightcontrols.button.l5": "L5",
"midnightcontrols.button.r4": "R4",
"midnightcontrols.button.r5": "L5",
"midnightcontrols.axis.left_x+": "Sinistra X+",
"midnightcontrols.axis.left_y+": "Sinistra Y+",
"midnightcontrols.axis.right_x+": "Destra X+",
"midnightcontrols.axis.right_y+": "Destra Y+",
"midnightcontrols.axis.left_trigger": "Trigger Sinistro",
"midnightcontrols.axis.right_trigger": "Trigger Destro",
"midnightcontrols.axis.left_x-": "Sinistra X-",
"midnightcontrols.axis.left_y-": "Sinistra Y-",
"midnightcontrols.axis.right_x-": "Destra X-",
"midnightcontrols.axis.right_y-": "Destra Y-",
"midnightcontrols.button.unknown": "Sconosciuto",
"midnightcontrols.controller.tutorial.title": "Gioca il gioco con un Controller!",
"midnightcontrols.controller.tutorial.description": "Vai a %s -> %s -> %s",
"midnightcontrols.controller.connected": "Controller %d connesso.",
"midnightcontrols.controller.disconnected": "Controller %d disconnesso",
"midnightcontrols.controller.mappings.1": "Per configurare le mappature dei controller, per favore usa %s",
"midnightcontrols.controller.mappings.3": "e incolla le mappature nel file editor.",
"midnightcontrols.controller.mappings.error": "Errore durante il caricamento delle mappature",
"midnightcontrols.controller.mappings.error.write": "Errore durante la scrittura delle mappature su file",
"midnightcontrols.controller.mappings.updated": "Aggiornate le mappature!",
"midnightcontrols.controller_type.default": "Default",
"midnightcontrols.controller_type.dualshock": "DualShock",
"midnightcontrols.controller_type.dualsense": "DualSense",
"midnightcontrols.controller_type.switch": "Controller Switch/Wii",
"midnightcontrols.controller_type.xbox": "Controller Xbox One/Series",
"midnightcontrols.controller_type.xbox_360": "Controller Xbox 360",
"midnightcontrols.controller_type.steam_controller": "Controller Steam",
"midnightcontrols.controller_type.steam_deck": "Steam Deck",
"midnightcontrols.controller_type.ouya": "Controller OUYA",
"midnightcontrols.controller_type.numbered": "Controller Numerato",
"midnightcontrols.controls_mode.default": "Tastiera/Mouse",
"midnightcontrols.controls_mode.controller": "Controller",
"midnightcontrols.controls_mode.touchscreen": "Touchscreen (WIP)",
"midnightcontrols.hud_side.left": "Left",
"midnightcontrols.hud_side.right": "Destra",
"midnightcontrols.menu.analog_movement": "Movimento Analogo",
"midnightcontrols.menu.auto_switch_mode": "Modalità Cambio Automatico",
"midnightcontrols.menu.controller": "Controller",
"midnightcontrols.menu.controller2": "Controller Secondario",
"midnightcontrols.menu.controller_toggle_sneak": "Attiva/Disattiva Accovacciamento su Controller",
"midnightcontrols.menu.controller_toggle_sprint": "Attiva/Disattiva Correre su Controller",
"midnightcontrols.menu.controller_type": "Tipo di Controller",
"midnightcontrols.menu.controls_mode": "Modalità",
"midnightcontrols.menu.double_tap_to_sprint": "Doppio Tap per Sprintare",
"midnightcontrols.menu.fast_block_placing": "Veloce Piazzamento di Blocchi",
"midnightcontrols.menu.fly_drifting": "Drift in Volo",
"midnightcontrols.menu.fly_drifting_vertical": "Drift in Volo Verticale",
"midnightcontrols.menu.hud_enable": "Attiva HUD",
"midnightcontrols.menu.hud_side": "Lato HUD",
"midnightcontrols.menu.invert_right_x_axis": "Inverti Destro X",
"midnightcontrols.menu.invert_right_y_axis": "Inverti Destro Y",
"midnightcontrols.menu.keyboard_controls": "Controlli da Tastiera...",
"midnightcontrols.menu.left_dead_zone": "Zona Morta dello Stick Sinistro",
"midnightcontrols.menu.mappings.open_input_str": "Apri il File Editor delle Mappature",
"midnightcontrols.menu.max_left_x_value": "Asse X Sinistro Massimo Valore",
"midnightcontrols.menu.max_left_y_value": "Asse Y Sinistro Massimo Valore",
"midnightcontrols.menu.max_right_x_value": "Asse Destro X Massimo Valore",
"midnightcontrols.menu.max_right_y_value": "Asse Destro Y Massimo Valore",
"midnightcontrols.menu.mouse_speed": "Velocità Mouse",
"midnightcontrols.menu.reacharound.horizontal": "Piazza blocchi Davanti",
"midnightcontrols.menu.reacharound.vertical": "Reach Verticale",
"midnightcontrols.menu.reload_controller_mappings": "Ricarica Mappature del Controller",
"midnightcontrols.menu.right_dead_zone": "Zona Morta Stick Destro",
"midnightcontrols.menu.rotation_speed": "Velocità di rotazione dell'Asse X",
"midnightcontrols.menu.y_axis_rotation_speed": "Velocità di rotazione dell'Asse Y",
"midnightcontrols.menu.separate_controller_profile": "Profilo Controller Separato",
"midnightcontrols.menu.separator.controller": "Controller",
"midnightcontrols.menu.separator.general": "Generale",
"midnightcontrols.menu.title": "MidnightControls - Impostazioni",
"midnightcontrols.menu.title.controller": "Opzioni Controller",
"midnightcontrols.menu.title.controller_controls": "Tasti Controller",
"midnightcontrols.menu.title.gameplay": "Opzioni del Gameplay",
"midnightcontrols.menu.title.general": "Impostazioni Generali",
"midnightcontrols.menu.title.hud": "Opzioni della HUD",
"midnightcontrols.menu.title.mappings.string": "Editor di file delle Mappature",
"midnightcontrols.menu.title.visual": "Aspetto",
"midnightcontrols.menu.unfocused_input": "Input non a fuoco",
"midnightcontrols.menu.virtual_mouse": "Mouse Virtuale",
"midnightcontrols.menu.virtual_mouse.skin": "Aspetto Mouse Virtuale",
"midnightcontrols.narrator.unbound": "Disimpostato %s",
"midnightcontrols.not_bound": "Non Impostato",
"midnightcontrols.menu.analog_movement.tooltip": "Quando possibile, attiva movimento analogo.",
"midnightcontrols.menu.auto_switch_mode.tooltip": "Quando la modalità controlli dovrebbe passare a Controller automaticamente se uno è connesso",
"midnightcontrols.menu.controller2.tooltip": "Secondo controller da usare, che permette (per esempio) Supporto dei Joy-Cons.",
"midnightcontrols.menu.controller_type.tooltip": "Il tipo di controller che stai usando (usato per mostrare i pulsanti corretti)",
"midnightcontrols.menu.controls_mode.tooltip": "Modalita controlli.",
"midnightcontrols.menu.double_tap_to_sprint.tooltip": "Attiva quando il tasto \"Cammina Avanti\" fa correre il giocatore con doppio tap velocemente",
"midnightcontrols.menu.fast_block_placing.tooltip": "Quando si vola in creativa, attiva il movimento veloce dei blocchi in base alla tua velocità. §cSu alcuni server potrebbe essere considerato un cheat.§r",
"midnightcontrols.menu.fly_drifting.tooltip": "Quando si vola, attiva L'inerzia del Vanilla",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "Quando si vola, attiva l'inerzia verticale Vanilla",
"midnightcontrols.menu.hud_enable.tooltip": "Attiva gli indicatori dei pulsanti dei controller sullo schermo.",
"midnightcontrols.menu.hud_side.tooltip": "La posizione della HUD",
"midnightcontrols.menu.left_dead_zone.tooltip": "La zona morta per lo stick sinistro del controller.",
"midnightcontrols.menu.max_left_x_value.tooltip": "Cambia cosa la mod considera il più alto valore per l'asse X sinistro. Utile se il tuo asse non usa il range massimo e sembra lento",
"midnightcontrols.menu.max_left_y_value.tooltip": "Cambia cosa la mod considera il più alto valore per l'asse Y sinistro. Utile se il tuo asse non usa il range massimo e sembra lento",
"midnightcontrols.menu.max_right_x_value.tooltip": "Cambia cosa la mod considera il più alto valore per l'asse X Destro. Utile se il tuo asse non usa il range massimo e sembra lento.",
"midnightcontrols.menu.max_right_y_value.tooltip": "Cambia cosa la mod considera il più alto valore per l'asse Y Destro. Utile se il tuo asse non usa il range massimo e sembra lento.",
"midnightcontrols.menu.mouse_speed.tooltip": "La velocità del controller emulato.",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Attiva il piazzare blocchi davanti, Potrebbe essere considerato un cheat su alcuni server.",
"midnightcontrols.menu.reacharound.vertical.tooltip": "Attiva il reach verticale, potrebbe essere considerato cheating su alcuni server",
"midnightcontrols.menu.reload_controller_mappings.tooltip": "Riavvia il file dlle mappature del controller",
"midnightcontrols.menu.right_dead_zone.tooltip": "La zona morta per lo stick destro del controller",
"midnightcontrols.menu.rotation_speed.tooltip": "L'asse X della velocità di rotazione della camera im modalità controller",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "L'asse Y della velocità di rotazione della camera im modalità controller",
"midnightcontrols.menu.unfocused_input.tooltip": "Permette imput dei controller quando la finestra non è messa a fuoco",
"midnightcontrols.menu.virtual_mouse.tooltip": "Attiva il mouse virtuale, che può essere utile nello schermo diviso.",
"midnightcontrols.virtual_mouse.skin.default_light": "Chiaro Default",
"midnightcontrols.virtual_mouse.skin.default_dark": "Scuro Default",
"midnightcontrols.virtual_mouse.skin.second_light": "Chiaro Secondario",
"midnightcontrols.virtual_mouse.skin.second_dark": "Scuro Secondario",
"modmenu.descriptionTranslation.midnightcontrols": "Aggiunge supporto e controlli migliorati in generale. \\nProveniente da LambdaControls, che è stato rimosso."
}

View File

@@ -0,0 +1,178 @@
{
"midnightcontrols.midnightconfig.title": "MidnightControls 고급 설정",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_LIGHT": "기본 밝게",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_DARK": "기본 어둡게",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_LIGHT": "두 번째 밝게",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_DARK": "두 번째 어둡게",
"midnightcontrols.midnightconfig.enum.ControllerType.DEFAULT": "기본값값",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSHOCK": "듀얼쇼크",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSENSE": "듀얼센스",
"midnightcontrols.midnightconfig.enum.ControllerType.SWITCH": "Switch/Wii 컨트롤러",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX": "엑스박스 원/시리즈 컨트롤러",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX_360": "엑스박스 360 컨트롤러",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_CONTROLLER": "스팀 컨트롤러",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_DECK": "스팀 덱",
"midnightcontrols.midnightconfig.enum.ControllerType.OUYA": "OUYA 컨트롤러",
"midnightcontrols.midnightconfig.enum.ControllerType.NUMBERED": "숫자 컨트롤러",
"midnightcontrols.midnightconfig.enum.ControlsMode.DEFAULT": "키보드/마우스",
"midnightcontrols.midnightconfig.enum.ControlsMode.CONTROLLER": "컨트롤러",
"midnightcontrols.midnightconfig.enum.ControlsMode.TOUCHSCREEN": "터치스크린 (미완성)",
"midnightcontrols.midnightconfig.enum.HudSide.LEFT": "왼쪽",
"midnightcontrols.midnightconfig.enum.HudSide.RIGHT": "오른쪽",
"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.debug_screen": "디버그 HUD 열기 (F3)",
"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.action.key.emotecraft.fastchoose": "이모트 빠른 선택",
"midnightcontrols.action.key.emotecraft.stop": "이모트 중지",
"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": "DPAD 위",
"midnightcontrols.button.dpad_right": "DPAD 오른쪽",
"midnightcontrols.button.dpad_down": "DPAD 아래",
"midnightcontrols.button.dpad_left": "DPAD 왼쪽",
"midnightcontrols.button.l4": "L4",
"midnightcontrols.button.l5": "L5",
"midnightcontrols.button.r4": "R4",
"midnightcontrols.button.r5": "L5",
"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": "그리고 매핑 파일 편집기에 매핑을 붙여 넣으세요.",
"midnightcontrols.controller.mappings.error": "매핑을 불러오던 중 오류.",
"midnightcontrols.controller.mappings.error.write": "파일에 매핑 작성 중 오류.",
"midnightcontrols.controller.mappings.updated": "매핑 업데이트됨!",
"midnightcontrols.controller_type.default": "기본",
"midnightcontrols.controller_type.dualshock": "듀얼쇼크",
"midnightcontrols.controller_type.switch": "스위치",
"midnightcontrols.controller_type.xbox": "엑스박스",
"midnightcontrols.controller_type.steam": "스팀",
"midnightcontrols.controller_type.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.menu.analog_movement.tooltip": "가능한 경우 아날로그 움직임을 사용합니다.",
"midnightcontrols.menu.auto_switch_mode.tooltip": "컨트롤러가 연결되면 자동으로 컨트롤 모드가 컨트롤러로 전환됩니다.",
"midnightcontrols.menu.controller2.tooltip": "보조 컨트롤러를 사용하려면 Joy-Cons 지원을 허용하세요.",
"midnightcontrols.menu.controller_type.tooltip": "올바른 버튼을 표시할 컨트롤러 종류입니다.",
"midnightcontrols.menu.controls_mode.tooltip": "컨트롤 모드.",
"midnightcontrols.menu.fast_block_placing.tooltip": "크리에이티브 모드에서 비행하는 동안 사용자 속도에 따른 빠른 블록 배치를 사용합니다. §c일부 서버에선 치팅 행위로 취급될 수 있습니다.",
"midnightcontrols.menu.fly_drifting.tooltip": "비행하는 동안 바닐라처럼 관성을 적용합니다.",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "비행하는 동안 바닐라처럼 수직 관성을 적용합니다.",
"midnightcontrols.menu.hud_enable.tooltip": "화면 컨트롤러 버튼 표시기 토글",
"midnightcontrols.menu.hud_side.tooltip": "HUD 위치.",
"midnightcontrols.menu.left_dead_zone.tooltip": "컨트롤러 왼쪽 아날로그 스틱 데드 존.",
"midnightcontrols.menu.max_left_x_value.tooltip": "모드가 인식하는 왼쪽 X 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.menu.max_left_y_value.tooltip": "모드가 인식하는 왼쪽 Y 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.menu.max_right_x_value.tooltip": "모드가 인식하는 오른쪽 X 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.menu.max_right_y_value.tooltip": "모드가 인식하는 오른쪽 Y 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.menu.mouse_speed.tooltip": "컨트롤러의 에뮬레이트된 마우스 속도.",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "블록 전면 배치를 사용합니다. §c일부 서버에선 치팅 행위로 취급될 수 있습니다§r.",
"midnightcontrols.menu.reacharound.vertical.tooltip": "블록 수직 배치를 사용합니다. 블록 아래에 다른 블록을 배치할 수 있습니다. §c일부 서버에선 치팅 행위로 취급될 수 있습니다§r.",
"midnightcontrols.menu.reload_controller_mappings.tooltip": "컨트롤러 매핑 파일을 다시 불러옵니다.",
"midnightcontrols.menu.right_dead_zone.tooltip": "컨트롤러 오른쪽 아날로그 스틱 데드 존",
"midnightcontrols.menu.rotation_speed.tooltip": "컨트롤러 모드에서 적용되는 카메라 회전 속도.",
"midnightcontrols.menu.unfocused_input.tooltip": "창이 활성화된 상태가 아니여도 컨트롤러 입력 허용.",
"midnightcontrols.menu.virtual_mouse.tooltip": "분할 화면에선 도움 되는 가상 마우스를 사용합니다.",
"midnightcontrols.virtual_mouse.skin.default_light": "기본 밝게",
"midnightcontrols.virtual_mouse.skin.default_dark": "기본 어둡게",
"midnightcontrols.virtual_mouse.skin.second_light": "두 번째 밝게",
"midnightcontrols.virtual_mouse.skin.second_dark": "두 번째 어둡게",
"modmenu.descriptionTranslation.midnightcontrols": "컨트롤러 제어 및 전반적인 향상된 제어 기능을 추가합니다.\n안타깝게도 업데이트가 끊긴 LambdaControls의 Fork 버전입니다."
}

View File

@@ -0,0 +1,177 @@
{
"midnightcontrols.midnightconfig.title": "Расширенная Конфигурация MidnightControls",
"key.midnightcontrols.look_down": "Смотреть Вниз",
"key.midnightcontrols.look_left": "Смотреть Налево",
"key.midnightcontrols.look_right": "Смотреть Направо",
"key.midnightcontrols.look_up": "Смотрeть Вверх",
"key.midnightcontrols.ring": "Показать Кольцо Управления",
"midnightcontrols.action.attack": "Атаковать",
"midnightcontrols.action.back": "Назад",
"midnightcontrols.action.chat": "Открыть Чат",
"midnightcontrols.action.debug_screen": "Открыть Отладку (F3)",
"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.slot_up": "Двинуть На Слот Вверх",
"midnightcontrols.action.slot_down": "Двинуть На Слот Вниз",
"midnightcontrols.action.slot_left": "Двинуть На Слот Влево",
"midnightcontrols.action.slot_right": "Двинуть На Слот Вправо",
"midnightcontrols.action.sneak": "Красться",
"midnightcontrols.action.sprint": "Бег",
"midnightcontrols.action.swap_hands": "Поменять Руку",
"midnightcontrols.action.toggle_perspective": "Переключить Перспективу",
"midnightcontrols.action.toggle_smooth_camera": "Переключить Кинематографическую Камеру",
"midnightcontrols.action.page_back": "Предыдущая Страница",
"midnightcontrols.action.page_next": "Следующая Страница",
"midnightcontrols.action.tab_back": "Предыдущая Секция",
"midnightcontrols.action.tab_next": "Следующая Секция",
"midnightcontrols.action.take": "Взять Предмет",
"midnightcontrols.action.take_all": "Взять Стак",
"midnightcontrols.action.use": "Использовать",
"midnightcontrols.action.zoom": "Приблизить",
"midnightcontrols.action.zoom_in": "Увеличить Масштаб",
"midnightcontrols.action.zoom_out": "Уменьшить Масштаб",
"midnightcontrols.action.zoom_reset": "Сбросить Масштаб",
"midnightcontrols.action.emi_page_left": "Предыдущая Страница",
"midnightcontrols.action.emi_page_right": "Следующая Страница",
"midnightcontrols.category.emi": "ЕМИ",
"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.button.l4": "L4",
"midnightcontrols.button.l5": "L5",
"midnightcontrols.button.r4": "R4",
"midnightcontrols.button.r5": "L5",
"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": "и вставте ваш итог в редактор файлов раскладок.",
"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.dualsense": "DualSense",
"midnightcontrols.controller_type.switch": "Switch",
"midnightcontrols.controller_type.xbox": "Xbox",
"midnightcontrols.controller_type.xbox_360": "Xbox 360",
"midnightcontrols.controller_type.steam_controller": "Steam Controller",
"midnightcontrols.controller_type.steam_deck": "Steam Deck",
"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.double_tap_to_sprint": "Дважды Отвести Левый Стик, Чтобы Начать Бежать",
"midnightcontrols.menu.fast_block_placing": "Быстрая Поставка Блоков",
"midnightcontrols.menu.fly_drifting": "Инерция При Полёте",
"midnightcontrols.menu.fly_drifting_vertical": "Вертикальная Инерция При Полёте",
"midnightcontrols.menu.hud_enable": "Включить Иконоки Контроллера",
"midnightcontrols.menu.hud_side": "Расположение Интерфейса",
"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": "Скорость Вращения По Оси X",
"midnightcontrols.menu.y_axis_rotation_speed": "Скорость Вращения По Оси Y",
"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": "Настройка Интерфейса",
"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.menu.analog_movement.tooltip": "Включает аналоговое движение, когда это возможно.",
"midnightcontrols.menu.auto_switch_mode.tooltip": "Автоматическое переключение на новый, только подключенный контроллер.",
"midnightcontrols.menu.controller2.tooltip": "Дополнительный контроллер, например для Джой-конов.",
"midnightcontrols.menu.controller_type.tooltip": "Тип контроллера, чтобы правильно сопоставить иконки кнопок.",
"midnightcontrols.menu.controls_mode.tooltip": "Тип контроля над игрой.",
"midnightcontrols.menu.double_tap_to_sprint.tooltip": "При двойном перемещением на левый стик, персонаж начинает бежать.",
"midnightcontrols.menu.fast_block_placing.tooltip": "Во время полета в творческом режиме позволяет быстро размещать блоки в зависимости от вашей скорости. §cНа некоторых серверах это может расцениваться как читерство.§r",
"midnightcontrols.menu.fly_drifting.tooltip": "Во время полета включает ванильную инерцию.",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "Во время полета включает ванильную вертикальную инерцию.",
"midnightcontrols.menu.hud_enable.tooltip": "Переключает видение иконок кнопок контроллера на экране.",
"midnightcontrols.menu.hud_side.tooltip": "Расположение интерфейса в определённую сторону.",
"midnightcontrols.menu.left_dead_zone.tooltip": "Мертвая зона для левого аналогового стика контроллера.",
"midnightcontrols.menu.max_left_x_value.tooltip": "Изменяет то, что мод в итоге считает максимальным значением для левой оси X. Полезно, если ваша ось не использует весь диапазон и кажется медленной.",
"midnightcontrols.menu.max_left_y_value.tooltip": "Изменяет то, что мод в итоге считает максимальным значением для левой оси Y. Полезно, если ваша ось не использует весь диапазон и кажется медленной.",
"midnightcontrols.menu.max_right_x_value.tooltip": "Изменяет то, что мод в итоге считает максимальным значением для правой оси X. Полезно, если ваша ось не использует весь диапазон и кажется медленной.",
"midnightcontrols.menu.max_right_y_value.tooltip": "Изменяет то, что мод в итоге считает максимальным значением для правой оси Y. Полезно, если ваша ось не использует весь диапазон и кажется медленной.",
"midnightcontrols.menu.mouse_speed.tooltip": "Скорость мыши, эмулируемая контроллером.",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Позволяет размещать передний блок перед собой. §cМожет рассматриваться как читерство на некоторых серверах§r.",
"midnightcontrols.menu.reacharound.vertical.tooltip": "Обеспечивает вертикальный охват. §cМожет рассматриваться как мошенничество на некоторых серверах§r.",
"midnightcontrols.menu.reload_controller_mappings.tooltip": "Перезагружает файл раскладки контроллеров.",
"midnightcontrols.menu.right_dead_zone.tooltip": "Мертвая зона для правого аналогового стика контроллера.",
"midnightcontrols.menu.rotation_speed.tooltip": "Скорость вращения камеры по оси X в режиме контроллера.",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "Скорость вращения камеры по оси Y в режиме контроллера.",
"midnightcontrols.menu.unfocused_input.tooltip": "Разрешить ввод с контроллера, даже если игра на сфокусирована.",
"midnightcontrols.menu.virtual_mouse.tooltip": "Включить виртуальную мышь, очень полезно при игре двоём на одном компьютере.",
"midnightcontrols.virtual_mouse.skin.default_light": "Обычный Светлый",
"midnightcontrols.virtual_mouse.skin.default_dark": "Обычный Тёмный",
"midnightcontrols.virtual_mouse.skin.second_light": "Дополнительный Светлый",
"midnightcontrols.virtual_mouse.skin.second_dark": "Дополнительный Тёмный",
"modmenu.descriptionTranslation.midnightcontrols": "Добавление поддержки контроллера и улучшенние элементов управления в целом.\nРазветвлен от LambdaControls, поддержка которого, к сожалению, прекращена.."
}

View File

@@ -98,7 +98,8 @@
"midnightcontrols.menu.reacharound.horizontal": "Alt Öne Blok Koyma", "midnightcontrols.menu.reacharound.horizontal": "Alt Öne Blok Koyma",
"midnightcontrols.menu.reacharound.vertical": "En Alta Blok Koyma", "midnightcontrols.menu.reacharound.vertical": "En Alta Blok Koyma",
"midnightcontrols.menu.reload_controller_mappings": "Oyun Kolu Eşleştirmelerini Yenile", "midnightcontrols.menu.reload_controller_mappings": "Oyun Kolu Eşleştirmelerini Yenile",
"midnightcontrols.menu.rotation_speed": "Dönme Hızı", "midnightcontrols.menu.rotation_speed": "Dönme Hızı (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Dönme Hızı (Y)",
"midnightcontrols.menu.title": "midnightcontrols - Ayarlar", "midnightcontrols.menu.title": "midnightcontrols - Ayarlar",
"midnightcontrols.menu.title.controller": "Oyun Kolu Seçenekleri", "midnightcontrols.menu.title.controller": "Oyun Kolu Seçenekleri",
"midnightcontrols.menu.title.controller_controls": "Oyun Kolu Kontrolleri", "midnightcontrols.menu.title.controller_controls": "Oyun Kolu Kontrolleri",
@@ -111,22 +112,23 @@
"midnightcontrols.menu.virtual_mouse.skin": "Sanal Fare Görünümü", "midnightcontrols.menu.virtual_mouse.skin": "Sanal Fare Görünümü",
"midnightcontrols.narrator.unbound": "%s Atanmamış", "midnightcontrols.narrator.unbound": "%s Atanmamış",
"midnightcontrols.not_bound": "Tuş ataması yok", "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.menu.auto_switch_mode.tooltip": "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.menu.controller2.tooltip": "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.menu.controller_type.tooltip": "Doğru tuşları göstermesi için oyun kolu türü.",
"midnightcontrols.tooltip.controls_mode": "Kontrol Modu", "midnightcontrols.menu.controls_mode.tooltip": "Kontrol Modu",
"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.menu.fast_block_placing.tooltip": "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.menu.fly_drifting.tooltip": "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.menu.fly_drifting_vertical.tooltip": "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.menu.hud_enable.tooltip": "Ekranın üstünde oyun kolu tuşu göstergesini açar/kapatır.",
"midnightcontrols.tooltip.hud_side": "HUD'un konumu", "midnightcontrols.menu.hud_side.tooltip": "HUD'un konumu",
"midnightcontrols.tooltip.mouse_speed": "Oyun kolunun taklit edilen fare hızı.", "midnightcontrols.menu.mouse_speed.tooltip": "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.menu.reacharound.horizontal.tooltip": "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.menu.reacharound.vertical.tooltip": "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.menu.reload_controller_mappings.tooltip": "Oyun kolu için eşleştirme dosyasını yeniler.",
"midnightcontrols.tooltip.rotation_speed": "Oyun kolu modunda olan kamera dönme hızı", "midnightcontrols.menu.rotation_speed.tooltip": "Oyun kolu modunda olan kamera dönme hızı (X)",
"midnightcontrols.tooltip.unfocused_input": "Oyun penceresinde değilken oyun kolu girişine izine verir.", "midnightcontrols.menu.y_axis_rotation_speed.tooltip": "Oyun kolu modunda olan kamera dönme hızı (Y)",
"midnightcontrols.tooltip.virtual_mouse": "Sanal fareyi etkinleştirir. Çift ekran oynanılacağı zaman işe yarar.", "midnightcontrols.menu.unfocused_input.tooltip": "Oyun penceresinde değilken oyun kolu girişine izine verir.",
"midnightcontrols.menu.virtual_mouse.tooltip": "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_light": "Varsayılan Aydınlık Tema",
"midnightcontrols.virtual_mouse.skin.default_dark": "Varsayılan Karanlı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_light": "İkincil Aydınlık Tema",

View File

@@ -0,0 +1,184 @@
{
"midnightcontrols.midnightconfig.title": "Розширена конфігурація MidnightControls",
"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.debug_screen": "Відкрити налагодження (F3)",
"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.slot_up": "Двинути на слот вгору",
"midnightcontrols.action.slot_down": "Повернути на слот вниз",
"midnightcontrols.action.slot_left": "Двинути на слот вліво",
"midnightcontrols.action.slot_right": "Повернути на слот вправо",
"midnightcontrols.action.sneak": "Крастися",
"midnightcontrols.action.sprint": "Біг",
"midnightcontrols.action.swap_hands": "Змінити руку",
"midnightcontrols.action.toggle_perspective": "Переключити перспективу",
"midnightcontrols.action.toggle_smooth_camera": "Переключити кінематографічну камеру",
"midnightcontrols.action.page_back": "Попередня сторінка",
"midnightcontrols.action.page_next": "Наступна сторінка",
"midnightcontrols.action.tab_back": "Попередня секція",
"midnightcontrols.action.tab_next": "Наступна секція",
"midnightcontrols.action.take": "Взяти предмет",
"midnightcontrols.action.take_all": "Взяти стак",
"midnightcontrols.action.use": "Використовувати",
"midnightcontrols.action.zoom": "Наблизити",
"midnightcontrols.action.zoom_in": "Збільшити масштаб",
"midnightcontrols.action.zoom_out": "Зменшити масштаб",
"midnightcontrols.action.zoom_reset": "Скинути масштаб",
"midnightcontrols.action.emi_page_left": "Попередня сторінка",
"midnightcontrols.action.emi_page_right": "Наступна сторінка",
"midnightcontrols.category.emi": "ЕМІ",
"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.button.l4": "L4",
"midnightcontrols.button.l5": "L5",
"midnightcontrols.button.r4": "R4",
"midnightcontrols.button.r5": "L5",
"midnightcontrols.axis.left_x+": "Лівий cтік X+",
"midnightcontrols.axis.left_y+": "Лівий cтік Y+",
"midnightcontrols.axis.right_x+": "Правий cтік X+",
"midnightcontrols.axis.right_y+": "Правий cтік 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": "і вставте ваш підсумок у редактор файлів розкладок.",
"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.dualsense": "DualSense",
"midnightcontrols.controller_type.switch": "Switch",
"midnightcontrols.controller_type.xbox": "Xbox",
"midnightcontrols.controller_type.xbox_360": "Xbox 360",
"midnightcontrols.controller_type.steam_controller": "Steam Controller",
"midnightcontrols.controller_type.steam_deck": "Steam Deck",
"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.double_tap_to_sprint": "Двічі відвести лівий стік, щоб почати бігти",
"midnightcontrols.menu.fast_block_placing": "Швидка постачання блоків",
"midnightcontrols.menu.fly_drifting": "Інерція при польоті",
"midnightcontrols.menu.fly_drifting_vertical": "Вертикальна інерція при польоті",
"midnightcontrols.menu.hud_enable": "Увімкнути іконоки контролера",
"midnightcontrols.menu.hud_side": "Розташування інтерфейсу",
"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": "Швидкість обертання по осі X",
"midnightcontrols.menu.y_axis_rotation_speed": "Швидкість обертання по осі Y",
"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": "Налаштування інтерфейсу",
"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.menu.analog_movement.tooltip": "Включає аналоговий рух, коли це можливо.",
"midnightcontrols.menu.auto_switch_mode.tooltip": "Автоматичне перемикання на новий, тільки підключений контролер.",
"midnightcontrols.menu.controller2.tooltip": "Додатковий контролер, наприклад для джой-конів.",
"midnightcontrols.menu.controller_type.tooltip": "Тип контролера, щоб правильно зіставити іконки кнопок.",
"midnightcontrols.menu.controls_mode.tooltip": "Тип контролю за грою.",
"midnightcontrols.menu.double_tap_to_sprint.tooltip": "При подвійному переміщенні на лівий стик, персонаж починає бігти.",
"midnightcontrols.menu.fast_block_placing.tooltip": "Під час польоту в творчому режимі дозволяє швидко розміщувати блоки в залежності від вашої швидкості. §cНа деяких серверах це може розцінюватися як читерство.§r",
"midnightcontrols.menu.fly_drifting.tooltip": "Під час польоту включає ванільну інерцію.",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "Під час польоту включає ванільну вертикальну інерцію.",
"midnightcontrols.menu.hud_enable.tooltip": "Переключає бачення іконок кнопок контролера на екрані.",
"midnightcontrols.menu.hud_side.tooltip": "Розташування інтерфейсу у певний бік.",
"midnightcontrols.menu.left_dead_zone.tooltip": "Мертва зона для лівого аналогового стику контролера.",
"midnightcontrols.menu.max_left_x_value.tooltip": "Змінює те, що мод в результаті вважає максимальним значенням для лівої осі X. Корисно, якщо ваша вісь не використовує весь діапазон і здається повільною.",
"midnightcontrols.menu.max_left_y_value.tooltip": "Змінює те, що мод в результаті вважає максимальним значенням для лівої осі Y. Корисно, якщо ваша вісь не використовує весь діапазон і здається повільною.",
"midnightcontrols.menu.max_right_x_value.tooltip": "Змінює те, що мод в результаті вважає максимальним значенням для правої осі X. Корисно, якщо ваша вісь не використовує весь діапазон і здається повільною.",
"midnightcontrols.menu.max_right_y_value.tooltip": "Змінює те, що мод в результаті вважає максимальним значенням для правої осі Y. Корисно, якщо ваша вісь не використовує весь діапазон і здається повільною.",
"midnightcontrols.menu.mouse_speed.tooltip": "Швидкість миші, що емульується контролером.",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Дозволяє розміщувати передній блок перед собою. §cМоже розглядатися як читерство на деяких серверах§r.",
"midnightcontrols.menu.reacharound.vertical.tooltip": "Забезпечує вертикальне охоплення. §cМоже розглядатися як шахрайство на деяких серверах§r.",
"midnightcontrols.menu.reload_controller_mappings.tooltip": "Перезавантажує файл розкладки контролерів.",
"midnightcontrols.menu.right_dead_zone.tooltip": "Мертва зона для правого аналогового стику контролера.",
"midnightcontrols.menu.rotation_speed.tooltip": "Швидкість обертання камери по осі X в режимі контролера.",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "Швидкість обертання камери по осі Y в режимі контролера.",
"midnightcontrols.menu.unfocused_input.tooltip": "Дозволити введення з контролера, навіть якщо гра сфокусована.",
"midnightcontrols.menu.virtual_mouse.tooltip": "Включити віртуальну мишу дуже корисно при грі двом на одному комп'ютері.",
"midnightcontrols.virtual_mouse.skin.default_light": "Звичайний світлий",
"midnightcontrols.virtual_mouse.skin.default_dark": "Звичайний темний",
"midnightcontrols.virtual_mouse.skin.second_light": "Додатковий світлий",
"midnightcontrols.virtual_mouse.skin.second_dark": "Додатковий темний",
"modmenu.descriptionTranslation.midnightcontrols": "Додавання підтримки контролера та покращення елементів керування в цілому.\nРозгалужений від LambdaControls, підтримка якого, на жаль, припинена..",
"midnightcontrols.menu.joystick_as_mouse": "Завжди використовуйте лівий стік як мишку",
"midnightcontrols.menu.joystick_as_mouse.tooltip": "Джойстик поводиться як миша в кожному меню.",
"midnightcontrols.menu.controller_toggle_sneak": "Перемикач присідання на контролері",
"midnightcontrols.menu.controller_toggle_sprint": "Перемикач бігу на контролері",
"midnightcontrols.menu.move_chat": "Перемістити поле введення чату вгору",
"midnightcontrols.action.controls_ring": "Показати кільце Управління",
"midnightcontrols.menu.separate_controller_profile": "Окремий профіль контролера"
}

View File

@@ -0,0 +1,214 @@
{
"midnightcontrols.midnightconfig.title": "Cấu hình MidnightControls nâng cao",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_LIGHT": "Sáng mặc định",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_DARK": "Tối mặc định",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_LIGHT": "Sáng thứ hai",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_DARK": "Tối thứ hai",
"midnightcontrols.midnightconfig.enum.ControllerType.DEFAULT": "Mặc định",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSHOCK": "DualShock",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSENSE": "DualSense",
"midnightcontrols.midnightconfig.enum.ControllerType.SWITCH": "Bộ điều khiển Switch/Wii",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX": "Bộ điều khiển Xbox One/Series",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX_360": "Bộ điều khiển Xbox 360",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_CONTROLLER": "Bộ điều khiển Steam",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_DECK": "Steam Deck",
"midnightcontrols.midnightconfig.enum.ControllerType.OUYA": "Bộ điều khiển OUYA",
"midnightcontrols.midnightconfig.enum.ControllerType.NUMBERED": "Bộ điều khiển được đánh số",
"midnightcontrols.midnightconfig.enum.ControlsMode.DEFAULT": "Bàn phím/Chuột",
"midnightcontrols.midnightconfig.enum.ControlsMode.CONTROLLER": "Bộ điều khiển",
"midnightcontrols.midnightconfig.enum.ControlsMode.TOUCHSCREEN": "Màn hình cảm ứng (WIP)",
"midnightcontrols.midnightconfig.enum.HudSide.LEFT": "Trái",
"midnightcontrols.midnightconfig.enum.HudSide.RIGHT": "Phải",
"key.midnightcontrols.look_down": "Nhìn xuống",
"key.midnightcontrols.look_left": "Nhìn trái",
"key.midnightcontrols.look_right": "Nhìn phải",
"key.midnightcontrols.look_up": "Nhìn lên",
"key.midnightcontrols.ring": "Mở vòng liên kết phím không liên kết",
"midnightcontrols.action.attack": "Tấn công",
"midnightcontrols.action.back": "Trở lại",
"midnightcontrols.action.chat": "Mở trò chuyện",
"midnightcontrols.action.controls_ring": "Mở vòng liên kết phím không liên kết",
"midnightcontrols.action.debug_screen": "Mở HUD gỡ lỗi (F3)",
"midnightcontrols.action.drop_item": "Thả vật phẩm",
"midnightcontrols.action.exit": "Màn hình thoát",
"midnightcontrols.action.forward": "Tiến",
"midnightcontrols.action.hit": "Đánh",
"midnightcontrols.action.hotbar_left": "Thanh nóng bên trái",
"midnightcontrols.action.hotbar_right": "Thanh nóng bên phải",
"midnightcontrols.action.inventory": "Túi đồ",
"midnightcontrols.action.jump": "Nhảy",
"midnightcontrols.action.left": "Trái",
"midnightcontrols.action.pause_game": "Tạm dừng trò chơi",
"midnightcontrols.action.pick_block": "Chọn khối",
"midnightcontrols.action.pickup": "Nhặt",
"midnightcontrols.action.pickup_all": "Nhặt tất cả",
"midnightcontrols.action.place": "Đặt",
"midnightcontrols.action.player_list": "Danh sách người chơi",
"midnightcontrols.action.quick_move": "Di chuyển nhanh",
"midnightcontrols.action.right": "Phải",
"midnightcontrols.action.screenshot": "Chụp màn hình",
"midnightcontrols.action.slot_up": "Di chuyển vị trí lên",
"midnightcontrols.action.slot_down": "Di chuyển vị trí xuống",
"midnightcontrols.action.slot_left": "Di chuyển vị trí qua trái",
"midnightcontrols.action.slot_right": "Di chuyển vị trí qua phải",
"midnightcontrols.action.sneak": "Đi rón rén",
"midnightcontrols.action.sprint": "Chạy nhanh",
"midnightcontrols.action.swap_hands": "Đổi tay",
"midnightcontrols.action.toggle_perspective": "Đổi góc nhìn",
"midnightcontrols.action.toggle_smooth_camera": "Đổi góc nhìn kịch tính",
"midnightcontrols.action.page_back": "Trang trước",
"midnightcontrols.action.page_next": "Trang tiếp theo",
"midnightcontrols.action.tab_back": "Tab trước",
"midnightcontrols.action.tab_next": "Tab trước",
"midnightcontrols.action.take": "Lấy vật phẩm",
"midnightcontrols.action.take_all": "Lấy Stack",
"midnightcontrols.action.use": "Sử dụng",
"midnightcontrols.action.zoom": "Phóng",
"midnightcontrols.action.zoom_in": "Tăng Phóng",
"midnightcontrols.action.zoom_out": "Giảm Phóng",
"midnightcontrols.action.zoom_reset": "Đặt lại Phóng",
"midnightcontrols.action.emi_page_left": "Trang trước",
"midnightcontrols.action.emi_page_right": "Trang tiếp theo",
"midnightcontrols.category.emi": "EMI",
"midnightcontrols.button.a": "A",
"midnightcontrols.button.b": "B",
"midnightcontrols.button.x": "X",
"midnightcontrols.button.y": "Y",
"midnightcontrols.button.left_bumper": "Cản trái",
"midnightcontrols.button.right_bumper": "Cản phải",
"midnightcontrols.button.back": "Trở lại",
"midnightcontrols.button.start": "Bắt đầu",
"midnightcontrols.button.guide": "Hướng dẫn",
"midnightcontrols.button.left_thumb": "Ngón cái trái",
"midnightcontrols.button.right_thumb": "Ngón cái phải",
"midnightcontrols.button.dpad_up": "DPAD lên",
"midnightcontrols.button.dpad_right": "DPAD qua phải",
"midnightcontrols.button.dpad_down": "DPAD xuống",
"midnightcontrols.button.dpad_left": "DPAD qua trái",
"midnightcontrols.button.l4": "L4",
"midnightcontrols.button.l5": "L5",
"midnightcontrols.button.r4": "R4",
"midnightcontrols.button.r5": "L5",
"midnightcontrols.axis.left_x+": "X+ trái",
"midnightcontrols.axis.left_y+": "Y+ phải",
"midnightcontrols.axis.right_x+": "X+ phải",
"midnightcontrols.axis.right_y+": "Y+ trái",
"midnightcontrols.axis.left_trigger": "Bấm nút trái",
"midnightcontrols.axis.right_trigger": "Bấm nút phải",
"midnightcontrols.axis.left_x-": "X- trái",
"midnightcontrols.axis.left_y-": "Y- phải",
"midnightcontrols.axis.right_x-": "X- phải",
"midnightcontrols.axis.right_y-": "Y- trái",
"midnightcontrols.button.unknown": "Không biết (%d)",
"midnightcontrols.controller.tutorial.title": "Chơi trò chơi với Bộ điều khiển!",
"midnightcontrols.controller.tutorial.description": "Đi tới %s -> %s -> %s",
"midnightcontrols.controller.connected": "Bộ điều khiển %d đã được kết nối.",
"midnightcontrols.controller.disconnected": "Bộ điều khiển %d đã bị ngắt kết nối.",
"midnightcontrols.controller.mappings.1": "Để định cấu hình mapping bộ điều khiển, vui lòng sử dụng %s",
"midnightcontrols.controller.mappings.3": "và dán mapping vào trình chỉnh sửa tệp mapping.",
"midnightcontrols.controller.mappings.error": "Lỗi khi tải mapping.",
"midnightcontrols.controller.mappings.error.write": "Lỗi khi ghi mapping vào tệp.",
"midnightcontrols.controller.mappings.updated": "Mapping đã được cập nhật!",
"midnightcontrols.controller_type.default": "Mặc định",
"midnightcontrols.controller_type.dualshock": "DualShock",
"midnightcontrols.controller_type.dualsense": "DualSense",
"midnightcontrols.controller_type.switch": "Bộ điều khiển Switch/Wii",
"midnightcontrols.controller_type.xbox": "Bộ điều khiển Xbox One/Series",
"midnightcontrols.controller_type.xbox_360": "Bộ điều khiển Xbox 360",
"midnightcontrols.controller_type.steam_controller": "Bộ điều khiển Steam",
"midnightcontrols.controller_type.steam_deck": "Steam Deck",
"midnightcontrols.controller_type.ouya": "Bộ điều khiển OUYA",
"midnightcontrols.controller_type.numbered": "Bộ điều khiển được đánh số",
"midnightcontrols.controls_mode.default": "Bàn phím/Chuột",
"midnightcontrols.controls_mode.controller": "Bộ điều khiển",
"midnightcontrols.controls_mode.touchscreen": "Màn hình cảm ứng (WIP)",
"midnightcontrols.hud_side.left": "Trái",
"midnightcontrols.hud_side.right": "Phải",
"midnightcontrols.menu.analog_movement": "Chuyển động tương tự",
"midnightcontrols.menu.analog_movement.tooltip": "Khi có thể, hãy bật chuyển động tương tự.",
"midnightcontrols.menu.auto_switch_mode": "Chế độ tự động chuyển đổi",
"midnightcontrols.menu.auto_switch_mode.tooltip": "Có nên tự động chuyển chế độ điều khiển sang Bộ điều khiển nếu một bộ điều khiển được kết nối hay không.",
"midnightcontrols.menu.controller": "Bộ điều khiển",
"midnightcontrols.menu.controller2": "Bộ điều khiển thứ hai",
"midnightcontrols.menu.controller2.tooltip": "Bộ điều khiển thứ hai để sử dụng, cho phép (ví dụ) hỗ trợ Joy-Cons.",
"midnightcontrols.menu.controller_toggle_sneak": "Đổi đi rón rén trên bộ điều khiển",
"midnightcontrols.menu.controller_toggle_sprint": "Đổi chạy nhanh trên bộ điều khiển",
"midnightcontrols.menu.controller_type": "Loại bộ điều khiển",
"midnightcontrols.menu.controller_type.tooltip": "Loại bộ điều khiển bạn đang sử dụng (cần thiết để hiển thị các nút chính xác)",
"midnightcontrols.menu.controls_mode": "Chế độ",
"midnightcontrols.menu.controls_mode.tooltip": "Chế độ điều khiển.",
"midnightcontrols.menu.double_tap_to_sprint": "Nhấn đúp để chạy nhanh",
"midnightcontrols.menu.double_tap_to_sprint.tooltip": "Chuyển đổi liệu phím Tiến lên phía trước có khiến người chơi chạy nhanh khi nhấn chạm nhanh hai lần hay không",
"midnightcontrols.menu.fast_block_placing": "Đặt khối nhanh",
"midnightcontrols.menu.fast_block_placing.tooltip": "Trong khi bay ở chế độ sáng tạo, cho phép đặt khối nhanh tùy thuộc vào tốc độ của bạn. §cTrên một số máy chủ, điều này có thể bị coi là gian lận.",
"midnightcontrols.menu.fly_drifting": "Trôi bay",
"midnightcontrols.menu.fly_drifting.tooltip": "Khi đang bay, cho phép trôi dọc/xen kẽ truyền thống.",
"midnightcontrols.menu.fly_drifting_vertical": "Trôi theo phương thẳng đứng",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "Trong khi bay, cho phép trôi dọc/xen kẽ truyền thống.",
"midnightcontrols.menu.hud_enable": "Bật HUD",
"midnightcontrols.menu.hud_enable.tooltip": "Chuyển đổi chỉ báo nút điều khiển trên màn hình.",
"midnightcontrols.menu.hud_side": "Phía HUD",
"midnightcontrols.menu.hud_side.tooltip": "Vị trí của HUD.",
"midnightcontrols.menu.invert_right_x_axis": "Đảo ngược X phải",
"midnightcontrols.menu.invert_right_y_axis": "Đảo ngược Y phải",
"midnightcontrols.menu.joystick_as_mouse": "Luôn sử dụng thanh bên trái làm chuột",
"midnightcontrols.menu.joystick_as_mouse.tooltip": "Làm cho cần điều khiển hoạt động giống như một con chuột trong mọi menu.",
"midnightcontrols.menu.keyboard_controls": "Điều khiển bàn phím...",
"midnightcontrols.menu.left_dead_zone": "Vùng chết thanh bên trái",
"midnightcontrols.menu.left_dead_zone.tooltip": "Vùng chết cho thanh analog bên trái của bộ điều khiển.",
"midnightcontrols.menu.mappings.open_input_str": "Mở Trình chỉnh sửa tệp mapping",
"midnightcontrols.menu.max_left_x_value": "Giá trị tối đa của trục X bên trái",
"midnightcontrols.menu.max_left_x_value.tooltip": "Thay đổi những gì mod coi là giá trị cao nhất cho trục X bên trái. Hữu ích nếu trục của bạn không sử dụng hết phạm vi và có vẻ chậm.",
"midnightcontrols.menu.max_left_y_value": "Giá trị tối đa của trục Y bên trái",
"midnightcontrols.menu.max_left_y_value.tooltip": "Thay đổi những gì mod coi là giá trị cao nhất cho trục Y bên trái. Hữu ích nếu trục của bạn không sử dụng hết phạm vi và có vẻ chậm.",
"midnightcontrols.menu.max_right_x_value": "Giá trị tối đa của trục X bên phải",
"midnightcontrols.menu.max_right_x_value.tooltip": "Thay đổi những gì mod coi là giá trị cao nhất cho trục X bên phải. Hữu ích nếu trục của bạn không sử dụng hết phạm vi và có vẻ chậm.",
"midnightcontrols.menu.max_right_y_value": "Giá trị tối đa của trục Y bên phải",
"midnightcontrols.menu.max_right_y_value.tooltip": "Thay đổi những gì mod coi là giá trị cao nhất cho trục Y bên phải. Hữu ích nếu trục của bạn không sử dụng hết phạm vi và có vẻ chậm.",
"midnightcontrols.menu.mouse_speed": "Tốc độ chuột",
"midnightcontrols.menu.mouse_speed.tooltip": "Tốc độ chuột mô phỏng của bộ điều khiển.",
"midnightcontrols.menu.move_chat": "Di chuyển hộp nhập trò chuyện lên trên cùng",
"midnightcontrols.menu.move_chat.tooltip": "Di chuyển phần nhập trò chuyện lên trên cùng để nhập tốt hơn trên các thiết bị có bàn phím ảo.",
"midnightcontrols.menu.reacharound.horizontal": "Đặt khối phía trước",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Cho phép đặt khối phía trước, §cmcó thể bị coi là gian lận trên một số máy chủ §r.",
"midnightcontrols.menu.reacharound.vertical": "Tiếp cận theo chiều dọc",
"midnightcontrols.menu.reacharound.vertical.tooltip": "Cho phép tiếp cận theo chiều dọc, §cm có thể bị coi là gian lận trên một số máy chủ §r.",
"midnightcontrols.menu.reload_controller_mappings": "Tải lại mapping bộ điều khiển",
"midnightcontrols.menu.reload_controller_mappings.tooltip": "Tải lại tệp mapping bộ điều khiển.",
"midnightcontrols.menu.right_dead_zone": "Vùng chết thanh bên phải",
"midnightcontrols.menu.right_dead_zone.tooltip": "Vùng chết cho thanh analog bên phải của bộ điều khiển.",
"midnightcontrols.menu.rotation_speed": "Tốc độ quay trục X",
"midnightcontrols.menu.rotation_speed.tooltip": "Tốc độ quay Trục X của máy ảnh ở chế độ bộ điều khiển.",
"midnightcontrols.menu.y_axis_rotation_speed": "Tốc độ quay trục Y",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "Tốc độ quay Trục Y của máy ảnh ở chế độ bộ điều khiển.",
"midnightcontrols.menu.separate_controller_profile": "Hồ sơ bộ điều khiển riêng biệt",
"midnightcontrols.menu.separator.controller": "Bộ điều khiển",
"midnightcontrols.menu.separator.general": "Chung",
"midnightcontrols.menu.title": "MidnightControls - Cài đặt",
"midnightcontrols.menu.title.controller": "Tùy chọn bộ điều khiển",
"midnightcontrols.menu.title.controller_controls": "Ràng buộc bộ điều khiển",
"midnightcontrols.menu.title.gameplay": "Tuỳ chọn Gameplay",
"midnightcontrols.menu.title.general": "Tuỳ chọn chung",
"midnightcontrols.menu.title.hud": "Tuỳ chọn HUD",
"midnightcontrols.menu.title.mappings.string": "Trình chỉnh sửa tệp mapping",
"midnightcontrols.menu.title.visual": "Tùy chọn giao diện",
"midnightcontrols.menu.unfocused_input": "Đầu vào không tập trung",
"midnightcontrols.menu.unfocused_input.tooltip": "Cho phép đầu vào bộ điều khiển khi cửa sổ không được đặt tiêu điểm.",
"midnightcontrols.menu.virtual_mouse": "Chuột ảo",
"midnightcontrols.menu.virtual_mouse.tooltip": "Bật chuột ảo, rất hữu ích trong quá trình chia đôi màn hình.",
"midnightcontrols.menu.virtual_mouse.skin": "Skin chuột ảo",
"midnightcontrols.menu.hide_cursor": "Ẩn con trỏ chuột bình thường",
"midnightcontrols.menu.hide_cursor.tooltip": "Ẩn con trỏ chuột bình thường, chỉ để lại con chuột ảo.",
"midnightcontrols.narrator.unbound": "Bỏ ràng buộc %s",
"midnightcontrols.not_bound": "Không ràng buộc",
"midnightcontrols.virtual_mouse.skin.default_light": "Sáng mặc định",
"midnightcontrols.virtual_mouse.skin.default_dark": "Tối mặc định",
"midnightcontrols.virtual_mouse.skin.second_light": "Sáng thứ hai",
"midnightcontrols.virtual_mouse.skin.second_dark": "Tối thứ hai",
"midnightcontrols.midnightconfig.category.controller": "Bộ điều khiển",
"midnightcontrols.midnightconfig.category.misc": "Khác",
"midnightcontrols.midnightconfig.category.screens": "Màn hình",
"midnightcontrols.midnightconfig.category.gameplay": "Gameplay",
"midnightcontrols.midnightconfig.category.visual": "Hình ảnh",
"modmenu.descriptionTranslation.midnightcontrols": "Thêm hỗ trợ bộ điều khiển và kiểm soát nâng cao tổng thể.\nĐược phân tách từ LambdaControls, đáng tiếc là đã ngừng hoạt động."
}

View File

@@ -104,7 +104,8 @@
"midnightcontrols.menu.reacharound.vertical": "垂直方向方块放置辅助", "midnightcontrols.menu.reacharound.vertical": "垂直方向方块放置辅助",
"midnightcontrols.menu.reload_controller_mappings": "重新加载手柄按键映射", "midnightcontrols.menu.reload_controller_mappings": "重新加载手柄按键映射",
"midnightcontrols.menu.right_dead_zone": "右摇杆死区", "midnightcontrols.menu.right_dead_zone": "右摇杆死区",
"midnightcontrols.menu.rotation_speed": "镜头旋转速度", "midnightcontrols.menu.rotation_speed": "镜头旋转速度 (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "镜头旋转速度 (Y)",
"midnightcontrols.menu.separator.controller": "手柄", "midnightcontrols.menu.separator.controller": "手柄",
"midnightcontrols.menu.separator.general": "通用", "midnightcontrols.menu.separator.general": "通用",
"midnightcontrols.menu.title": "midnightcontrols — 设置", "midnightcontrols.menu.title": "midnightcontrols — 设置",
@@ -120,29 +121,30 @@
"midnightcontrols.menu.virtual_mouse.skin": "虚拟鼠标指针样式", "midnightcontrols.menu.virtual_mouse.skin": "虚拟鼠标指针样式",
"midnightcontrols.narrator.unbound": "取消绑定 %s", "midnightcontrols.narrator.unbound": "取消绑定 %s",
"midnightcontrols.not_bound": "未绑定", "midnightcontrols.not_bound": "未绑定",
"midnightcontrols.tooltip.analog_movement": "若游戏机制允许,则可根据推动摇杆的力度与幅度决定移动的速度。", "midnightcontrols.menu.analog_movement.tooltip": "若游戏机制允许,则可根据推动摇杆的力度与幅度决定移动的速度。",
"midnightcontrols.tooltip.auto_switch_mode": "如果已有手柄连接,则自动切换为手柄操作模式。", "midnightcontrols.menu.auto_switch_mode.tooltip": "如果已有手柄连接,则自动切换为手柄操作模式。",
"midnightcontrols.tooltip.controller2": "使用额外的手柄,比如将一左一右的两个 Joy-Con 合为一个功能完全的手柄。", "midnightcontrols.menu.controller2.tooltip": "使用额外的手柄,比如将一左一右的两个 Joy-Con 合为一个功能完全的手柄。",
"midnightcontrols.tooltip.controller_type": "选择手柄类型,以显示对应的按键图标。", "midnightcontrols.menu.controller_type.tooltip": "选择手柄类型,以显示对应的按键图标。",
"midnightcontrols.tooltip.controls_mode": "操作模式", "midnightcontrols.menu.controls_mode.tooltip": "操作模式",
"midnightcontrols.tooltip.fast_block_placing": "在创造模式中处于飞行状态时,可以根据你飞行的速度快速放置方块。\n§c在部分服务器可能会被认定为作弊。", "midnightcontrols.menu.fast_block_placing.tooltip": "在创造模式中处于飞行状态时,可以根据你飞行的速度快速放置方块。\n§c在部分服务器可能会被认定为作弊。",
"midnightcontrols.tooltip.fly_drifting": "处于飞行状态时,启用原版的水平方向飞行惯性(缓停滑行)。", "midnightcontrols.menu.fly_drifting.tooltip": "处于飞行状态时,启用原版的水平方向飞行惯性(缓停滑行)。",
"midnightcontrols.tooltip.fly_drifting_vertical": "处于飞行状态时,启用原版的垂直方向飞行惯性(缓停滑行)。", "midnightcontrols.menu.fly_drifting_vertical.tooltip": "处于飞行状态时,启用原版的垂直方向飞行惯性(缓停滑行)。",
"midnightcontrols.tooltip.hud_enable": "显示手柄按键操作提示。", "midnightcontrols.menu.hud_enable.tooltip": "显示手柄按键操作提示。",
"midnightcontrols.tooltip.hud_side": "HUD的位置位于画面的哪一侧。", "midnightcontrols.menu.hud_side.tooltip": "HUD的位置位于画面的哪一侧。",
"midnightcontrols.tooltip.left_dead_zone": "左摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。", "midnightcontrols.menu.left_dead_zone.tooltip": "左摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。",
"midnightcontrols.tooltip.max_left_x_value": "更改左摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致在识别摇杆输入的精确值的情况下左右移动较为缓慢等问题本项可能会有所帮助。", "midnightcontrols.menu.max_left_x_value.tooltip": "更改左摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致在识别摇杆输入的精确值的情况下左右移动较为缓慢等问题本项可能会有所帮助。",
"midnightcontrols.tooltip.max_left_y_value": "更改左摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致在识别摇杆输入的精确值的情况下前后移动较为缓慢等问题本项可能会有所帮助。", "midnightcontrols.menu.max_left_y_value.tooltip": "更改左摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致在识别摇杆输入的精确值的情况下前后移动较为缓慢等问题本项可能会有所帮助。",
"midnightcontrols.tooltip.max_right_x_value": "更改右摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致镜头左右旋转较为缓慢等问题本项可能会有所帮助。", "midnightcontrols.menu.max_right_x_value.tooltip": "更改右摇杆X轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致镜头左右旋转较为缓慢等问题本项可能会有所帮助。",
"midnightcontrols.tooltip.max_right_y_value": "更改右摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致镜头上下旋转较为缓慢等问题本项可能会有所帮助。", "midnightcontrols.menu.max_right_y_value.tooltip": "更改右摇杆Y轴最大值的识别范围。\n若感觉即便推满摇杆也未达到最大的输入值导致镜头上下旋转较为缓慢等问题本项可能会有所帮助。",
"midnightcontrols.tooltip.mouse_speed": "手柄模拟的鼠标的移动速度。", "midnightcontrols.menu.mouse_speed.tooltip": "手柄模拟的鼠标的移动速度。",
"midnightcontrols.tooltip.reacharound.horizontal": "启用水平方向方块放置辅助,可在脚下方块的前方放置方块。\n§c在部分服务器可能会被认定为作弊。", "midnightcontrols.menu.reacharound.horizontal.tooltip": "启用水平方向方块放置辅助,可在脚下方块的前方放置方块。\n§c在部分服务器可能会被认定为作弊。",
"midnightcontrols.tooltip.reacharound.vertical": "启用垂直方向方块放置辅助,可在脚下方块的下方放置方块。\n§c在部分服务器可能会被认定为作弊。", "midnightcontrols.menu.reacharound.vertical.tooltip": "启用垂直方向方块放置辅助,可在脚下方块的下方放置方块。\n§c在部分服务器可能会被认定为作弊。",
"midnightcontrols.tooltip.reload_controller_mappings": "重新加载手柄的按键映射文件。", "midnightcontrols.menu.reload_controller_mappings.tooltip": "重新加载手柄的按键映射文件。",
"midnightcontrols.tooltip.right_dead_zone": "右摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。", "midnightcontrols.menu.right_dead_zone.tooltip": "右摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。",
"midnightcontrols.tooltip.rotation_speed": "手柄操作模式下的镜头旋转速度。", "midnightcontrols.menu.rotation_speed.tooltip": "手柄操作模式下的镜头旋转速度。(X)",
"midnightcontrols.tooltip.unfocused_input": "即使游戏窗口处于非活动状态,也允许手柄进行按键输入。", "midnightcontrols.menu.y_axis_rotation_speed.tooltip": "手柄操作模式下的镜头旋转速度。(Y)",
"midnightcontrols.tooltip.virtual_mouse": "启用虚拟鼠标,在分屏的情况下很有用。", "midnightcontrols.menu.unfocused_input.tooltip": "即使游戏窗口处于非活动状态,也允许手柄进行按键输入。",
"midnightcontrols.menu.virtual_mouse.tooltip": "启用虚拟鼠标,在分屏的情况下很有用。",
"midnightcontrols.virtual_mouse.skin.default_light": "默认样式(白色)", "midnightcontrols.virtual_mouse.skin.default_light": "默认样式(白色)",
"midnightcontrols.virtual_mouse.skin.default_dark": "默认样式(黑色)", "midnightcontrols.virtual_mouse.skin.default_dark": "默认样式(黑色)",
"midnightcontrols.virtual_mouse.skin.second_light": "额外样式(白色)", "midnightcontrols.virtual_mouse.skin.second_light": "额外样式(白色)",

View File

@@ -0,0 +1,214 @@
{
"midnightcontrols.midnightconfig.title": "Midnightcontrols 進階設定",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_LIGHT": "預設淺色",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.DEFAULT_DARK": "預設深色",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_LIGHT": "額外淺色",
"midnightcontrols.midnightconfig.enum.VirtualMouseSkin.SECOND_DARK": "額外深色",
"midnightcontrols.midnightconfig.enum.ControllerType.DEFAULT": "預設",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSHOCK": "DualShock",
"midnightcontrols.midnightconfig.enum.ControllerType.DUALSENSE": "DualSense",
"midnightcontrols.midnightconfig.enum.ControllerType.SWITCH": "SwitchWii 手把",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX": "Xbox OneSeries 手把",
"midnightcontrols.midnightconfig.enum.ControllerType.XBOX_360": "Xbox 360 手把",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_CONTROLLER": "Steam 手把",
"midnightcontrols.midnightconfig.enum.ControllerType.STEAM_DECK": "Steam Deck",
"midnightcontrols.midnightconfig.enum.ControllerType.OUYA": "OUYA 手把",
"midnightcontrols.midnightconfig.enum.ControllerType.NUMBERED": "Numbered 手把",
"midnightcontrols.midnightconfig.enum.ControlsMode.DEFAULT": "鍵盤/滑鼠",
"midnightcontrols.midnightconfig.enum.ControlsMode.CONTROLLER": "手把",
"midnightcontrols.midnightconfig.enum.ControlsMode.TOUCHSCREEN": "觸控螢幕",
"midnightcontrols.midnightconfig.enum.HudSide.LEFT": "左",
"midnightcontrols.midnightconfig.enum.HudSide.RIGHT": "右",
"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.controls_ring": "開啟未綁定",
"midnightcontrols.action.debug_screen": "開啟除錯畫面F3",
"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.slot_up": "上移物品欄",
"midnightcontrols.action.slot_down": "下移物品欄",
"midnightcontrols.action.slot_left": "左移物品欄",
"midnightcontrols.action.slot_right": "右移物品欄",
"midnightcontrols.action.sneak": "潛行",
"midnightcontrols.action.sprint": "跑步",
"midnightcontrols.action.swap_hands": "與副手交換",
"midnightcontrols.action.toggle_perspective": "切換視角",
"midnightcontrols.action.toggle_smooth_camera": "切換電影視角",
"midnightcontrols.action.page_back": "上一頁",
"midnightcontrols.action.page_next": "下一頁",
"midnightcontrols.action.tab_back": "上一個頁籤",
"midnightcontrols.action.tab_next": "下一個頁籤",
"midnightcontrols.action.take": "拿取物品",
"midnightcontrols.action.take_all": "拿取全部",
"midnightcontrols.action.use": "使用物品/放置方塊",
"midnightcontrols.action.zoom": "視野縮放",
"midnightcontrols.action.zoom_in": "縮放時將視野推近",
"midnightcontrols.action.zoom_out": "縮放時將視野拉遠",
"midnightcontrols.action.zoom_reset": "縮放時重置縮放距離",
"midnightcontrols.action.emi_page_left": "上一頁",
"midnightcontrols.action.emi_page_right": "下一頁",
"midnightcontrols.category.emi": "EMI",
"midnightcontrols.button.a": "A",
"midnightcontrols.button.b": "B",
"midnightcontrols.button.x": "X",
"midnightcontrols.button.y": "Y",
"midnightcontrols.button.left_bumper": "LB 鍵",
"midnightcontrols.button.right_bumper": "RB 鍵",
"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.button.l4": "L4",
"midnightcontrols.button.l5": "L5",
"midnightcontrols.button.r4": "R4",
"midnightcontrols.button.r5": "L5",
"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.tutorial.title": "使用手把玩遊戲!",
"midnightcontrols.controller.tutorial.description": "前往 %s -> %s -> %s",
"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.dualsense": "DualSense",
"midnightcontrols.controller_type.switch": "SwitchWii 手把",
"midnightcontrols.controller_type.xbox": "Xbox OneSeries 手把",
"midnightcontrols.controller_type.xbox_360": "Xbox 360 手把",
"midnightcontrols.controller_type.steam_controller": "Steam 手把",
"midnightcontrols.controller_type.steam_deck": "Steam Deck",
"midnightcontrols.controller_type.ouya": "OUYA",
"midnightcontrols.controller_type.numbered": "Numbered 手把",
"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.analog_movement.tooltip": "若遊戲機制允許,則可根據推動搖桿的力度與幅度決定移動的速度。",
"midnightcontrols.menu.auto_switch_mode": "自動切換模式",
"midnightcontrols.menu.auto_switch_mode.tooltip": "如果已有搖桿連接,則自動切換為搖桿操作模式。",
"midnightcontrols.menu.controller": "搖桿",
"midnightcontrols.menu.controller2": "額外搖桿",
"midnightcontrols.menu.controller2.tooltip": "使用額外的搖桿,例如將左右兩個的 Joy-Con 合為一個功能完全的搖桿。",
"midnightcontrols.menu.controller_toggle_sneak": "搖桿潛行切換",
"midnightcontrols.menu.controller_toggle_sprint": "搖桿衝刺切換",
"midnightcontrols.menu.controller_type": "搖桿類型",
"midnightcontrols.menu.controller_type.tooltip": "你正在使用的搖桿類型(需要以顯示正確的按鈕)",
"midnightcontrols.menu.controls_mode": "模式",
"midnightcontrols.menu.controls_mode.tooltip": "操作模式。",
"midnightcontrols.menu.double_tap_to_sprint": "雙擊以奔跑",
"midnightcontrols.menu.double_tap_to_sprint.tooltip": "切換是否啟用向前行走按鍵,快速按兩次走路讓玩家奔跑",
"midnightcontrols.menu.fast_block_placing": "快速放置方塊",
"midnightcontrols.menu.fast_block_placing.tooltip": "在創造模式中處於飛行狀態時,可以根據你飛行的速度快速放置方塊。\n§c在部分伺服器可能會被認定為作弊。",
"midnightcontrols.menu.fly_drifting": "水平方向飛行慣性",
"midnightcontrols.menu.fly_drifting.tooltip": "處於飛行狀態時,啟用原版的水平方向飛行慣性(緩停滑行)。",
"midnightcontrols.menu.fly_drifting_vertical": "垂直方向飛行慣性",
"midnightcontrols.menu.fly_drifting_vertical.tooltip": "處於飛行狀態時,啟用原版的垂直方向飛行慣性(緩停滑行)。",
"midnightcontrols.menu.hud_enable": "啟用 HUD",
"midnightcontrols.menu.hud_enable.tooltip": "顯示搖桿按鍵操作提示。",
"midnightcontrols.menu.hud_side": "HUD 位置",
"midnightcontrols.menu.hud_side.tooltip": "HUD 的位置位於畫面的哪一側。",
"midnightcontrols.menu.invert_right_x_axis": "反轉右搖桿 X 軸",
"midnightcontrols.menu.invert_right_y_axis": "反轉右搖桿 Y 軸",
"midnightcontrols.menu.joystick_as_mouse": "總是將左搖桿作為滑鼠",
"midnightcontrols.menu.joystick_as_mouse.tooltip": "讓左搖桿在每個選單的像滑鼠一樣。",
"midnightcontrols.menu.keyboard_controls": "鍵盤控制...",
"midnightcontrols.menu.left_dead_zone": "左搖桿死區",
"midnightcontrols.menu.left_dead_zone.tooltip": "左搖桿設定的死區。",
"midnightcontrols.menu.mappings.open_input_str": "編輯按鍵映射檔案",
"midnightcontrols.menu.max_left_x_value": "左搖桿 X 軸最大值識別範圍",
"midnightcontrols.menu.max_left_x_value.tooltip": "更改左搖桿 X 軸最大值的識別範圍。若感覺即便推滿搖桿也未達到最大的輸入值,導致在識別搖桿輸入的精確值的情況下,左右移動較為緩慢等問題,本項可能會有所幫助。",
"midnightcontrols.menu.max_left_y_value": "左搖桿 Y 軸最大值識別範圍",
"midnightcontrols.menu.max_left_y_value.tooltip": "更改左搖桿 Y 軸最大值的識別範圍。若感覺即便推滿搖桿也未達到最大的輸入值,導致在識別搖桿輸入的精確值的情況下,前後移動較為緩慢等問題,本項可能會有所幫助。",
"midnightcontrols.menu.max_right_x_value": "右搖桿 X 軸最大值識別範圍",
"midnightcontrols.menu.max_right_x_value.tooltip": "更改右搖桿 X 軸最大值的識別範圍。若感覺即便推滿搖桿也未達到最大的輸入值,導致鏡頭左右旋轉較為緩慢等問題,本項可能會有所幫助。",
"midnightcontrols.menu.max_right_y_value": "右搖桿 Y 軸最大值識別範圍",
"midnightcontrols.menu.max_right_y_value.tooltip": "更改右搖桿 Y 軸最大值的識別範圍。若感覺即便推滿搖桿也未達到最大的輸入值,導致鏡頭上下旋轉較為緩慢等問題,本項可能會有所幫助。",
"midnightcontrols.menu.mouse_speed": "游標移動速度",
"midnightcontrols.menu.mouse_speed.tooltip": "搖桿模擬的游標的移動速度。",
"midnightcontrols.menu.move_chat": "將聊天輸入框移至頂部",
"midnightcontrols.menu.move_chat.tooltip": "將聊天輸入欄位移至頂部,以便在使用虛擬鍵盤的裝置上更好地輸入。",
"midnightcontrols.menu.reacharound.horizontal": "水平方向方塊放置輔助",
"midnightcontrols.menu.reacharound.horizontal.tooltip": "啟用水平方向方塊放置輔助可在腳下方塊的前方放置方塊。§c在部分伺服器可能會被認定為作弊§r。",
"midnightcontrols.menu.reacharound.vertical": "垂直方向方塊放置輔助",
"midnightcontrols.menu.reacharound.vertical.tooltip": "啟用垂直方向方塊放置輔助可在腳下方塊的下方放置方塊。§c在部分伺服器可能會被認定為作弊§r。",
"midnightcontrols.menu.reload_controller_mappings": "重新載入搖桿按鍵映射",
"midnightcontrols.menu.reload_controller_mappings.tooltip": "重新載入搖桿的按鍵映射檔案。",
"midnightcontrols.menu.right_dead_zone": "右搖桿死區",
"midnightcontrols.menu.right_dead_zone.tooltip": "右搖桿設定的死區。",
"midnightcontrols.menu.rotation_speed": "X 軸鏡頭旋轉速度",
"midnightcontrols.menu.rotation_speed.tooltip": "搖桿操作模式下的鏡頭旋轉速度。X",
"midnightcontrols.menu.y_axis_rotation_speed": "Y 軸鏡頭旋轉速度",
"midnightcontrols.menu.y_axis_rotation_speed.tooltip": "搖桿操作模式下的鏡頭旋轉速度。Y",
"midnightcontrols.menu.separate_controller_profile": "搖桿設定檔",
"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.unfocused_input.tooltip": "即使遊戲窗口處於非活動狀態,也允許搖桿進行按鍵輸入。",
"midnightcontrols.menu.virtual_mouse": "虛擬游標",
"midnightcontrols.menu.virtual_mouse.tooltip": "啟用虛擬游標,在分屏的情況下很有用。",
"midnightcontrols.menu.virtual_mouse.skin": "虛擬游標樣式",
"midnightcontrols.menu.hide_cursor": "隱藏正常游標",
"midnightcontrols.menu.hide_cursor.tooltip": "隱藏正常游標",
"midnightcontrols.narrator.unbound": "取消綁定 %s",
"midnightcontrols.not_bound": "未綁定",
"midnightcontrols.virtual_mouse.skin.default_light": "預設樣式(白色)",
"midnightcontrols.virtual_mouse.skin.default_dark": "預設樣式(黑色)",
"midnightcontrols.virtual_mouse.skin.second_light": "額外樣式(白色)",
"midnightcontrols.virtual_mouse.skin.second_dark": "額外樣式(黑色)",
"midnightcontrols.midnightconfig.category.controller": "手把",
"midnightcontrols.midnightconfig.category.misc": "雜項",
"midnightcontrols.midnightconfig.category.screens": "螢幕",
"midnightcontrols.midnightconfig.category.gameplay": "遊戲內容",
"midnightcontrols.midnightconfig.category.visual": "界面",
"modmenu.descriptionTranslation.midnightcontrols": "增加控制器支援和整體增強控制。\n此版本是從 LambdaControls 分支而來,可惜的是 LambdaControls 已經停止維護。"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Some files were not shown because too many files have changed in this diff Show More