mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-13 15:25:08 +01:00
Compare commits
4 Commits
1.6.0-1.16
...
1.7.1+1.17
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1039ea5344 | ||
|
|
bb19ea4da5 | ||
|
|
a1773cc0d9 | ||
|
|
e652390583 |
26
.github/workflows/gradlebuild.yml
vendored
Executable file
26
.github/workflows/gradlebuild.yml
vendored
Executable file
@@ -0,0 +1,26 @@
|
||||
name: Gradle Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 16
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 16
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Artifacts
|
||||
path: ./build/libs/
|
||||
40
.github/workflows/gradlepublish.yml
vendored
Executable file
40
.github/workflows/gradlepublish.yml
vendored
Executable file
@@ -0,0 +1,40 @@
|
||||
name: Gradle Package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 16
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 16
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Artifacts
|
||||
path: ./build/libs/
|
||||
|
||||
# The USERNAME and PASSWORD need to correspond to the credentials environment variables used in
|
||||
# the publishing section of your build.gradle
|
||||
- name: Publish to GitHub Packages and other Mavens
|
||||
run: ./gradlew publish
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.ref }}
|
||||
RUN_COUNT: ${{ github.run_number }}
|
||||
REPO_NAME: ${{ github.repository }}
|
||||
USERNAME: ${{ github.actor }}
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
LAMBDACONTROLS_MAVEN: ${{ secrets.MAVEN_URL }}
|
||||
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
|
||||
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||
23
.github/workflows/modrinth_update.yml
vendored
Executable file
23
.github/workflows/modrinth_update.yml
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
name: Gradle Build
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 16
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 16
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- name: Build with Gradle
|
||||
env:
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
run: ./gradlew publishModrinth
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# LambdAurora's ignore file
|
||||
#
|
||||
# v0.13
|
||||
# v0.15
|
||||
|
||||
# JetBrains
|
||||
.idea/
|
||||
@@ -53,6 +53,8 @@ __pycache__/
|
||||
# OS
|
||||
## Windows
|
||||
desktop.ini
|
||||
# MacOS
|
||||
.DS_Store
|
||||
|
||||
# File types
|
||||
*.dll
|
||||
@@ -61,10 +63,13 @@ desktop.ini
|
||||
*.lib
|
||||
lib*.a
|
||||
*.png~
|
||||
*.tar.?z
|
||||
|
||||
# Common
|
||||
bin/
|
||||
build/
|
||||
dist/
|
||||
lib/
|
||||
obj/
|
||||
run/
|
||||
target/
|
||||
|
||||
47
CHANGELOG.md
47
CHANGELOG.md
@@ -1,6 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
## v1.0.0
|
||||
## 1.0.0
|
||||
|
||||
:tada: First release! :tada:
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
- Added key bindings for look around.
|
||||
- And more!
|
||||
|
||||
### v1.0.1
|
||||
### 1.0.1
|
||||
|
||||
- Fixed tutorial toast to look around not affected by camera movement done with a controller. ([#2](https://github.com/LambdAurora/LambdaControls/issues/2))
|
||||
|
||||
### v1.0.2 (Unofficial)
|
||||
### 1.0.2 (Unofficial)
|
||||
|
||||
This update was never pushed but was aiming to fix [#4](https://github.com/LambdAurora/LambdaControls/issues/4).
|
||||
|
||||
@@ -24,7 +24,7 @@ This update was never pushed but was aiming to fix [#4](https://github.com/Lambd
|
||||
- Fixed broken chat arrow keys.
|
||||
- Optimized a little bit the button indicator. (need more work)
|
||||
|
||||
## v1.1.0 - Chording update
|
||||
## 1.1.0 - Chording update
|
||||
|
||||
This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAurora/LambdaControls/issues/9)).
|
||||
|
||||
@@ -46,9 +46,9 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur
|
||||
- HUD side affects button indicators now.
|
||||
- Added support for Advancements tabs.
|
||||
|
||||
### v1.1.1
|
||||
### 1.1.1
|
||||
|
||||
## v1.2.0-1.3.0
|
||||
## 1.2.0-1.3.0
|
||||
|
||||
- Improved rotation algorithm ([#11](https://github.com/LambdAurora/LambdaControls/issues/11)).
|
||||
- Added virtual mouse.
|
||||
@@ -60,21 +60,21 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur
|
||||
- And more!
|
||||
- v1.3.0 specific: Updated to Minecraft 1.16.1
|
||||
|
||||
### v1.3.1
|
||||
### 1.3.1
|
||||
|
||||
- Fixed broken inventory interactions ([#13](https://github.com/LambdAurora/LambdaControls/issues/13))
|
||||
- Fixed virtual mouse preventing continuous attack (thus making breaking blocks impossible).
|
||||
- Added support for [ModUpdater](https://gitea.thebrokenrail.com/TheBrokenRail/ModUpdater) hopefully.
|
||||
- Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to 1.5.2.
|
||||
|
||||
### v1.3.2
|
||||
### 1.3.2
|
||||
|
||||
- Added vertical reacharound.
|
||||
- Added more API for compatibility handlers.
|
||||
- Improved reacharound API.
|
||||
- Improved [REI](https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items) compatibility.
|
||||
|
||||
## v1.4.0
|
||||
## 1.4.0
|
||||
|
||||
- Added analog movements ([#10](https://github.com/LambdAurora/LambdaControls/issues/10)).
|
||||
- Improved Ok Zoomer compability.
|
||||
@@ -90,11 +90,11 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur
|
||||
- Will allow for better compability with other mods.
|
||||
- Might be interesting for keyboard users too.
|
||||
|
||||
### v1.4.1
|
||||
### 1.4.1
|
||||
|
||||
- Fixed crash with [REI](https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items).
|
||||
|
||||
## v1.5.0
|
||||
## 1.5.0
|
||||
|
||||
- Added mappings string editor screen.
|
||||
- Added Simplified Chinese translations ([#18](https://github.com/LambdAurora/LambdaControls/pull/18)).
|
||||
@@ -104,9 +104,32 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur
|
||||
- Respect toggle setting in Accessibility screen.
|
||||
- Tweaked rotation speeds.
|
||||
- Updated to Minecraft 1.16.2.
|
||||
- Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to 1.6.4.
|
||||
- Updated [SpruceUI] to 1.6.4.
|
||||
- Overhauled REI compatibility.
|
||||
- Improved horizontal reach-around.
|
||||
- Fixed crashes with Ok Zoomer.
|
||||
- Fixed crashes with key unbinding.
|
||||
- More WIP on keybind ring.
|
||||
|
||||
## 1.6.0
|
||||
|
||||
- Reworked entirely the settings screen.
|
||||
- Added independent stick dead zones. ([#32](https://github.com/LambdAurora/LambdaControls/issues/32))
|
||||
- Added max values range. ([#41](https://github.com/LambdAurora/LambdaControls/issues/41))
|
||||
- Updated [SpruceUI] and fix related crashes due to incompatible versions ([#40](https://github.com/LambdAurora/LambdaControls/issues/40), [#48](https://github.com/LambdAurora/LambdaControls/issues/48)).
|
||||
- Fix boat control issues ([#37](https://github.com/LambdAurora/LambdaControls/issues/37)).
|
||||
- Fix incompatibilities with mods using night-config. Now shadowing properly night-config. ([#33](https://github.com/LambdAurora/LambdaControls/issues/33), [#39](https://github.com/LambdAurora/LambdaControls/issues/39))
|
||||
|
||||
## 1.7.0
|
||||
|
||||
- Updated to 1.17.
|
||||
- Small improvements to the codebase thanks to Java 16.
|
||||
- Fix controller bindings not being saved ([#31](https://github.com/LambdAurora/LambdaControls/issues/31), [#55](https://github.com/LambdAurora/LambdaControls/issues/55)).
|
||||
- Dropped entirely Touchscreen Input Mode.
|
||||
- Dropped Roughly Enough Items compatibility.
|
||||
|
||||
### 1.7.1
|
||||
|
||||
- Fix crash at startup.
|
||||
|
||||
[SpruceUI]: https://github.com/LambdAurora/SpruceUI
|
||||
@@ -26,7 +26,7 @@ By participating, you are expected to uphold this code. Please report unacceptab
|
||||
|
||||
[Fabric](https://fabricmc.net/) is the mod loader and the software which allows Gradle to setup the workspace.
|
||||
|
||||
### Java 8
|
||||
### Java 16
|
||||
|
||||
Java is the main language used to make LambdaControls alive.
|
||||
Knowing how to code in Java is necessary if you contribute to the code.
|
||||
@@ -47,7 +47,7 @@ As it is a Minecraft mod you should know a bit how Minecraft works and how moddi
|
||||
|
||||
Git is the control version software we use for LambdaControls, please know how to use it if you consider contributing to the code.
|
||||
|
||||
Git commits should be and must be signed.
|
||||
Git commits should be signed.
|
||||
|
||||
## How can I contribute?
|
||||
|
||||
@@ -55,17 +55,17 @@ Git commits should be and must be signed.
|
||||
|
||||
#### Before submitting a bug report
|
||||
|
||||
- Check if you can reproduce it on other platforms, on multiple web browsers.
|
||||
- Check if you can reproduce it on other platforms.
|
||||
- Perform a search to see if the problem has already been reported. If it has **and the issue is still open**, add a comment to the existing issue instead of opening a new one.
|
||||
|
||||
#### How do I submit a bug report?
|
||||
|
||||
Go in the issues tab in GitHub and read the [bug report guide](https://github.com/LambdAurora/LambdaControls/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)
|
||||
Go in the issues tab in GitHub and read the [bug report guide](https://github.com/LambdAurora/LambdaControls/blob/1.17/.github/ISSUE_TEMPLATE/bug_report.md)
|
||||
|
||||
### Suggesting enhancements
|
||||
|
||||
Enhancement suggestions are tracked as [GitHub issues](https://github.com/LambdAurora/LambdaControls/issues).
|
||||
Check out the [feature request](https://github.com/LambdAurora/LambdaControls/blob/master/.github/ISSUE_TEMPLATE/feature_request.md) guide.
|
||||
Check out the [feature request](https://github.com/LambdAurora/LambdaControls/blob/1.17/.github/ISSUE_TEMPLATE/feature_request.md) guide.
|
||||
|
||||
### Do pull requests
|
||||
|
||||
@@ -81,21 +81,16 @@ Feel free to pull request!
|
||||
### Git commit messages
|
||||
|
||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
* Consider starting the commit message with an emote, emotes for your commit can be found at the [gitmoji guide](https://gitmoji.carloscuesta.me/).
|
||||
* (Not for the message) Don't forget to sign the commit.
|
||||
|
||||
### Naming convention
|
||||
|
||||
Names in the code should be explicit and always in `snake_case`, `camelCase` will not be allowed.
|
||||
Names in the code should be explicit and always in `camelCase`, `snake_case` will not be allowed.
|
||||
`PascalCase` can be used for class name.
|
||||
|
||||
We chose `snake_case` because it is more accessible for everyone: for people who don't speak English as their native language it is more easy to see the words when they are separated,
|
||||
it also allows the correct use of screen reader on the code with `snake_case` due to the absence of upper case characters.
|
||||
|
||||
### Brace placement
|
||||
|
||||
Every braces should be at the end of the line of function declaration, etc...
|
||||
The only exception is class declarations: braces must be on the next line.
|
||||
Every braces should be at the end of the line of function declaration, etc.
|
||||
|
||||
### Quick note for users of the Intellij IDEA IDE
|
||||
|
||||
|
||||
16
README.md
16
README.md
@@ -1,11 +1,13 @@
|
||||
# LambdaControls
|
||||
|
||||

|
||||
<!-- modrinth_exclude.start -->
|
||||
 <!-- modrinth_exclude.end -->
|
||||
[](https://raw.githubusercontent.com/LambdAurora/LambdaControls/master/LICENSE)
|
||||

|
||||
[![Mod loader: Fabric]][fabric]
|
||||
[![Mod loader: Fabric]][fabric] <!-- modrinth_exclude.start -->
|
||||

|
||||
[](https://www.curseforge.com/minecraft/mc-mods/lambdacontrols)
|
||||
<!-- modrinth_exclude.end -->
|
||||
|
||||
A Fabric Minecraft mod which adds better controls, reach-around and controller support.
|
||||
|
||||
@@ -42,14 +44,14 @@ This mod also adds controller support.
|
||||
|
||||
## Screenshots
|
||||
|
||||
![controller_controls]
|
||||
![controller_options]
|
||||

|
||||

|
||||
|
||||
<!-- modrinth_exclude.start -->
|
||||
## Build
|
||||
|
||||
Just do `./gradlew shadowRemapJar` and everything should build just fine!
|
||||
Just do `./gradlew build` and everything should build just fine!
|
||||
<!-- modrinth_exclude.end -->
|
||||
|
||||
[controller_controls]: images/controller_controls.png
|
||||
[controller_options]: images/controller_options.png
|
||||
[fabric]: https://fabricmc.net
|
||||
[Mod loader: Fabric]: https://img.shields.io/badge/modloader-Fabric-1976d2?style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE4LTEyLTE2VDE2OjU0OjE3LTA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wNy0yOFQyMToxNzo0OC0wNzowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wNy0yOFQyMToxNzo0OC0wNzowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowZWRiMWMyYy1mZjhjLWU0NDEtOTMxZi00OTVkNGYxNGM3NjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MGVkYjFjMmMtZmY4Yy1lNDQxLTkzMWYtNDk1ZDRmMTRjNzYwIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MGVkYjFjMmMtZmY4Yy1lNDQxLTkzMWYtNDk1ZDRmMTRjNzYwIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowZWRiMWMyYy1mZjhjLWU0NDEtOTMxZi00OTVkNGYxNGM3NjAiIHN0RXZ0OndoZW49IjIwMTgtMTItMTZUMTY6NTQ6MTctMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4/HiGMAAAAtUlEQVRYw+XXrQqAMBQF4D2P2eBL+QIG8RnEJFaNBjEum+0+zMQLtwwv+wV3ZzhhMDgfJ0wUSinxZUQWgKos1JP/AbD4OneIDyQPwCFniA+EJ4CaXm4TxAXCC0BNHgLhAdAnx9hC8PwGSRtAFVMQjF7cNTWED8B1cgwW20yfJgAvrssAsZ1cB3g/xckAxr6FmCDU5N6f488BrpCQ4rQBJkiMYh4ACmLzwOQF0CExinkCsvw7vgGikl+OotaKRwAAAABJRU5ErkJggg==
|
||||
|
||||
221
build.gradle
221
build.gradle
@@ -1,59 +1,77 @@
|
||||
buildscript {
|
||||
dependencies {
|
||||
constraints {
|
||||
["asm", "asm-util", "asm-tree", "asm-analysis"].each {
|
||||
classpath("org.ow2.asm:$it") {
|
||||
version { require("9.1") }
|
||||
because("Fabric's TinyRemapper requires ASM 9")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'fabric-loom' version '0.6-SNAPSHOT'
|
||||
id 'fabric-loom' version '0.9.+'
|
||||
id 'java-library'
|
||||
id 'maven-publish'
|
||||
id 'com.github.johnrengelman.shadow' version '6.1.0'
|
||||
id 'org.cadixdev.licenser' version '0.5.0'
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
id 'org.cadixdev.licenser' version '0.6.1'
|
||||
id 'com.modrinth.minotaur' version '1.2.+'
|
||||
}
|
||||
|
||||
import net.fabricmc.loom.task.RemapJarTask
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonObject
|
||||
import com.modrinth.minotaur.TaskModrinthUpload
|
||||
import com.modrinth.minotaur.request.VersionType
|
||||
import com.modrinth.minotaur.responses.ResponseError
|
||||
import org.apache.http.client.config.CookieSpecs
|
||||
import org.apache.http.client.config.RequestConfig
|
||||
import org.apache.http.client.entity.EntityBuilder
|
||||
import org.apache.http.client.methods.HttpPatch
|
||||
import org.apache.http.entity.ContentType
|
||||
import org.apache.http.impl.client.HttpClientBuilder
|
||||
import org.apache.http.util.EntityUtils
|
||||
|
||||
group = project.maven_group
|
||||
version = "${project.mod_version}+${getMCVersionString()}"
|
||||
archivesBaseName = project.archives_base_name + "-fabric"
|
||||
archivesBaseName = project.archives_base_name
|
||||
|
||||
// This field defines the Java version your mod target.
|
||||
// The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too.
|
||||
def targetJavaVersion = 8
|
||||
def targetJavaVersion = 16
|
||||
|
||||
def getMCVersionString() {
|
||||
if (project.minecraft_version.matches("\\d\\dw\\d\\d[a-z]")) {
|
||||
boolean isMCVersionNonRelease() {
|
||||
return project.minecraft_version.matches('^\\d\\dw\\d\\d[a-z]$')
|
||||
|| project.minecraft_version.matches('\\d+\\.\\d+-(pre|rc)(\\d+)')
|
||||
}
|
||||
|
||||
String getMCVersionString() {
|
||||
if (isMCVersionNonRelease()) {
|
||||
return project.minecraft_version
|
||||
}
|
||||
int lastDot = project.minecraft_version.lastIndexOf('.')
|
||||
return project.minecraft_version.substring(0, lastDot)
|
||||
def version = project.minecraft_version.split('\\.')
|
||||
return version[0] + '.' + version[1]
|
||||
}
|
||||
|
||||
String parseReadme() {
|
||||
def excludeRegex = /(?m)<!-- modrinth_exclude\.start -->(.|\n)*?<!-- modrinth_exclude\.end -->/
|
||||
def linkRegex = /!\[([A-z_ ]+)]\((images\/[A-z.\/_]+)\)/
|
||||
|
||||
def readme = (String) file('README.md').text
|
||||
readme = readme.replaceAll(excludeRegex, '')
|
||||
readme = readme.replaceAll(linkRegex, '')
|
||||
return readme
|
||||
}
|
||||
|
||||
minecraft {
|
||||
accessWidener file('src/main/resources/lambdacontrols.accesswidener')
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url = 'https://aperlambda.github.io/maven' }
|
||||
maven { url 'https://aperlambda.github.io/maven' }
|
||||
maven {
|
||||
name = 'CottonMC'
|
||||
url = 'http://server.bbkr.space:8081/artifactory/libs-snapshot'
|
||||
name 'Gegy'
|
||||
url 'https://maven.gegy.dev'
|
||||
}
|
||||
maven {
|
||||
name = 'Terraformers'
|
||||
url = 'https://maven.terraformersmc.com/releases'
|
||||
name 'CottonMC'
|
||||
url 'https://server.bbkr.space:8081/artifactory/libs-snapshot'
|
||||
}
|
||||
maven { url "https://maven.shedaniel.me/" }
|
||||
maven { url = "https://jitpack.io" }
|
||||
maven {
|
||||
name 'Terraformers'
|
||||
url 'https://maven.terraformersmc.com/releases'
|
||||
}
|
||||
maven { url 'https://maven.shedaniel.me/' }
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -70,20 +88,19 @@ dependencies {
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
modImplementation "dev.lambdaurora:spruceui:${project.spruceui_version}"
|
||||
include "dev.lambdaurora:spruceui:${project.spruceui_version}"
|
||||
|
||||
modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}"
|
||||
modImplementation "com.github.lambdaurora:spruceui:${project.spruceui_version}"
|
||||
include "com.github.lambdaurora:spruceui:${project.spruceui_version}"
|
||||
|
||||
// Compatibility mods
|
||||
modImplementation("com.github.joaoh1:okzoomer:e13183c59b") {
|
||||
/*modImplementation("com.github.joaoh1:okzoomer:e13183c59b") {
|
||||
exclude group: 'me.shedaniel.cloth'
|
||||
exclude group: 'io.github.prospector'
|
||||
}
|
||||
}*/
|
||||
|
||||
modImplementation("me.shedaniel:RoughlyEnoughItems:5.10.184")
|
||||
|
||||
shadow "com.electronwill.night-config:core:3.6.3"
|
||||
shadow "com.electronwill.night-config:toml:3.6.3"
|
||||
shadow 'com.electronwill.night-config:core:3.6.3'
|
||||
shadow 'com.electronwill.night-config:toml:3.6.3'
|
||||
}
|
||||
|
||||
java {
|
||||
@@ -94,25 +111,21 @@ java {
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
it.options.encoding = "UTF-8"
|
||||
it.options.encoding = 'UTF-8'
|
||||
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
it.options.release = targetJavaVersion
|
||||
}
|
||||
}
|
||||
it.options.release.set(targetJavaVersion)
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
inputs.property 'version', project.version
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version
|
||||
filesMatching('fabric.mod.json') {
|
||||
expand 'version': project.version
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
from("LICENSE") {
|
||||
from('LICENSE') {
|
||||
rename { "${it}_${project.archivesBaseName}" }
|
||||
}
|
||||
}
|
||||
@@ -133,37 +146,119 @@ shadowJar {
|
||||
exclude 'org/**'
|
||||
relocate 'com.electronwill.nightconfig', 'dev.lambdaurora.lambdacontrols.shadow.nightconfig'
|
||||
}
|
||||
remapJar.dependsOn(shadowJar)
|
||||
|
||||
task shadowRemapJar(type: RemapJarTask) {
|
||||
dependsOn shadowJar
|
||||
|
||||
input = file("${project.buildDir}/libs/$archivesBaseName-$version-dev.jar")
|
||||
archiveName = "${archivesBaseName}-${version}.jar"
|
||||
addNestedDependencies = true
|
||||
input.set(file("${project.buildDir}/libs/$archivesBaseName-$version-dev.jar"))
|
||||
archiveFileName = "${archivesBaseName}-${version}.jar"
|
||||
addNestedDependencies.set(true)
|
||||
remapAccessWidener.set(true)
|
||||
}
|
||||
build.dependsOn(shadowRemapJar)
|
||||
|
||||
task publishModrinth(type: TaskModrinthUpload) {
|
||||
dependsOn(build)
|
||||
onlyIf {
|
||||
System.getenv('MODRINTH_TOKEN')
|
||||
}
|
||||
|
||||
token = System.getenv('MODRINTH_TOKEN')
|
||||
projectId = project.modrinth_id
|
||||
versionNumber = version
|
||||
versionName = "LambdaControls ${project.mod_version} (${getMCVersionString()})"
|
||||
uploadFile = shadowRemapJar
|
||||
addGameVersion((String) project.minecraft_version)
|
||||
addLoader('fabric')
|
||||
versionType = isMCVersionNonRelease() ? VersionType.BETA : VersionType.RELEASE
|
||||
|
||||
// Changelog fetching
|
||||
def changelogText = file('CHANGELOG.md').text
|
||||
def regexVersion = ((String) project.mod_version).replaceAll('\\.', /\\./).replaceAll('\\+', '\\+')
|
||||
def changelogRegex = ~"###? ${regexVersion}\\n\\n(( *- .+\\n)+)"
|
||||
def matcher = changelogText =~ changelogRegex
|
||||
matcher.find()
|
||||
|
||||
changelog = matcher.group(1)
|
||||
|
||||
// Readme
|
||||
doFirst {
|
||||
final def client = HttpClientBuilder.create().setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.IGNORE_COOKIES).build()).build()
|
||||
final def patch = new HttpPatch((String) (apiURL + '/v1/mod/' + projectId))
|
||||
patch.addHeader("Authorization", token)
|
||||
|
||||
var json = new JsonObject()
|
||||
json.addProperty("body", parseReadme())
|
||||
patch.setEntity(EntityBuilder.create()
|
||||
.setText(json.toString())
|
||||
.setContentType(ContentType.APPLICATION_JSON)
|
||||
.build())
|
||||
|
||||
final def response = client.execute(patch)
|
||||
final int status = response.getStatusLine().getStatusCode()
|
||||
|
||||
final def gson = new GsonBuilder().create()
|
||||
if (status == 200) {
|
||||
project.getLogger().lifecycle("Successfully updated readme to ${projectId}.")
|
||||
} else {
|
||||
errorInfo = gson.fromJson(EntityUtils.toString(response.getEntity()), ResponseError.class)
|
||||
project.getLogger().error("Upload failed! Status: ${status} Error: ${errorInfo.getError()} Reason: ${errorInfo.getDescription()}")
|
||||
throw new GradleException("Upload failed! Status: ${status} Reason: ${errorInfo.getDescription()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact(shadowRemapJar) {
|
||||
builtBy shadowRemapJar
|
||||
}
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
|
||||
pom {
|
||||
name = 'LambdaControls'
|
||||
description = 'Adds better controls, and controller support.'
|
||||
}
|
||||
|
||||
pom.withXml {
|
||||
def dependenciesNode = asNode().appendNode('dependencies')
|
||||
|
||||
configurations.shadow.allDependencies.each {
|
||||
def dependencyNode = dependenciesNode.appendNode('dependency')
|
||||
|
||||
dependencyNode.appendNode('groupId', it.group)
|
||||
dependencyNode.appendNode('artifactId', it.name)
|
||||
dependencyNode.appendNode('version', it.version)
|
||||
dependencyNode.appendNode('scope', 'compile')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven {
|
||||
name = "GithubPackages"
|
||||
url = uri("https://maven.pkg.github.com/LambdAurora/LambdaControls")
|
||||
name "GithubPackages"
|
||||
url uri("https://maven.pkg.github.com/LambdAurora/LambdaControls")
|
||||
credentials {
|
||||
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
|
||||
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
// add all the jars that should be included when publishing to maven
|
||||
artifact(remapJar) {
|
||||
builtBy remapJar
|
||||
}
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
def lambdacontrolsMaven = System.getenv('LAMBDACONTROLS_MAVEN')
|
||||
if (lambdacontrolsMaven) {
|
||||
maven {
|
||||
name 'LambdaControlsMaven'
|
||||
url uri(lambdacontrolsMaven)
|
||||
credentials {
|
||||
username = project.findProperty('gpr.user') ?: System.getenv('MAVEN_USERNAME')
|
||||
password = project.findProperty('gpr.key') ?: System.getenv('MAVEN_PASSWORD')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,18 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version=1.16.5
|
||||
yarn_mappings=1.16.5+build.5
|
||||
loader_version=0.11.3
|
||||
minecraft_version=1.17
|
||||
yarn_mappings=1.17+build.13
|
||||
loader_version=0.11.6
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.6.0
|
||||
maven_group = dev.lambdaurora.lambdacontrols
|
||||
mod_version = 1.7.1
|
||||
maven_group = dev.lambdaurora
|
||||
archives_base_name = lambdacontrols
|
||||
modrinth_id=W1D3UXEc
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.32.0+1.16
|
||||
spruceui_version=2.1.4-1.16
|
||||
modmenu_version=1.16.8
|
||||
fabric_version=0.36.0+1.17
|
||||
spruceui_version=3.2.0+1.17
|
||||
modmenu_version=2.0.2
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
name 'Fabric'
|
||||
url 'https://maven.fabricmc.net/'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
@@ -19,21 +19,20 @@ import java.util.Optional;
|
||||
* Represents the controls mode.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public enum ControlsMode implements Nameable {
|
||||
DEFAULT,
|
||||
CONTROLLER,
|
||||
TOUCHSCREEN;
|
||||
CONTROLLER;
|
||||
|
||||
/**
|
||||
* Returns the next controls mode available.
|
||||
*
|
||||
* @return The next available controls mode.
|
||||
* @return the next available controls mode
|
||||
*/
|
||||
public ControlsMode next() {
|
||||
ControlsMode[] v = values();
|
||||
var v = values();
|
||||
if (v.length == this.ordinal() + 1)
|
||||
return v[0];
|
||||
return v[this.ordinal() + 1];
|
||||
@@ -42,7 +41,7 @@ public enum ControlsMode implements Nameable {
|
||||
/**
|
||||
* Gets the translation key of this controls mode.
|
||||
*
|
||||
* @return The translated key of this controls mode.
|
||||
* @return the translated key of this controls mode
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public String getTranslationKey() {
|
||||
@@ -57,8 +56,8 @@ public enum ControlsMode implements Nameable {
|
||||
/**
|
||||
* Gets the controls mode from its identifier.
|
||||
*
|
||||
* @param id The identifier of the controls mode.
|
||||
* @return The controls mode if found, else empty.
|
||||
* @param id the identifier of the controls mode
|
||||
* @return the controls mode if found, else empty
|
||||
*/
|
||||
public static Optional<ControlsMode> byId(@NotNull String id) {
|
||||
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();
|
||||
|
||||
@@ -12,7 +12,7 @@ package dev.lambdaurora.lambdacontrols;
|
||||
import dev.lambdaurora.lambdacontrols.event.PlayerChangeControlsModeCallback;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
@@ -29,7 +29,7 @@ import java.util.Optional;
|
||||
* Represents the LambdaControls mod.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.6.0
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaControls implements ModInitializer {
|
||||
@@ -47,25 +47,25 @@ public class LambdaControls implements ModInitializer {
|
||||
INSTANCE = this;
|
||||
this.log("Initializing LambdaControls...");
|
||||
|
||||
ServerSidePacketRegistry.INSTANCE.register(HELLO_CHANNEL,
|
||||
(context, attachedData) -> {
|
||||
String version = attachedData.readString(32);
|
||||
ControlsMode.byId(attachedData.readString(32))
|
||||
.ifPresent(controlsMode -> context.getTaskQueue()
|
||||
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode)));
|
||||
context.getTaskQueue().execute(() ->
|
||||
ServerSidePacketRegistry.INSTANCE.sendToPlayer(context.getPlayer(), FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.HORIZONTAL_REACHAROUND)));
|
||||
});
|
||||
ServerSidePacketRegistry.INSTANCE.register(CONTROLS_MODE_CHANNEL,
|
||||
(context, attachedData) -> ControlsMode.byId(attachedData.readString(32))
|
||||
.ifPresent(controlsMode -> context.getTaskQueue()
|
||||
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode))));
|
||||
ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> {
|
||||
String version = buf.readString(32);
|
||||
ControlsMode.byId(buf.readString(32))
|
||||
.ifPresent(controlsMode -> server
|
||||
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode)));
|
||||
server.execute(() -> {
|
||||
ServerPlayNetworking.send(player, FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.HORIZONTAL_REACHAROUND));
|
||||
});
|
||||
});
|
||||
ServerPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL,
|
||||
(server, player, handler, buf, responseSender) -> ControlsMode.byId(buf.readString(32))
|
||||
.ifPresent(controlsMode -> server
|
||||
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to the terminal.
|
||||
*
|
||||
* @param info The message to print.
|
||||
* @param info the message to print
|
||||
*/
|
||||
public void log(String info) {
|
||||
this.logger.info("[LambdaControls] " + info);
|
||||
@@ -74,7 +74,7 @@ public class LambdaControls implements ModInitializer {
|
||||
/**
|
||||
* Prints a warning to the terminal.
|
||||
*
|
||||
* @param warning The warning to print.
|
||||
* @param warning the warning to print
|
||||
*/
|
||||
public void warn(String warning) {
|
||||
this.logger.info("[LambdaControls] " + warning);
|
||||
@@ -83,8 +83,8 @@ public class LambdaControls implements ModInitializer {
|
||||
/**
|
||||
* Returns a packet byte buffer made for the lambdacontrols:controls_mode plugin message.
|
||||
*
|
||||
* @param controlsMode The controls mode to send.
|
||||
* @return The packet byte buffer.
|
||||
* @param controlsMode the controls mode to send
|
||||
* @return the packet byte buffer
|
||||
*/
|
||||
public PacketByteBuf makeControlsModeBuffer(@NotNull ControlsMode controlsMode) {
|
||||
Objects.requireNonNull(controlsMode, "Controls mode cannot be null.");
|
||||
@@ -94,18 +94,23 @@ public class LambdaControls implements ModInitializer {
|
||||
/**
|
||||
* Returns a packet byte buffer made for the lambdacontrols:feature plugin message.
|
||||
*
|
||||
* @param feature The feature data to send.
|
||||
* @return The packet byte buffer.
|
||||
* @param features the features data to send
|
||||
* @return the packet byte buffer
|
||||
*/
|
||||
public PacketByteBuf makeFeatureBuffer(@NotNull LambdaControlsFeature feature) {
|
||||
Objects.requireNonNull(feature, "Feature cannot be null.");
|
||||
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer()).writeString(feature.getName(), 64);
|
||||
buffer.writeBoolean(feature.isAllowed());
|
||||
public PacketByteBuf makeFeatureBuffer(LambdaControlsFeature... features) {
|
||||
if (features.length == 0)
|
||||
throw new IllegalArgumentException("At least one feature must be provided.");
|
||||
var buffer = new PacketByteBuf(Unpooled.buffer());
|
||||
buffer.writeVarInt(features.length);
|
||||
for (var feature : features) {
|
||||
buffer.writeString(feature.getName(), 64);
|
||||
buffer.writeBoolean(feature.isAllowed());
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public PacketByteBuf makeHello(@NotNull ControlsMode controlsMode) {
|
||||
String version = "";
|
||||
var version = "";
|
||||
Optional<ModContainer> container;
|
||||
if ((container = FabricLoader.getInstance().getModContainer(LambdaControlsConstants.NAMESPACE)).isPresent()) {
|
||||
version = container.get().getMetadata().getVersion().getFriendlyString();
|
||||
@@ -116,7 +121,7 @@ public class LambdaControls implements ModInitializer {
|
||||
/**
|
||||
* Gets the LambdaControls instance.
|
||||
*
|
||||
* @return The LambdaControls instance.
|
||||
* @return the LambdaControls instance
|
||||
*/
|
||||
public static LambdaControls get() {
|
||||
return INSTANCE;
|
||||
|
||||
@@ -57,7 +57,7 @@ public class LambdaControlsFeature implements Nameable {
|
||||
/**
|
||||
* Returns whether this feature is allowed.
|
||||
*
|
||||
* @return True if this feature is allowed, else false.
|
||||
* @return {@code true} if this feature is allowed, else {@code false}
|
||||
*/
|
||||
public boolean isAllowed() {
|
||||
return this.allowed;
|
||||
@@ -66,7 +66,7 @@ public class LambdaControlsFeature implements Nameable {
|
||||
/**
|
||||
* Sets whether this feature is allowed.
|
||||
*
|
||||
* @param allowed True if this feature is allowed, else false.
|
||||
* @param allowed {@code true} if this feature is allowed, else {@code false}
|
||||
*/
|
||||
public void setAllowed(boolean allowed) {
|
||||
this.allowed = allowed;
|
||||
@@ -82,7 +82,7 @@ public class LambdaControlsFeature implements Nameable {
|
||||
/**
|
||||
* Returns whether this feature is enabled.
|
||||
*
|
||||
* @return True if this feature is enabled, else false.
|
||||
* @return {@code true} if this feature is enabled, else {@code false}
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
@@ -91,7 +91,7 @@ public class LambdaControlsFeature implements Nameable {
|
||||
/**
|
||||
* Returns whether this feature is enabled.
|
||||
*
|
||||
* @param enabled True if this feature is enabled, else false.
|
||||
* @param enabled {@code true} if this feature is enabled, else {@code false}
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
@@ -100,7 +100,7 @@ public class LambdaControlsFeature implements Nameable {
|
||||
/**
|
||||
* Returns whether this feature is available or not.
|
||||
*
|
||||
* @return True if this feature is available, else false.
|
||||
* @return {@code true} if this feature is available, else {@code false}
|
||||
* @see #isAllowed()
|
||||
* @see #isEnabled()
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ public enum ButtonState {
|
||||
/**
|
||||
* Returns whether this state is a pressed state.
|
||||
*
|
||||
* @return True if this state is a pressed state, else false.
|
||||
* @return true if this state is a pressed state, else false
|
||||
*/
|
||||
public boolean isPressed() {
|
||||
return this == PRESS || this == REPEAT;
|
||||
@@ -40,7 +40,7 @@ public enum ButtonState {
|
||||
/**
|
||||
* Returns whether this state is an unpressed state.
|
||||
*
|
||||
* @return True if this state is an unpressed state, else false.
|
||||
* @return true if this state is an unpressed state, else false
|
||||
*/
|
||||
public boolean isUnpressed() {
|
||||
return this == RELEASE || this == NONE;
|
||||
|
||||
@@ -50,7 +50,7 @@ public enum ControllerType implements Nameable {
|
||||
/**
|
||||
* Returns the controller type's identifier.
|
||||
*
|
||||
* @return The controller type's identifier.
|
||||
* @return the controller type's identifier
|
||||
*/
|
||||
public int getId() {
|
||||
return this.id;
|
||||
@@ -59,10 +59,10 @@ public enum ControllerType implements Nameable {
|
||||
/**
|
||||
* Returns the next controller type available.
|
||||
*
|
||||
* @return The next available controller type.
|
||||
* @return the next available controller type
|
||||
*/
|
||||
public @NotNull ControllerType next() {
|
||||
ControllerType[] v = values();
|
||||
var v = values();
|
||||
if (v.length == this.ordinal() + 1)
|
||||
return v[0];
|
||||
return v[this.ordinal() + 1];
|
||||
@@ -71,7 +71,7 @@ public enum ControllerType implements Nameable {
|
||||
/**
|
||||
* Gets the translated text of this controller type.
|
||||
*
|
||||
* @return The translated text of this controller type.
|
||||
* @return the translated text of this controller type
|
||||
*/
|
||||
public @NotNull Text getTranslatedText() {
|
||||
return this.text;
|
||||
@@ -85,8 +85,8 @@ public enum ControllerType implements Nameable {
|
||||
/**
|
||||
* Gets the controller type from its identifier.
|
||||
*
|
||||
* @param id The identifier of the controller type.
|
||||
* @return The controller type if found, else empty.
|
||||
* @param id the identifier of the controller type
|
||||
* @return the controller type if found, else empty
|
||||
*/
|
||||
public static @NotNull Optional<ControllerType> byId(@NotNull String id) {
|
||||
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();
|
||||
|
||||
@@ -37,10 +37,10 @@ public enum HudSide implements Nameable {
|
||||
/**
|
||||
* Returns the next side available.
|
||||
*
|
||||
* @return The next available side.
|
||||
* @return the next available side
|
||||
*/
|
||||
public @NotNull HudSide next() {
|
||||
HudSide[] v = values();
|
||||
var v = values();
|
||||
if (v.length == this.ordinal() + 1)
|
||||
return v[0];
|
||||
return v[this.ordinal() + 1];
|
||||
@@ -49,7 +49,7 @@ public enum HudSide implements Nameable {
|
||||
/**
|
||||
* Returns the translation key of this hud side.
|
||||
*
|
||||
* @return The translation key of this hude side.
|
||||
* @return the translation key of this hude side
|
||||
*/
|
||||
public @NotNull String getTranslationKey() {
|
||||
return "lambdacontrols.hud_side." + this.getName();
|
||||
@@ -58,7 +58,7 @@ public enum HudSide implements Nameable {
|
||||
/**
|
||||
* Gets the translated text of this hud side.
|
||||
*
|
||||
* @return The translated text of this hud side.
|
||||
* @return the translated text of this hud side
|
||||
*/
|
||||
public @NotNull Text getTranslatedText() {
|
||||
return this.text;
|
||||
@@ -72,8 +72,8 @@ public enum HudSide implements Nameable {
|
||||
/**
|
||||
* Gets the hud side from its identifier.
|
||||
*
|
||||
* @param id The identifier of the hud side.
|
||||
* @return The hud side if found, else empty.
|
||||
* @param id the identifier of the hud side
|
||||
* @return the hud side if found, else empty
|
||||
*/
|
||||
public static @NotNull Optional<HudSide> byId(@NotNull String id) {
|
||||
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();
|
||||
|
||||
@@ -18,11 +18,9 @@ import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.Controller;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.InputManager;
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsHud;
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay;
|
||||
import dev.lambdaurora.lambdacontrols.client.ring.KeyBindingRingAction;
|
||||
import dev.lambdaurora.lambdacontrols.client.ring.LambdaRing;
|
||||
import me.lambdaurora.spruceui.event.OpenScreenCallback;
|
||||
import me.lambdaurora.spruceui.hud.HudManager;
|
||||
import dev.lambdaurora.spruceui.hud.HudManager;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
@@ -30,7 +28,7 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.text.LiteralText;
|
||||
@@ -45,7 +43,7 @@ import java.io.File;
|
||||
* Represents the LambdaControls client mod.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.6.0
|
||||
* @version 1.7.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class LambdaControlsClient extends LambdaControls implements ClientModInitializer {
|
||||
@@ -86,9 +84,12 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(this.config.getControlsMode()));
|
||||
});
|
||||
ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> {
|
||||
String name = buf.readString(64);
|
||||
boolean allowed = buf.readBoolean();
|
||||
LambdaControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed)));
|
||||
int features = buf.readVarInt();
|
||||
for (int i = 0; i < features; i++) {
|
||||
var name = buf.readString(64);
|
||||
boolean allowed = buf.readBoolean();
|
||||
LambdaControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed)));
|
||||
}
|
||||
});
|
||||
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
|
||||
sender.sendPacket(HELLO_CHANNEL, this.makeHello(this.config.getControlsMode()));
|
||||
@@ -99,7 +100,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick);
|
||||
ClientTickEvents.END_CLIENT_TICK.register(this::onTick);
|
||||
|
||||
OpenScreenCallback.EVENT.register((client, screen) -> {
|
||||
/*OpenScreenCallback.EVENT.register((client, screen) -> {
|
||||
if (screen == null && this.config.getControlsMode() == ControlsMode.TOUCHSCREEN) {
|
||||
screen = new TouchscreenOverlay(this);
|
||||
screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
@@ -108,7 +109,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
} else if (screen != null) {
|
||||
this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight());
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
HudManager.register(this.hud = new LambdaControlsHud(this));
|
||||
}
|
||||
@@ -123,7 +124,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
Controller.updateMappings();
|
||||
GLFW.glfwSetJoystickCallback((jid, event) -> {
|
||||
if (event == GLFW.GLFW_CONNECTED) {
|
||||
Controller controller = Controller.byId(jid);
|
||||
var controller = Controller.byId(jid);
|
||||
client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.connected", jid),
|
||||
new LiteralText(controller.getName())));
|
||||
} else if (event == GLFW.GLFW_DISCONNECTED) {
|
||||
@@ -184,7 +185,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
/**
|
||||
* Sets whether the HUD is enabled or not.
|
||||
*
|
||||
* @param enabled True if the HUD is enabled, else false.
|
||||
* @param enabled true if the HUD is enabled, else false
|
||||
*/
|
||||
public void setHudEnabled(boolean enabled) {
|
||||
this.config.setHudEnabled(enabled);
|
||||
@@ -194,7 +195,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
|
||||
/**
|
||||
* Gets the LambdaControls client instance.
|
||||
*
|
||||
* @return The LambdaControls client instance.
|
||||
* @return the LambdaControls client instance
|
||||
*/
|
||||
public static LambdaControlsClient get() {
|
||||
return INSTANCE;
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -144,8 +143,8 @@ public class LambdaControlsConfig {
|
||||
|
||||
public void checkAndFix() {
|
||||
InputManager.streamBindings().forEach(binding -> {
|
||||
String path = "controller.controls." + binding.getName();
|
||||
Object raw = this.config.getRaw(path);
|
||||
var path = "controller.controls." + binding.getName();
|
||||
var raw = this.config.getRaw(path);
|
||||
if (raw instanceof Number) {
|
||||
this.mod.warn("Invalid data at \"" + path + "\", fixing...");
|
||||
this.config.set(path, String.valueOf(raw));
|
||||
@@ -175,7 +174,7 @@ public class LambdaControlsConfig {
|
||||
private void renamed(String oldPath, String newPath) {
|
||||
if (!this.config.contains(oldPath))
|
||||
return;
|
||||
Object raw = this.config.getRaw(oldPath);
|
||||
var raw = this.config.getRaw(oldPath);
|
||||
this.config.remove(oldPath);
|
||||
this.config.set(newPath, raw);
|
||||
}
|
||||
@@ -218,7 +217,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets the controls mode from the configuration.
|
||||
*
|
||||
* @return The controls mode.
|
||||
* @return the controls mode
|
||||
*/
|
||||
public @NotNull ControlsMode getControlsMode() {
|
||||
return this.controlsMode;
|
||||
@@ -227,7 +226,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets the controls mode in the configuration.
|
||||
*
|
||||
* @param controlsMode The controls mode.
|
||||
* @param controlsMode the controls mode
|
||||
*/
|
||||
public void setControlsMode(@NotNull ControlsMode controlsMode) {
|
||||
this.controlsMode = controlsMode;
|
||||
@@ -237,7 +236,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether the auto switch mode is enabled or not.
|
||||
*
|
||||
* @return True if the auto switch mode is enabled, else false.
|
||||
* @return true if the auto switch mode is enabled, else false
|
||||
*/
|
||||
public boolean hasAutoSwitchMode() {
|
||||
return this.config.getOrElse("auto_switch_mode", DEFAULT_AUTO_SWITCH_MODE);
|
||||
@@ -246,7 +245,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether the auto switch mode is enabled or not.
|
||||
*
|
||||
* @param autoSwitchMode True if the auto switch mode is enabled, else false.
|
||||
* @param autoSwitchMode true if the auto switch mode is enabled, else false
|
||||
*/
|
||||
public void setAutoSwitchMode(boolean autoSwitchMode) {
|
||||
this.config.set("auto_switch_mode", autoSwitchMode);
|
||||
@@ -255,7 +254,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether the mod has debug enabled or not.
|
||||
*
|
||||
* @return True if debug is enabled, else false.
|
||||
* @return true if debug is enabled, else false
|
||||
*/
|
||||
public boolean hasDebug() {
|
||||
return this.config.getOrElse("debug", DEFAULT_DEBUG);
|
||||
@@ -264,7 +263,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether the mod has debug enabled or not.
|
||||
*
|
||||
* @param debug True if debug is enabled, else false.
|
||||
* @param debug true if debug is enabled, else false
|
||||
*/
|
||||
protected void setDebug(boolean debug) {
|
||||
this.config.set("debug", debug);
|
||||
@@ -277,7 +276,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether the HUD is enabled.
|
||||
*
|
||||
* @return True if the HUD is enabled, else false.
|
||||
* @return true if the HUD is enabled, else false
|
||||
*/
|
||||
public boolean isHudEnabled() {
|
||||
return this.hudEnable;
|
||||
@@ -286,7 +285,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether the HUD is enabled.
|
||||
*
|
||||
* @param enable True if the HUD is enabled, else false.
|
||||
* @param enable true if the HUD is enabled, else false
|
||||
*/
|
||||
public void setHudEnabled(boolean enable) {
|
||||
this.hudEnable = enable;
|
||||
@@ -296,7 +295,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets the HUD side from the configuration.
|
||||
*
|
||||
* @return The HUD side.
|
||||
* @return the HUD side
|
||||
*/
|
||||
public @NotNull HudSide getHudSide() {
|
||||
return this.hudSide;
|
||||
@@ -305,7 +304,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets the HUD side in the configuration.
|
||||
*
|
||||
* @param hudSide The HUD side.
|
||||
* @param hudSide the HUD side
|
||||
*/
|
||||
public void setHudSide(@NotNull HudSide hudSide) {
|
||||
this.hudSide = hudSide;
|
||||
@@ -337,7 +336,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets whether fast block placing is enabled or not.
|
||||
*
|
||||
* @return True if fast block placing is enabled, else false.
|
||||
* @return true if fast block placing is enabled, else false
|
||||
*/
|
||||
public boolean hasFastBlockPlacing() {
|
||||
return LambdaControlsFeature.FAST_BLOCK_PLACING.isEnabled();
|
||||
@@ -346,7 +345,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether fast block placing is enabled or not.
|
||||
*
|
||||
* @param enable True if fast block placing is enabled, else false.
|
||||
* @param enable true if fast block placing is enabled, else false
|
||||
*/
|
||||
public void setFastBlockPlacing(boolean enable) {
|
||||
LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(enable);
|
||||
@@ -356,7 +355,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether fly drifting is enabled or not.
|
||||
*
|
||||
* @return True if fly drifting is enabled, else false.
|
||||
* @return true if fly drifting is enabled, else false
|
||||
*/
|
||||
public boolean hasFlyDrifting() {
|
||||
return this.config.getOrElse("gameplay.fly.drifting", DEFAULT_FLY_DRIFTING);
|
||||
@@ -365,7 +364,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether fly drifting is enabled or not.
|
||||
*
|
||||
* @param flyDrifting True if fly drifting is enabled, else false.
|
||||
* @param flyDrifting true if fly drifting is enabled, else false
|
||||
*/
|
||||
public void setFlyDrifting(boolean flyDrifting) {
|
||||
this.config.set("gameplay.fly.drifting", flyDrifting);
|
||||
@@ -374,7 +373,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether vertical fly drifting is enabled or not.
|
||||
*
|
||||
* @return True if vertical fly drifting is enabled, else false.
|
||||
* @return true if vertical fly drifting is enabled, else false
|
||||
*/
|
||||
public boolean hasFlyVerticalDrifting() {
|
||||
return this.config.getOrElse("gameplay.fly.vertical_drifting", DEFAULT_FLY_VERTICAL_DRIFTING);
|
||||
@@ -383,7 +382,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether vertical fly drifting is enabled or not.
|
||||
*
|
||||
* @param flyDrifting True if vertical fly drifting is enabled, else false.
|
||||
* @param flyDrifting true if vertical fly drifting is enabled, else false
|
||||
*/
|
||||
public void setFlyVerticalDrifting(boolean flyDrifting) {
|
||||
this.config.set("gameplay.fly.vertical_drifting", flyDrifting);
|
||||
@@ -392,7 +391,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether front block placing is enabled or not.
|
||||
*
|
||||
* @return True if front block placing is enabled, else false.
|
||||
* @return true if front block placing is enabled, else false
|
||||
*/
|
||||
public boolean hasFrontBlockPlacing() {
|
||||
return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isEnabled();
|
||||
@@ -401,7 +400,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether front block placing is enabled or not.
|
||||
*
|
||||
* @param enable True if front block placing is enabled, else false.
|
||||
* @param enable true if front block placing is enabled, else false
|
||||
*/
|
||||
public void setFrontBlockPlacing(boolean enable) {
|
||||
LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(enable);
|
||||
@@ -411,7 +410,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether vertical reacharound is enabled or not.
|
||||
*
|
||||
* @return True if vertical reacharound is enabled, else false.
|
||||
* @return true if vertical reacharound is enabled, else false
|
||||
*/
|
||||
public boolean hasVerticalReacharound() {
|
||||
return LambdaControlsFeature.VERTICAL_REACHAROUND.isEnabled();
|
||||
@@ -420,7 +419,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether vertical reacharound is enabled or not.
|
||||
*
|
||||
* @param enable True if vertical reacharound is enabled, else false.
|
||||
* @param enable true if vertical reacharound is enabled, else false
|
||||
*/
|
||||
public void setVerticalReacharound(boolean enable) {
|
||||
LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(enable);
|
||||
@@ -430,7 +429,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether front block placing outline is enabled or not.
|
||||
*
|
||||
* @return True if front block placing outline is enabled, else false.
|
||||
* @return true if front block placing outline is enabled, else false
|
||||
*/
|
||||
public boolean shouldRenderReacharoundOutline() {
|
||||
return this.shouldRenderReacharoundOutline;
|
||||
@@ -439,7 +438,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether front block placing outline is enabled or not.
|
||||
*
|
||||
* @param render True if front block placing outline is enabled, else false.
|
||||
* @param render true if front block placing outline is enabled, else false
|
||||
*/
|
||||
public void setRenderReacharoundOutline(boolean render) {
|
||||
this.config.set("gameplay.reacharound.outline", this.shouldRenderReacharoundOutline = render);
|
||||
@@ -450,7 +449,7 @@ public class LambdaControlsConfig {
|
||||
* <p>
|
||||
* The integer array has 4 elements: red, green, blue and alpha.
|
||||
*
|
||||
* @return The color as a RGBA integer array.
|
||||
* @return the color as a RGBA integer array
|
||||
*/
|
||||
public int[] getReacharoundOutlineColor() {
|
||||
return this.reacharoundOutlineColor;
|
||||
@@ -466,7 +465,7 @@ public class LambdaControlsConfig {
|
||||
* @return the controller
|
||||
*/
|
||||
public Controller getController() {
|
||||
Object raw = this.config.getRaw("controller.id");
|
||||
var raw = this.config.getRaw("controller.id");
|
||||
if (raw instanceof Number) {
|
||||
return Controller.byId((Integer) raw);
|
||||
} else if (raw instanceof String) {
|
||||
@@ -481,7 +480,7 @@ public class LambdaControlsConfig {
|
||||
* @param controller the controller
|
||||
*/
|
||||
public void setController(Controller controller) {
|
||||
this.config.set("controller.id", controller.getId());
|
||||
this.config.set("controller.id", controller.id());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -490,7 +489,7 @@ public class LambdaControlsConfig {
|
||||
* @return the second controller
|
||||
*/
|
||||
public Optional<Controller> getSecondController() {
|
||||
Object raw = this.config.getRaw("controller.id2");
|
||||
var raw = this.config.getRaw("controller.id2");
|
||||
if (raw instanceof Number) {
|
||||
if ((int) raw == -1)
|
||||
return Optional.empty();
|
||||
@@ -507,13 +506,13 @@ public class LambdaControlsConfig {
|
||||
* @param controller the second controller
|
||||
*/
|
||||
public void setSecondController(@Nullable Controller controller) {
|
||||
this.config.set("controller.id2", controller == null ? -1 : controller.getId());
|
||||
this.config.set("controller.id2", controller == null ? -1 : controller.id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the controller's type.
|
||||
*
|
||||
* @return The controller's type.
|
||||
* @return the controller's type
|
||||
*/
|
||||
public @NotNull ControllerType getControllerType() {
|
||||
return this.controllerType;
|
||||
@@ -522,7 +521,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets the controller's type.
|
||||
*
|
||||
* @param controllerType The controller's type.
|
||||
* @param controllerType the controller's type
|
||||
*/
|
||||
public void setControllerType(@NotNull ControllerType controllerType) {
|
||||
this.controllerType = controllerType;
|
||||
@@ -568,7 +567,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets the controller's rotation speed.
|
||||
*
|
||||
* @return The rotation speed.
|
||||
* @return the rotation speed
|
||||
*/
|
||||
public double getRotationSpeed() {
|
||||
return this.rotationSpeed;
|
||||
@@ -577,7 +576,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets the controller's rotation speed.
|
||||
*
|
||||
* @param rotationSpeed The rotation speed.
|
||||
* @param rotationSpeed the rotation speed
|
||||
*/
|
||||
public void setRotationSpeed(double rotationSpeed) {
|
||||
this.rotationSpeed = rotationSpeed;
|
||||
@@ -586,7 +585,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets the controller's mouse speed.
|
||||
*
|
||||
* @return The mouse speed.
|
||||
* @return the mouse speed
|
||||
*/
|
||||
public double getMouseSpeed() {
|
||||
return this.mouseSpeed;
|
||||
@@ -595,7 +594,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets the controller's mouse speed.
|
||||
*
|
||||
* @param mouseSpeed The mouse speed.
|
||||
* @param mouseSpeed the mouse speed
|
||||
*/
|
||||
public void setMouseSpeed(double mouseSpeed) {
|
||||
this.mouseSpeed = mouseSpeed;
|
||||
@@ -604,7 +603,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether the right X axis is inverted or not.
|
||||
*
|
||||
* @return True if the right X axis is inverted, else false.
|
||||
* @return true if the right X axis is inverted, else false
|
||||
*/
|
||||
public boolean doesInvertRightXAxis() {
|
||||
return this.config.getOrElse("controller.invert_right_x_axis", false);
|
||||
@@ -613,7 +612,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether the right X axis is inverted or not.
|
||||
*
|
||||
* @param invert True if the right X axis is inverted, else false.
|
||||
* @param invert true if the right X axis is inverted, else false
|
||||
*/
|
||||
public void setInvertRightXAxis(boolean invert) {
|
||||
this.config.set("controller.invert_right_x_axis", invert);
|
||||
@@ -622,7 +621,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether the right Y axis is inverted or not.
|
||||
*
|
||||
* @return True if the right Y axis is inverted, else false.
|
||||
* @return true if the right Y axis is inverted, else false
|
||||
*/
|
||||
public boolean doesInvertRightYAxis() {
|
||||
return this.config.getOrElse("controller.invert_right_y_axis", false);
|
||||
@@ -631,7 +630,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether the right Y axis is inverted or not.
|
||||
*
|
||||
* @param invert True if the right Y axis is inverted, else false.
|
||||
* @param invert true if the right Y axis is inverted, else false
|
||||
*/
|
||||
public void setInvertRightYAxis(boolean invert) {
|
||||
this.config.set("controller.invert_right_y_axis", invert);
|
||||
@@ -640,7 +639,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether unfocused controller input is allowed or not.
|
||||
*
|
||||
* @return True if unfocused controller input is allowed, else false.
|
||||
* @return true if unfocused controller input is allowed, else false
|
||||
*/
|
||||
public boolean hasUnfocusedInput() {
|
||||
return this.unfocusedInput;
|
||||
@@ -649,7 +648,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether unfocused controller input is allowed or not.
|
||||
*
|
||||
* @param unfocusedInput True if unfocused controller input is allowed, else false.
|
||||
* @param unfocusedInput true if unfocused controller input is allowed, else false
|
||||
*/
|
||||
public void setUnfocusedInput(boolean unfocusedInput) {
|
||||
this.unfocusedInput = unfocusedInput;
|
||||
@@ -658,7 +657,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether the mouse is virtual or not.
|
||||
*
|
||||
* @return True if the mouse is virtual, else false.
|
||||
* @return true if the mouse is virtual, else false
|
||||
*/
|
||||
public boolean hasVirtualMouse() {
|
||||
return this.virtualMouse;
|
||||
@@ -667,7 +666,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets whether the mouse is virtual or not.
|
||||
*
|
||||
* @param virtualMouse True if the mouse is virtual, else false.
|
||||
* @param virtualMouse true if the mouse is virtual, else false
|
||||
*/
|
||||
public void setVirtualMouse(boolean virtualMouse) {
|
||||
this.virtualMouse = virtualMouse;
|
||||
@@ -676,7 +675,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets the virtual mouse skin.
|
||||
*
|
||||
* @return The virtual mouse skin.
|
||||
* @return the virtual mouse skin
|
||||
*/
|
||||
public VirtualMouseSkin getVirtualMouseSkin() {
|
||||
return this.virtualMouseSkin;
|
||||
@@ -685,7 +684,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets the virtual mouse skin.
|
||||
*
|
||||
* @param skin The virtual mouse skin.
|
||||
* @param skin the virtual mouse skin
|
||||
*/
|
||||
public void setVirtualMouseSkin(VirtualMouseSkin skin) {
|
||||
this.virtualMouseSkin = skin;
|
||||
@@ -695,7 +694,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets the right X axis sign.
|
||||
*
|
||||
* @return The right X axis sign.
|
||||
* @return the right X axis sign
|
||||
*/
|
||||
public double getRightXAxisSign() {
|
||||
return this.doesInvertRightXAxis() ? -1.0 : 1.0;
|
||||
@@ -704,7 +703,7 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Gets the right Y axis sign.
|
||||
*
|
||||
* @return The right Y axis sign.
|
||||
* @return the right Y axis sign
|
||||
*/
|
||||
public double getRightYAxisSign() {
|
||||
return this.doesInvertRightYAxis() ? -1.0 : 1.0;
|
||||
@@ -724,16 +723,16 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Loads the button binding from configuration.
|
||||
*
|
||||
* @param button The button binding.
|
||||
* @param button the button binding
|
||||
*/
|
||||
public void loadButtonBinding(@NotNull ButtonBinding button) {
|
||||
button.setButton(button.getDefaultButton());
|
||||
String code = this.config.getOrElse("controller.controls." + button.getName(), button.getButtonCode());
|
||||
var code = this.config.getOrElse("controller.controls." + button.getName(), button.getButtonCode());
|
||||
|
||||
Matcher matcher = BUTTON_BINDING_PATTERN.matcher(code);
|
||||
var matcher = BUTTON_BINDING_PATTERN.matcher(code);
|
||||
|
||||
try {
|
||||
int[] buttons = new int[1];
|
||||
var buttons = new int[1];
|
||||
int count = 0;
|
||||
while (matcher.find()) {
|
||||
count++;
|
||||
@@ -768,8 +767,8 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Sets the button binding in configuration.
|
||||
*
|
||||
* @param binding The button binding.
|
||||
* @param button The button.
|
||||
* @param binding the button binding
|
||||
* @param button the button
|
||||
*/
|
||||
public void setButtonBinding(@NotNull ButtonBinding binding, int[] button) {
|
||||
binding.setButton(button);
|
||||
@@ -803,8 +802,8 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Returns whether the specified axis is an axis used for movements.
|
||||
*
|
||||
* @param axis The axis index.
|
||||
* @return True if the axis is used for movements, else false.
|
||||
* @param axis the axis index
|
||||
* @return true if the axis is used for movements, else false
|
||||
*/
|
||||
public boolean isMovementAxis(int axis) {
|
||||
return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X;
|
||||
@@ -813,27 +812,25 @@ public class LambdaControlsConfig {
|
||||
/**
|
||||
* Parses a color from a hexadecimal color string.
|
||||
*
|
||||
* @param hex The hexadecimal color.
|
||||
* @return The color instance, null if invalid.
|
||||
* @param hex the hexadecimal color
|
||||
* @return the color instance, null if invalid
|
||||
*/
|
||||
private static int[] parseColor(String hex) {
|
||||
hex = hex.replace("#", "");
|
||||
switch (hex.length()) {
|
||||
case 6:
|
||||
return new int[]{
|
||||
Integer.valueOf(hex.substring(0, 2), 16),
|
||||
Integer.valueOf(hex.substring(2, 4), 16),
|
||||
Integer.valueOf(hex.substring(4, 6), 16),
|
||||
255
|
||||
};
|
||||
case 8:
|
||||
return new int[]{
|
||||
Integer.valueOf(hex.substring(0, 2), 16),
|
||||
Integer.valueOf(hex.substring(2, 4), 16),
|
||||
Integer.valueOf(hex.substring(4, 6), 16),
|
||||
Integer.valueOf(hex.substring(6, 8), 16)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
return switch (hex.length()) {
|
||||
case 6 -> new int[]{
|
||||
Integer.valueOf(hex.substring(0, 2), 16),
|
||||
Integer.valueOf(hex.substring(2, 4), 16),
|
||||
Integer.valueOf(hex.substring(4, 6), 16),
|
||||
255
|
||||
};
|
||||
case 8 -> new int[]{
|
||||
Integer.valueOf(hex.substring(0, 2), 16),
|
||||
Integer.valueOf(hex.substring(2, 4), 16),
|
||||
Integer.valueOf(hex.substring(4, 6), 16),
|
||||
Integer.valueOf(hex.substring(6, 8), 16)
|
||||
};
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client;
|
||||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen;
|
||||
import io.github.prospector.modmenu.api.ConfigScreenFactory;
|
||||
import io.github.prospector.modmenu.api.ModMenuApi;
|
||||
|
||||
/**
|
||||
* Represents the API implementation of ModMenu for LambdaControls.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.0
|
||||
* @version 1.7.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class LambdaControlsModMenu implements ModMenuApi {
|
||||
|
||||
@@ -21,12 +21,12 @@ import dev.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccess
|
||||
import dev.lambdaurora.lambdacontrols.client.mixin.EntryListWidgetAccessor;
|
||||
import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
|
||||
import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor;
|
||||
import me.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
import me.lambdaurora.spruceui.screen.SpruceScreen;
|
||||
import me.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget;
|
||||
import me.lambdaurora.spruceui.widget.SpruceElement;
|
||||
import me.lambdaurora.spruceui.widget.SpruceLabelWidget;
|
||||
import me.lambdaurora.spruceui.widget.container.SpruceParentWidget;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
import dev.lambdaurora.spruceui.screen.SpruceScreen;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceElement;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.ParentElement;
|
||||
@@ -39,11 +39,10 @@ import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
|
||||
import net.minecraft.client.gui.screen.pack.PackScreen;
|
||||
import net.minecraft.client.gui.screen.world.WorldListWidget;
|
||||
import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
|
||||
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
|
||||
import net.minecraft.client.gui.widget.EntryListWidget;
|
||||
import net.minecraft.client.gui.widget.PressableWidget;
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
@@ -54,8 +53,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWGamepadState;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -69,7 +66,7 @@ import static org.lwjgl.glfw.GLFW.*;
|
||||
* Represents the LambdaControls' input handler.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.6.0
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaInput {
|
||||
@@ -97,7 +94,7 @@ public class LambdaInput {
|
||||
/**
|
||||
* This method is called every Minecraft tick.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void tick(@NotNull MinecraftClient client) {
|
||||
this.targetYaw = 0.F;
|
||||
@@ -121,19 +118,20 @@ public class LambdaInput {
|
||||
/**
|
||||
* This method is called every Minecraft tick for controller input update.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void tickController(@NotNull MinecraftClient client) {
|
||||
BUTTON_COOLDOWNS.entrySet().stream().filter(entry -> entry.getValue() > 0).forEach(entry -> BUTTON_COOLDOWNS.put(entry.getKey(), entry.getValue() - 1));
|
||||
BUTTON_COOLDOWNS.entrySet().stream().filter(entry -> entry.getValue() > 0)
|
||||
.forEach(entry -> BUTTON_COOLDOWNS.put(entry.getKey(), entry.getValue() - 1));
|
||||
// Decreases the cooldown for GUI actions.
|
||||
if (this.actionGuiCooldown > 0)
|
||||
--this.actionGuiCooldown;
|
||||
|
||||
InputManager.updateStates();
|
||||
|
||||
Controller controller = this.config.getController();
|
||||
var controller = this.config.getController();
|
||||
if (controller.isConnected()) {
|
||||
GLFWGamepadState state = controller.getState();
|
||||
var state = controller.getState();
|
||||
this.fetchButtonInput(client, state, false);
|
||||
this.fetchAxeInput(client, state, false);
|
||||
}
|
||||
@@ -153,13 +151,12 @@ public class LambdaInput {
|
||||
InputManager.updateBindings(client);
|
||||
|
||||
if (this.controlsInput != null
|
||||
&& InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::isUnpressed)) {
|
||||
&& InputManager.STATES.int2ObjectEntrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::isUnpressed)) {
|
||||
if (this.controlsInput.focusedBinding != null && !this.controlsInput.waiting) {
|
||||
int[] buttons = new int[this.controlsInput.currentButtons.size()];
|
||||
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
|
||||
buttons[i] = this.controlsInput.currentButtons.get(i);
|
||||
this.controlsInput.focusedBinding.setButton(buttons);
|
||||
this.controlsInput.focusedBinding = null;
|
||||
this.controlsInput.finishBindingEdit(buttons);
|
||||
this.controlsInput = null;
|
||||
}
|
||||
}
|
||||
@@ -171,8 +168,8 @@ public class LambdaInput {
|
||||
/**
|
||||
* This method is called before the screen is rendered.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param screen The screen to render.
|
||||
* @param client the client instance
|
||||
* @param screen the screen to render
|
||||
*/
|
||||
public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen) {
|
||||
if (!isScreenInteractive(screen)) {
|
||||
@@ -183,21 +180,21 @@ public class LambdaInput {
|
||||
/**
|
||||
* This method is called when Minecraft renders.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void onRender(float tickDelta, @NotNull MinecraftClient client) {
|
||||
if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay))
|
||||
return;
|
||||
|
||||
PlayerEntity player = client.player;
|
||||
var player = client.player;
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
if (this.targetYaw != 0.f || this.targetPitch != 0.f) {
|
||||
float rotationYaw = (float) (player.prevYaw + (this.targetYaw / 0.10) * tickDelta);
|
||||
float rotationPitch = (float) (player.prevPitch + (this.targetPitch / 0.10) * tickDelta);
|
||||
client.player.yaw = rotationYaw;
|
||||
client.player.pitch = MathHelper.clamp(rotationPitch, -90.f, 90.f);
|
||||
client.player.setYaw(rotationYaw);
|
||||
client.player.setPitch(MathHelper.clamp(rotationPitch, -90.f, 90.f));
|
||||
if (client.player.isRiding()) {
|
||||
client.player.getVehicle().onPassengerLookAround(client.player);
|
||||
}
|
||||
@@ -208,9 +205,9 @@ public class LambdaInput {
|
||||
/**
|
||||
* This method is called when a Screen is opened.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param windowWidth The window width.
|
||||
* @param windowHeight The window height.
|
||||
* @param client the client instance
|
||||
* @param windowWidth the window width
|
||||
* @param windowHeight the window height
|
||||
*/
|
||||
public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight) {
|
||||
if (client.currentScreen == null) {
|
||||
@@ -232,12 +229,12 @@ public class LambdaInput {
|
||||
}
|
||||
|
||||
private void fetchButtonInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
ByteBuffer buffer = gamepadState.buttons();
|
||||
var buffer = gamepadState.buttons();
|
||||
for (int i = 0; i < buffer.limit(); i++) {
|
||||
int btn = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
||||
boolean btnState = buffer.get() == (byte) 1;
|
||||
ButtonState state = ButtonState.NONE;
|
||||
ButtonState previousState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE);
|
||||
var state = ButtonState.NONE;
|
||||
var previousState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE);
|
||||
|
||||
if (btnState != previousState.isPressed()) {
|
||||
state = btnState ? ButtonState.PRESS : ButtonState.RELEASE;
|
||||
@@ -257,7 +254,7 @@ public class LambdaInput {
|
||||
}
|
||||
|
||||
private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
FloatBuffer buffer = gamepadState.axes();
|
||||
var buffer = gamepadState.axes();
|
||||
for (int i = 0; i < buffer.limit(); i++) {
|
||||
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
||||
float value = buffer.get();
|
||||
@@ -276,7 +273,7 @@ public class LambdaInput {
|
||||
if (action == 0 && !this.controlsInput.currentButtons.contains(button)) {
|
||||
this.controlsInput.currentButtons.add(button);
|
||||
|
||||
int[] buttons = new int[this.controlsInput.currentButtons.size()];
|
||||
var buttons = new int[this.controlsInput.currentButtons.size()];
|
||||
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
|
||||
buttons[i] = this.controlsInput.currentButtons.get(i);
|
||||
this.controlsInput.focusedBinding.setButton(buttons);
|
||||
@@ -295,11 +292,7 @@ public class LambdaInput {
|
||||
this.changeFocus(client.currentScreen, NavigationDirection.UP);
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) {
|
||||
this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT) {
|
||||
this.handleLeftRight(client.currentScreen, false);
|
||||
} else {
|
||||
this.handleLeftRight(client.currentScreen, true);
|
||||
}
|
||||
} else this.handleLeftRight(client.currentScreen, button != GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -308,7 +301,7 @@ public class LambdaInput {
|
||||
if (action == 1) {
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) {
|
||||
if (this.actionGuiCooldown == 0) {
|
||||
Element focused = client.currentScreen.getFocused();
|
||||
var focused = client.currentScreen.getFocused();
|
||||
if (focused != null && isScreenInteractive(client.currentScreen)) {
|
||||
if (this.handleAButton(client.currentScreen, focused)) {
|
||||
this.actionGuiCooldown = 5; // Prevent to press too quickly the focused element, so we have to skip 5 ticks.
|
||||
@@ -333,7 +326,8 @@ public class LambdaInput {
|
||||
}
|
||||
}
|
||||
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen) && this.actionGuiCooldown == 0) {
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen)
|
||||
&& this.actionGuiCooldown == 0) {
|
||||
if (!this.ignoreNextARelease) {
|
||||
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();
|
||||
@@ -354,9 +348,9 @@ public class LambdaInput {
|
||||
/**
|
||||
* Handles inventory interaction.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param button The button pressed.
|
||||
* @return True if an inventory interaction was done.
|
||||
* @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))
|
||||
@@ -376,20 +370,20 @@ public class LambdaInput {
|
||||
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();
|
||||
|
||||
HandledScreen screen = (HandledScreen) client.currentScreen;
|
||||
HandledScreenAccessor accessor = (HandledScreenAccessor) screen;
|
||||
var screen = (HandledScreen) client.currentScreen;
|
||||
var accessor = (HandledScreenAccessor) screen;
|
||||
Slot slot = ((HandledScreenAccessor) client.currentScreen).lambdacontrols$getSlotAt(x, y);
|
||||
|
||||
int slotId;
|
||||
if (slot == null) {
|
||||
if (client.player.inventory.getCursorStack().isEmpty())
|
||||
if (client.player.currentScreenHandler.getCursorStack().isEmpty())
|
||||
return false;
|
||||
slotId = accessor.lambdacontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1;
|
||||
} else {
|
||||
slotId = slot.id;
|
||||
}
|
||||
|
||||
SlotActionType actionType = SlotActionType.PICKUP;
|
||||
var actionType = SlotActionType.PICKUP;
|
||||
int clickData = GLFW.GLFW_MOUSE_BUTTON_1;
|
||||
switch (button) {
|
||||
case GLFW_GAMEPAD_BUTTON_A:
|
||||
@@ -416,13 +410,13 @@ public class LambdaInput {
|
||||
/**
|
||||
* Tries to go back.
|
||||
*
|
||||
* @param screen The current screen.
|
||||
* @return True if successful, else false.
|
||||
* @param screen the current screen
|
||||
* @return true if successful, else false
|
||||
*/
|
||||
public boolean tryGoBack(@NotNull Screen screen) {
|
||||
ImmutableSet<String> set = ImmutableSet.of("gui.back", "gui.done", "gui.cancel", "gui.toTitle", "gui.toMenu");
|
||||
return screen.children().stream().filter(element -> element instanceof AbstractPressableButtonWidget)
|
||||
.map(element -> (AbstractPressableButtonWidget) element)
|
||||
var set = ImmutableSet.of("gui.back", "gui.done", "gui.cancel", "gui.toTitle", "gui.toMenu");
|
||||
return screen.children().stream().filter(element -> element instanceof PressableWidget)
|
||||
.map(element -> (PressableWidget) element)
|
||||
.filter(element -> element.getMessage() instanceof TranslatableText)
|
||||
.anyMatch(element -> {
|
||||
if (set.stream().anyMatch(key -> key.equals(((TranslatableText) element.getMessage()).getKey()))) {
|
||||
@@ -450,8 +444,8 @@ public class LambdaInput {
|
||||
{
|
||||
boolean currentPlusState = asButtonState == 1;
|
||||
boolean currentMinusState = asButtonState == 2;
|
||||
ButtonState previousPlusState = InputManager.STATES.getOrDefault(axisAsButton(axis, true), ButtonState.NONE);
|
||||
ButtonState previousMinusState = InputManager.STATES.getOrDefault(axisAsButton(axis, false), ButtonState.NONE);
|
||||
var previousPlusState = InputManager.STATES.getOrDefault(axisAsButton(axis, true), ButtonState.NONE);
|
||||
var previousMinusState = InputManager.STATES.getOrDefault(axisAsButton(axis, false), ButtonState.NONE);
|
||||
|
||||
if (currentPlusState != previousPlusState.isPressed()) {
|
||||
InputManager.STATES.put(axisAsButton(axis, true), currentPlusState ? ButtonState.PRESS : ButtonState.RELEASE);
|
||||
@@ -505,20 +499,18 @@ public class LambdaInput {
|
||||
this.controlsInput.waiting = false;
|
||||
}
|
||||
return;
|
||||
} else if (client.currentScreen instanceof CreativeInventoryScreen) {
|
||||
} else if (client.currentScreen instanceof CreativeInventoryScreen creativeInventoryScreen) {
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
|
||||
CreativeInventoryScreen screen = (CreativeInventoryScreen) client.currentScreen;
|
||||
CreativeInventoryScreenAccessor accessor = (CreativeInventoryScreenAccessor) screen;
|
||||
var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen;
|
||||
// @TODO allow rebinding to left stick
|
||||
if (accessor.lambdacontrols$hasScrollbar() && absValue >= deadZone) {
|
||||
screen.mouseScrolled(0.0, 0.0, -value);
|
||||
creativeInventoryScreen.mouseScrolled(0.0, 0.0, -value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (client.currentScreen instanceof AdvancementsScreen) {
|
||||
} else if (client.currentScreen instanceof AdvancementsScreen advancementsScreen) {
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X || axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
|
||||
AdvancementsScreen screen = (AdvancementsScreen) client.currentScreen;
|
||||
AdvancementsScreenAccessor accessor = (AdvancementsScreenAccessor) screen;
|
||||
var accessor = (AdvancementsScreenAccessor) advancementsScreen;
|
||||
if (absValue >= deadZone) {
|
||||
AdvancementTab tab = accessor.getSelectedTab();
|
||||
tab.move(axis == GLFW_GAMEPAD_AXIS_RIGHT_X ? -value * 5.0 : 0.0, axis == GLFW_GAMEPAD_AXIS_RIGHT_Y ? -value * 5.0 : 0.0);
|
||||
@@ -595,36 +587,32 @@ public class LambdaInput {
|
||||
}
|
||||
|
||||
private boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) {
|
||||
if (focused instanceof AbstractPressableButtonWidget) {
|
||||
AbstractPressableButtonWidget widget = (AbstractPressableButtonWidget) focused;
|
||||
if (focused instanceof PressableWidget widget) {
|
||||
widget.playDownSound(MinecraftClient.getInstance().getSoundManager());
|
||||
widget.onPress();
|
||||
return true;
|
||||
} else if (focused instanceof AbstractSprucePressableButtonWidget) {
|
||||
AbstractSprucePressableButtonWidget widget = (AbstractSprucePressableButtonWidget) focused;
|
||||
} else if (focused instanceof AbstractSprucePressableButtonWidget widget) {
|
||||
widget.playDownSound();
|
||||
widget.onPress();
|
||||
return true;
|
||||
} else if (focused instanceof SpruceLabelWidget) {
|
||||
((SpruceLabelWidget) focused).onPress();
|
||||
} else if (focused instanceof SpruceLabelWidget labelWidget) {
|
||||
labelWidget.onPress();
|
||||
return true;
|
||||
} else if (focused instanceof WorldListWidget) {
|
||||
WorldListWidget list = (WorldListWidget) focused;
|
||||
} else if (focused instanceof WorldListWidget list) {
|
||||
list.getSelectedAsOptional().ifPresent(WorldListWidget.Entry::play);
|
||||
return true;
|
||||
} else if (focused instanceof MultiplayerServerListWidget) {
|
||||
MultiplayerServerListWidget list = (MultiplayerServerListWidget) focused;
|
||||
MultiplayerServerListWidget.Entry entry = list.getSelected();
|
||||
} else if (focused instanceof MultiplayerServerListWidget list) {
|
||||
var entry = list.getSelectedOrNull();
|
||||
if (entry instanceof MultiplayerServerListWidget.LanServerEntry || entry instanceof MultiplayerServerListWidget.ServerEntry) {
|
||||
((MultiplayerScreen) screen).select(entry);
|
||||
((MultiplayerScreen) screen).connect();
|
||||
}
|
||||
} else if (focused instanceof SpruceParentWidget) {
|
||||
Element childFocused = ((SpruceParentWidget<?>) focused).getFocused();
|
||||
var childFocused = ((SpruceParentWidget<?>) focused).getFocused();
|
||||
if (childFocused != null)
|
||||
return this.handleAButton(screen, childFocused);
|
||||
} else if (focused instanceof ParentElement) {
|
||||
Element childFocused = ((ParentElement) focused).getFocused();
|
||||
} else if (focused instanceof ParentElement widget) {
|
||||
var childFocused = widget.getFocused();
|
||||
if (childFocused != null)
|
||||
return this.handleAButton(screen, childFocused);
|
||||
}
|
||||
@@ -634,16 +622,16 @@ public class LambdaInput {
|
||||
/**
|
||||
* Handles the left and right buttons.
|
||||
*
|
||||
* @param screen The current screen.
|
||||
* @param right True if the right button is pressed, else false.
|
||||
* @param screen the current screen
|
||||
* @param right true if the right button is pressed, else false
|
||||
*/
|
||||
private boolean handleLeftRight(@NotNull Screen screen, boolean right) {
|
||||
if (screen instanceof SpruceScreen) {
|
||||
((SpruceScreen) screen).onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
|
||||
if (screen instanceof SpruceScreen spruceScreen) {
|
||||
spruceScreen.onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
|
||||
this.actionGuiCooldown = 5;
|
||||
return false;
|
||||
}
|
||||
Element focused = screen.getFocused();
|
||||
var focused = screen.getFocused();
|
||||
if (focused != null)
|
||||
if (this.handleRightLeftElement(focused, right))
|
||||
return this.changeFocus(screen, right ? NavigationDirection.RIGHT : NavigationDirection.LEFT);
|
||||
@@ -651,22 +639,20 @@ public class LambdaInput {
|
||||
}
|
||||
|
||||
private boolean handleRightLeftElement(@NotNull Element element, boolean right) {
|
||||
if (element instanceof SpruceElement) {
|
||||
if (((SpruceElement) element).requiresCursor())
|
||||
if (element instanceof SpruceElement spruceElement) {
|
||||
if (spruceElement.requiresCursor())
|
||||
return true;
|
||||
return !((SpruceElement) element).onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
|
||||
return !spruceElement.onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
|
||||
}
|
||||
if (element instanceof SliderWidget) {
|
||||
SliderWidget slider = (SliderWidget) element;
|
||||
if (element instanceof SliderWidget slider) {
|
||||
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.
|
||||
return false;
|
||||
} else if (element instanceof AlwaysSelectedEntryListWidget) {
|
||||
((EntryListWidgetAccessor) element).lambdacontrols$moveSelection(right ? EntryListWidget.MoveDirection.UP : EntryListWidget.MoveDirection.DOWN);
|
||||
return false;
|
||||
} else if (element instanceof ParentElement) {
|
||||
ParentElement entryList = (ParentElement) element;
|
||||
Element focused = entryList.getFocused();
|
||||
} else if (element instanceof ParentElement entryList) {
|
||||
var focused = entryList.getFocused();
|
||||
if (focused == null)
|
||||
return true;
|
||||
return this.handleRightLeftElement(focused, right);
|
||||
@@ -677,10 +663,10 @@ public class LambdaInput {
|
||||
/**
|
||||
* Handles the look direction input.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param axis The axis to change.
|
||||
* @param value The value of the look.
|
||||
* @param state The state.
|
||||
* @param client the client instance
|
||||
* @param axis the axis to change
|
||||
* @param value the value of the look
|
||||
* @param state the state
|
||||
*/
|
||||
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) {
|
||||
// Handles the look direction.
|
||||
@@ -704,8 +690,8 @@ public class LambdaInput {
|
||||
}
|
||||
|
||||
private boolean changeFocus(@NotNull Screen screen, NavigationDirection direction) {
|
||||
if (screen instanceof SpruceScreen) {
|
||||
if (((SpruceScreen) screen).onNavigation(direction, false)) {
|
||||
if (screen instanceof SpruceScreen spruceScreen) {
|
||||
if (spruceScreen.onNavigation(direction, false)) {
|
||||
this.actionGuiCooldown = 5;
|
||||
}
|
||||
return false;
|
||||
@@ -731,9 +717,8 @@ public class LambdaInput {
|
||||
// Inspired from https://github.com/MrCrayfish/Controllable/blob/1.14.X/src/main/java/com/mrcrayfish/controllable/client/ControllerInput.java#L686.
|
||||
private void moveMouseToClosestSlot(@NotNull MinecraftClient client, @Nullable Screen screen) {
|
||||
// Makes the mouse attracted to slots. This helps with selecting items when using a controller.
|
||||
if (screen instanceof HandledScreen) {
|
||||
HandledScreen inventoryScreen = (HandledScreen) screen;
|
||||
HandledScreenAccessor accessor = (HandledScreenAccessor) inventoryScreen;
|
||||
if (screen instanceof HandledScreen inventoryScreen) {
|
||||
var accessor = (HandledScreenAccessor) inventoryScreen;
|
||||
int guiLeft = accessor.getX();
|
||||
int guiTop = accessor.getY();
|
||||
int mouseX = (int) (targetMouseX * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth());
|
||||
@@ -752,8 +737,8 @@ public class LambdaInput {
|
||||
.min(Comparator.comparingDouble(p -> p.value));
|
||||
|
||||
if (closestSlot.isPresent()) {
|
||||
Slot slot = closestSlot.get().key;
|
||||
if (slot.hasStack() || !client.player.inventory.getMainHandStack().isEmpty()) {
|
||||
var slot = closestSlot.get().key;
|
||||
if (slot.hasStack() || !client.player.getInventory().getMainHandStack().isEmpty()) {
|
||||
int slotCenterXScaled = guiLeft + slot.x + 8;
|
||||
int slotCenterYScaled = guiTop + slot.y + 8;
|
||||
int slotCenterX = (int) (slotCenterXScaled / ((double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()));
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents the reach-around API of LambdaControls.
|
||||
*
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.3.2
|
||||
*/
|
||||
public class LambdaReacharound {
|
||||
@@ -49,7 +49,7 @@ public class LambdaReacharound {
|
||||
/**
|
||||
* Returns the last reach around result.
|
||||
*
|
||||
* @return The last reach around result.
|
||||
* @return the last reach around result
|
||||
*/
|
||||
public @Nullable BlockHitResult getLastReacharoundResult() {
|
||||
return this.lastReacharoundResult;
|
||||
@@ -58,7 +58,7 @@ public class LambdaReacharound {
|
||||
/**
|
||||
* Returns whether the last reach around is vertical.
|
||||
*
|
||||
* @return True if the reach around is vertical.
|
||||
* @return {@code true} if the reach around is vertical
|
||||
*/
|
||||
public boolean isLastReacharoundVertical() {
|
||||
return this.lastReacharoundVertical;
|
||||
@@ -67,7 +67,7 @@ public class LambdaReacharound {
|
||||
/**
|
||||
* Returns whether reacharound is available or not.
|
||||
*
|
||||
* @return True if reacharound is available, else false.
|
||||
* @return {@code true} if reacharound is available, else {@code false}
|
||||
*/
|
||||
public boolean isReacharoundAvailable() {
|
||||
return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable();
|
||||
@@ -80,22 +80,22 @@ public class LambdaReacharound {
|
||||
/**
|
||||
* Returns a nullable block hit result if vertical reach-around is possible.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @return A block hit result if vertical reach-around is possible, else null.
|
||||
* @param client the client instance
|
||||
* @return a block hit result if vertical reach-around is possible, else {@code null}
|
||||
*/
|
||||
public @Nullable BlockHitResult tryVerticalReachAround(@NotNull MinecraftClient client) {
|
||||
if (!LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable())
|
||||
return null;
|
||||
if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.MISS
|
||||
|| !client.player.isOnGround() || client.player.pitch < 80.0F
|
||||
|| !client.player.isOnGround() || client.player.getPitch(0.f) < 80.0F
|
||||
|| client.player.isRiding())
|
||||
return null;
|
||||
|
||||
Vec3d pos = client.player.getCameraPosVec(1.0F);
|
||||
Vec3d rotationVec = client.player.getRotationVec(1.0F);
|
||||
float range = getPlayerRange(client);
|
||||
Vec3d rayVec = pos.add(rotationVec.x * range, rotationVec.y * range, rotationVec.z * range).add(0, 0.75, 0);
|
||||
BlockHitResult result = client.world.raycast(new RaycastContext(pos, rayVec, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, client.player));
|
||||
var rayVec = pos.add(rotationVec.x * range, rotationVec.y * range, rotationVec.z * range).add(0, 0.75, 0);
|
||||
var result = client.world.raycast(new RaycastContext(pos, rayVec, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, client.player));
|
||||
|
||||
if (result.getType() == HitResult.Type.BLOCK) {
|
||||
BlockPos blockPos = result.getBlockPos().down();
|
||||
@@ -112,33 +112,34 @@ public class LambdaReacharound {
|
||||
/**
|
||||
* Returns a nullable block hit result if horizontal reach-around is possible.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @return A block hit result if horizontal reach-around is possible.
|
||||
* @param client the client instance
|
||||
* @return a block hit result if horizontal reach-around is possible
|
||||
*/
|
||||
public @Nullable BlockHitResult tryHorizontalReachAround(@NotNull MinecraftClient client) {
|
||||
if (!LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable())
|
||||
return null;
|
||||
|
||||
if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS && client.player.isOnGround() && client.player.pitch > 35.0F) {
|
||||
if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS
|
||||
&& client.player.isOnGround() && client.player.getPitch(0.f) > 35.f) {
|
||||
if (client.player.isRiding())
|
||||
return null;
|
||||
BlockPos playerPos = client.player.getBlockPos().down();
|
||||
var playerPos = client.player.getBlockPos().down();
|
||||
if (client.player.getY() - playerPos.getY() - 1.0 >= 0.25) {
|
||||
playerPos = playerPos.up();
|
||||
this.onSlab = true;
|
||||
} else {
|
||||
this.onSlab = false;
|
||||
}
|
||||
BlockPos targetPos = new BlockPos(client.crosshairTarget.getPos()).subtract(playerPos);
|
||||
BlockPos vector = new BlockPos(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1));
|
||||
BlockPos blockPos = playerPos.add(vector);
|
||||
var targetPos = new BlockPos(client.crosshairTarget.getPos()).subtract(playerPos);
|
||||
var vector = new BlockPos.Mutable(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1));
|
||||
var blockPos = playerPos.add(vector);
|
||||
|
||||
Direction direction = client.player.getHorizontalFacing();
|
||||
var direction = client.player.getHorizontalFacing();
|
||||
|
||||
BlockState state = client.world.getBlockState(blockPos);
|
||||
var state = client.world.getBlockState(blockPos);
|
||||
if (!state.isAir())
|
||||
return null;
|
||||
BlockState adjacentBlockState = client.world.getBlockState(blockPos.offset(direction.getOpposite()));
|
||||
var adjacentBlockState = client.world.getBlockState(blockPos.offset(direction.getOpposite()));
|
||||
if (adjacentBlockState.isAir() || adjacentBlockState.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Optional;
|
||||
/**
|
||||
* Represents the virtual mouse skins.
|
||||
*
|
||||
* @version 1.4.0
|
||||
* @version 1.7.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public enum VirtualMouseSkin implements Nameable {
|
||||
@@ -40,10 +40,10 @@ public enum VirtualMouseSkin implements Nameable {
|
||||
/**
|
||||
* Returns the next virtual mouse skin available.
|
||||
*
|
||||
* @return The next available virtual mouse skin.
|
||||
* @return the next available virtual mouse skin
|
||||
*/
|
||||
public @NotNull VirtualMouseSkin next() {
|
||||
VirtualMouseSkin[] v = values();
|
||||
var v = values();
|
||||
if (v.length == this.ordinal() + 1)
|
||||
return v[0];
|
||||
return v[this.ordinal() + 1];
|
||||
@@ -52,7 +52,7 @@ public enum VirtualMouseSkin implements Nameable {
|
||||
/**
|
||||
* Returns the translation key of this virtual mouse skin.
|
||||
*
|
||||
* @return The virtual mouse skin's translation key.
|
||||
* @return the virtual mouse skin's translation key
|
||||
*/
|
||||
public @NotNull String getTranslationKey() {
|
||||
return "lambdacontrols.virtual_mouse.skin." + this.getName();
|
||||
@@ -61,7 +61,7 @@ public enum VirtualMouseSkin implements Nameable {
|
||||
/**
|
||||
* Gets the translated text of this virtual mouse skin.
|
||||
*
|
||||
* @return The translated text of this virtual mouse skin.
|
||||
* @return the translated text of this virtual mouse skin
|
||||
*/
|
||||
public @NotNull Text getTranslatedText() {
|
||||
return this.text;
|
||||
@@ -75,8 +75,8 @@ public enum VirtualMouseSkin implements Nameable {
|
||||
/**
|
||||
* Gets the virtual mouse skin from its identifier.
|
||||
*
|
||||
* @param id The identifier of the virtual mouse skin.
|
||||
* @return The virtual mouse skin if found, else empty.
|
||||
* @param id the identifier of the virtual mouse skin
|
||||
* @return the virtual mouse skin if found, else empty
|
||||
*/
|
||||
public static @NotNull Optional<VirtualMouseSkin> byId(@NotNull String id) {
|
||||
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();
|
||||
|
||||
@@ -15,7 +15,6 @@ import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -23,22 +22,22 @@ import org.jetbrains.annotations.Nullable;
|
||||
* Represents a compatibility handler for a mod.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public interface CompatHandler {
|
||||
/**
|
||||
* Handles compatibility of a mod.
|
||||
*
|
||||
* @param mod This mod instance.
|
||||
* @param mod this mod instance
|
||||
*/
|
||||
void handle(@NotNull LambdaControlsClient mod);
|
||||
|
||||
/**
|
||||
* Returns whether the mouse is required on the specified screen.
|
||||
*
|
||||
* @param screen The screen.
|
||||
* @return True if the mouse is required on the specified screen, else false.
|
||||
* @param screen the screen
|
||||
* @return true if the mouse is required on the specified screen, else false
|
||||
*/
|
||||
default boolean requireMouseOnScreen(Screen screen) {
|
||||
return false;
|
||||
@@ -47,22 +46,22 @@ public interface CompatHandler {
|
||||
/**
|
||||
* Returns a slot at the specified location if possible.
|
||||
*
|
||||
* @param screen The screen.
|
||||
* @param mouseX The mouse X-coordinate.
|
||||
* @param mouseY The mouse Y-coordinate.
|
||||
* @return A slot if present, else null.
|
||||
* @param screen the screen
|
||||
* @param mouseX the mouse X-coordinate
|
||||
* @param mouseY the mouse Y-coordinate
|
||||
* @return a slot if present, else null
|
||||
* @since 1.5.0
|
||||
*/
|
||||
default @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
|
||||
default @Nullable CompatHandler.SlotPos getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current slot is a creative slot or not.
|
||||
*
|
||||
* @param screen The screen.
|
||||
* @param slot The slot to check.
|
||||
* @return True if the slot is a creative slot, else false.
|
||||
* @param screen the screen
|
||||
* @param slot the slot to check
|
||||
* @return true if the slot is a creative slot, else false
|
||||
*/
|
||||
default boolean isCreativeSlot(@NotNull HandledScreen screen, @NotNull Slot slot) {
|
||||
return false;
|
||||
@@ -71,9 +70,9 @@ public interface CompatHandler {
|
||||
/**
|
||||
* Returns a custom translation key to make custom attack action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
* @param client the client instance
|
||||
* @param placeResult the last place block result
|
||||
* @return null if untouched, else a translation key
|
||||
*/
|
||||
default String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
|
||||
return null;
|
||||
@@ -82,9 +81,9 @@ public interface CompatHandler {
|
||||
/**
|
||||
* Returns a custom translation key to make custom use action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
* @param client the client instance
|
||||
* @param placeResult the last place block result
|
||||
* @return null if untouched, else a translation key
|
||||
*/
|
||||
default String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
|
||||
return null;
|
||||
@@ -93,11 +92,15 @@ public interface CompatHandler {
|
||||
/**
|
||||
* Handles the menu back button.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param screen The screen.
|
||||
* @return True if the handle was fired and succeed, else false.
|
||||
* @param client the client instance
|
||||
* @param screen the screen
|
||||
* @return true if the handle was fired and succeed, else false
|
||||
*/
|
||||
default boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
record SlotPos(int x, int y) {
|
||||
public static final SlotPos INVALID_SLOT = new SlotPos(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import org.aperlambda.lambdacommon.utils.LambdaReflection;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -37,17 +36,17 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Initializes compatibility with other mods if needed.
|
||||
*
|
||||
* @param mod The mod instance.
|
||||
* @param mod the mod instance
|
||||
*/
|
||||
public static void init(@NotNull LambdaControlsClient mod) {
|
||||
if (FabricLoader.getInstance().isModLoaded("okzoomer")) {
|
||||
/*if (FabricLoader.getInstance().isModLoaded("okzoomer")) {
|
||||
mod.log("Adding okzoomer compatibility...");
|
||||
HANDLERS.add(new OkZoomerCompat());
|
||||
}
|
||||
if (isReiPresent()) {
|
||||
mod.log("Adding REI compatiblity...");
|
||||
HANDLERS.add(new ReiCompat());
|
||||
}
|
||||
}*/
|
||||
if (FabricLoader.getInstance().isModLoaded("hardcorequesting") && LambdaReflection.doesClassExist(HQMCompat.GUI_BASE_CLASS_PATH)) {
|
||||
mod.log("Adding HQM compatibility...");
|
||||
HANDLERS.add(new HQMCompat());
|
||||
@@ -59,7 +58,7 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Registers a new compatibility handler.
|
||||
*
|
||||
* @param handler The compatibility handler to register.
|
||||
* @param handler the compatibility handler to register
|
||||
*/
|
||||
public static void registerCompatHandler(@NotNull CompatHandler handler) {
|
||||
HANDLERS.add(handler);
|
||||
@@ -68,7 +67,7 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Streams through compatibility handlers.
|
||||
*
|
||||
* @return A stream of compatibility handlers.
|
||||
* @return a stream of compatibility handlers
|
||||
*/
|
||||
public static Stream<CompatHandler> streamCompatHandlers() {
|
||||
return HANDLERS.stream();
|
||||
@@ -77,8 +76,8 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Returns whether the mouse is required on the specified screen.
|
||||
*
|
||||
* @param screen The screen.
|
||||
* @return True if the mouse is requried on the specified screen, else false.
|
||||
* @param screen the screen
|
||||
* @return true if the mouse is requried on the specified screen, else false
|
||||
*/
|
||||
public static boolean requireMouseOnScreen(Screen screen) {
|
||||
return HANDLERS.stream().anyMatch(handler -> handler.requireMouseOnScreen(screen));
|
||||
@@ -87,14 +86,14 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Returns a slot at the specified location if possible.
|
||||
*
|
||||
* @param screen The screen.
|
||||
* @param mouseX The mouse X-coordinate.
|
||||
* @param mouseY The mouse Y-coordinate.
|
||||
* @return A slot if present, else null.
|
||||
* @param screen the screen
|
||||
* @param mouseX the mouse X-coordinate
|
||||
* @param mouseY the mouse Y-coordinate
|
||||
* @return a slot if present, else null
|
||||
*/
|
||||
public static @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
|
||||
for (CompatHandler handler : HANDLERS) {
|
||||
Pair<Integer, Integer> slot = handler.getSlotAt(screen, mouseX, mouseY);
|
||||
public static @Nullable CompatHandler.SlotPos getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
|
||||
for (var handler : HANDLERS) {
|
||||
var slot = handler.getSlotAt(screen, mouseX, mouseY);
|
||||
if (slot != null)
|
||||
return slot;
|
||||
}
|
||||
@@ -104,9 +103,9 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Returns a custom translation key to make custom attack action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
* @param client the client instance
|
||||
* @param placeResult the last place block result
|
||||
* @return null if untouched, else a translation key
|
||||
*/
|
||||
public static String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
|
||||
for (CompatHandler handler : HANDLERS) {
|
||||
@@ -121,9 +120,9 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Returns a custom translation key to make custom use action strings on the HUD.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param placeResult The last place block result.
|
||||
* @return Null if untouched, else a translation key.
|
||||
* @param client the client instance
|
||||
* @param placeResult the last place block result
|
||||
* @return null if untouched, else a translation key
|
||||
*/
|
||||
public static String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
|
||||
for (CompatHandler handler : HANDLERS) {
|
||||
@@ -138,9 +137,9 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Handles the menu back button.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param screen The screen.
|
||||
* @return True if the handle was fired and succeed, else false.
|
||||
* @param client the client instance
|
||||
* @param screen the screen
|
||||
* @return true if the handle was fired and succeed, else false
|
||||
*/
|
||||
public static boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) {
|
||||
for (CompatHandler handler : HANDLERS) {
|
||||
@@ -153,7 +152,7 @@ public class LambdaControlsCompat {
|
||||
/**
|
||||
* Returns whether Roughly Enough Items is present.
|
||||
*
|
||||
* @return True if Roughly Enough Items is present, else false.
|
||||
* @return true if Roughly Enough Items is present, else false
|
||||
*/
|
||||
public static boolean isReiPresent() {
|
||||
return FabricLoader.getInstance().isModLoaded("roughlyenoughitems");
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
package dev.lambdaurora.lambdacontrols.client.compat;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import io.github.joaoh1.okzoomer.client.keybinds.ZoomKeybinds;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Represents a compatibility handler for OkZoomer.
|
||||
@@ -25,7 +22,7 @@ import org.lwjgl.glfw.GLFW;
|
||||
public class OkZoomerCompat implements CompatHandler {
|
||||
@Override
|
||||
public void handle(@NotNull LambdaControlsClient mod) {
|
||||
new ButtonBinding.Builder("zoom")
|
||||
/*new ButtonBinding.Builder("zoom")
|
||||
.buttons(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_X)
|
||||
.onlyInGame()
|
||||
.cooldown(true)
|
||||
@@ -54,6 +51,6 @@ public class OkZoomerCompat implements CompatHandler {
|
||||
.category(ButtonBinding.MISC_CATEGORY)
|
||||
.linkKeybind(ZoomKeybinds.resetZoomKey)
|
||||
.register();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,48 +11,26 @@ package dev.lambdaurora.lambdacontrols.client.compat;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.ButtonState;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.compat.mixin.EntryListWidgetAccessor;
|
||||
import dev.lambdaurora.lambdacontrols.client.compat.mixin.EntryWidgetAccessor;
|
||||
import dev.lambdaurora.lambdacontrols.client.compat.mixin.RecipeViewingScreenAccessor;
|
||||
import dev.lambdaurora.lambdacontrols.client.compat.mixin.VillagerRecipeViewingScreenAccessor;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.InputHandlers;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.PressAction;
|
||||
import me.shedaniel.rei.api.*;
|
||||
import me.shedaniel.rei.gui.ContainerScreenOverlay;
|
||||
import me.shedaniel.rei.gui.PreRecipeViewingScreen;
|
||||
import me.shedaniel.rei.gui.RecipeViewingScreen;
|
||||
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
|
||||
import me.shedaniel.rei.gui.widget.EntryListEntryWidget;
|
||||
import me.shedaniel.rei.gui.widget.EntryListWidget;
|
||||
import me.shedaniel.rei.gui.widget.EntryWidget;
|
||||
import me.shedaniel.rei.gui.widget.WidgetWithBounds;
|
||||
import me.shedaniel.rei.impl.ScreenHelper;
|
||||
import me.shedaniel.rei.impl.widgets.ButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.aperlambda.lambdacommon.utils.LambdaReflection;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
/**
|
||||
* Represents a compatibility handler for REI.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class ReiCompat implements CompatHandler {
|
||||
private static final Pair<Integer, Integer> INVALID_SLOT = new Pair<>(-1, -1);
|
||||
private static EntryListWidget ENTRY_LIST_WIDGET;
|
||||
//private static EntryListWidget ENTRY_LIST_WIDGET;
|
||||
|
||||
@Override
|
||||
public void handle(@NotNull LambdaControlsClient mod) {
|
||||
@@ -113,57 +91,57 @@ public class ReiCompat implements CompatHandler {
|
||||
|
||||
@Override
|
||||
public boolean requireMouseOnScreen(Screen screen) {
|
||||
return isViewingScreen(screen) || screen instanceof PreRecipeViewingScreen;
|
||||
return isViewingScreen(screen) /*|| screen instanceof PreRecipeViewingScreen*/;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
|
||||
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
|
||||
public @Nullable SlotPos getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
|
||||
/*var overlay = ScreenHelper.getOptionalOverlay();
|
||||
if (overlay.isPresent() && overlay.get().isInside(mouseX, mouseY)) {
|
||||
EntryListWidget widget = getEntryListWidget();
|
||||
var widget = getEntryListWidget();
|
||||
if (widget == null)
|
||||
return null;
|
||||
|
||||
Pair<Integer, Integer> slot = this.getSlotAt(widget, mouseX, mouseY, false);
|
||||
var slot = this.getSlotAt(widget, mouseX, mouseY, false);
|
||||
if (slot != null && slot != INVALID_SLOT)
|
||||
return slot;
|
||||
} else if (isViewingScreen(screen)) {
|
||||
for (Element element : screen.children()) {
|
||||
Pair<Integer, Integer> slot = this.getSlotAt(element, mouseX, mouseY, true);
|
||||
for (var element : screen.children()) {
|
||||
var slot = this.getSlotAt(element, mouseX, mouseY, true);
|
||||
if (slot != null && slot != INVALID_SLOT)
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
private @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Element element, int mouseX, int mouseY, boolean allowEmpty) {
|
||||
if (element instanceof EntryWidget) {
|
||||
EntryWidget entry = (EntryWidget) element;
|
||||
/*private @Nullable SlotPos getSlotAt(@NotNull Element element, int mouseX, int mouseY, boolean allowEmpty) {
|
||||
if (element instanceof EntryWidget entry) {
|
||||
if (entry.containsMouse(mouseX, mouseY)) {
|
||||
if (!allowEmpty && entry.entries().isEmpty())
|
||||
return INVALID_SLOT;
|
||||
return Pair.of(entry.getBounds().getX() + 1, entry.getBounds().getY() + 1);
|
||||
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) {
|
||||
Pair<Integer, Integer> slot = this.getSlotAt(entry, mouseX, mouseY, allowEmpty);
|
||||
var slot = this.getSlotAt(entry, mouseX, mouseY, allowEmpty);
|
||||
if (slot != null && slot != INVALID_SLOT)
|
||||
return slot;
|
||||
}
|
||||
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds) {
|
||||
for (Element child : ((WidgetWithBounds) element).children()) {
|
||||
Pair<Integer, Integer> slot = this.getSlotAt(child, mouseX, mouseY, allowEmpty);
|
||||
} 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 RecipeViewingScreen || screen instanceof VillagerRecipeViewingScreen;
|
||||
return true;
|
||||
//return screen instanceof DefaultDisplayViewingScreen || screen instanceof CompositeDisplayViewingScreen;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -171,12 +149,12 @@ public class ReiCompat implements CompatHandler {
|
||||
if (!isViewingScreen(screen))
|
||||
return false;
|
||||
|
||||
MinecraftClient.getInstance().openScreen(REIHelper.getInstance().getPreviousContainerScreen());
|
||||
ScreenHelper.getLastOverlay().init();
|
||||
/*MinecraftClient.getInstance().openScreen(REIRuntimeImpl.getInstance().getPreviousContainerScreen());
|
||||
ScreenHelper.getLastOverlay().init();*/
|
||||
return true;
|
||||
}
|
||||
|
||||
private static EntryListWidget getEntryListWidget() {
|
||||
/*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))
|
||||
@@ -190,17 +168,17 @@ public class ReiCompat implements CompatHandler {
|
||||
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);
|
||||
for (var element : client.currentScreen.children()) {
|
||||
var stack = getCurrentStack(element, x, y);
|
||||
if (stack != null)
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
|
||||
var overlay = ScreenHelper.getOptionalOverlay();
|
||||
if (!overlay.isPresent())
|
||||
return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
|
||||
EntryListWidget widget = getEntryListWidget();
|
||||
var widget = getEntryListWidget();
|
||||
if (widget == null)
|
||||
return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
|
||||
|
||||
@@ -208,33 +186,32 @@ public class ReiCompat implements CompatHandler {
|
||||
}
|
||||
|
||||
private static @Nullable EntryStack getCurrentStack(@NotNull Element element, double mouseX, double mouseY) {
|
||||
if (element instanceof EntryWidget) {
|
||||
EntryWidget entry = (EntryWidget) element;
|
||||
if (element instanceof EntryWidget entry) {
|
||||
if (entry.containsMouse(mouseX, mouseY))
|
||||
return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry();
|
||||
} else if (element instanceof EntryListWidget) {
|
||||
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries();
|
||||
var 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);
|
||||
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds widgetWithBounds) {
|
||||
for (var child : widgetWithBounds.children()) {
|
||||
var 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);
|
||||
/*EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
|
||||
if (stack == null) {
|
||||
stack = getCurrentStack(client);
|
||||
}
|
||||
@@ -246,7 +223,7 @@ public class ReiCompat implements CompatHandler {
|
||||
} else {
|
||||
return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return false;
|
||||
};
|
||||
@@ -257,11 +234,11 @@ public class ReiCompat implements CompatHandler {
|
||||
if (action == ButtonState.RELEASE)
|
||||
return false;
|
||||
|
||||
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
|
||||
/*Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
|
||||
if (!overlay.isPresent())
|
||||
return false;
|
||||
|
||||
EntryListWidget widget = getEntryListWidget();
|
||||
var widget = getEntryListWidget();
|
||||
if (widget == null)
|
||||
return false;
|
||||
|
||||
@@ -269,7 +246,7 @@ public class ReiCompat implements CompatHandler {
|
||||
widget.nextPage();
|
||||
else
|
||||
widget.previousPage();
|
||||
widget.updateEntriesPosition();
|
||||
widget.updateEntriesPosition();*/
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -286,14 +263,14 @@ public class ReiCompat implements CompatHandler {
|
||||
if (action != ButtonState.RELEASE)
|
||||
return false;
|
||||
|
||||
if (client.currentScreen instanceof RecipeViewingScreen) {
|
||||
/*if (client.currentScreen instanceof DefaultDisplayViewingScreen) {
|
||||
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
|
||||
if (next)
|
||||
screen.getCategoryNext().onClick();
|
||||
else
|
||||
screen.getCategoryBack().onClick();
|
||||
return true;
|
||||
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) {
|
||||
} else if (client.currentScreen instanceof CompositeDisplayViewingScreen) {
|
||||
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
|
||||
List<RecipeCategory<?>> categories = screen.getCategories();
|
||||
int currentTab = screen.getSelectedCategoryIndex();
|
||||
@@ -301,7 +278,7 @@ public class ReiCompat implements CompatHandler {
|
||||
screen.setSelectedRecipeIndex(0);
|
||||
screen.lambdacontrols_init();
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
return false;
|
||||
};
|
||||
}
|
||||
@@ -311,15 +288,13 @@ public class ReiCompat implements CompatHandler {
|
||||
if (action.isUnpressed())
|
||||
return false;
|
||||
|
||||
if (client.currentScreen instanceof RecipeViewingScreen) {
|
||||
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
|
||||
/*if (client.currentScreen instanceof RecipeViewingScreenAccessor screen) {
|
||||
if (next)
|
||||
screen.getRecipeNext().onClick();
|
||||
else
|
||||
screen.getRecipeBack().onClick();
|
||||
return true;
|
||||
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) {
|
||||
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
|
||||
} else if (client.currentScreen instanceof VillagerRecipeViewingScreenAccessor screen) {
|
||||
List<RecipeCategory<?>> categories = screen.getCategories();
|
||||
int currentTab = screen.getSelectedCategoryIndex();
|
||||
List<RecipeDisplay> recipes = screen.getCategoryMap().get(categories.get(currentTab));
|
||||
@@ -343,7 +318,7 @@ public class ReiCompat implements CompatHandler {
|
||||
screen.lambdacontrols_init();
|
||||
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -9,13 +9,6 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client.compat.mixin;
|
||||
|
||||
import me.shedaniel.rei.gui.widget.EntryListEntryWidget;
|
||||
import me.shedaniel.rei.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.
|
||||
*
|
||||
@@ -23,8 +16,8 @@ import java.util.List;
|
||||
* @version 1.5.0
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@Mixin(value = EntryListWidget.class, remap = false)
|
||||
//@Mixin(value = EntryListWidget.class, remap = false)
|
||||
public interface EntryListWidgetAccessor {
|
||||
@Accessor(value = "entries")
|
||||
List<EntryListEntryWidget> getEntries();
|
||||
/*@Accessor(value = "entries")
|
||||
List<EntryListEntryWidget> getEntries();*/
|
||||
}
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client.compat.mixin;
|
||||
|
||||
import me.shedaniel.rei.api.EntryStack;
|
||||
import me.shedaniel.rei.gui.widget.EntryWidget;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
/**
|
||||
* Represents an accessor to REI's EntryWidget.
|
||||
*
|
||||
@@ -21,8 +16,8 @@ import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
* @version 1.5.0
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@Mixin(value = EntryWidget.class, remap = false)
|
||||
//@Mixin(value = EntryWidget.class, remap = false)
|
||||
public interface EntryWidgetAccessor {
|
||||
@Invoker("getCurrentEntry")
|
||||
EntryStack lambdacontrols_getCurrentEntry();
|
||||
/*@Invoker("getCurrentEntry")
|
||||
EntryStack lambdacontrols_getCurrentEntry();*/
|
||||
}
|
||||
|
||||
@@ -9,21 +9,16 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client.compat.mixin;
|
||||
|
||||
import me.shedaniel.rei.api.widgets.Button;
|
||||
import me.shedaniel.rei.gui.RecipeViewingScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
/**
|
||||
* Represents an accessor to REI's RecipeViewingScreen.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Mixin(value = RecipeViewingScreen.class, remap = false)
|
||||
//@Mixin(value = DefaultDisplayViewingScreen.class, remap = false)
|
||||
public interface RecipeViewingScreenAccessor {
|
||||
@Accessor("categoryBack")
|
||||
/*@Accessor("categoryBack")
|
||||
Button getCategoryBack();
|
||||
|
||||
@Accessor("categoryNext")
|
||||
@@ -33,5 +28,5 @@ public interface RecipeViewingScreenAccessor {
|
||||
Button getRecipeBack();
|
||||
|
||||
@Accessor("recipeNext")
|
||||
Button getRecipeNext();
|
||||
Button getRecipeNext();*/
|
||||
}
|
||||
|
||||
@@ -9,31 +9,20 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client.compat.mixin;
|
||||
|
||||
import me.shedaniel.clothconfig2.api.ScrollingContainer;
|
||||
import me.shedaniel.rei.api.RecipeCategory;
|
||||
import me.shedaniel.rei.api.RecipeDisplay;
|
||||
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents an accessor to REI's VillagerRecipeViewingScreen.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Mixin(VillagerRecipeViewingScreen.class)
|
||||
//@Mixin(CompositeDisplayViewingScreen.class)
|
||||
public interface VillagerRecipeViewingScreenAccessor {
|
||||
@Accessor(value = "categoryMap", remap = false)
|
||||
Map<RecipeCategory<?>, List<RecipeDisplay>> getCategoryMap();
|
||||
/*@Accessor(value = "categoryMap", remap = false)
|
||||
Map<DisplayCategory<?>, List<Display>> getCategoryMap();
|
||||
|
||||
@Accessor(value = "categories", remap = false)
|
||||
List<RecipeCategory<?>> getCategories();
|
||||
List<DisplayCategory<?>> getCategories();
|
||||
|
||||
@Accessor(value = "selectedCategoryIndex", remap = false)
|
||||
int getSelectedCategoryIndex();
|
||||
@@ -51,5 +40,5 @@ public interface VillagerRecipeViewingScreenAccessor {
|
||||
ScrollingContainer getScrolling();
|
||||
|
||||
@Invoker("init")
|
||||
void lambdacontrols_init();
|
||||
void lambdacontrols_init();*/
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ package dev.lambdaurora.lambdacontrols.client.controller;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.ButtonState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.option.GameOptions;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import org.aperlambda.lambdacommon.Identifier;
|
||||
@@ -31,7 +31,7 @@ import static org.lwjgl.glfw.GLFW.*;
|
||||
* Represents a button binding.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class ButtonBinding implements Nameable {
|
||||
@@ -89,12 +89,12 @@ public class ButtonBinding implements Nameable {
|
||||
private final Text text;
|
||||
private KeyBinding mcKeyBinding = null;
|
||||
protected PairPredicate<MinecraftClient, ButtonBinding> filter;
|
||||
private 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 int cooldown = 0;
|
||||
boolean pressed = false;
|
||||
|
||||
public ButtonBinding(@NotNull String key, int[] defaultButton, @NotNull List<PressAction> actions, PairPredicate<MinecraftClient, ButtonBinding> filter, boolean hasCooldown) {
|
||||
public ButtonBinding(String key, int[] defaultButton, List<PressAction> actions, PairPredicate<MinecraftClient, ButtonBinding> filter, boolean hasCooldown) {
|
||||
this.setButton(this.defaultButton = defaultButton);
|
||||
this.key = key;
|
||||
this.text = new TranslatableText(this.key);
|
||||
@@ -103,14 +103,14 @@ public class ButtonBinding implements Nameable {
|
||||
this.hasCooldown = hasCooldown;
|
||||
}
|
||||
|
||||
public ButtonBinding(@NotNull String key, int[] defaultButton, boolean hasCooldown) {
|
||||
public ButtonBinding(String key, int[] defaultButton, boolean hasCooldown) {
|
||||
this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the button bound.
|
||||
*
|
||||
* @return The bound button.
|
||||
* @return the bound button
|
||||
*/
|
||||
public int[] getButton() {
|
||||
return this.button;
|
||||
@@ -119,7 +119,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets the bound button.
|
||||
*
|
||||
* @param button The bound button.
|
||||
* @param button the bound button
|
||||
*/
|
||||
public void setButton(int[] button) {
|
||||
this.button = button;
|
||||
@@ -131,8 +131,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns whether the bound button is the specified button or not.
|
||||
*
|
||||
* @param button The button to check.
|
||||
* @return True if the bound button is the specified button, else false.
|
||||
* @param button the button to check
|
||||
* @return true if the bound button is the specified button, else false
|
||||
*/
|
||||
public boolean isButton(int[] button) {
|
||||
return InputManager.areButtonsEquivalent(button, this.button);
|
||||
@@ -141,7 +141,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns whether this button is down or not.
|
||||
*
|
||||
* @return True if the button is down, else false.
|
||||
* @return true if the button is down, else false
|
||||
*/
|
||||
public boolean isButtonDown() {
|
||||
return this.pressed;
|
||||
@@ -150,7 +150,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns whether this button binding is bound or not.
|
||||
*
|
||||
* @return True if this button binding is bound, else false.
|
||||
* @return true if this button binding is bound, else false
|
||||
*/
|
||||
public boolean isNotBound() {
|
||||
return this.button.length == 0 || this.button[0] == -1;
|
||||
@@ -159,7 +159,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Gets the default button assigned to this binding.
|
||||
*
|
||||
* @return The default button.
|
||||
* @return the default button
|
||||
*/
|
||||
public int[] getDefaultButton() {
|
||||
return this.defaultButton;
|
||||
@@ -168,7 +168,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns whether the assigned button is the default button.
|
||||
*
|
||||
* @return True if the assigned button is the default button, else false.
|
||||
* @return true if the assigned button is the default button, else false
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return this.button.length == this.defaultButton.length && InputManager.areButtonsEquivalent(this.button, this.defaultButton);
|
||||
@@ -177,10 +177,9 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns the button code.
|
||||
*
|
||||
* @return The button code.
|
||||
* @return the button code
|
||||
*/
|
||||
public @NotNull
|
||||
String getButtonCode() {
|
||||
public String getButtonCode() {
|
||||
return Arrays.stream(this.button)
|
||||
.mapToObj(btn -> Integer.valueOf(btn).toString())
|
||||
.collect(Collectors.joining("+"));
|
||||
@@ -189,7 +188,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets the key binding to emulate with this button binding.
|
||||
*
|
||||
* @param keyBinding The optional key binding.
|
||||
* @param keyBinding the optional key binding
|
||||
*/
|
||||
public void setKeyBinding(@Nullable KeyBinding keyBinding) {
|
||||
this.mcKeyBinding = keyBinding;
|
||||
@@ -198,8 +197,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns whether the button binding is available in the current context.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @return True if the button binding is available, else false.
|
||||
* @param client the client instance
|
||||
* @return true if the button binding is available, else false
|
||||
*/
|
||||
public boolean isAvailable(@NotNull MinecraftClient client) {
|
||||
return this.filter.test(client, this);
|
||||
@@ -216,8 +215,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Handles the button binding.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param state The state.
|
||||
* @param client the client instance
|
||||
* @param state the state
|
||||
*/
|
||||
public void handle(@NotNull MinecraftClient client, float value, @NotNull ButtonState state) {
|
||||
if (state == ButtonState.REPEAT && this.hasCooldown && this.cooldown != 0)
|
||||
@@ -239,7 +238,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns the translation key of this button binding.
|
||||
*
|
||||
* @return The translation key.
|
||||
* @return the translation key
|
||||
*/
|
||||
public @NotNull String getTranslationKey() {
|
||||
return "lambdacontrols.action." + this.getName();
|
||||
@@ -252,7 +251,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns the key binding equivalent of this button binding.
|
||||
*
|
||||
* @return The key binding equivalent.
|
||||
* @return the key binding equivalent
|
||||
*/
|
||||
public @NotNull Optional<KeyBinding> asKeyBinding() {
|
||||
return Optional.ofNullable(this.mcKeyBinding);
|
||||
@@ -268,9 +267,9 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns the specified axis as a button.
|
||||
*
|
||||
* @param axis The axis.
|
||||
* @param positive True if the axis part is positive, else false.
|
||||
* @return The axis as a button.
|
||||
* @param axis the axis
|
||||
* @param positive true if the axis part is positive, else false
|
||||
* @return the axis as a button
|
||||
*/
|
||||
public static int axisAsButton(int axis, boolean positive) {
|
||||
return positive ? 100 + axis : 200 + axis;
|
||||
@@ -279,8 +278,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns whether the specified button is an axis or not.
|
||||
*
|
||||
* @param button The button.
|
||||
* @return True if the button is an axis, else false.
|
||||
* @param button the button
|
||||
* @return true if the button is an axis, else false
|
||||
*/
|
||||
public static boolean isAxis(int button) {
|
||||
button %= 500;
|
||||
@@ -290,8 +289,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns the second Joycon's specified button code.
|
||||
*
|
||||
* @param button The raw button code.
|
||||
* @return The second Joycon's button code.
|
||||
* @param button the raw button code
|
||||
* @return the second Joycon's button code
|
||||
*/
|
||||
public static int controller2Button(int button) {
|
||||
return 500 + button;
|
||||
@@ -321,66 +320,39 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns the localized name of the specified button.
|
||||
*
|
||||
* @param button The button.
|
||||
* @return The localized name of the button.
|
||||
* @param button the button
|
||||
* @return the localized name of the button
|
||||
*/
|
||||
public static @NotNull Text getLocalizedButtonName(int button) {
|
||||
switch (button % 500) {
|
||||
case -1:
|
||||
return new TranslatableText("key.keyboard.unknown");
|
||||
case GLFW_GAMEPAD_BUTTON_A:
|
||||
return new TranslatableText("lambdacontrols.button.a");
|
||||
case GLFW_GAMEPAD_BUTTON_B:
|
||||
return new TranslatableText("lambdacontrols.button.b");
|
||||
case GLFW_GAMEPAD_BUTTON_X:
|
||||
return new TranslatableText("lambdacontrols.button.x");
|
||||
case GLFW_GAMEPAD_BUTTON_Y:
|
||||
return new TranslatableText("lambdacontrols.button.y");
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
|
||||
return new TranslatableText("lambdacontrols.button.left_bumper");
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
|
||||
return new TranslatableText("lambdacontrols.button.right_bumper");
|
||||
case GLFW_GAMEPAD_BUTTON_BACK:
|
||||
return new TranslatableText("lambdacontrols.button.back");
|
||||
case GLFW_GAMEPAD_BUTTON_START:
|
||||
return new TranslatableText("lambdacontrols.button.start");
|
||||
case GLFW_GAMEPAD_BUTTON_GUIDE:
|
||||
return new TranslatableText("lambdacontrols.button.guide");
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
|
||||
return new TranslatableText("lambdacontrols.button.left_thumb");
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
|
||||
return new TranslatableText("lambdacontrols.button.right_thumb");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP:
|
||||
return new TranslatableText("lambdacontrols.button.dpad_up");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
|
||||
return new TranslatableText("lambdacontrols.button.dpad_right");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
|
||||
return new TranslatableText("lambdacontrols.button.dpad_down");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
|
||||
return new TranslatableText("lambdacontrols.button.dpad_left");
|
||||
case 100:
|
||||
return new TranslatableText("lambdacontrols.axis.left_x+");
|
||||
case 101:
|
||||
return new TranslatableText("lambdacontrols.axis.left_y+");
|
||||
case 102:
|
||||
return new TranslatableText("lambdacontrols.axis.right_x+");
|
||||
case 103:
|
||||
return new TranslatableText("lambdacontrols.axis.right_y+");
|
||||
case 104:
|
||||
return new TranslatableText("lambdacontrols.axis.left_trigger");
|
||||
case 105:
|
||||
return new TranslatableText("lambdacontrols.axis.right_trigger");
|
||||
case 200:
|
||||
return new TranslatableText("lambdacontrols.axis.left_x-");
|
||||
case 201:
|
||||
return new TranslatableText("lambdacontrols.axis.left_y-");
|
||||
case 202:
|
||||
return new TranslatableText("lambdacontrols.axis.right_x-");
|
||||
case 203:
|
||||
return new TranslatableText("lambdacontrols.axis.right_y-");
|
||||
default:
|
||||
return new TranslatableText("lambdacontrols.button.unknown", button);
|
||||
}
|
||||
return switch (button % 500) {
|
||||
case -1 -> new TranslatableText("key.keyboard.unknown");
|
||||
case GLFW_GAMEPAD_BUTTON_A -> new TranslatableText("lambdacontrols.button.a");
|
||||
case GLFW_GAMEPAD_BUTTON_B -> new TranslatableText("lambdacontrols.button.b");
|
||||
case GLFW_GAMEPAD_BUTTON_X -> new TranslatableText("lambdacontrols.button.x");
|
||||
case GLFW_GAMEPAD_BUTTON_Y -> new TranslatableText("lambdacontrols.button.y");
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> new TranslatableText("lambdacontrols.button.left_bumper");
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> new TranslatableText("lambdacontrols.button.right_bumper");
|
||||
case GLFW_GAMEPAD_BUTTON_BACK -> new TranslatableText("lambdacontrols.button.back");
|
||||
case GLFW_GAMEPAD_BUTTON_START -> new TranslatableText("lambdacontrols.button.start");
|
||||
case GLFW_GAMEPAD_BUTTON_GUIDE -> new TranslatableText("lambdacontrols.button.guide");
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> new TranslatableText("lambdacontrols.button.left_thumb");
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> new TranslatableText("lambdacontrols.button.right_thumb");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP -> new TranslatableText("lambdacontrols.button.dpad_up");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> new TranslatableText("lambdacontrols.button.dpad_right");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> new TranslatableText("lambdacontrols.button.dpad_down");
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> new TranslatableText("lambdacontrols.button.dpad_left");
|
||||
case 100 -> new TranslatableText("lambdacontrols.axis.left_x+");
|
||||
case 101 -> new TranslatableText("lambdacontrols.axis.left_y+");
|
||||
case 102 -> new TranslatableText("lambdacontrols.axis.right_x+");
|
||||
case 103 -> new TranslatableText("lambdacontrols.axis.right_y+");
|
||||
case 104 -> new TranslatableText("lambdacontrols.axis.left_trigger");
|
||||
case 105 -> new TranslatableText("lambdacontrols.axis.right_trigger");
|
||||
case 200 -> new TranslatableText("lambdacontrols.axis.left_x-");
|
||||
case 201 -> new TranslatableText("lambdacontrols.axis.left_y-");
|
||||
case 202 -> new TranslatableText("lambdacontrols.axis.right_x-");
|
||||
case 203 -> new TranslatableText("lambdacontrols.axis.right_y-");
|
||||
default -> new TranslatableText("lambdacontrols.button.unknown", button);
|
||||
};
|
||||
}
|
||||
|
||||
static {
|
||||
@@ -416,8 +388,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns a builder instance.
|
||||
*
|
||||
* @param identifier The identifier of the button binding.
|
||||
* @return The builder instance
|
||||
* @param identifier the identifier of the button binding
|
||||
* @return the builder instanc
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static Builder builder(@NotNull Identifier identifier) {
|
||||
@@ -427,8 +399,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Returns a builder instance.
|
||||
*
|
||||
* @param identifier The identifier of the button binding.
|
||||
* @return The builder instance.
|
||||
* @param identifier the identifier of the button binding
|
||||
* @return the builder instance
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static Builder builder(@NotNull net.minecraft.util.Identifier identifier) {
|
||||
@@ -446,7 +418,7 @@ public class ButtonBinding implements Nameable {
|
||||
public static class Builder {
|
||||
private final String key;
|
||||
private int[] buttons = new int[0];
|
||||
private List<PressAction> actions = new ArrayList<>();
|
||||
private final List<PressAction> actions = new ArrayList<>();
|
||||
private PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue();
|
||||
private boolean cooldown = false;
|
||||
private ButtonCategory category = null;
|
||||
@@ -455,7 +427,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* This constructor shouldn't be used for other mods.
|
||||
*
|
||||
* @param key The key with format {@code "<namespace>.<name>"}.
|
||||
* @param key the key with format {@code "<namespace>.<name>"}
|
||||
*/
|
||||
public Builder(@NotNull String key) {
|
||||
this.key = key;
|
||||
@@ -473,8 +445,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Defines the default buttons of the {@link ButtonBinding}.
|
||||
*
|
||||
* @param buttons The default buttons.
|
||||
* @return The builder instance.
|
||||
* @param buttons the default buttons
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder buttons(int... buttons) {
|
||||
this.buttons = buttons;
|
||||
@@ -484,7 +456,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets the {@link ButtonBinding} to unbound.
|
||||
*
|
||||
* @return The builder instance.
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder unbound() {
|
||||
return this.buttons(-1);
|
||||
@@ -493,8 +465,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Adds the actions to the {@link ButtonBinding}.
|
||||
*
|
||||
* @param actions The actions to add.
|
||||
* @return The builder instance.
|
||||
* @param actions the actions to add
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder actions(@NotNull PressAction... actions) {
|
||||
this.actions.addAll(Arrays.asList(actions));
|
||||
@@ -504,8 +476,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Adds an action to the {@link ButtonBinding}.
|
||||
*
|
||||
* @param action The action to add.
|
||||
* @return The builder instance.
|
||||
* @param action the action to add
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder action(@NotNull PressAction action) {
|
||||
this.actions.add(action);
|
||||
@@ -515,8 +487,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets a filter for the {@link ButtonBinding}.
|
||||
*
|
||||
* @param filter The filter.
|
||||
* @return The builder instance.
|
||||
* @param filter the filter
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder filter(@NotNull PairPredicate<MinecraftClient, ButtonBinding> filter) {
|
||||
this.filter = filter;
|
||||
@@ -526,7 +498,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets the filter of {@link ButtonBinding} to only in game.
|
||||
*
|
||||
* @return The builder instance.
|
||||
* @return the builder instance
|
||||
* @see #filter(PairPredicate)
|
||||
* @see InputHandlers#inGame(MinecraftClient, ButtonBinding)
|
||||
*/
|
||||
@@ -537,7 +509,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets the filter of {@link ButtonBinding} to only in inventory.
|
||||
*
|
||||
* @return The builder instance.
|
||||
* @return the builder instance
|
||||
* @see #filter(PairPredicate)
|
||||
* @see InputHandlers#inInventory(MinecraftClient, ButtonBinding)
|
||||
*/
|
||||
@@ -548,8 +520,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets whether the {@link ButtonBinding} has a cooldown or not.
|
||||
*
|
||||
* @param cooldown True if the {@link ButtonBinding} has a cooldown, else false.
|
||||
* @return The builder instance.
|
||||
* @param cooldown true if the {@link ButtonBinding} has a cooldown, else false
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder cooldown(boolean cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
@@ -559,7 +531,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Puts a cooldown on the {@link ButtonBinding}.
|
||||
*
|
||||
* @return The builder instance.
|
||||
* @return the builder instance
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public Builder cooldown() {
|
||||
@@ -569,8 +541,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets the category of the {@link ButtonBinding}.
|
||||
*
|
||||
* @param category The category.
|
||||
* @return The builder instance.
|
||||
* @param category the category
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder category(@Nullable ButtonCategory category) {
|
||||
this.category = category;
|
||||
@@ -580,8 +552,8 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Sets the keybinding linked to the {@link ButtonBinding}.
|
||||
*
|
||||
* @param binding The keybinding to link.
|
||||
* @return The builder instance.
|
||||
* @param binding the keybinding to link
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder linkKeybind(@Nullable KeyBinding binding) {
|
||||
this.mcBinding = binding;
|
||||
@@ -591,10 +563,10 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Builds the {@link ButtonBinding}.
|
||||
*
|
||||
* @return The built {@link ButtonBinding}.
|
||||
* @return the built {@link ButtonBinding}
|
||||
*/
|
||||
public ButtonBinding build() {
|
||||
ButtonBinding 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);
|
||||
if (this.category != null)
|
||||
this.category.registerBinding(binding);
|
||||
if (this.mcBinding != null)
|
||||
@@ -605,7 +577,7 @@ public class ButtonBinding implements Nameable {
|
||||
/**
|
||||
* Builds and registers the {@link ButtonBinding}.
|
||||
*
|
||||
* @return The built {@link ButtonBinding}.
|
||||
* @return the built {@link ButtonBinding}
|
||||
* @see #build()
|
||||
*/
|
||||
public ButtonBinding register() {
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
public class ButtonCategory implements Identifiable {
|
||||
private final List<ButtonBinding> bindings = new ArrayList<>();
|
||||
private final Identifier id;
|
||||
private int priority;
|
||||
private final int priority;
|
||||
|
||||
public ButtonCategory(@NotNull Identifier id, int priority) {
|
||||
this.id = id;
|
||||
@@ -57,7 +57,7 @@ public class ButtonCategory implements Identifiable {
|
||||
/**
|
||||
* Gets the bindings assigned to this category.
|
||||
*
|
||||
* @return The bindings assigned to this category.
|
||||
* @return the bindings assigned to this category
|
||||
*/
|
||||
public @NotNull List<ButtonBinding> getBindings() {
|
||||
return Collections.unmodifiableList(this.bindings);
|
||||
@@ -68,7 +68,7 @@ public class ButtonCategory implements Identifiable {
|
||||
* <p>
|
||||
* The translation key should be `modid.identifier_name`.
|
||||
*
|
||||
* @return The translated name.
|
||||
* @return the translated name
|
||||
*/
|
||||
public @NotNull String getTranslatedName() {
|
||||
if (this.id.getNamespace().equals("minecraft"))
|
||||
@@ -81,7 +81,7 @@ public class ButtonCategory implements Identifiable {
|
||||
* Gets the priority display of this category.
|
||||
* It will defines in which order the categories will display on the controls screen.
|
||||
*
|
||||
* @return The priority of this category.
|
||||
* @return the priority of this category
|
||||
*/
|
||||
public int getPriority() {
|
||||
return this.priority;
|
||||
|
||||
@@ -17,18 +17,14 @@ import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import org.aperlambda.lambdacommon.utils.Nameable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWGamepadState;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@@ -41,30 +37,16 @@ import static org.lwjgl.BufferUtils.createByteBuffer;
|
||||
* Represents a controller.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.4.3
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Controller implements Nameable {
|
||||
public record Controller(int id) implements Nameable {
|
||||
private static final Map<Integer, Controller> CONTROLLERS = new HashMap<>();
|
||||
private final int id;
|
||||
|
||||
public Controller(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the identifier of this controller.
|
||||
*
|
||||
* @return The identifier of this controller.
|
||||
*/
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the controller's globally unique identifier.
|
||||
*
|
||||
* @return The controller's GUID.
|
||||
* @return the controller's GUID
|
||||
*/
|
||||
public String getGuid() {
|
||||
String guid = GLFW.glfwGetJoystickGUID(this.id);
|
||||
@@ -74,7 +56,7 @@ public class Controller implements Nameable {
|
||||
/**
|
||||
* Returns whether this controller is connected or not.
|
||||
*
|
||||
* @return True if this controller is connected, else false.
|
||||
* @return true if this controller is connected, else false
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return GLFW.glfwJoystickPresent(this.id);
|
||||
@@ -83,7 +65,7 @@ public class Controller implements Nameable {
|
||||
/**
|
||||
* Returns whether this controller is a gamepad or not.
|
||||
*
|
||||
* @return True if this controller is a gamepad, else false.
|
||||
* @return true if this controller is a gamepad, else false
|
||||
*/
|
||||
public boolean isGamepad() {
|
||||
return this.isConnected() && GLFW.glfwJoystickIsGamepad(this.id);
|
||||
@@ -92,27 +74,27 @@ public class Controller implements Nameable {
|
||||
/**
|
||||
* Gets the name of the controller.
|
||||
*
|
||||
* @return The controller's name.
|
||||
* @return the controller's name
|
||||
*/
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
String name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id);
|
||||
return name == null ? String.valueOf(this.getId()) : name;
|
||||
public String getName() {
|
||||
var name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id);
|
||||
return name == null ? String.valueOf(this.id()) : name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of the controller.
|
||||
*
|
||||
* @return The state of the controller input.
|
||||
* @return the state of the controller input
|
||||
*/
|
||||
public GLFWGamepadState getState() {
|
||||
GLFWGamepadState state = GLFWGamepadState.create();
|
||||
var state = GLFWGamepadState.create();
|
||||
if (this.isGamepad())
|
||||
GLFW.glfwGetGamepadState(this.id, state);
|
||||
return state;
|
||||
}
|
||||
|
||||
public static @NotNull Controller byId(int id) {
|
||||
public static Controller byId(int id) {
|
||||
if (id > GLFW.GLFW_JOYSTICK_LAST) {
|
||||
LambdaControlsClient.get().log("Controller '" + id + "' doesn't exist.");
|
||||
id = GLFW.GLFW_JOYSTICK_LAST;
|
||||
@@ -127,33 +109,33 @@ public class Controller implements Nameable {
|
||||
}
|
||||
}
|
||||
|
||||
public static @NotNull Optional<Controller> byGuid(@NotNull String guid) {
|
||||
public static Optional<Controller> byGuid(@NotNull String guid) {
|
||||
return CONTROLLERS.values().stream().filter(Controller::isConnected)
|
||||
.filter(controller -> controller.getGuid().equals(guid))
|
||||
.max(Comparator.comparingInt(Controller::getId));
|
||||
.max(Comparator.comparingInt(Controller::id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the specified resource and returns the raw data as a ByteBuffer.
|
||||
*
|
||||
* @param resource The resource to read.
|
||||
* @param bufferSize The initial buffer size.
|
||||
* @return The resource data.
|
||||
* @param resource the resource to read
|
||||
* @param bufferSize the initial buffer size
|
||||
* @return the resource data
|
||||
* @throws IOException If an IO error occurs.
|
||||
*/
|
||||
private static ByteBuffer ioResourceToBuffer(String resource, int bufferSize) throws IOException {
|
||||
ByteBuffer buffer = null;
|
||||
|
||||
Path path = Paths.get(resource);
|
||||
var path = Paths.get(resource);
|
||||
if (Files.isReadable(path)) {
|
||||
try (SeekableByteChannel fc = Files.newByteChannel(path)) {
|
||||
try (var fc = Files.newByteChannel(path)) {
|
||||
buffer = createByteBuffer((int) fc.size() + 2);
|
||||
while (fc.read(buffer) != -1) ;
|
||||
buffer.put((byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
((Buffer) buffer).flip(); // Force Java 8 >.<
|
||||
buffer.flip(); // Force Java 8 >.<
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -165,20 +147,19 @@ public class Controller implements Nameable {
|
||||
if (!LambdaControlsClient.MAPPINGS_FILE.exists())
|
||||
return;
|
||||
LambdaControlsClient.get().log("Updating controller mappings...");
|
||||
ByteBuffer buffer = ioResourceToBuffer(LambdaControlsClient.MAPPINGS_FILE.getPath(), 1024);
|
||||
var buffer = ioResourceToBuffer(LambdaControlsClient.MAPPINGS_FILE.getPath(), 1024);
|
||||
GLFW.glfwUpdateGamepadMappings(buffer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
MemoryStack memoryStack = MemoryStack.stackPush();
|
||||
try {
|
||||
PointerBuffer pointerBuffer = memoryStack.mallocPointer(1);
|
||||
try (var memoryStack = MemoryStack.stackPush()) {
|
||||
var pointerBuffer = memoryStack.mallocPointer(1);
|
||||
int i = GLFW.glfwGetError(pointerBuffer);
|
||||
if (i != 0) {
|
||||
long l = pointerBuffer.get();
|
||||
String string = l == 0L ? "" : MemoryUtil.memUTF8(l);
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
var string = l == 0L ? "" : MemoryUtil.memUTF8(l);
|
||||
var client = MinecraftClient.getInstance();
|
||||
if (client != null) {
|
||||
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT,
|
||||
new TranslatableText("lambdacontrols.controller.mappings.error"), new LiteralText(string)));
|
||||
@@ -186,13 +167,11 @@ public class Controller implements Nameable {
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
/* Ignored :concern: */
|
||||
} finally {
|
||||
memoryStack.close();
|
||||
}
|
||||
|
||||
if (LambdaControlsClient.get().config.hasDebug()) {
|
||||
for (int i = GLFW.GLFW_JOYSTICK_1; i <= GLFW.GLFW_JOYSTICK_16; i++) {
|
||||
Controller controller = byId(i);
|
||||
var controller = byId(i);
|
||||
|
||||
if (!controller.isConnected())
|
||||
continue;
|
||||
|
||||
@@ -16,20 +16,16 @@ import dev.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccess
|
||||
import dev.lambdaurora.lambdacontrols.client.mixin.RecipeBookWidgetAccessor;
|
||||
import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.advancement.AdvancementTab;
|
||||
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
|
||||
import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget;
|
||||
import net.minecraft.client.util.ScreenshotUtils;
|
||||
import net.minecraft.client.util.ScreenshotRecorder;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -38,7 +34,7 @@ import java.util.stream.Collectors;
|
||||
* Represents some input handlers.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.4.3
|
||||
* @version 1.7.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class InputHandlers {
|
||||
@@ -53,12 +49,11 @@ public class InputHandlers {
|
||||
// When ingame
|
||||
if (client.currentScreen == null && client.player != null) {
|
||||
if (next)
|
||||
client.player.inventory.selectedSlot = client.player.inventory.selectedSlot == 8 ? 0 : client.player.inventory.selectedSlot + 1;
|
||||
client.player.getInventory().selectedSlot = client.player.getInventory().selectedSlot == 8 ? 0 : client.player.getInventory().selectedSlot + 1;
|
||||
else
|
||||
client.player.inventory.selectedSlot = client.player.inventory.selectedSlot == 0 ? 8 : client.player.inventory.selectedSlot - 1;
|
||||
client.player.getInventory().selectedSlot = client.player.getInventory().selectedSlot == 0 ? 8 : client.player.getInventory().selectedSlot - 1;
|
||||
return true;
|
||||
} else if (client.currentScreen instanceof CreativeInventoryScreen) {
|
||||
CreativeInventoryScreenAccessor inventory = (CreativeInventoryScreenAccessor) client.currentScreen;
|
||||
} else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) {
|
||||
int currentTab = inventory.getSelectedTab();
|
||||
int nextTab = currentTab + (next ? 1 : -1);
|
||||
if (nextTab < 0)
|
||||
@@ -67,10 +62,10 @@ public class InputHandlers {
|
||||
nextTab = 0;
|
||||
inventory.lambdacontrols$setSelectedTab(ItemGroup.GROUPS[nextTab]);
|
||||
return true;
|
||||
} else if (client.currentScreen instanceof InventoryScreen) {
|
||||
RecipeBookWidgetAccessor recipeBook = (RecipeBookWidgetAccessor) ((InventoryScreen) client.currentScreen).getRecipeBookWidget();
|
||||
List<RecipeGroupButtonWidget> tabs = recipeBook.getTabButtons();
|
||||
RecipeGroupButtonWidget currentTab = recipeBook.getCurrentTab();
|
||||
} else if (client.currentScreen instanceof InventoryScreen inventoryScreen) {
|
||||
var recipeBook = (RecipeBookWidgetAccessor) inventoryScreen.getRecipeBookWidget();
|
||||
var tabs = recipeBook.getTabButtons();
|
||||
var currentTab = recipeBook.getCurrentTab();
|
||||
if (currentTab == null)
|
||||
return false;
|
||||
int nextTab = tabs.indexOf(currentTab) + (next ? 1 : -1);
|
||||
@@ -83,10 +78,9 @@ public class InputHandlers {
|
||||
currentTab.setToggled(true);
|
||||
recipeBook.lambdacontrols$refreshResults(true);
|
||||
return true;
|
||||
} else if (client.currentScreen instanceof AdvancementsScreen) {
|
||||
AdvancementsScreenAccessor screen = (AdvancementsScreenAccessor) client.currentScreen;
|
||||
List<AdvancementTab> tabs = screen.getTabs().values().stream().distinct().collect(Collectors.toList());
|
||||
AdvancementTab tab = screen.getSelectedTab();
|
||||
} else if (client.currentScreen instanceof AdvancementsScreenAccessor screen) {
|
||||
var tabs = screen.getTabs().values().stream().distinct().collect(Collectors.toList());
|
||||
var tab = screen.getSelectedTab();
|
||||
if (tab == null)
|
||||
return false;
|
||||
for (int i = 0; i < tabs.size(); i++) {
|
||||
@@ -122,14 +116,14 @@ public class InputHandlers {
|
||||
/**
|
||||
* Handles the screenshot action.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param binding The binding which fired the action.
|
||||
* @param action The action done on the binding.
|
||||
* @return True if handled, else false.
|
||||
* @param client the client instance
|
||||
* @param binding the binding which fired the action
|
||||
* @param action the action done on the binding
|
||||
* @return true if handled, else false
|
||||
*/
|
||||
public static boolean handleScreenshot(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, float value, @NotNull ButtonState action) {
|
||||
if (action == ButtonState.RELEASE)
|
||||
ScreenshotUtils.saveScreenshot(client.runDirectory, client.getWindow().getFramebufferWidth(), client.getWindow().getFramebufferHeight(), client.getFramebuffer(),
|
||||
ScreenshotRecorder.saveScreenshot(client.runDirectory, client.getWindow().getFramebufferWidth(), client.getWindow().getFramebufferHeight(), client.getFramebuffer(),
|
||||
text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)));
|
||||
return true;
|
||||
}
|
||||
@@ -137,10 +131,10 @@ public class InputHandlers {
|
||||
public static boolean handleToggleSneak(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action) {
|
||||
button.asKeyBinding().ifPresent(binding -> {
|
||||
boolean sneakToggled = client.options.sneakToggled;
|
||||
if (client.player.abilities.flying && sneakToggled)
|
||||
if (client.player.getAbilities().flying && sneakToggled)
|
||||
client.options.sneakToggled = false;
|
||||
binding.setPressed(button.pressed);
|
||||
if (client.player.abilities.flying && sneakToggled)
|
||||
if (client.player.getAbilities().flying && sneakToggled)
|
||||
client.options.sneakToggled = true;
|
||||
});
|
||||
return true;
|
||||
@@ -148,18 +142,17 @@ public class InputHandlers {
|
||||
|
||||
public static PressAction handleInventorySlotPad(int direction) {
|
||||
return (client, binding, value, action) -> {
|
||||
if (!(client.currentScreen instanceof HandledScreen && action != ButtonState.RELEASE))
|
||||
if (!(client.currentScreen instanceof HandledScreen inventory && action != ButtonState.RELEASE))
|
||||
return false;
|
||||
|
||||
HandledScreen inventory = (HandledScreen) client.currentScreen;
|
||||
HandledScreenAccessor accessor = (HandledScreenAccessor) inventory;
|
||||
var accessor = (HandledScreenAccessor) inventory;
|
||||
int guiLeft = accessor.getX();
|
||||
int guiTop = accessor.getY();
|
||||
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
|
||||
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
|
||||
|
||||
// Finds the hovered slot.
|
||||
Slot mouseSlot = accessor.lambdacontrols$getSlotAt(mouseX, mouseY);
|
||||
var mouseSlot = accessor.lambdacontrols$getSlotAt(mouseX, mouseY);
|
||||
|
||||
// Finds the closest slot in the GUI within 14 pixels.
|
||||
Optional<Slot> closestSlot = inventory.getScreenHandler().slots.parallelStream()
|
||||
@@ -179,7 +172,7 @@ public class InputHandlers {
|
||||
double distance = Math.sqrt(Math.pow(posX - otherPosX, 2) + Math.pow(posY - otherPosY, 2));
|
||||
return Pair.of(slot, distance);
|
||||
}).filter(entry -> {
|
||||
Slot slot = entry.key;
|
||||
var slot = entry.key;
|
||||
int posX = guiLeft + slot.x + 8;
|
||||
int posY = guiTop + slot.y + 8;
|
||||
int otherPosX = (int) mouseX;
|
||||
@@ -203,7 +196,7 @@ public class InputHandlers {
|
||||
.map(p -> p.key);
|
||||
|
||||
if (closestSlot.isPresent()) {
|
||||
Slot slot = closestSlot.get();
|
||||
var slot = closestSlot.get();
|
||||
int x = guiLeft + slot.x + 8;
|
||||
int y = guiTop + slot.y + 8;
|
||||
InputManager.queueMousePosition(x * (double) client.getWindow().getWidth() / (double) client.getWindow().getScaledWidth(),
|
||||
@@ -217,9 +210,9 @@ public class InputHandlers {
|
||||
/**
|
||||
* Returns always true to the filter.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param binding The affected binding.
|
||||
* @return True.
|
||||
* @param client the client instance
|
||||
* @param binding the affected binding
|
||||
* @return true
|
||||
*/
|
||||
public static boolean always(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
|
||||
return true;
|
||||
@@ -228,9 +221,9 @@ public class InputHandlers {
|
||||
/**
|
||||
* Returns whether the client is in game or not.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param binding The affected binding.
|
||||
* @return True if the client is in game, else false.
|
||||
* @param client the client instance
|
||||
* @param binding the affected binding
|
||||
* @return true if the client is in game, else false
|
||||
*/
|
||||
public static boolean inGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
|
||||
return client.currentScreen == null;
|
||||
@@ -239,9 +232,9 @@ public class InputHandlers {
|
||||
/**
|
||||
* Returns whether the client is in a non-interactive screen (which means require mouse input) or not.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param binding The affected binding.
|
||||
* @return True if the client is in a non-interactive screen, else false.
|
||||
* @param client the client instance
|
||||
* @param binding the affected binding
|
||||
* @return true if the client is in a non-interactive screen, else false
|
||||
*/
|
||||
public static boolean inNonInteractiveScreens(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
|
||||
if (client.currentScreen == null)
|
||||
@@ -252,9 +245,9 @@ public class InputHandlers {
|
||||
/**
|
||||
* Returns whether the client is in an inventory or not.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param binding The affected binding.
|
||||
* @return True if the client is in an inventory, else false.
|
||||
* @param client the client instance
|
||||
* @param binding the affected binding
|
||||
* @return true if the client is in an inventory, else false
|
||||
*/
|
||||
public static boolean inInventory(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
|
||||
return client.currentScreen instanceof HandledScreen;
|
||||
@@ -263,9 +256,9 @@ public class InputHandlers {
|
||||
/**
|
||||
* Returns whether the client is in the advancements screen or not.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param binding The affected binding.
|
||||
* @return True if the client is in the advancements screen, else false.
|
||||
* @param client the client instance
|
||||
* @param binding the affected binding
|
||||
* @return true if the client is in the advancements screen, else false
|
||||
*/
|
||||
public static boolean inAdvancements(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
|
||||
return client.currentScreen instanceof AdvancementsScreen;
|
||||
|
||||
@@ -14,12 +14,13 @@ import dev.lambdaurora.lambdacontrols.client.ButtonState;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig;
|
||||
import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.aperlambda.lambdacommon.Identifier;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.aperlambda.lambdacommon.utils.function.PairPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
@@ -33,15 +34,15 @@ import java.util.stream.Stream;
|
||||
* Represents an input manager for controllers.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.4.0
|
||||
* @version 1.7.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class InputManager {
|
||||
public static final InputManager INPUT_MANAGER = new InputManager();
|
||||
private static final List<ButtonBinding> BINDINGS = new ArrayList<>();
|
||||
private static final List<ButtonCategory> CATEGORIES = new ArrayList<>();
|
||||
public static final Map<Integer, ButtonState> STATES = new HashMap<>();
|
||||
public static final Map<Integer, Float> BUTTON_VALUES = new HashMap<>();
|
||||
public static final Int2ObjectMap<ButtonState> STATES = new Int2ObjectOpenHashMap<>();
|
||||
public static final Int2FloatMap BUTTON_VALUES = new Int2FloatOpenHashMap();
|
||||
private int prevTargetMouseX = 0;
|
||||
private int prevTargetMouseY = 0;
|
||||
private int targetMouseX = 0;
|
||||
@@ -64,7 +65,7 @@ public class InputManager {
|
||||
/**
|
||||
* Updates the mouse position. Should only be called on pre render of a screen.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void updateMousePosition(@NotNull MinecraftClient client) {
|
||||
Objects.requireNonNull(client, "Client instance cannot be null.");
|
||||
@@ -80,8 +81,8 @@ public class InputManager {
|
||||
/**
|
||||
* Resets the mouse position.
|
||||
*
|
||||
* @param windowWidth The window width.
|
||||
* @param windowHeight The window height.
|
||||
* @param windowWidth the window width
|
||||
* @param windowHeight the window height
|
||||
*/
|
||||
public void resetMousePosition(int windowWidth, int windowHeight) {
|
||||
this.targetMouseX = this.prevTargetMouseX = (int) (windowWidth / 2.F);
|
||||
@@ -98,8 +99,8 @@ public class InputManager {
|
||||
/**
|
||||
* Returns whether the specified binding is registered or not.
|
||||
*
|
||||
* @param binding The binding to check.
|
||||
* @return True if the binding is registered, else false.
|
||||
* @param binding the binding to check
|
||||
* @return true if the binding is registered, else false
|
||||
*/
|
||||
public static boolean hasBinding(@NotNull ButtonBinding binding) {
|
||||
return BINDINGS.contains(binding);
|
||||
@@ -108,8 +109,8 @@ public class InputManager {
|
||||
/**
|
||||
* Returns whether the specified binding is registered or not.
|
||||
*
|
||||
* @param name The name of the binding to check.
|
||||
* @return True if the binding is registered, else false.
|
||||
* @param name the name of the binding to check
|
||||
* @return true if the binding is registered, else false
|
||||
*/
|
||||
public static boolean hasBinding(@NotNull String name) {
|
||||
return BINDINGS.parallelStream().map(ButtonBinding::getName).anyMatch(binding -> binding.equalsIgnoreCase(name));
|
||||
@@ -118,8 +119,8 @@ public class InputManager {
|
||||
/**
|
||||
* Returns whether the specified binding is registered or not.
|
||||
*
|
||||
* @param identifier The identifier of the binding to check.
|
||||
* @return True if the binding is registered, else false.
|
||||
* @param identifier the identifier of the binding to check
|
||||
* @return true if the binding is registered, else false
|
||||
*/
|
||||
public static boolean hasBinding(@NotNull Identifier identifier) {
|
||||
return hasBinding(identifier.getNamespace() + "." + identifier.getName());
|
||||
@@ -128,8 +129,8 @@ public class InputManager {
|
||||
/**
|
||||
* Registers a button binding.
|
||||
*
|
||||
* @param binding The binding to register.
|
||||
* @return The registered binding.
|
||||
* @param binding the binding to register
|
||||
* @return the registered binding
|
||||
*/
|
||||
public static @NotNull ButtonBinding registerBinding(@NotNull ButtonBinding binding) {
|
||||
if (hasBinding(binding))
|
||||
@@ -159,7 +160,8 @@ public class InputManager {
|
||||
*/
|
||||
public static void sortBindings() {
|
||||
synchronized (BINDINGS) {
|
||||
List<ButtonBinding> sorted = BINDINGS.stream().sorted(Collections.reverseOrder(Comparator.comparingInt(binding -> binding.getButton().length)))
|
||||
var sorted = BINDINGS.stream()
|
||||
.sorted(Collections.reverseOrder(Comparator.comparingInt(binding -> binding.getButton().length)))
|
||||
.collect(Collectors.toList());
|
||||
BINDINGS.clear();
|
||||
BINDINGS.addAll(sorted);
|
||||
@@ -169,8 +171,8 @@ public class InputManager {
|
||||
/**
|
||||
* Registers a category of button bindings.
|
||||
*
|
||||
* @param category The category to register.
|
||||
* @return The registered category.
|
||||
* @param category the category to register
|
||||
* @return the registered category
|
||||
*/
|
||||
public static ButtonCategory registerCategory(@NotNull ButtonCategory category) {
|
||||
CATEGORIES.add(category);
|
||||
@@ -186,7 +188,7 @@ public class InputManager {
|
||||
}
|
||||
|
||||
protected static ButtonCategory registerDefaultCategory(@NotNull String key, @NotNull Consumer<ButtonCategory> keyAdder) {
|
||||
ButtonCategory category = registerCategory(new Identifier("minecraft", key), CATEGORIES.size());
|
||||
var category = registerCategory(new Identifier("minecraft", key), CATEGORIES.size());
|
||||
keyAdder.accept(category);
|
||||
return category;
|
||||
}
|
||||
@@ -194,23 +196,23 @@ public class InputManager {
|
||||
/**
|
||||
* Loads the button bindings from configuration.
|
||||
*
|
||||
* @param config The configuration instance.
|
||||
* @param config the configuration instance
|
||||
*/
|
||||
public static void loadButtonBindings(@NotNull LambdaControlsConfig config) {
|
||||
List<ButtonBinding> queue = new ArrayList<>(BINDINGS);
|
||||
var queue = new ArrayList<>(BINDINGS);
|
||||
queue.forEach(config::loadButtonBinding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the binding state.
|
||||
*
|
||||
* @param binding The binding.
|
||||
* @return The current state of the binding.
|
||||
* @param binding the binding
|
||||
* @return the current state of the binding
|
||||
*/
|
||||
public static @NotNull ButtonState getBindingState(@NotNull ButtonBinding binding) {
|
||||
ButtonState state = ButtonState.REPEAT;
|
||||
var state = ButtonState.REPEAT;
|
||||
for (int btn : binding.getButton()) {
|
||||
ButtonState btnState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE);
|
||||
var btnState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE);
|
||||
if (btnState == ButtonState.PRESS)
|
||||
state = ButtonState.PRESS;
|
||||
else if (btnState == ButtonState.RELEASE) {
|
||||
@@ -243,8 +245,8 @@ public class InputManager {
|
||||
/**
|
||||
* Returns whether the button has duplicated bindings.
|
||||
*
|
||||
* @param button The button to check.
|
||||
* @return True if the button has duplicated bindings, else false.
|
||||
* @param button the button to check
|
||||
* @return true if the button has duplicated bindings, else false
|
||||
*/
|
||||
public static boolean hasDuplicatedBindings(int[] button) {
|
||||
return BINDINGS.parallelStream().filter(binding -> areButtonsEquivalent(binding.getButton(), button)).count() > 1;
|
||||
@@ -253,8 +255,8 @@ public class InputManager {
|
||||
/**
|
||||
* Returns whether the button has duplicated bindings.
|
||||
*
|
||||
* @param binding The binding to check.
|
||||
* @return True if the button has duplicated bindings, else false.
|
||||
* @param binding the binding to check
|
||||
* @return true if the button has duplicated bindings, else false
|
||||
*/
|
||||
public static boolean hasDuplicatedBindings(ButtonBinding binding) {
|
||||
return BINDINGS.parallelStream().filter(other -> areButtonsEquivalent(other.getButton(), binding.getButton()) && other.filter.equals(binding.filter)).count() > 1;
|
||||
@@ -263,9 +265,9 @@ public class InputManager {
|
||||
/**
|
||||
* Returns whether the specified buttons are equivalent or not.
|
||||
*
|
||||
* @param buttons1 First set of buttons.
|
||||
* @param buttons2 Second set of buttons.
|
||||
* @return True if the two sets of buttons are equivalent, else false.
|
||||
* @param buttons1 first set of buttons
|
||||
* @param buttons2 second set of buttons
|
||||
* @return true if the two sets of buttons are equivalent, else false
|
||||
*/
|
||||
public static boolean areButtonsEquivalent(int[] buttons1, int[] buttons2) {
|
||||
if (buttons1.length != buttons2.length)
|
||||
@@ -285,9 +287,9 @@ public class InputManager {
|
||||
/**
|
||||
* Returns whether the button set contains the specified button or not.
|
||||
*
|
||||
* @param buttons The button set.
|
||||
* @param button The button to check.
|
||||
* @return True if the button set contains the specified button, else false.
|
||||
* @param buttons the button set
|
||||
* @param button the button to check
|
||||
* @return true if the button set contains the specified button, else false
|
||||
*/
|
||||
public static boolean containsButton(int[] buttons, int button) {
|
||||
return Arrays.stream(buttons).anyMatch(btn -> btn == button);
|
||||
@@ -297,19 +299,21 @@ public class InputManager {
|
||||
* Updates the button states.
|
||||
*/
|
||||
public static void updateStates() {
|
||||
STATES.forEach((btn, state) -> {
|
||||
if (state == ButtonState.PRESS)
|
||||
STATES.put(btn, ButtonState.REPEAT);
|
||||
else if (state == ButtonState.RELEASE)
|
||||
STATES.put(btn, ButtonState.NONE);
|
||||
});
|
||||
for (var entry : STATES.int2ObjectEntrySet()) {
|
||||
if (entry.getValue() == ButtonState.PRESS)
|
||||
STATES.put(entry.getIntKey(), ButtonState.REPEAT);
|
||||
else if (entry.getValue() == ButtonState.RELEASE)
|
||||
STATES.put(entry.getIntKey(), ButtonState.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateBindings(@NotNull MinecraftClient client) {
|
||||
List<Integer> skipButtons = new ArrayList<>();
|
||||
Map<ButtonBinding, Pair<ButtonState, Float>> states = new HashMap<>();
|
||||
for (ButtonBinding binding : BINDINGS) {
|
||||
ButtonState state = binding.isAvailable(client) ? getBindingState(binding) : ButtonState.NONE;
|
||||
var skipButtons = new IntArrayList();
|
||||
record ButtonStateValue(ButtonState state, float value) {
|
||||
}
|
||||
var states = new Object2ObjectOpenHashMap<ButtonBinding, ButtonStateValue>();
|
||||
for (var binding : BINDINGS) {
|
||||
var state = binding.isAvailable(client) ? getBindingState(binding) : ButtonState.NONE;
|
||||
if (skipButtons.stream().anyMatch(btn -> containsButton(binding.getButton(), btn))) {
|
||||
if (binding.pressed)
|
||||
state = ButtonState.RELEASE;
|
||||
@@ -328,12 +332,12 @@ public class InputManager {
|
||||
|
||||
float value = getBindingValue(binding, state);
|
||||
|
||||
states.put(binding, Pair.of(state, value));
|
||||
states.put(binding, new ButtonStateValue(state, value));
|
||||
}
|
||||
|
||||
states.forEach((binding, state) -> {
|
||||
if (state.key != ButtonState.NONE) {
|
||||
binding.handle(client, state.value, state.key);
|
||||
if (state.state() != ButtonState.NONE) {
|
||||
binding.handle(client, state.value(), state.state());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -358,11 +362,11 @@ public class InputManager {
|
||||
/**
|
||||
* Returns a new key binding instance.
|
||||
*
|
||||
* @param id The identifier of the key binding.
|
||||
* @param type The type.
|
||||
* @param code The code.
|
||||
* @param category The category of the key binding.
|
||||
* @return The key binding.
|
||||
* @param id the identifier of the key binding
|
||||
* @param type the type
|
||||
* @param code the code
|
||||
* @param category the category of the key binding
|
||||
* @return the key binding
|
||||
* @see #makeKeyBinding(Identifier, InputUtil.Type, int, String)
|
||||
*/
|
||||
public static @NotNull KeyBinding makeKeyBinding(@NotNull net.minecraft.util.Identifier id, InputUtil.Type type, int code, @NotNull String category) {
|
||||
@@ -372,11 +376,11 @@ public class InputManager {
|
||||
/**
|
||||
* Returns a new key binding instance.
|
||||
*
|
||||
* @param id The identifier of the key binding.
|
||||
* @param type The type.
|
||||
* @param code The code.
|
||||
* @param category The category of the key binding.
|
||||
* @return The key binding.
|
||||
* @param id the identifier of the key binding
|
||||
* @param type the type
|
||||
* @param code the code
|
||||
* @param category the category of the key binding
|
||||
* @return the key binding
|
||||
* @see #makeKeyBinding(net.minecraft.util.Identifier, InputUtil.Type, int, String)
|
||||
*/
|
||||
public static @NotNull KeyBinding makeKeyBinding(@NotNull Identifier id, InputUtil.Type type, int code, @NotNull String category) {
|
||||
|
||||
@@ -12,14 +12,14 @@ package dev.lambdaurora.lambdacontrols.client.controller;
|
||||
import dev.lambdaurora.lambdacontrols.client.ButtonState;
|
||||
import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.options.StickyKeyBinding;
|
||||
import net.minecraft.client.option.StickyKeyBinding;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a press action callback.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.4.3
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@@ -31,7 +31,7 @@ public interface PressAction {
|
||||
if (binding instanceof StickyKeyBinding)
|
||||
binding.setPressed(button.pressed);
|
||||
else
|
||||
((KeyBindingAccessor) binding).lambdacontrols_handlePressState(button.isButtonDown());
|
||||
((KeyBindingAccessor) binding).lambdacontrols$handlePressState(button.isButtonDown());
|
||||
});
|
||||
return true;
|
||||
};
|
||||
@@ -39,8 +39,8 @@ public interface PressAction {
|
||||
/**
|
||||
* Handles when there is a press action.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param action The action done.
|
||||
* @param client the client instance
|
||||
* @param action the action done
|
||||
*/
|
||||
boolean press(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,9 @@ import dev.lambdaurora.lambdacontrols.client.HudSide;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import me.lambdaurora.spruceui.hud.Hud;
|
||||
import dev.lambdaurora.spruceui.hud.Hud;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.Window;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -32,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* Represents the LambdaControls HUD.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.3.2
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaControlsHud extends Hud {
|
||||
@@ -87,8 +86,8 @@ public class LambdaControlsHud extends Hud {
|
||||
|
||||
if (this.mod.reacharound.isLastReacharoundVertical()) {
|
||||
// Render crosshair indicator.
|
||||
Window window = this.client.getWindow();
|
||||
String text = "[ ]";
|
||||
var window = this.client.getWindow();
|
||||
var text = "[ ]";
|
||||
|
||||
float scale = Math.min(5, this.ticksDisplayedCrosshair + tickDelta) / 5F;
|
||||
scale *= scale;
|
||||
@@ -203,7 +202,7 @@ public class LambdaControlsHud extends Hud {
|
||||
this.ticksDisplayedCrosshair = 0;
|
||||
}
|
||||
|
||||
String customAttackAction = LambdaControlsCompat.getAttackActionAt(this.client, this.placeHitResult);
|
||||
var customAttackAction = LambdaControlsCompat.getAttackActionAt(this.client, this.placeHitResult);
|
||||
if (customAttackAction != null) {
|
||||
this.attackAction = customAttackAction;
|
||||
this.attackWidth = this.width(customAttackAction);
|
||||
@@ -225,7 +224,7 @@ public class LambdaControlsHud extends Hud {
|
||||
}
|
||||
}
|
||||
|
||||
String customUseAction = LambdaControlsCompat.getUseActionAt(this.client, this.placeHitResult);
|
||||
var customUseAction = LambdaControlsCompat.getUseActionAt(this.client, this.placeHitResult);
|
||||
if (customUseAction != null)
|
||||
placeAction = customUseAction;
|
||||
|
||||
@@ -270,7 +269,7 @@ public class LambdaControlsHud extends Hud {
|
||||
private void drawTip(MatrixStack matrices, int x, int y, @NotNull String action, boolean display) {
|
||||
if (!display)
|
||||
return;
|
||||
String translatedAction = I18n.translate(action);
|
||||
var translatedAction = I18n.translate(action);
|
||||
int textY = (LambdaControlsRenderer.ICON_SIZE / 2 - this.client.textRenderer.fontHeight / 2) + 1;
|
||||
this.client.textRenderer.draw(matrices, translatedAction, (float) x, (float) (y + textY), 14737632);
|
||||
}
|
||||
|
||||
@@ -18,11 +18,9 @@ import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
@@ -30,7 +28,7 @@ import org.lwjgl.glfw.GLFW;
|
||||
* Represents the LambdaControls renderer.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class LambdaControlsRenderer {
|
||||
@@ -39,28 +37,21 @@ public class LambdaControlsRenderer {
|
||||
private static final int AXIS_SIZE = 18;
|
||||
|
||||
public static int getButtonSize(int button) {
|
||||
switch (button) {
|
||||
case -1:
|
||||
return 0;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200:
|
||||
return AXIS_SIZE;
|
||||
default:
|
||||
return BUTTON_SIZE;
|
||||
}
|
||||
return switch (button) {
|
||||
case -1 -> 0;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200,
|
||||
GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200,
|
||||
GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200,
|
||||
GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200 -> AXIS_SIZE;
|
||||
default -> BUTTON_SIZE;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the binding icon width.
|
||||
*
|
||||
* @param binding The binding.
|
||||
* @return The width.
|
||||
* @param binding the binding
|
||||
* @return the width
|
||||
*/
|
||||
public static int getBindingIconWidth(@NotNull ButtonBinding binding) {
|
||||
return getBindingIconWidth(binding.getButton());
|
||||
@@ -69,8 +60,8 @@ public class LambdaControlsRenderer {
|
||||
/**
|
||||
* Gets the binding icon width.
|
||||
*
|
||||
* @param buttons The buttons.
|
||||
* @return The width.
|
||||
* @param buttons the buttons
|
||||
* @return the width
|
||||
*/
|
||||
public static int getBindingIconWidth(int[] buttons) {
|
||||
int width = 0;
|
||||
@@ -83,11 +74,11 @@ public class LambdaControlsRenderer {
|
||||
return width;
|
||||
}
|
||||
|
||||
public static Pair<Integer, Integer> drawButton(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) {
|
||||
public static ButtonSize drawButton(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) {
|
||||
return drawButton(matrices, x, y, button.getButton(), client);
|
||||
}
|
||||
|
||||
public static Pair<Integer, Integer> drawButton(MatrixStack matrices, int x, int y, int[] buttons, @NotNull MinecraftClient client) {
|
||||
public static ButtonSize drawButton(MatrixStack matrices, int x, int y, int[] buttons, @NotNull MinecraftClient client) {
|
||||
int height = 0;
|
||||
int length = 0;
|
||||
int currentX = x;
|
||||
@@ -102,7 +93,7 @@ public class LambdaControlsRenderer {
|
||||
currentX = x + length;
|
||||
}
|
||||
}
|
||||
return Pair.of(length, height);
|
||||
return new ButtonSize(length, height);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecated")
|
||||
@@ -119,75 +110,55 @@ public class LambdaControlsRenderer {
|
||||
boolean axis = false;
|
||||
int buttonOffset = button * 15;
|
||||
switch (button) {
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
|
||||
buttonOffset = 7 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
|
||||
buttonOffset = 8 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_BACK:
|
||||
buttonOffset = 4 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_START:
|
||||
buttonOffset = 6 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE:
|
||||
buttonOffset = 5 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
|
||||
buttonOffset = 15 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
|
||||
buttonOffset = 16 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100:
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> buttonOffset = 7 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> buttonOffset = 8 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_BACK -> buttonOffset = 4 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_START -> buttonOffset = 6 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE -> buttonOffset = 5 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> buttonOffset = 15 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> buttonOffset = 16 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100 -> {
|
||||
buttonOffset = 0;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100:
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100 -> {
|
||||
buttonOffset = 18;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100:
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100 -> {
|
||||
buttonOffset = 2 * 18;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100:
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100 -> {
|
||||
buttonOffset = 3 * 18;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200:
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200 -> {
|
||||
buttonOffset = 4 * 18;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200:
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200 -> {
|
||||
buttonOffset = 5 * 18;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200:
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200 -> {
|
||||
buttonOffset = 6 * 18;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200:
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200 -> {
|
||||
buttonOffset = 7 * 18;
|
||||
axis = true;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200:
|
||||
buttonOffset = 9 * 15;
|
||||
break;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100:
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200:
|
||||
buttonOffset = 10 * 15;
|
||||
break;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200 -> buttonOffset = 9 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200 -> buttonOffset = 10 * 15;
|
||||
}
|
||||
|
||||
client.getTextureManager().bindTexture(axis ? LambdaControlsClient.CONTROLLER_AXIS : LambdaControlsClient.CONTROLLER_BUTTONS);
|
||||
RenderSystem.setShaderTexture(0, axis ? LambdaControlsClient.CONTROLLER_AXIS : LambdaControlsClient.CONTROLLER_BUTTONS);
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
int assetSize = axis ? AXIS_SIZE : BUTTON_SIZE;
|
||||
|
||||
RenderSystem.color4f(1.0F, second ? 0.0F : 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.setShaderColor(1.f, second ? 0.f : 1.f, 1.f, 1.f);
|
||||
DrawableHelper.drawTexture(matrices, x + (ICON_SIZE / 2 - assetSize / 2), y + (ICON_SIZE / 2 - assetSize / 2),
|
||||
(float) buttonOffset, (float) (controllerType * (axis ? AXIS_SIZE : BUTTON_SIZE)),
|
||||
assetSize, assetSize,
|
||||
@@ -203,9 +174,9 @@ public class LambdaControlsRenderer {
|
||||
|
||||
public static int drawButtonTip(MatrixStack matrices, int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client) {
|
||||
if (display) {
|
||||
int buttonWidth = drawButton(matrices, x, y, button, client).key;
|
||||
int buttonWidth = drawButton(matrices, x, y, button, client).length();
|
||||
|
||||
String translatedAction = I18n.translate(action);
|
||||
var translatedAction = I18n.translate(action);
|
||||
int textY = (LambdaControlsRenderer.ICON_SIZE / 2 - client.textRenderer.fontHeight / 2) + 1;
|
||||
|
||||
return client.textRenderer.drawWithShadow(matrices, translatedAction, (float) (x + buttonWidth + 2), (float) (y + textY), 14737632);
|
||||
@@ -219,7 +190,8 @@ public class LambdaControlsRenderer {
|
||||
}
|
||||
|
||||
public static void renderVirtualCursor(@NotNull MatrixStack matrices, @NotNull MinecraftClient client) {
|
||||
if (!LambdaControlsClient.get().config.hasVirtualMouse() || (client.currentScreen == null || LambdaInput.isScreenInteractive(client.currentScreen)))
|
||||
if (!LambdaControlsClient.get().config.hasVirtualMouse() || (client.currentScreen == null
|
||||
|| LambdaInput.isScreenInteractive(client.currentScreen)))
|
||||
return;
|
||||
|
||||
int mouseX = (int) (client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth());
|
||||
@@ -227,8 +199,7 @@ public class LambdaControlsRenderer {
|
||||
|
||||
boolean hoverSlot = false;
|
||||
|
||||
if (client.currentScreen instanceof HandledScreen) {
|
||||
HandledScreenAccessor inventoryScreen = (HandledScreenAccessor) client.currentScreen;
|
||||
if (client.currentScreen instanceof HandledScreenAccessor inventoryScreen) {
|
||||
int guiLeft = inventoryScreen.getX();
|
||||
int guiTop = inventoryScreen.getY();
|
||||
|
||||
@@ -242,11 +213,11 @@ public class LambdaControlsRenderer {
|
||||
}
|
||||
|
||||
if (!hoverSlot) {
|
||||
Pair<Integer, Integer> slot = LambdaControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY);
|
||||
var slot = LambdaControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY);
|
||||
|
||||
if (slot != null) {
|
||||
mouseX = slot.getFirst();
|
||||
mouseY = slot.getSecond();
|
||||
mouseX = slot.x();
|
||||
mouseY = slot.y();
|
||||
hoverSlot = true;
|
||||
}
|
||||
}
|
||||
@@ -262,19 +233,23 @@ public class LambdaControlsRenderer {
|
||||
/**
|
||||
* Draws the virtual cursor.
|
||||
*
|
||||
* @param matrices The matrix stack.
|
||||
* @param x X coordinate.
|
||||
* @param y Y coordinate.
|
||||
* @param hoverSlot True if hovering a slot, else false.
|
||||
* @param client The client instance.
|
||||
* @param matrices the matrix stack
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @param hoverSlot true if hovering a slot, else false
|
||||
* @param client the client instance
|
||||
*/
|
||||
public static void drawCursor(@NotNull MatrixStack matrices, int x, int y, boolean hoverSlot, @NotNull MinecraftClient client) {
|
||||
client.getTextureManager().bindTexture(LambdaControlsClient.CURSOR_TEXTURE);
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
DrawableHelper.drawTexture(matrices, x, y, hoverSlot ? 16.F : 0.F, LambdaControlsClient.get().config.getVirtualMouseSkin().ordinal() * 16.F, 16, 16, 32, 64);
|
||||
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
|
||||
RenderSystem.setShaderTexture(0, LambdaControlsClient.CURSOR_TEXTURE);
|
||||
DrawableHelper.drawTexture(matrices, x, y,
|
||||
hoverSlot ? 16.f : 0.f, LambdaControlsClient.get().config.getVirtualMouseSkin().ordinal() * 16.f,
|
||||
16, 16, 32, 64);
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
|
||||
public record ButtonSize(int length, int height) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,21 +9,20 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client.gui;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.ControlsMode;
|
||||
import dev.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.Controller;
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget;
|
||||
import me.lambdaurora.spruceui.Position;
|
||||
import me.lambdaurora.spruceui.SpruceTexts;
|
||||
import me.lambdaurora.spruceui.option.*;
|
||||
import me.lambdaurora.spruceui.screen.SpruceScreen;
|
||||
import me.lambdaurora.spruceui.widget.AbstractSpruceWidget;
|
||||
import me.lambdaurora.spruceui.widget.SpruceLabelWidget;
|
||||
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import me.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
|
||||
import me.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.option.*;
|
||||
import dev.lambdaurora.spruceui.screen.SpruceScreen;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
@@ -71,7 +70,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
private final SpruceOption controllerOption =
|
||||
new SpruceCyclingOption("lambdacontrols.menu.controller",
|
||||
amount -> {
|
||||
int id = this.config.getController().getId();
|
||||
int id = this.config.getController().id();
|
||||
id += amount;
|
||||
if (id > GLFW.GLFW_JOYSTICK_LAST)
|
||||
id = GLFW.GLFW_JOYSTICK_1;
|
||||
@@ -79,8 +78,8 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
this.config.setController(Controller.byId(id));
|
||||
},
|
||||
option -> {
|
||||
Controller controller = this.config.getController();
|
||||
String controllerName = controller.getName();
|
||||
var controller = this.config.getController();
|
||||
var controllerName = controller.getName();
|
||||
if (!controller.isConnected())
|
||||
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED));
|
||||
else if (!controller.isGamepad())
|
||||
@@ -90,7 +89,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
}, null);
|
||||
private final SpruceOption secondControllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller2",
|
||||
amount -> {
|
||||
int id = this.config.getSecondController().map(Controller::getId).orElse(-1);
|
||||
int id = this.config.getSecondController().map(Controller::id).orElse(-1);
|
||||
id += amount;
|
||||
if (id > GLFW.GLFW_JOYSTICK_LAST)
|
||||
id = -1;
|
||||
@@ -98,7 +97,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
this.config.setSecondController(id == -1 ? null : Controller.byId(id));
|
||||
},
|
||||
option -> this.config.getSecondController().map(controller -> {
|
||||
String controllerName = controller.getName();
|
||||
var controllerName = controller.getName();
|
||||
if (!controller.isConnected())
|
||||
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED));
|
||||
else if (!controller.isGamepad())
|
||||
@@ -152,7 +151,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
// General options
|
||||
this.inputModeOption = new SpruceCyclingOption("lambdacontrols.menu.controls_mode",
|
||||
amount -> {
|
||||
ControlsMode next = this.config.getControlsMode().next();
|
||||
var next = this.config.getControlsMode().next();
|
||||
this.config.setControlsMode(next);
|
||||
this.config.save();
|
||||
|
||||
@@ -181,7 +180,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
new TranslatableText("lambdacontrols.tooltip.mouse_speed"));
|
||||
this.resetOption = SpruceSimpleActionOption.reset(btn -> {
|
||||
this.config.reset();
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
var client = MinecraftClient.getInstance();
|
||||
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
});
|
||||
// Gameplay options
|
||||
@@ -225,7 +224,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
this.config.setRightDeadZone(newValue);
|
||||
}
|
||||
}, option -> {
|
||||
String value = String.valueOf(option.get());
|
||||
var value = String.valueOf(option.get());
|
||||
return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5))));
|
||||
}, new TranslatableText("lambdacontrols.tooltip.right_dead_zone"));
|
||||
this.leftDeadZoneOption = new SpruceDoubleOption("lambdacontrols.menu.left_dead_zone", 0.05, 1.0, .05f,
|
||||
@@ -235,7 +234,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
this.config.setLeftDeadZone(newValue);
|
||||
}
|
||||
}, option -> {
|
||||
String value = String.valueOf(option.get());
|
||||
var value = String.valueOf(option.get());
|
||||
return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5))));
|
||||
}, new TranslatableText("lambdacontrols.tooltip.left_dead_zone"));
|
||||
this.invertsRightXAxis = new SpruceToggleBooleanOption("lambdacontrols.menu.invert_right_x_axis", this.config::doesInvertRightXAxis,
|
||||
@@ -278,16 +277,16 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
|
||||
this.buildTabs();
|
||||
|
||||
this.addChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150));
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
|
||||
this.addDrawableChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150));
|
||||
this.addDrawableChild(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
|
||||
btn -> this.client.openScreen(this.parent)));
|
||||
}
|
||||
|
||||
public void buildTabs() {
|
||||
SpruceTabbedWidget tabs = new SpruceTabbedWidget(Position.of(0, 24), this.width, this.height - 32 - 24,
|
||||
var tabs = new SpruceTabbedWidget(Position.of(0, 24), this.width, this.height - 32 - 24,
|
||||
null,
|
||||
Math.max(116, this.width / 8), 0);
|
||||
this.addChild(tabs);
|
||||
this.addDrawableChild(tabs);
|
||||
|
||||
tabs.addSeparatorEntry(new TranslatableText("lambdacontrols.menu.separator.general"));
|
||||
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.general"), null,
|
||||
@@ -309,7 +308,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
}
|
||||
|
||||
public SpruceOptionListWidget buildGeneralTab(int width, int height) {
|
||||
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
list.addSingleOptionEntry(this.inputModeOption);
|
||||
list.addSingleOptionEntry(this.autoSwitchModeOption);
|
||||
list.addSingleOptionEntry(this.rotationSpeedOption);
|
||||
@@ -319,7 +318,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
}
|
||||
|
||||
public SpruceOptionListWidget buildGameplayTab(int width, int height) {
|
||||
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
list.addSingleOptionEntry(this.analogMovementOption);
|
||||
list.addSingleOptionEntry(this.fastBlockPlacingOption);
|
||||
list.addSingleOptionEntry(this.frontBlockPlacingOption);
|
||||
@@ -331,7 +330,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
}
|
||||
|
||||
public SpruceOptionListWidget buildVisualTab(int width, int height) {
|
||||
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
list.addSingleOptionEntry(this.controllerTypeOption);
|
||||
list.addSingleOptionEntry(this.virtualMouseSkinOption);
|
||||
list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null));
|
||||
@@ -345,38 +344,38 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
}
|
||||
|
||||
public AbstractSpruceWidget buildControllerTab(int width, int height) {
|
||||
SpruceContainerWidget root = new SpruceContainerWidget(Position.origin(), width, height);
|
||||
var root = new SpruceContainerWidget(Position.origin(), width, height);
|
||||
|
||||
SpruceLabelWidget aboutMappings1 = new SpruceLabelWidget(Position.of(0, 2),
|
||||
var aboutMappings1 = new SpruceLabelWidget(Position.of(0, 2),
|
||||
new TranslatableText("lambdacontrols.controller.mappings.1", SDL2_GAMEPAD_TOOL),
|
||||
width, true);
|
||||
|
||||
SpruceLabelWidget gamepadToolUrlLabel = new SpruceLabelWidget(Position.of(0, aboutMappings1.getHeight() + 4),
|
||||
var gamepadToolUrlLabel = new SpruceLabelWidget(Position.of(0, aboutMappings1.getHeight() + 4),
|
||||
this.controllerMappingsUrlText, width,
|
||||
label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true);
|
||||
gamepadToolUrlLabel.setTooltip(new TranslatableText("chat.link.open"));
|
||||
|
||||
SpruceLabelWidget aboutMappings3 = new SpruceLabelWidget(Position.of(0,
|
||||
var aboutMappings3 = new SpruceLabelWidget(Position.of(0,
|
||||
aboutMappings1.getHeight() + gamepadToolUrlLabel.getHeight() + 6),
|
||||
new TranslatableText("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()),
|
||||
width, true);
|
||||
|
||||
int listHeight = height - 8 - aboutMappings1.getHeight() - aboutMappings3.getHeight() - gamepadToolUrlLabel.getHeight();
|
||||
SpruceContainerWidget labels = new SpruceContainerWidget(Position.of(0,
|
||||
var labels = new SpruceContainerWidget(Position.of(0,
|
||||
listHeight),
|
||||
width, height - listHeight);
|
||||
labels.addChild(aboutMappings1);
|
||||
labels.addChild(gamepadToolUrlLabel);
|
||||
labels.addChild(aboutMappings3);
|
||||
|
||||
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, listHeight);
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, listHeight);
|
||||
list.addSingleOptionEntry(this.controllerOption);
|
||||
list.addSingleOptionEntry(this.secondControllerOption);
|
||||
list.addSingleOptionEntry(this.unfocusedInputOption);
|
||||
list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis);
|
||||
list.addSingleOptionEntry(this.rightDeadZoneOption);
|
||||
list.addSingleOptionEntry(this.leftDeadZoneOption);
|
||||
for (SpruceOption option : this.maxAnalogValueOptions) {
|
||||
for (var option : this.maxAnalogValueOptions) {
|
||||
list.addSingleOptionEntry(option);
|
||||
}
|
||||
|
||||
@@ -391,6 +390,6 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
|
||||
|
||||
@Override
|
||||
public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215);
|
||||
drawCenteredText(matrices, this.textRenderer, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ package dev.lambdaurora.lambdacontrols.client.gui;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.Controller;
|
||||
import me.lambdaurora.spruceui.Position;
|
||||
import me.lambdaurora.spruceui.option.SpruceOption;
|
||||
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import me.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.option.SpruceOption;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import dev.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
@@ -27,7 +27,7 @@ import java.nio.file.Files;
|
||||
* Represents the controller mappings file editor screen.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.4.3
|
||||
* @version 1.7.0
|
||||
* @since 1.4.3
|
||||
*/
|
||||
public class MappingsStringInputWidget extends SpruceContainerWidget {
|
||||
@@ -59,7 +59,7 @@ public class MappingsStringInputWidget extends SpruceContainerWidget {
|
||||
if (this.textArea != null) {
|
||||
this.mappings = this.textArea.getText();
|
||||
try {
|
||||
FileWriter fw = new FileWriter(LambdaControlsClient.MAPPINGS_FILE, false);
|
||||
var fw = new FileWriter(LambdaControlsClient.MAPPINGS_FILE, false);
|
||||
fw.write(this.mappings);
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
@@ -76,7 +76,7 @@ public class MappingsStringInputWidget extends SpruceContainerWidget {
|
||||
this.mappings = this.textArea.getText();
|
||||
}
|
||||
|
||||
String mappings = "";
|
||||
var mappings = "";
|
||||
|
||||
if (this.mappings != null)
|
||||
mappings = this.mappings;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
package dev.lambdaurora.lambdacontrols.client.gui;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.Controller;
|
||||
import me.lambdaurora.spruceui.option.SpruceSimpleActionOption;
|
||||
import me.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.option.SpruceSimpleActionOption;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.text.LiteralText;
|
||||
@@ -28,7 +28,7 @@ public class ReloadControllerMappingsOption {
|
||||
|
||||
public static SpruceSimpleActionOption newOption(@Nullable Consumer<SpruceButtonWidget> before) {
|
||||
return SpruceSimpleActionOption.of(KEY, btn -> {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
var client = MinecraftClient.getInstance();
|
||||
if (before != null)
|
||||
before.accept(btn);
|
||||
Controller.updateMappings();
|
||||
|
||||
@@ -11,14 +11,13 @@ package dev.lambdaurora.lambdacontrols.client.gui.widget;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer;
|
||||
import me.lambdaurora.spruceui.Position;
|
||||
import me.lambdaurora.spruceui.SpruceTexts;
|
||||
import me.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -52,8 +51,8 @@ public class ControllerButtonWidget extends AbstractSpruceIconButtonWidget {
|
||||
if (this.binding.getButton().length > 1) {
|
||||
x += (this.width / 2 - this.iconWidth / 2) - 4;
|
||||
}
|
||||
Pair<Integer, Integer> size = LambdaControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance());
|
||||
this.iconWidth = size.key;
|
||||
return size.value;
|
||||
var size = LambdaControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance());
|
||||
this.iconWidth = size.length();
|
||||
return size.height();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ package dev.lambdaurora.lambdacontrols.client.gui.widget;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.InputManager;
|
||||
import me.lambdaurora.spruceui.Position;
|
||||
import me.lambdaurora.spruceui.SpruceTexts;
|
||||
import me.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import org.aperlambda.lambdacommon.utils.function.Predicates;
|
||||
@@ -61,4 +61,10 @@ public class ControllerControlsWidget extends SpruceContainerWidget {
|
||||
this.resetButton.setActive(InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault)));
|
||||
super.renderWidget(matrices, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
public void finishBindingEdit(int... buttons) {
|
||||
if (this.focusedBinding == null) return;
|
||||
this.mod.config.setButtonBinding(this.focusedBinding, buttons);
|
||||
this.focusedBinding = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,22 +13,20 @@ import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.ButtonCategory;
|
||||
import dev.lambdaurora.lambdacontrols.client.controller.InputManager;
|
||||
import me.lambdaurora.spruceui.Position;
|
||||
import me.lambdaurora.spruceui.SpruceTexts;
|
||||
import me.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
import me.lambdaurora.spruceui.navigation.NavigationUtils;
|
||||
import me.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import me.lambdaurora.spruceui.widget.SpruceSeparatorWidget;
|
||||
import me.lambdaurora.spruceui.widget.SpruceWidget;
|
||||
import me.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
|
||||
import me.lambdaurora.spruceui.widget.container.SpruceParentWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationUtils;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceSeparatorWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Formatting;
|
||||
@@ -36,7 +34,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a control list widget.
|
||||
@@ -91,8 +91,9 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
|
||||
gui.focusedBinding = binding;
|
||||
LambdaControlsClient.get().input.beginControlsInput(gui);
|
||||
}) {
|
||||
protected Optional<Text> getNarrationMessage() {
|
||||
return Optional.of(binding.isNotBound() ? new TranslatableText("narrator.controls.unbound", bindingName) : new TranslatableText("narrator.controls.bound", bindingName, super.getNarrationMessage()));
|
||||
protected Text getNarrationMessage() {
|
||||
return binding.isNotBound() ? new TranslatableText("narrator.controls.unbound", bindingName)
|
||||
: new TranslatableText("narrator.controls.bound", bindingName, super.getNarrationMessage());
|
||||
}
|
||||
};
|
||||
this.children.add(editButton);
|
||||
@@ -100,8 +101,8 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
|
||||
this.editButton.getPosition().getRelativeX() + this.editButton.getWidth() + 2, 0),
|
||||
44, 20, new TranslatableText("controls.reset"),
|
||||
btn -> LambdaControlsClient.get().config.setButtonBinding(binding, binding.getDefaultButton())) {
|
||||
protected Optional<Text> getNarrationMessage() {
|
||||
return Optional.of(new TranslatableText("narrator.controls.reset", bindingName));
|
||||
protected Text getNarrationMessage() {
|
||||
return new TranslatableText("narrator.controls.reset", bindingName);
|
||||
}
|
||||
};
|
||||
this.children.add(this.resetButton);
|
||||
@@ -113,8 +114,8 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
|
||||
gui.focusedBinding = null;
|
||||
LambdaControlsClient.get().input.beginControlsInput(null);
|
||||
}) {
|
||||
protected Optional<Text> getNarrationMessage() {
|
||||
return Optional.of(new TranslatableText("lambdacontrols.narrator.unbound", bindingName));
|
||||
protected Text getNarrationMessage() {
|
||||
return new TranslatableText("lambdacontrols.narrator.unbound", bindingName);
|
||||
}
|
||||
};
|
||||
this.children.add(this.unbindButton);
|
||||
@@ -151,7 +152,7 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
|
||||
|
||||
@Override
|
||||
protected boolean onMouseClick(double mouseX, double mouseY, int button) {
|
||||
Iterator<SpruceWidget> it = this.children().iterator();
|
||||
var it = this.children().iterator();
|
||||
|
||||
SpruceWidget element;
|
||||
do {
|
||||
@@ -229,12 +230,11 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
|
||||
protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
boolean focused = gui.focusedBinding == this.binding;
|
||||
|
||||
TextRenderer textRenderer = ControlsListWidget.this.client.textRenderer;
|
||||
String bindingName = this.bindingName;
|
||||
var textRenderer = ControlsListWidget.this.client.textRenderer;
|
||||
int height = this.getHeight();
|
||||
//float textX = (float) (this.getX() + 70 - ControlsListWidget.this.maxTextLength);
|
||||
int textY = this.getY() + height / 2;
|
||||
textRenderer.draw(matrices, bindingName, this.getX(), (float) (textY - 9 / 2), 16777215);
|
||||
textRenderer.draw(matrices, this.bindingName, this.getX(), (float) (textY - 9 / 2), 16777215);
|
||||
|
||||
this.resetButton.setVisible(!focused);
|
||||
this.unbindButton.setVisible(focused);
|
||||
@@ -242,14 +242,14 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
|
||||
|
||||
this.editButton.update();
|
||||
if (focused) {
|
||||
MutableText text = new LiteralText("> ").formatted(Formatting.WHITE);
|
||||
var text = new LiteralText("> ").formatted(Formatting.WHITE);
|
||||
text.append(this.editButton.getMessage().copy().formatted(Formatting.YELLOW));
|
||||
this.editButton.setMessage(text.append(new LiteralText(" <").formatted(Formatting.WHITE)));
|
||||
} else if (!this.binding.isNotBound() && InputManager.hasDuplicatedBindings(this.binding)) {
|
||||
MutableText text = this.editButton.getMessage().copy();
|
||||
var text = this.editButton.getMessage().copy();
|
||||
this.editButton.setMessage(text.formatted(Formatting.RED));
|
||||
} else if (this.binding.isNotBound()) {
|
||||
MutableText text = this.editButton.getMessage().copy();
|
||||
var text = this.editButton.getMessage().copy();
|
||||
this.editButton.setMessage(text.formatted(Formatting.GOLD));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client.mixin;
|
||||
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ClickableWidget;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(AbstractButtonWidget.class)
|
||||
public interface AbstractButtonWidgetAccessor {
|
||||
@Mixin(ClickableWidget.class)
|
||||
public interface ClickableWidgetAccessor {
|
||||
@Accessor("height")
|
||||
int getHeight();
|
||||
}
|
||||
@@ -52,9 +52,9 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
|
||||
|
||||
@Inject(method = "move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V"))
|
||||
public void onMove(MovementType type, Vec3d movement, CallbackInfo ci) {
|
||||
LambdaControlsClient mod = LambdaControlsClient.get();
|
||||
var mod = LambdaControlsClient.get();
|
||||
if (type == MovementType.SELF) {
|
||||
if (this.abilities.flying && (!mod.config.hasFlyDrifting() || !mod.config.hasFlyVerticalDrifting())) {
|
||||
if (this.getAbilities().flying && (!mod.config.hasFlyDrifting() || !mod.config.hasFlyVerticalDrifting())) {
|
||||
if (!this.hasMovementInput()) {
|
||||
if (!this.lambdacontrols$driftingPrevented) {
|
||||
if (!mod.config.hasFlyDrifting())
|
||||
@@ -74,7 +74,7 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
|
||||
|
||||
@Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z"))
|
||||
public void onTickMovement(CallbackInfo ci) {
|
||||
if (this.abilities.flying && this.isCamera()) {
|
||||
if (this.getAbilities().flying && this.isCamera()) {
|
||||
if (LambdaControlsClient.get().config.hasFlyVerticalDrifting())
|
||||
return;
|
||||
int moving = 0;
|
||||
|
||||
@@ -10,12 +10,15 @@
|
||||
package dev.lambdaurora.lambdacontrols.client.mixin;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen;
|
||||
import net.minecraft.client.gui.Drawable;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.Selectable;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
|
||||
import net.minecraft.client.gui.screen.options.GameOptionsScreen;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
|
||||
import net.minecraft.client.gui.screen.option.GameOptionsScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.gui.widget.CyclingButtonWidget;
|
||||
import net.minecraft.client.option.GameOptions;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -31,12 +34,25 @@ public class ControlsOptionsScreenMixin extends GameOptionsScreen {
|
||||
super(parent, gameOptions, text);
|
||||
}
|
||||
|
||||
@Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/options/ControlsOptionsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 1))
|
||||
private AbstractButtonWidget onInit(ControlsOptionsScreen screen, AbstractButtonWidget btn) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Redirect(
|
||||
method = "init",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/gui/screen/option/ControlsOptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;",
|
||||
ordinal = 1
|
||||
)
|
||||
)
|
||||
private <T extends Element & Drawable & Selectable, R extends Element & Drawable & Selectable> R onInit(ControlsOptionsScreen screen, T element) {
|
||||
/*if (this.parent instanceof ControllerControlsWidget)
|
||||
return this.addButton(btn);
|
||||
else*/
|
||||
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).getHeight(), new TranslatableText("menu.options"),
|
||||
b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, true))));
|
||||
if (element instanceof CyclingButtonWidget btn) {
|
||||
return (R) this.addDrawableChild(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((ClickableWidgetAccessor) btn).getHeight(),
|
||||
new TranslatableText("menu.options"),
|
||||
b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, true))));
|
||||
} else {
|
||||
return (R) this.addDrawableChild(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public interface CreativeInventoryScreenAccessor {
|
||||
/**
|
||||
* Gets the selected tab.
|
||||
*
|
||||
* @return The selected tab index.
|
||||
* @return the selected tab index
|
||||
*/
|
||||
@Accessor("selectedTab")
|
||||
int getSelectedTab();
|
||||
@@ -34,7 +34,7 @@ public interface CreativeInventoryScreenAccessor {
|
||||
/**
|
||||
* Sets the selected tab.
|
||||
*
|
||||
* @param group The tab's item group.
|
||||
* @param group the tab's item group
|
||||
*/
|
||||
@Invoker("setSelectedTab")
|
||||
void lambdacontrols$setSelectedTab(@NotNull ItemGroup group);
|
||||
@@ -42,8 +42,8 @@ public interface CreativeInventoryScreenAccessor {
|
||||
/**
|
||||
* Returns whether the slot belongs to the creative inventory or not.
|
||||
*
|
||||
* @param slot The slot to check.
|
||||
* @return True if the slot is from the creative inventory, else false.
|
||||
* @param slot the slot to check
|
||||
* @return true if the slot is from the creative inventory, else false
|
||||
*/
|
||||
@Invoker("isCreativeInventorySlot")
|
||||
boolean lambdacontrols$isCreativeInventorySlot(@Nullable Slot slot);
|
||||
@@ -51,7 +51,7 @@ public interface CreativeInventoryScreenAccessor {
|
||||
/**
|
||||
* Returns whether the current tab has a scrollbar or not.
|
||||
*
|
||||
* @return True if the current tab has a scrollbar, else false.
|
||||
* @return true if the current tab has a scrollbar, else false
|
||||
*/
|
||||
@Invoker("hasScrollbar")
|
||||
boolean lambdacontrols$hasScrollbar();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
package dev.lambdaurora.lambdacontrols.client.mixin;
|
||||
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.option.GameOptions;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@@ -51,7 +51,7 @@ public abstract class HandledScreenMixin implements HandledScreenAccessor {
|
||||
@Inject(method = "render", at = @At("RETURN"))
|
||||
public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
|
||||
if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
var client = MinecraftClient.getInstance();
|
||||
int x = 2, y = client.getWindow().getScaledHeight() - 2 - LambdaControlsRenderer.ICON_SIZE;
|
||||
|
||||
x = LambdaControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 2;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
package dev.lambdaurora.lambdacontrols.client.mixin;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import dev.lambdaurora.lambdacontrols.LambdaControlsFeature;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.network.ClientPlayerInteractionManager;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
@@ -83,10 +82,10 @@ public abstract class MinecraftClientMixin {
|
||||
|
||||
int cooldown = this.itemUseCooldown;
|
||||
BlockHitResult hitResult;
|
||||
if (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.BLOCK && this.player.abilities.flying) {
|
||||
if (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.BLOCK && this.player.getAbilities().flying) {
|
||||
hitResult = (BlockHitResult) this.crosshairTarget;
|
||||
BlockPos targetPos = hitResult.getBlockPos();
|
||||
Direction side = hitResult.getSide();
|
||||
var targetPos = hitResult.getBlockPos();
|
||||
var side = hitResult.getSide();
|
||||
|
||||
boolean sidewaysBlockPlacing = this.lambdacontrols$lastTargetPos == null || !targetPos.equals(this.lambdacontrols$lastTargetPos.offset(this.lambdacontrols$lastTargetSide));
|
||||
boolean backwardsBlockPlacing = this.player.input.movementForward < 0.0f && (this.lambdacontrols$lastTargetPos == null || targetPos.equals(this.lambdacontrols$lastTargetPos.offset(this.lambdacontrols$lastTargetSide)));
|
||||
@@ -123,11 +122,11 @@ public abstract class MinecraftClientMixin {
|
||||
|
||||
@Inject(method = "doItemUse()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"), locals = LocalCapture.CAPTURE_FAILEXCEPTION, cancellable = true)
|
||||
private void onItemUse(CallbackInfo ci, Hand[] hands, int handCount, int handIndex, Hand hand, ItemStack stackInHand) {
|
||||
LambdaControlsClient mod = LambdaControlsClient.get();
|
||||
if (!stackInHand.isEmpty() && this.player.pitch > 35.0F && mod.reacharound.isReacharoundAvailable()) {
|
||||
var mod = LambdaControlsClient.get();
|
||||
if (!stackInHand.isEmpty() && this.player.getPitch(0.f) > 35.0F && mod.reacharound.isReacharoundAvailable()) {
|
||||
if (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.MISS && this.player.isOnGround()) {
|
||||
if (!stackInHand.isEmpty() && stackInHand.getItem() instanceof BlockItem) {
|
||||
BlockHitResult hitResult = mod.reacharound.getLastReacharoundResult();
|
||||
var hitResult = mod.reacharound.getLastReacharoundResult();
|
||||
|
||||
if (hitResult == null)
|
||||
return;
|
||||
@@ -135,7 +134,7 @@ public abstract class MinecraftClientMixin {
|
||||
hitResult = mod.reacharound.withSideForReacharound(hitResult, stackInHand);
|
||||
|
||||
int previousStackCount = stackInHand.getCount();
|
||||
ActionResult result = this.interactionManager.interactBlock(this.player, this.world, hand, hitResult);
|
||||
var result = this.interactionManager.interactBlock(this.player, this.world, hand, hitResult);
|
||||
if (result.isAccepted()) {
|
||||
if (result.shouldSwingHand()) {
|
||||
this.player.swingHand(hand);
|
||||
|
||||
@@ -15,6 +15,7 @@ import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig;
|
||||
import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.Mouse;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -29,8 +30,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
* Adds extra access to the mouse.
|
||||
*/
|
||||
@Mixin(Mouse.class)
|
||||
public abstract class MouseMixin implements MouseAccessor
|
||||
{
|
||||
public abstract class MouseMixin implements MouseAccessor {
|
||||
@Shadow
|
||||
@Final
|
||||
private MinecraftClient client;
|
||||
@@ -39,20 +39,18 @@ public abstract class MouseMixin implements MouseAccessor
|
||||
public abstract void lambdacontrols$onCursorPos(long window, double x, double y);
|
||||
|
||||
@Inject(method = "method_1605", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/screen/Screen;mouseReleased(DDI)Z"))
|
||||
private void onMouseBackButton(boolean[] result, double mouseX, double mouseY, int button, CallbackInfo ci)
|
||||
{
|
||||
if (!result[0] && button == GLFW.GLFW_MOUSE_BUTTON_4 && this.client.currentScreen != null) {
|
||||
if (LambdaControlsClient.get().input.tryGoBack(this.client.currentScreen)) {
|
||||
private static void onMouseBackButton(boolean[] result, Screen screen, double mouseX, double mouseY, int button, CallbackInfo ci) {
|
||||
if (!result[0] && button == GLFW.GLFW_MOUSE_BUTTON_4 && screen != null) {
|
||||
if (LambdaControlsClient.get().input.tryGoBack(screen)) {
|
||||
result[0] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "isCursorLocked", at = @At("HEAD"), cancellable = true)
|
||||
private void isCursorLocked(CallbackInfoReturnable<Boolean> ci)
|
||||
{
|
||||
private void isCursorLocked(CallbackInfoReturnable<Boolean> ci) {
|
||||
if (this.client.currentScreen == null) {
|
||||
LambdaControlsConfig config = LambdaControlsClient.get().config;
|
||||
var config = LambdaControlsClient.get().config;
|
||||
if (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()) {
|
||||
ci.setReturnValue(true);
|
||||
ci.cancel();
|
||||
@@ -61,11 +59,10 @@ public abstract class MouseMixin implements MouseAccessor
|
||||
}
|
||||
|
||||
@Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true)
|
||||
private void onCursorLocked(CallbackInfo ci)
|
||||
{
|
||||
private void onCursorLocked(CallbackInfo ci) {
|
||||
LambdaControlsConfig config = LambdaControlsClient.get().config;
|
||||
if (config.getControlsMode() == ControlsMode.TOUCHSCREEN
|
||||
|| (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()))
|
||||
if (/*config.getControlsMode() == ControlsMode.TOUCHSCREEN
|
||||
||*/ (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()))
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,11 @@ package dev.lambdaurora.lambdacontrols.client.mixin;
|
||||
import dev.lambdaurora.lambdacontrols.ControlsMode;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen;
|
||||
import net.minecraft.client.gui.Drawable;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.Selectable;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.options.OptionsScreen;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.screen.option.OptionsScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.text.Text;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -30,13 +32,22 @@ public class OptionsScreenMixin extends Screen {
|
||||
super(title);
|
||||
}
|
||||
|
||||
@Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/options/OptionsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 7))
|
||||
private AbstractButtonWidget lambdacontrols$onInit(OptionsScreen screen, AbstractButtonWidget btn) {
|
||||
if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) {
|
||||
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).getHeight(), btn.getMessage(),
|
||||
@SuppressWarnings("unchecked")
|
||||
@Redirect(
|
||||
method = "init",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/gui/screen/option/OptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;",
|
||||
ordinal = 7
|
||||
)
|
||||
)
|
||||
private <T extends Element & Drawable & Selectable> T lambdacontrols$onInit(OptionsScreen screen, T element) {
|
||||
if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER && element instanceof ButtonWidget btn) {
|
||||
return (T) this.addDrawableChild(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((ClickableWidgetAccessor) btn).getHeight(),
|
||||
btn.getMessage(),
|
||||
b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, false))));
|
||||
} else {
|
||||
return this.addButton(btn);
|
||||
return this.addDrawableChild(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
package dev.lambdaurora.lambdacontrols.client.mixin;
|
||||
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.*;
|
||||
@@ -19,14 +17,10 @@ import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -70,30 +64,30 @@ public abstract class WorldRendererMixin {
|
||||
LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !LambdaControlsClient.get().config.shouldRenderReacharoundOutline())
|
||||
return;
|
||||
BlockHitResult result = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
|
||||
var result = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
|
||||
if (result == null)
|
||||
return;
|
||||
BlockPos blockPos = result.getBlockPos();
|
||||
var blockPos = result.getBlockPos();
|
||||
if (this.world.getWorldBorder().contains(blockPos)) {
|
||||
ItemStack stack = this.client.player.getStackInHand(Hand.MAIN_HAND);
|
||||
var stack = this.client.player.getStackInHand(Hand.MAIN_HAND);
|
||||
if (stack == null || !(stack.getItem() instanceof BlockItem))
|
||||
return;
|
||||
|
||||
LambdaControlsClient mod = LambdaControlsClient.get();
|
||||
var mod = LambdaControlsClient.get();
|
||||
|
||||
Block block = ((BlockItem) stack.getItem()).getBlock();
|
||||
var block = ((BlockItem) stack.getItem()).getBlock();
|
||||
result = mod.reacharound.withSideForReacharound(result, block);
|
||||
ItemPlacementContext context = new ItemPlacementContext(new ItemUsageContext(this.client.player, Hand.MAIN_HAND, result));
|
||||
var context = new ItemPlacementContext(new ItemUsageContext(this.client.player, Hand.MAIN_HAND, result));
|
||||
|
||||
BlockState placementState = block.getPlacementState(context);
|
||||
var placementState = block.getPlacementState(context);
|
||||
if (placementState == null)
|
||||
return;
|
||||
Vec3d pos = camera.getPos();
|
||||
var pos = camera.getPos();
|
||||
|
||||
VoxelShape 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 = mod.config.getReacharoundOutlineColor();
|
||||
|
||||
VertexConsumer vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
|
||||
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
|
||||
drawShapeOutline(matrices, vertexConsumer, outlineShape,
|
||||
(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);
|
||||
|
||||
@@ -31,6 +31,6 @@ public class DummyRingAction extends RingAction {
|
||||
|
||||
@Override
|
||||
public void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered) {
|
||||
drawCenteredString(matrices, textRenderer, this.getName(), x + 25, y + 25 - textRenderer.fontHeight / 2, 0xffffff);
|
||||
drawCenteredText(matrices, textRenderer, this.getName(), x + 25, y + 25 - textRenderer.fontHeight / 2, 0xffffff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.electronwill.nightconfig.core.Config;
|
||||
import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,14 +39,11 @@ public class KeyBindingRingAction extends RingAction {
|
||||
public void onAction(@NotNull RingButtonMode mode) {
|
||||
KeyBindingAccessor accessor = (KeyBindingAccessor) this.binding;
|
||||
switch (mode) {
|
||||
case PRESS:
|
||||
case HOLD:
|
||||
accessor.lambdacontrols_handlePressState(this.activated);
|
||||
break;
|
||||
case TOGGLE:
|
||||
accessor.lambdacontrols_handlePressState(!this.binding.isPressed());
|
||||
case PRESS, HOLD -> accessor.lambdacontrols$handlePressState(this.activated);
|
||||
case TOGGLE -> {
|
||||
accessor.lambdacontrols$handlePressState(!this.binding.isPressed());
|
||||
this.activated = !this.binding.isPressed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,25 +11,25 @@ package dev.lambdaurora.lambdacontrols.client.ring;
|
||||
|
||||
import com.electronwill.nightconfig.core.Config;
|
||||
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a key binding ring.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @version 1.7.0
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public final class LambdaRing {
|
||||
public static final int ELEMENT_SIZE = 50;
|
||||
|
||||
private final Object2ObjectMap<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 LambdaControlsClient mod;
|
||||
private int currentPage = 0;
|
||||
@@ -49,13 +49,13 @@ public final class LambdaRing {
|
||||
/**
|
||||
* Loads the ring from configuration.
|
||||
*
|
||||
* @param config The configuration.
|
||||
* @param config the configuration
|
||||
*/
|
||||
public void load(@NotNull Config config) {
|
||||
List<Config> configPages = config.get("ring.pages");
|
||||
if (configPages != null) {
|
||||
this.pages.clear();
|
||||
for (Config configPage : configPages) {
|
||||
for (var configPage : configPages) {
|
||||
RingPage.parseRingPage(configPage).ifPresent(this.pages::add);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public abstract class RingAction extends DrawableHelper implements Nameable {
|
||||
/**
|
||||
* Gets the text name of the ring action.
|
||||
*
|
||||
* @return The text name.
|
||||
* @return the text name
|
||||
*/
|
||||
public Text getTextName() {
|
||||
return new TranslatableText(this.getName());
|
||||
@@ -49,7 +49,7 @@ public abstract class RingAction extends DrawableHelper implements Nameable {
|
||||
/**
|
||||
* Returns whether the action is activated or not.
|
||||
*
|
||||
* @return True if the action is activated, else false.
|
||||
* @return true if the action is activated, else false
|
||||
*/
|
||||
public boolean isActivated() {
|
||||
return this.activated;
|
||||
|
||||
@@ -37,10 +37,10 @@ public enum RingButtonMode implements Nameable {
|
||||
/**
|
||||
* Returns the next ring button mode available.
|
||||
*
|
||||
* @return The next ring button mode.
|
||||
* @return the next ring button mode
|
||||
*/
|
||||
public @NotNull RingButtonMode next() {
|
||||
RingButtonMode[] v = values();
|
||||
var v = values();
|
||||
if (v.length == this.ordinal() + 1)
|
||||
return v[0];
|
||||
return v[this.ordinal() + 1];
|
||||
@@ -49,7 +49,7 @@ public enum RingButtonMode implements Nameable {
|
||||
/**
|
||||
* Returns the translation key of this ring button mode.
|
||||
*
|
||||
* @return The translation key of this ring button mode.
|
||||
* @return the translation key of this ring button mode
|
||||
*/
|
||||
public @NotNull String getTranslationKey() {
|
||||
return "lambdacontrols.ring.button_mode." + this.getName();
|
||||
@@ -58,7 +58,7 @@ public enum RingButtonMode implements Nameable {
|
||||
/**
|
||||
* Gets the translated name of this ring button mode.
|
||||
*
|
||||
* @return The translated name of this ring button mode.
|
||||
* @return the translated name of this ring button mode
|
||||
*/
|
||||
public @NotNull Text getTranslatedText() {
|
||||
return this.text;
|
||||
|
||||
@@ -41,12 +41,12 @@ public class RingPage extends DrawableHelper {
|
||||
/**
|
||||
* Renders the ring page.
|
||||
*
|
||||
* @param matrices The matrices.
|
||||
* @param width The screen width.
|
||||
* @param height The screen height.
|
||||
* @param mouseX The mouse X-coordinate.
|
||||
* @param mouseY The mouse Y-coordinate.
|
||||
* @param tickDelta The tick delta.
|
||||
* @param matrices the matrices
|
||||
* @param width the screen width
|
||||
* @param height the screen height
|
||||
* @param mouseX the mouse X-coordinate
|
||||
* @param mouseY the mouse Y-coordinate
|
||||
* @param tickDelta the tick delta
|
||||
*/
|
||||
public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int width, int height, int mouseX, int mouseY, float tickDelta) {
|
||||
int centerX = width / 2;
|
||||
@@ -57,7 +57,7 @@ public class RingPage extends DrawableHelper {
|
||||
int y = centerY - offset;
|
||||
int x = centerX - offset;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
RingAction ringAction = this.actions[i];
|
||||
var ringAction = this.actions[i];
|
||||
if (ringAction != null)
|
||||
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
|
||||
x += 55;
|
||||
@@ -65,7 +65,7 @@ public class RingPage extends DrawableHelper {
|
||||
y += 55;
|
||||
x = centerX - offset;
|
||||
for (int i = 3; i < 5; i++) {
|
||||
RingAction ringAction = this.actions[i];
|
||||
var ringAction = this.actions[i];
|
||||
if (ringAction != null)
|
||||
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
|
||||
x += 55 * 2;
|
||||
@@ -73,7 +73,7 @@ public class RingPage extends DrawableHelper {
|
||||
y += 55;
|
||||
x = centerX - offset;
|
||||
for (int i = 5; i < 8; i++) {
|
||||
RingAction ringAction = this.actions[i];
|
||||
var ringAction = this.actions[i];
|
||||
if (ringAction != null)
|
||||
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
|
||||
x += 55;
|
||||
@@ -87,15 +87,15 @@ public class RingPage extends DrawableHelper {
|
||||
/**
|
||||
* Tries to parse a ring page configuration.
|
||||
*
|
||||
* @param config The configuration.
|
||||
* @return An optional ring page.
|
||||
* @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();
|
||||
|
||||
RingPage page = new RingPage(name);
|
||||
var page = new RingPage(name);
|
||||
|
||||
List<Config> actionConfigs = config.get("actions");
|
||||
|
||||
|
||||
@@ -20,35 +20,35 @@ public interface HandledScreenAccessor {
|
||||
/**
|
||||
* Gets the left coordinate of the GUI.
|
||||
*
|
||||
* @return The left coordinate of the GUI.
|
||||
* @return the left coordinate of the GUI
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* Gets the top coordinate of the GUI.
|
||||
*
|
||||
* @return The top coordinate of the GUI.
|
||||
* @return the top coordinate of the GUI
|
||||
*/
|
||||
int getY();
|
||||
|
||||
/**
|
||||
* Gets the slot at position.
|
||||
*
|
||||
* @param pos_x The X position to check.
|
||||
* @param pos_y The Y position to check.
|
||||
* @return The slot at the specified position.
|
||||
* @param posX the X position to check
|
||||
* @param posY the Y position to check
|
||||
* @return the slot at the specified position
|
||||
*/
|
||||
Slot lambdacontrols$getSlotAt(double pos_x, double pos_y);
|
||||
Slot lambdacontrols$getSlotAt(double posX, double posY);
|
||||
|
||||
boolean lambdacontrols$isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button);
|
||||
|
||||
/**
|
||||
* Handles a mouse click on the specified slot.
|
||||
*
|
||||
* @param slot The slot instance.
|
||||
* @param slotId The slot id.
|
||||
* @param clickData The click data.
|
||||
* @param actionType The action type.
|
||||
* @param slot the slot instance
|
||||
* @param slotId the slot id
|
||||
* @param clickData the click data
|
||||
* @param actionType the action type
|
||||
*/
|
||||
void lambdacontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public interface KeyBindingAccessor {
|
||||
|
||||
boolean lambdacontrols$unpress();
|
||||
|
||||
default boolean lambdacontrols_handlePressState(boolean pressed) {
|
||||
default boolean lambdacontrols$handlePressState(boolean pressed) {
|
||||
if (pressed)
|
||||
return this.lambdacontrols$press();
|
||||
else
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
"id": "lambdacontrols",
|
||||
"name": "LambdaControls",
|
||||
"version": "${version}",
|
||||
"description": "Adds better controls: controller and touchscreen support.",
|
||||
"description": "Adds better controls, and controller support.",
|
||||
"authors": [
|
||||
"LambdAurora"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/lambdacontrols",
|
||||
"homepage": "https://modrinth.com/mod/lambdacontrols",
|
||||
"sources": "https://github.com/LambdAurora/LambdaControls.git",
|
||||
"issues": "https://github.com/LambdAurora/LambdaControls/issues"
|
||||
},
|
||||
@@ -26,23 +26,23 @@
|
||||
"dev.lambdaurora.lambdacontrols.client.LambdaControlsModMenu"
|
||||
]
|
||||
},
|
||||
"accessWidener": "lambdacontrols.accesswidener",
|
||||
"mixins": [
|
||||
"lambdacontrols.mixins.json",
|
||||
"lambdacontrols_compat.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.1",
|
||||
"fabric": ">=0.29.3",
|
||||
"minecraft": ">=1.16.2",
|
||||
"spruceui": ">=1.6.3"
|
||||
"fabricloader": ">=0.11.3",
|
||||
"fabric": ">=0.36.0",
|
||||
"minecraft": ">=1.17",
|
||||
"spruceui": ">=3.2.0",
|
||||
"java": ">=16"
|
||||
},
|
||||
"recommends": {
|
||||
"modmenu": ">=1.12.2"
|
||||
},
|
||||
"suggests": {
|
||||
"flamingo": "*",
|
||||
"roughlyenoughitems": ">=4.5.5",
|
||||
"okzoomer": ">=4.0.0"
|
||||
"flamingo": "*"
|
||||
},
|
||||
"breaks": {
|
||||
"modmenu": "<1.12.2",
|
||||
|
||||
3
src/main/resources/lambdacontrols.accesswidener
Normal file
3
src/main/resources/lambdacontrols.accesswidener
Normal file
@@ -0,0 +1,3 @@
|
||||
accessWidener v1 named
|
||||
|
||||
accessible class net/minecraft/client/gui/widget/EntryListWidget$MoveDirection
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "dev.lambdaurora.lambdacontrols.client.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"client": [
|
||||
"AbstractButtonWidgetAccessor",
|
||||
"ClickableWidgetAccessor",
|
||||
"AdvancementsScreenAccessor",
|
||||
"ClientPlayerEntityMixin",
|
||||
"ControlsOptionsScreenMixin",
|
||||
|
||||
@@ -2,12 +2,8 @@
|
||||
"required": true,
|
||||
"package": "dev.lambdaurora.lambdacontrols.client.compat.mixin",
|
||||
"plugin": "dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsMixinPlugin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"client": [
|
||||
"EntryListWidgetAccessor",
|
||||
"EntryWidgetAccessor",
|
||||
"RecipeViewingScreenAccessor",
|
||||
"VillagerRecipeViewingScreenAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
||||
Reference in New Issue
Block a user