Compare commits

..

3 Commits

Author SHA1 Message Date
LambdAurora
bb19ea4da5 Fix buildscript for Modrinth publishing. 2021-06-23 14:32:20 +02:00
LambdAurora
a1773cc0d9 Quick fix. 2021-06-23 14:24:49 +02:00
LambdAurora
e652390583 LambdaControls 1.7.0: update to 1.17. 2021-06-23 14:18:20 +02:00
69 changed files with 1198 additions and 1118 deletions

26
.github/workflows/gradlebuild.yml vendored Executable file
View 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
View 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
View 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
View File

@@ -1,7 +1,7 @@
# #
# LambdAurora's ignore file # LambdAurora's ignore file
# #
# v0.13 # v0.15
# JetBrains # JetBrains
.idea/ .idea/
@@ -53,6 +53,8 @@ __pycache__/
# OS # OS
## Windows ## Windows
desktop.ini desktop.ini
# MacOS
.DS_Store
# File types # File types
*.dll *.dll
@@ -61,10 +63,13 @@ desktop.ini
*.lib *.lib
lib*.a lib*.a
*.png~ *.png~
*.tar.?z
# Common # Common
bin/ bin/
build/ build/
dist/ dist/
lib/
obj/
run/ run/
target/ target/

View File

@@ -1,6 +1,6 @@
# Changelog # Changelog
## v1.0.0 ## 1.0.0
:tada: First release! :tada: :tada: First release! :tada:
@@ -12,11 +12,11 @@
- Added key bindings for look around. - Added key bindings for look around.
- And more! - 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)) - 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). 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. - Fixed broken chat arrow keys.
- Optimized a little bit the button indicator. (need more work) - 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)). 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. - HUD side affects button indicators now.
- Added support for Advancements tabs. - 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)). - Improved rotation algorithm ([#11](https://github.com/LambdAurora/LambdaControls/issues/11)).
- Added virtual mouse. - Added virtual mouse.
@@ -60,21 +60,21 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur
- And more! - And more!
- v1.3.0 specific: Updated to Minecraft 1.16.1 - 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 broken inventory interactions ([#13](https://github.com/LambdAurora/LambdaControls/issues/13))
- Fixed virtual mouse preventing continuous attack (thus making breaking blocks impossible). - Fixed virtual mouse preventing continuous attack (thus making breaking blocks impossible).
- Added support for [ModUpdater](https://gitea.thebrokenrail.com/TheBrokenRail/ModUpdater) hopefully. - Added support for [ModUpdater](https://gitea.thebrokenrail.com/TheBrokenRail/ModUpdater) hopefully.
- Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to 1.5.2. - Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to 1.5.2.
### v1.3.2 ### 1.3.2
- Added vertical reacharound. - Added vertical reacharound.
- Added more API for compatibility handlers. - Added more API for compatibility handlers.
- Improved reacharound API. - Improved reacharound API.
- Improved [REI](https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items) compatibility. - 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)). - Added analog movements ([#10](https://github.com/LambdAurora/LambdaControls/issues/10)).
- Improved Ok Zoomer compability. - 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. - Will allow for better compability with other mods.
- Might be interesting for keyboard users too. - 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). - 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 mappings string editor screen.
- Added Simplified Chinese translations ([#18](https://github.com/LambdAurora/LambdaControls/pull/18)). - Added Simplified Chinese translations ([#18](https://github.com/LambdAurora/LambdaControls/pull/18)).
@@ -104,9 +104,28 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur
- Respect toggle setting in Accessibility screen. - Respect toggle setting in Accessibility screen.
- Tweaked rotation speeds. - Tweaked rotation speeds.
- Updated to Minecraft 1.16.2. - 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. - Overhauled REI compatibility.
- Improved horizontal reach-around. - Improved horizontal reach-around.
- Fixed crashes with Ok Zoomer. - Fixed crashes with Ok Zoomer.
- Fixed crashes with key unbinding. - Fixed crashes with key unbinding.
- More WIP on keybind ring. - 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.
[SpruceUI]: https://github.com/LambdAurora/SpruceUI

View File

@@ -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. [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. Java is the main language used to make LambdaControls alive.
Knowing how to code in Java is necessary if you contribute to the code. 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 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? ## How can I contribute?
@@ -55,17 +55,17 @@ Git commits should be and must be signed.
#### Before submitting a bug report #### 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. - 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? #### 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 ### Suggesting enhancements
Enhancement suggestions are tracked as [GitHub issues](https://github.com/LambdAurora/LambdaControls/issues). 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 ### Do pull requests
@@ -81,21 +81,16 @@ Feel free to pull request!
### Git commit messages ### Git commit messages
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") * 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. * (Not for the message) Don't forget to sign the commit.
### Naming convention ### 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. `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 ### Brace placement
Every braces should be at the end of the line of function declaration, etc... 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.
### Quick note for users of the Intellij IDEA IDE ### Quick note for users of the Intellij IDEA IDE

View File

@@ -1,11 +1,13 @@
# LambdaControls # LambdaControls
![Java 8](https://img.shields.io/badge/language-Java%208-9B599A.svg?style=flat-square) <!-- modrinth_exclude.start -->
![Java 16](https://img.shields.io/badge/language-Java%2016-9B599A.svg?style=flat-square) <!-- modrinth_exclude.end -->
[![GitHub license](https://img.shields.io/github/license/LambdAurora/LambdaControls?style=flat-square)](https://raw.githubusercontent.com/LambdAurora/LambdaControls/master/LICENSE) [![GitHub license](https://img.shields.io/github/license/LambdAurora/LambdaControls?style=flat-square)](https://raw.githubusercontent.com/LambdAurora/LambdaControls/master/LICENSE)
![Environment: Client](https://img.shields.io/badge/environment-client-1976d2?style=flat-square) ![Environment: Client](https://img.shields.io/badge/environment-client-1976d2?style=flat-square)
[![Mod loader: Fabric]][fabric] [![Mod loader: Fabric]][fabric] <!-- modrinth_exclude.start -->
![Version](https://img.shields.io/github/v/tag/LambdAurora/LambdaControls?label=version&style=flat-square) ![Version](https://img.shields.io/github/v/tag/LambdAurora/LambdaControls?label=version&style=flat-square)
[![CurseForge](http://cf.way2muchnoise.eu/title/354231.svg)](https://www.curseforge.com/minecraft/mc-mods/lambdacontrols) [![CurseForge](http://cf.way2muchnoise.eu/title/354231.svg)](https://www.curseforge.com/minecraft/mc-mods/lambdacontrols)
<!-- modrinth_exclude.end -->
A Fabric Minecraft mod which adds better controls, reach-around and controller support. A Fabric Minecraft mod which adds better controls, reach-around and controller support.
@@ -45,9 +47,11 @@ This mod also adds controller support.
![controller_controls] ![controller_controls]
![controller_options] ![controller_options]
<!-- modrinth_exclude.start -->
## Build ## 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_controls]: images/controller_controls.png
[controller_options]: images/controller_options.png [controller_options]: images/controller_options.png

View File

@@ -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 { plugins {
id 'fabric-loom' version '0.6-SNAPSHOT' id 'fabric-loom' version '0.9.+'
id 'java-library' id 'java-library'
id 'maven-publish' id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '6.1.0' id 'com.github.johnrengelman.shadow' version '7.0.0'
id 'org.cadixdev.licenser' version '0.5.0' id 'org.cadixdev.licenser' version '0.6.1'
id 'com.modrinth.minotaur' version '1.2.+'
} }
import net.fabricmc.loom.task.RemapJarTask 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 group = project.maven_group
version = "${project.mod_version}+${getMCVersionString()}" 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. // 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 = 16
def targetJavaVersion = 8
def getMCVersionString() { boolean isMCVersionNonRelease() {
if (project.minecraft_version.matches("\\d\\dw\\d\\d[a-z]")) { 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 return project.minecraft_version
} }
int lastDot = project.minecraft_version.lastIndexOf('.') def version = project.minecraft_version.split('\\.')
return project.minecraft_version.substring(0, lastDot) 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, '![$1](https://raw.githubusercontent.com/LambdAurora/LambdaControls/1.17/$2)')
return readme
} }
minecraft { minecraft {
accessWidener file('src/main/resources/lambdacontrols.accesswidener')
} }
repositories { repositories {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
maven { url = 'https://aperlambda.github.io/maven' } maven { url 'https://aperlambda.github.io/maven' }
maven { maven {
name = 'CottonMC' name 'Gegy'
url = 'http://server.bbkr.space:8081/artifactory/libs-snapshot' url 'https://maven.gegy.dev'
} }
maven { maven {
name = 'Terraformers' name 'CottonMC'
url = 'https://maven.terraformersmc.com/releases' url 'https://server.bbkr.space:8081/artifactory/libs-snapshot'
} }
maven { url "https://maven.shedaniel.me/" } maven {
maven { url = "https://jitpack.io" } name 'Terraformers'
url 'https://maven.terraformersmc.com/releases'
}
maven { url 'https://maven.shedaniel.me/' }
} }
configurations { configurations {
@@ -70,20 +88,19 @@ dependencies {
// Fabric API. This is technically optional, but you probably want it anyway. // Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "dev.lambdaurora:spruceui:${project.spruceui_version}"
include "dev.lambdaurora:spruceui:${project.spruceui_version}"
modImplementation "com.terraformersmc:modmenu:${project.modmenu_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 // Compatibility mods
modImplementation("com.github.joaoh1:okzoomer:e13183c59b") { /*modImplementation("com.github.joaoh1:okzoomer:e13183c59b") {
exclude group: 'me.shedaniel.cloth' exclude group: 'me.shedaniel.cloth'
exclude group: 'io.github.prospector' 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 { java {
@@ -94,25 +111,21 @@ java {
} }
tasks.withType(JavaCompile).configureEach { tasks.withType(JavaCompile).configureEach {
it.options.encoding = "UTF-8" it.options.encoding = 'UTF-8'
if (JavaVersion.current().isJava9Compatible()) { it.options.release.set(targetJavaVersion)
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetJavaVersion
}
}
} }
processResources { processResources {
inputs.property "version", project.version inputs.property 'version', project.version
filesMatching("fabric.mod.json") { filesMatching('fabric.mod.json') {
expand "version": project.version expand 'version': project.version
} }
} }
jar { jar {
from("LICENSE") { from('LICENSE') {
rename { "${it}_${project.archivesBaseName}" } rename { "${it}_${project.archivesBaseName}" }
} }
} }
@@ -133,37 +146,118 @@ shadowJar {
exclude 'org/**' exclude 'org/**'
relocate 'com.electronwill.nightconfig', 'dev.lambdaurora.lambdacontrols.shadow.nightconfig' relocate 'com.electronwill.nightconfig', 'dev.lambdaurora.lambdacontrols.shadow.nightconfig'
} }
remapJar.dependsOn(shadowJar)
task shadowRemapJar(type: RemapJarTask) { task shadowRemapJar(type: RemapJarTask) {
dependsOn shadowJar dependsOn shadowJar
input = file("${project.buildDir}/libs/$archivesBaseName-$version-dev.jar") input.set(file("${project.buildDir}/libs/$archivesBaseName-$version-dev.jar"))
archiveName = "${archivesBaseName}-${version}.jar" archiveFileName = "${archivesBaseName}-${version}.jar"
addNestedDependencies = true addNestedDependencies.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 // configure the maven publication
publishing { 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 { repositories {
mavenLocal() mavenLocal()
maven { maven {
name = "GithubPackages" name "GithubPackages"
url = uri("https://maven.pkg.github.com/LambdAurora/LambdaControls") url uri("https://maven.pkg.github.com/LambdAurora/LambdaControls")
credentials { credentials {
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN") password = project.findProperty("gpr.key") ?: System.getenv("TOKEN")
} }
} }
} def lambdacontrolsMaven = System.getenv('LAMBDACONTROLS_MAVEN')
if (lambdacontrolsMaven) {
publications { maven {
mavenJava(MavenPublication) { name 'LambdaControlsMaven'
// add all the jars that should be included when publishing to maven url uri(lambdacontrolsMaven)
artifact(remapJar) { credentials {
builtBy remapJar username = project.findProperty('gpr.user') ?: System.getenv('MAVEN_USERNAME')
} password = project.findProperty('gpr.key') ?: System.getenv('MAVEN_PASSWORD')
artifact(sourcesJar) { }
builtBy remapSourcesJar
} }
} }
} }

View File

@@ -3,17 +3,18 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/use # check these on https://fabricmc.net/use
minecraft_version=1.16.5 minecraft_version=1.17
yarn_mappings=1.16.5+build.5 yarn_mappings=1.17+build.13
loader_version=0.11.3 loader_version=0.11.6
# Mod Properties # Mod Properties
mod_version = 1.6.0 mod_version = 1.7.0
maven_group = dev.lambdaurora.lambdacontrols maven_group = dev.lambdaurora
archives_base_name = lambdacontrols archives_base_name = lambdacontrols
modrinth_id=W1D3UXEc
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.32.0+1.16 fabric_version=0.36.0+1.17
spruceui_version=2.1.4-1.16 spruceui_version=3.1.0+1.17
modmenu_version=1.16.8 modmenu_version=2.0.2

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

0
gradlew vendored Normal file → Executable file
View File

View File

@@ -1,8 +1,8 @@
pluginManagement { pluginManagement {
repositories { repositories {
maven { maven {
name = 'Fabric' name 'Fabric'
url = 'https://maven.fabricmc.net/' url 'https://maven.fabricmc.net/'
} }
gradlePluginPortal() gradlePluginPortal()
} }

View File

@@ -19,21 +19,20 @@ import java.util.Optional;
* Represents the controls mode. * Represents the controls mode.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.1.0 * @version 1.7.0
* @since 1.0.0 * @since 1.0.0
*/ */
public enum ControlsMode implements Nameable { public enum ControlsMode implements Nameable {
DEFAULT, DEFAULT,
CONTROLLER, CONTROLLER;
TOUCHSCREEN;
/** /**
* Returns the next controls mode available. * Returns the next controls mode available.
* *
* @return The next available controls mode. * @return the next available controls mode
*/ */
public ControlsMode next() { public ControlsMode next() {
ControlsMode[] v = values(); var v = values();
if (v.length == this.ordinal() + 1) if (v.length == this.ordinal() + 1)
return v[0]; return v[0];
return v[this.ordinal() + 1]; return v[this.ordinal() + 1];
@@ -42,7 +41,7 @@ public enum ControlsMode implements Nameable {
/** /**
* Gets the translation key of this controls mode. * 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 * @since 1.1.0
*/ */
public String getTranslationKey() { public String getTranslationKey() {
@@ -57,8 +56,8 @@ public enum ControlsMode implements Nameable {
/** /**
* Gets the controls mode from its identifier. * Gets the controls mode from its identifier.
* *
* @param id The identifier of the controls mode. * @param id the identifier of the controls mode
* @return The controls mode if found, else empty. * @return the controls mode if found, else empty
*/ */
public static Optional<ControlsMode> byId(@NotNull String id) { public static Optional<ControlsMode> byId(@NotNull String id) {
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst(); return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();

View File

@@ -12,7 +12,7 @@ package dev.lambdaurora.lambdacontrols;
import dev.lambdaurora.lambdacontrols.event.PlayerChangeControlsModeCallback; import dev.lambdaurora.lambdacontrols.event.PlayerChangeControlsModeCallback;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.fabricmc.api.ModInitializer; 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.FabricLoader;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
@@ -29,7 +29,7 @@ import java.util.Optional;
* Represents the LambdaControls mod. * Represents the LambdaControls mod.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.6.0 * @version 1.7.0
* @since 1.0.0 * @since 1.0.0
*/ */
public class LambdaControls implements ModInitializer { public class LambdaControls implements ModInitializer {
@@ -47,25 +47,25 @@ public class LambdaControls implements ModInitializer {
INSTANCE = this; INSTANCE = this;
this.log("Initializing LambdaControls..."); this.log("Initializing LambdaControls...");
ServerSidePacketRegistry.INSTANCE.register(HELLO_CHANNEL, ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> {
(context, attachedData) -> { String version = buf.readString(32);
String version = attachedData.readString(32); ControlsMode.byId(buf.readString(32))
ControlsMode.byId(attachedData.readString(32)) .ifPresent(controlsMode -> server
.ifPresent(controlsMode -> context.getTaskQueue() .execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode)));
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode))); server.execute(() -> {
context.getTaskQueue().execute(() -> ServerPlayNetworking.send(player, FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.HORIZONTAL_REACHAROUND));
ServerSidePacketRegistry.INSTANCE.sendToPlayer(context.getPlayer(), FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.HORIZONTAL_REACHAROUND))); });
}); });
ServerSidePacketRegistry.INSTANCE.register(CONTROLS_MODE_CHANNEL, ServerPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL,
(context, attachedData) -> ControlsMode.byId(attachedData.readString(32)) (server, player, handler, buf, responseSender) -> ControlsMode.byId(buf.readString(32))
.ifPresent(controlsMode -> context.getTaskQueue() .ifPresent(controlsMode -> server
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode)))); .execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode))));
} }
/** /**
* Prints a message to the terminal. * Prints a message to the terminal.
* *
* @param info The message to print. * @param info the message to print
*/ */
public void log(String info) { public void log(String info) {
this.logger.info("[LambdaControls] " + info); this.logger.info("[LambdaControls] " + info);
@@ -74,7 +74,7 @@ public class LambdaControls implements ModInitializer {
/** /**
* Prints a warning to the terminal. * Prints a warning to the terminal.
* *
* @param warning The warning to print. * @param warning the warning to print
*/ */
public void warn(String warning) { public void warn(String warning) {
this.logger.info("[LambdaControls] " + 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. * Returns a packet byte buffer made for the lambdacontrols:controls_mode plugin message.
* *
* @param controlsMode The controls mode to send. * @param controlsMode the controls mode to send
* @return The packet byte buffer. * @return the packet byte buffer
*/ */
public PacketByteBuf makeControlsModeBuffer(@NotNull ControlsMode controlsMode) { public PacketByteBuf makeControlsModeBuffer(@NotNull ControlsMode controlsMode) {
Objects.requireNonNull(controlsMode, "Controls mode cannot be null."); 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. * Returns a packet byte buffer made for the lambdacontrols:feature plugin message.
* *
* @param feature The feature data to send. * @param features the features data to send
* @return The packet byte buffer. * @return the packet byte buffer
*/ */
public PacketByteBuf makeFeatureBuffer(@NotNull LambdaControlsFeature feature) { public PacketByteBuf makeFeatureBuffer(LambdaControlsFeature... features) {
Objects.requireNonNull(feature, "Feature cannot be null."); if (features.length == 0)
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer()).writeString(feature.getName(), 64); throw new IllegalArgumentException("At least one feature must be provided.");
buffer.writeBoolean(feature.isAllowed()); 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; return buffer;
} }
public PacketByteBuf makeHello(@NotNull ControlsMode controlsMode) { public PacketByteBuf makeHello(@NotNull ControlsMode controlsMode) {
String version = ""; var version = "";
Optional<ModContainer> container; Optional<ModContainer> container;
if ((container = FabricLoader.getInstance().getModContainer(LambdaControlsConstants.NAMESPACE)).isPresent()) { if ((container = FabricLoader.getInstance().getModContainer(LambdaControlsConstants.NAMESPACE)).isPresent()) {
version = container.get().getMetadata().getVersion().getFriendlyString(); version = container.get().getMetadata().getVersion().getFriendlyString();
@@ -116,7 +121,7 @@ public class LambdaControls implements ModInitializer {
/** /**
* Gets the LambdaControls instance. * Gets the LambdaControls instance.
* *
* @return The LambdaControls instance. * @return the LambdaControls instance
*/ */
public static LambdaControls get() { public static LambdaControls get() {
return INSTANCE; return INSTANCE;

View File

@@ -57,7 +57,7 @@ public class LambdaControlsFeature implements Nameable {
/** /**
* Returns whether this feature is allowed. * 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() { public boolean isAllowed() {
return this.allowed; return this.allowed;
@@ -66,7 +66,7 @@ public class LambdaControlsFeature implements Nameable {
/** /**
* Sets whether this feature is allowed. * 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) { public void setAllowed(boolean allowed) {
this.allowed = allowed; this.allowed = allowed;
@@ -82,7 +82,7 @@ public class LambdaControlsFeature implements Nameable {
/** /**
* Returns whether this feature is enabled. * 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() { public boolean isEnabled() {
return this.enabled; return this.enabled;
@@ -91,7 +91,7 @@ public class LambdaControlsFeature implements Nameable {
/** /**
* Returns whether this feature is enabled. * 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) { public void setEnabled(boolean enabled) {
this.enabled = enabled; this.enabled = enabled;
@@ -100,7 +100,7 @@ public class LambdaControlsFeature implements Nameable {
/** /**
* Returns whether this feature is available or not. * 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 #isAllowed()
* @see #isEnabled() * @see #isEnabled()
*/ */

View File

@@ -31,7 +31,7 @@ public enum ButtonState {
/** /**
* Returns whether this state is a pressed state. * 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() { public boolean isPressed() {
return this == PRESS || this == REPEAT; return this == PRESS || this == REPEAT;
@@ -40,7 +40,7 @@ public enum ButtonState {
/** /**
* Returns whether this state is an unpressed state. * 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() { public boolean isUnpressed() {
return this == RELEASE || this == NONE; return this == RELEASE || this == NONE;

View File

@@ -50,7 +50,7 @@ public enum ControllerType implements Nameable {
/** /**
* Returns the controller type's identifier. * Returns the controller type's identifier.
* *
* @return The controller type's identifier. * @return the controller type's identifier
*/ */
public int getId() { public int getId() {
return this.id; return this.id;
@@ -59,10 +59,10 @@ public enum ControllerType implements Nameable {
/** /**
* Returns the next controller type available. * Returns the next controller type available.
* *
* @return The next available controller type. * @return the next available controller type
*/ */
public @NotNull ControllerType next() { public @NotNull ControllerType next() {
ControllerType[] v = values(); var v = values();
if (v.length == this.ordinal() + 1) if (v.length == this.ordinal() + 1)
return v[0]; return v[0];
return v[this.ordinal() + 1]; return v[this.ordinal() + 1];
@@ -71,7 +71,7 @@ public enum ControllerType implements Nameable {
/** /**
* Gets the translated text of this controller type. * 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() { public @NotNull Text getTranslatedText() {
return this.text; return this.text;
@@ -85,8 +85,8 @@ public enum ControllerType implements Nameable {
/** /**
* Gets the controller type from its identifier. * Gets the controller type from its identifier.
* *
* @param id The identifier of the controller type. * @param id the identifier of the controller type
* @return The controller type if found, else empty. * @return the controller type if found, else empty
*/ */
public static @NotNull Optional<ControllerType> byId(@NotNull String id) { public static @NotNull Optional<ControllerType> byId(@NotNull String id) {
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst(); return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();

View File

@@ -37,10 +37,10 @@ public enum HudSide implements Nameable {
/** /**
* Returns the next side available. * Returns the next side available.
* *
* @return The next available side. * @return the next available side
*/ */
public @NotNull HudSide next() { public @NotNull HudSide next() {
HudSide[] v = values(); var v = values();
if (v.length == this.ordinal() + 1) if (v.length == this.ordinal() + 1)
return v[0]; return v[0];
return v[this.ordinal() + 1]; return v[this.ordinal() + 1];
@@ -49,7 +49,7 @@ public enum HudSide implements Nameable {
/** /**
* Returns the translation key of this hud side. * 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() { public @NotNull String getTranslationKey() {
return "lambdacontrols.hud_side." + this.getName(); return "lambdacontrols.hud_side." + this.getName();
@@ -58,7 +58,7 @@ public enum HudSide implements Nameable {
/** /**
* Gets the translated text of this hud side. * 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() { public @NotNull Text getTranslatedText() {
return this.text; return this.text;
@@ -72,8 +72,8 @@ public enum HudSide implements Nameable {
/** /**
* Gets the hud side from its identifier. * Gets the hud side from its identifier.
* *
* @param id The identifier of the hud side. * @param id the identifier of the hud side
* @return The hud side if found, else empty. * @return the hud side if found, else empty
*/ */
public static @NotNull Optional<HudSide> byId(@NotNull String id) { public static @NotNull Optional<HudSide> byId(@NotNull String id) {
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst(); return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();

View File

@@ -18,11 +18,9 @@ import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import dev.lambdaurora.lambdacontrols.client.controller.Controller; import dev.lambdaurora.lambdacontrols.client.controller.Controller;
import dev.lambdaurora.lambdacontrols.client.controller.InputManager; import dev.lambdaurora.lambdacontrols.client.controller.InputManager;
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsHud; 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.KeyBindingRingAction;
import dev.lambdaurora.lambdacontrols.client.ring.LambdaRing; import dev.lambdaurora.lambdacontrols.client.ring.LambdaRing;
import me.lambdaurora.spruceui.event.OpenScreenCallback; import dev.lambdaurora.spruceui.hud.HudManager;
import me.lambdaurora.spruceui.hud.HudManager;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
@@ -30,7 +28,7 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler; 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.toast.SystemToast;
import net.minecraft.client.util.InputUtil; import net.minecraft.client.util.InputUtil;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
@@ -45,7 +43,7 @@ import java.io.File;
* Represents the LambdaControls client mod. * Represents the LambdaControls client mod.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.6.0 * @version 1.7.0
* @since 1.1.0 * @since 1.1.0
*/ */
public class LambdaControlsClient extends LambdaControls implements ClientModInitializer { 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())); responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(this.config.getControlsMode()));
}); });
ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> { ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> {
String name = buf.readString(64); int features = buf.readVarInt();
boolean allowed = buf.readBoolean(); for (int i = 0; i < features; i++) {
LambdaControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed))); 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) -> { ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
sender.sendPacket(HELLO_CHANNEL, this.makeHello(this.config.getControlsMode())); 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.START_CLIENT_TICK.register(this.reacharound::tick);
ClientTickEvents.END_CLIENT_TICK.register(this::onTick); 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) { if (screen == null && this.config.getControlsMode() == ControlsMode.TOUCHSCREEN) {
screen = new TouchscreenOverlay(this); screen = new TouchscreenOverlay(this);
screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
@@ -108,7 +109,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
} else if (screen != null) { } else if (screen != null) {
this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight()); this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight());
} }
}); });*/
HudManager.register(this.hud = new LambdaControlsHud(this)); HudManager.register(this.hud = new LambdaControlsHud(this));
} }
@@ -123,7 +124,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
Controller.updateMappings(); Controller.updateMappings();
GLFW.glfwSetJoystickCallback((jid, event) -> { GLFW.glfwSetJoystickCallback((jid, event) -> {
if (event == GLFW.GLFW_CONNECTED) { 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), client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.connected", jid),
new LiteralText(controller.getName()))); new LiteralText(controller.getName())));
} else if (event == GLFW.GLFW_DISCONNECTED) { } 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. * 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) { public void setHudEnabled(boolean enabled) {
this.config.setHudEnabled(enabled); this.config.setHudEnabled(enabled);
@@ -194,7 +195,7 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
/** /**
* Gets the LambdaControls client instance. * Gets the LambdaControls client instance.
* *
* @return The LambdaControls client instance. * @return the LambdaControls client instance
*/ */
public static LambdaControlsClient get() { public static LambdaControlsClient get() {
return INSTANCE; return INSTANCE;

View File

@@ -21,7 +21,6 @@ import org.lwjgl.glfw.GLFW;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -144,8 +143,8 @@ public class LambdaControlsConfig {
public void checkAndFix() { public void checkAndFix() {
InputManager.streamBindings().forEach(binding -> { InputManager.streamBindings().forEach(binding -> {
String path = "controller.controls." + binding.getName(); var path = "controller.controls." + binding.getName();
Object raw = this.config.getRaw(path); var raw = this.config.getRaw(path);
if (raw instanceof Number) { if (raw instanceof Number) {
this.mod.warn("Invalid data at \"" + path + "\", fixing..."); this.mod.warn("Invalid data at \"" + path + "\", fixing...");
this.config.set(path, String.valueOf(raw)); this.config.set(path, String.valueOf(raw));
@@ -175,7 +174,7 @@ public class LambdaControlsConfig {
private void renamed(String oldPath, String newPath) { private void renamed(String oldPath, String newPath) {
if (!this.config.contains(oldPath)) if (!this.config.contains(oldPath))
return; return;
Object raw = this.config.getRaw(oldPath); var raw = this.config.getRaw(oldPath);
this.config.remove(oldPath); this.config.remove(oldPath);
this.config.set(newPath, raw); this.config.set(newPath, raw);
} }
@@ -218,7 +217,7 @@ public class LambdaControlsConfig {
/** /**
* Gets the controls mode from the configuration. * Gets the controls mode from the configuration.
* *
* @return The controls mode. * @return the controls mode
*/ */
public @NotNull ControlsMode getControlsMode() { public @NotNull ControlsMode getControlsMode() {
return this.controlsMode; return this.controlsMode;
@@ -227,7 +226,7 @@ public class LambdaControlsConfig {
/** /**
* Sets the controls mode in the configuration. * Sets the controls mode in the configuration.
* *
* @param controlsMode The controls mode. * @param controlsMode the controls mode
*/ */
public void setControlsMode(@NotNull ControlsMode controlsMode) { public void setControlsMode(@NotNull ControlsMode controlsMode) {
this.controlsMode = controlsMode; this.controlsMode = controlsMode;
@@ -237,7 +236,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether the auto switch mode is enabled or not. * 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() { public boolean hasAutoSwitchMode() {
return this.config.getOrElse("auto_switch_mode", DEFAULT_AUTO_SWITCH_MODE); 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. * 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) { public void setAutoSwitchMode(boolean autoSwitchMode) {
this.config.set("auto_switch_mode", autoSwitchMode); this.config.set("auto_switch_mode", autoSwitchMode);
@@ -255,7 +254,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether the mod has debug enabled or not. * 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() { public boolean hasDebug() {
return this.config.getOrElse("debug", DEFAULT_DEBUG); return this.config.getOrElse("debug", DEFAULT_DEBUG);
@@ -264,7 +263,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether the mod has debug enabled or not. * 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) { protected void setDebug(boolean debug) {
this.config.set("debug", debug); this.config.set("debug", debug);
@@ -277,7 +276,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether the HUD is enabled. * 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() { public boolean isHudEnabled() {
return this.hudEnable; return this.hudEnable;
@@ -286,7 +285,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether the HUD is enabled. * 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) { public void setHudEnabled(boolean enable) {
this.hudEnable = enable; this.hudEnable = enable;
@@ -296,7 +295,7 @@ public class LambdaControlsConfig {
/** /**
* Gets the HUD side from the configuration. * Gets the HUD side from the configuration.
* *
* @return The HUD side. * @return the HUD side
*/ */
public @NotNull HudSide getHudSide() { public @NotNull HudSide getHudSide() {
return this.hudSide; return this.hudSide;
@@ -305,7 +304,7 @@ public class LambdaControlsConfig {
/** /**
* Sets the HUD side in the configuration. * Sets the HUD side in the configuration.
* *
* @param hudSide The HUD side. * @param hudSide the HUD side
*/ */
public void setHudSide(@NotNull HudSide hudSide) { public void setHudSide(@NotNull HudSide hudSide) {
this.hudSide = hudSide; this.hudSide = hudSide;
@@ -337,7 +336,7 @@ public class LambdaControlsConfig {
/** /**
* Gets whether fast block placing is enabled or not. * 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() { public boolean hasFastBlockPlacing() {
return LambdaControlsFeature.FAST_BLOCK_PLACING.isEnabled(); return LambdaControlsFeature.FAST_BLOCK_PLACING.isEnabled();
@@ -346,7 +345,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether fast block placing is enabled or not. * 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) { public void setFastBlockPlacing(boolean enable) {
LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(enable); LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(enable);
@@ -356,7 +355,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether fly drifting is enabled or not. * 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() { public boolean hasFlyDrifting() {
return this.config.getOrElse("gameplay.fly.drifting", DEFAULT_FLY_DRIFTING); 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. * 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) { public void setFlyDrifting(boolean flyDrifting) {
this.config.set("gameplay.fly.drifting", flyDrifting); this.config.set("gameplay.fly.drifting", flyDrifting);
@@ -374,7 +373,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether vertical fly drifting is enabled or not. * 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() { public boolean hasFlyVerticalDrifting() {
return this.config.getOrElse("gameplay.fly.vertical_drifting", DEFAULT_FLY_VERTICAL_DRIFTING); 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. * 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) { public void setFlyVerticalDrifting(boolean flyDrifting) {
this.config.set("gameplay.fly.vertical_drifting", 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. * 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() { public boolean hasFrontBlockPlacing() {
return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isEnabled(); return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isEnabled();
@@ -401,7 +400,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether front block placing is enabled or not. * 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) { public void setFrontBlockPlacing(boolean enable) {
LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(enable); LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(enable);
@@ -411,7 +410,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether vertical reacharound is enabled or not. * 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() { public boolean hasVerticalReacharound() {
return LambdaControlsFeature.VERTICAL_REACHAROUND.isEnabled(); return LambdaControlsFeature.VERTICAL_REACHAROUND.isEnabled();
@@ -420,7 +419,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether vertical reacharound is enabled or not. * 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) { public void setVerticalReacharound(boolean enable) {
LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(enable); LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(enable);
@@ -430,7 +429,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether front block placing outline is enabled or not. * 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() { public boolean shouldRenderReacharoundOutline() {
return this.shouldRenderReacharoundOutline; return this.shouldRenderReacharoundOutline;
@@ -439,7 +438,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether front block placing outline is enabled or not. * 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) { public void setRenderReacharoundOutline(boolean render) {
this.config.set("gameplay.reacharound.outline", this.shouldRenderReacharoundOutline = render); this.config.set("gameplay.reacharound.outline", this.shouldRenderReacharoundOutline = render);
@@ -450,7 +449,7 @@ public class LambdaControlsConfig {
* <p> * <p>
* The integer array has 4 elements: red, green, blue and alpha. * 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() { public int[] getReacharoundOutlineColor() {
return this.reacharoundOutlineColor; return this.reacharoundOutlineColor;
@@ -466,7 +465,7 @@ public class LambdaControlsConfig {
* @return the controller * @return the controller
*/ */
public Controller getController() { public Controller getController() {
Object raw = this.config.getRaw("controller.id"); var raw = this.config.getRaw("controller.id");
if (raw instanceof Number) { if (raw instanceof Number) {
return Controller.byId((Integer) raw); return Controller.byId((Integer) raw);
} else if (raw instanceof String) { } else if (raw instanceof String) {
@@ -481,7 +480,7 @@ public class LambdaControlsConfig {
* @param controller the controller * @param controller the controller
*/ */
public void setController(Controller 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 * @return the second controller
*/ */
public Optional<Controller> getSecondController() { public Optional<Controller> getSecondController() {
Object raw = this.config.getRaw("controller.id2"); var raw = this.config.getRaw("controller.id2");
if (raw instanceof Number) { if (raw instanceof Number) {
if ((int) raw == -1) if ((int) raw == -1)
return Optional.empty(); return Optional.empty();
@@ -507,13 +506,13 @@ public class LambdaControlsConfig {
* @param controller the second controller * @param controller the second controller
*/ */
public void setSecondController(@Nullable Controller 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. * Gets the controller's type.
* *
* @return The controller's type. * @return the controller's type
*/ */
public @NotNull ControllerType getControllerType() { public @NotNull ControllerType getControllerType() {
return this.controllerType; return this.controllerType;
@@ -522,7 +521,7 @@ public class LambdaControlsConfig {
/** /**
* Sets the controller's type. * Sets the controller's type.
* *
* @param controllerType The controller's type. * @param controllerType the controller's type
*/ */
public void setControllerType(@NotNull ControllerType controllerType) { public void setControllerType(@NotNull ControllerType controllerType) {
this.controllerType = controllerType; this.controllerType = controllerType;
@@ -568,7 +567,7 @@ public class LambdaControlsConfig {
/** /**
* Gets the controller's rotation speed. * Gets the controller's rotation speed.
* *
* @return The rotation speed. * @return the rotation speed
*/ */
public double getRotationSpeed() { public double getRotationSpeed() {
return this.rotationSpeed; return this.rotationSpeed;
@@ -577,7 +576,7 @@ public class LambdaControlsConfig {
/** /**
* Sets the controller's rotation speed. * Sets the controller's rotation speed.
* *
* @param rotationSpeed The rotation speed. * @param rotationSpeed the rotation speed
*/ */
public void setRotationSpeed(double rotationSpeed) { public void setRotationSpeed(double rotationSpeed) {
this.rotationSpeed = rotationSpeed; this.rotationSpeed = rotationSpeed;
@@ -586,7 +585,7 @@ public class LambdaControlsConfig {
/** /**
* Gets the controller's mouse speed. * Gets the controller's mouse speed.
* *
* @return The mouse speed. * @return the mouse speed
*/ */
public double getMouseSpeed() { public double getMouseSpeed() {
return this.mouseSpeed; return this.mouseSpeed;
@@ -595,7 +594,7 @@ public class LambdaControlsConfig {
/** /**
* Sets the controller's mouse speed. * Sets the controller's mouse speed.
* *
* @param mouseSpeed The mouse speed. * @param mouseSpeed the mouse speed
*/ */
public void setMouseSpeed(double mouseSpeed) { public void setMouseSpeed(double mouseSpeed) {
this.mouseSpeed = mouseSpeed; this.mouseSpeed = mouseSpeed;
@@ -604,7 +603,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether the right X axis is inverted or not. * 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() { public boolean doesInvertRightXAxis() {
return this.config.getOrElse("controller.invert_right_x_axis", false); 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. * 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) { public void setInvertRightXAxis(boolean invert) {
this.config.set("controller.invert_right_x_axis", 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. * 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() { public boolean doesInvertRightYAxis() {
return this.config.getOrElse("controller.invert_right_y_axis", false); 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. * 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) { public void setInvertRightYAxis(boolean invert) {
this.config.set("controller.invert_right_y_axis", 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. * 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() { public boolean hasUnfocusedInput() {
return this.unfocusedInput; return this.unfocusedInput;
@@ -649,7 +648,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether unfocused controller input is allowed or not. * 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) { public void setUnfocusedInput(boolean unfocusedInput) {
this.unfocusedInput = unfocusedInput; this.unfocusedInput = unfocusedInput;
@@ -658,7 +657,7 @@ public class LambdaControlsConfig {
/** /**
* Returns whether the mouse is virtual or not. * 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() { public boolean hasVirtualMouse() {
return this.virtualMouse; return this.virtualMouse;
@@ -667,7 +666,7 @@ public class LambdaControlsConfig {
/** /**
* Sets whether the mouse is virtual or not. * 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) { public void setVirtualMouse(boolean virtualMouse) {
this.virtualMouse = virtualMouse; this.virtualMouse = virtualMouse;
@@ -676,7 +675,7 @@ public class LambdaControlsConfig {
/** /**
* Gets the virtual mouse skin. * Gets the virtual mouse skin.
* *
* @return The virtual mouse skin. * @return the virtual mouse skin
*/ */
public VirtualMouseSkin getVirtualMouseSkin() { public VirtualMouseSkin getVirtualMouseSkin() {
return this.virtualMouseSkin; return this.virtualMouseSkin;
@@ -685,7 +684,7 @@ public class LambdaControlsConfig {
/** /**
* Sets the virtual mouse skin. * Sets the virtual mouse skin.
* *
* @param skin The virtual mouse skin. * @param skin the virtual mouse skin
*/ */
public void setVirtualMouseSkin(VirtualMouseSkin skin) { public void setVirtualMouseSkin(VirtualMouseSkin skin) {
this.virtualMouseSkin = skin; this.virtualMouseSkin = skin;
@@ -695,7 +694,7 @@ public class LambdaControlsConfig {
/** /**
* Gets the right X axis sign. * Gets the right X axis sign.
* *
* @return The right X axis sign. * @return the right X axis sign
*/ */
public double getRightXAxisSign() { public double getRightXAxisSign() {
return this.doesInvertRightXAxis() ? -1.0 : 1.0; return this.doesInvertRightXAxis() ? -1.0 : 1.0;
@@ -704,7 +703,7 @@ public class LambdaControlsConfig {
/** /**
* Gets the right Y axis sign. * Gets the right Y axis sign.
* *
* @return The right Y axis sign. * @return the right Y axis sign
*/ */
public double getRightYAxisSign() { public double getRightYAxisSign() {
return this.doesInvertRightYAxis() ? -1.0 : 1.0; return this.doesInvertRightYAxis() ? -1.0 : 1.0;
@@ -724,16 +723,16 @@ public class LambdaControlsConfig {
/** /**
* Loads the button binding from configuration. * Loads the button binding from configuration.
* *
* @param button The button binding. * @param button the button binding
*/ */
public void loadButtonBinding(@NotNull ButtonBinding button) { public void loadButtonBinding(@NotNull ButtonBinding button) {
button.setButton(button.getDefaultButton()); 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 { try {
int[] buttons = new int[1]; var buttons = new int[1];
int count = 0; int count = 0;
while (matcher.find()) { while (matcher.find()) {
count++; count++;
@@ -768,8 +767,8 @@ public class LambdaControlsConfig {
/** /**
* Sets the button binding in configuration. * Sets the button binding in configuration.
* *
* @param binding The button binding. * @param binding the button binding
* @param button The button. * @param button the button
*/ */
public void setButtonBinding(@NotNull ButtonBinding binding, int[] button) { public void setButtonBinding(@NotNull ButtonBinding binding, int[] button) {
binding.setButton(button); binding.setButton(button);
@@ -803,8 +802,8 @@ public class LambdaControlsConfig {
/** /**
* Returns whether the specified axis is an axis used for movements. * Returns whether the specified axis is an axis used for movements.
* *
* @param axis The axis index. * @param axis the axis index
* @return True if the axis is used for movements, else false. * @return true if the axis is used for movements, else false
*/ */
public boolean isMovementAxis(int axis) { public boolean isMovementAxis(int axis) {
return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X; return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X;
@@ -813,27 +812,25 @@ public class LambdaControlsConfig {
/** /**
* Parses a color from a hexadecimal color string. * Parses a color from a hexadecimal color string.
* *
* @param hex The hexadecimal color. * @param hex the hexadecimal color
* @return The color instance, null if invalid. * @return the color instance, null if invalid
*/ */
private static int[] parseColor(String hex) { private static int[] parseColor(String hex) {
hex = hex.replace("#", ""); hex = hex.replace("#", "");
switch (hex.length()) { return switch (hex.length()) {
case 6: case 6 -> new int[]{
return new int[]{ Integer.valueOf(hex.substring(0, 2), 16),
Integer.valueOf(hex.substring(0, 2), 16), Integer.valueOf(hex.substring(2, 4), 16),
Integer.valueOf(hex.substring(2, 4), 16), Integer.valueOf(hex.substring(4, 6), 16),
Integer.valueOf(hex.substring(4, 6), 16), 255
255 };
}; case 8 -> new int[]{
case 8: Integer.valueOf(hex.substring(0, 2), 16),
return new int[]{ Integer.valueOf(hex.substring(2, 4), 16),
Integer.valueOf(hex.substring(0, 2), 16), Integer.valueOf(hex.substring(4, 6), 16),
Integer.valueOf(hex.substring(2, 4), 16), Integer.valueOf(hex.substring(6, 8), 16)
Integer.valueOf(hex.substring(4, 6), 16), };
Integer.valueOf(hex.substring(6, 8), 16) default -> null;
}; };
}
return null;
} }
} }

View File

@@ -9,15 +9,15 @@
package dev.lambdaurora.lambdacontrols.client; 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 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. * Represents the API implementation of ModMenu for LambdaControls.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.3.0 * @version 1.7.0
* @since 1.1.0 * @since 1.1.0
*/ */
public class LambdaControlsModMenu implements ModMenuApi { public class LambdaControlsModMenu implements ModMenuApi {

View File

@@ -21,12 +21,12 @@ import dev.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccess
import dev.lambdaurora.lambdacontrols.client.mixin.EntryListWidgetAccessor; import dev.lambdaurora.lambdacontrols.client.mixin.EntryListWidgetAccessor;
import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor; import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor; import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor;
import me.lambdaurora.spruceui.navigation.NavigationDirection; import dev.lambdaurora.spruceui.navigation.NavigationDirection;
import me.lambdaurora.spruceui.screen.SpruceScreen; import dev.lambdaurora.spruceui.screen.SpruceScreen;
import me.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget; import dev.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget;
import me.lambdaurora.spruceui.widget.SpruceElement; import dev.lambdaurora.spruceui.widget.SpruceElement;
import me.lambdaurora.spruceui.widget.SpruceLabelWidget; import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
import me.lambdaurora.spruceui.widget.container.SpruceParentWidget; import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement; import net.minecraft.client.gui.ParentElement;
@@ -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.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.gui.screen.pack.PackScreen; import net.minecraft.client.gui.screen.pack.PackScreen;
import net.minecraft.client.gui.screen.world.WorldListWidget; 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.AlwaysSelectedEntryListWidget;
import net.minecraft.client.gui.widget.EntryListWidget; import net.minecraft.client.gui.widget.EntryListWidget;
import net.minecraft.client.gui.widget.PressableWidget;
import net.minecraft.client.gui.widget.SliderWidget; import net.minecraft.client.gui.widget.SliderWidget;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType; import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
@@ -54,8 +53,6 @@ import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWGamepadState; import org.lwjgl.glfw.GLFWGamepadState;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -69,7 +66,7 @@ import static org.lwjgl.glfw.GLFW.*;
* Represents the LambdaControls' input handler. * Represents the LambdaControls' input handler.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.6.0 * @version 1.7.0
* @since 1.0.0 * @since 1.0.0
*/ */
public class LambdaInput { public class LambdaInput {
@@ -97,7 +94,7 @@ public class LambdaInput {
/** /**
* This method is called every Minecraft tick. * This method is called every Minecraft tick.
* *
* @param client The client instance. * @param client the client instance
*/ */
public void tick(@NotNull MinecraftClient client) { public void tick(@NotNull MinecraftClient client) {
this.targetYaw = 0.F; this.targetYaw = 0.F;
@@ -121,19 +118,20 @@ public class LambdaInput {
/** /**
* This method is called every Minecraft tick for controller input update. * 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) { 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. // Decreases the cooldown for GUI actions.
if (this.actionGuiCooldown > 0) if (this.actionGuiCooldown > 0)
--this.actionGuiCooldown; --this.actionGuiCooldown;
InputManager.updateStates(); InputManager.updateStates();
Controller controller = this.config.getController(); var controller = this.config.getController();
if (controller.isConnected()) { if (controller.isConnected()) {
GLFWGamepadState state = controller.getState(); var state = controller.getState();
this.fetchButtonInput(client, state, false); this.fetchButtonInput(client, state, false);
this.fetchAxeInput(client, state, false); this.fetchAxeInput(client, state, false);
} }
@@ -153,13 +151,12 @@ public class LambdaInput {
InputManager.updateBindings(client); InputManager.updateBindings(client);
if (this.controlsInput != null 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) { if (this.controlsInput.focusedBinding != null && !this.controlsInput.waiting) {
int[] buttons = new int[this.controlsInput.currentButtons.size()]; int[] buttons = new int[this.controlsInput.currentButtons.size()];
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++) for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
buttons[i] = this.controlsInput.currentButtons.get(i); buttons[i] = this.controlsInput.currentButtons.get(i);
this.controlsInput.focusedBinding.setButton(buttons); this.controlsInput.finishBindingEdit(buttons);
this.controlsInput.focusedBinding = null;
this.controlsInput = null; this.controlsInput = null;
} }
} }
@@ -171,8 +168,8 @@ public class LambdaInput {
/** /**
* This method is called before the screen is rendered. * This method is called before the screen is rendered.
* *
* @param client The client instance. * @param client the client instance
* @param screen The screen to render. * @param screen the screen to render
*/ */
public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen) { public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen) {
if (!isScreenInteractive(screen)) { if (!isScreenInteractive(screen)) {
@@ -183,21 +180,21 @@ public class LambdaInput {
/** /**
* This method is called when Minecraft renders. * 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) { public void onRender(float tickDelta, @NotNull MinecraftClient client) {
if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay)) if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay))
return; return;
PlayerEntity player = client.player; var player = client.player;
if (player == null) if (player == null)
return; return;
if (this.targetYaw != 0.f || this.targetPitch != 0.f) { if (this.targetYaw != 0.f || this.targetPitch != 0.f) {
float rotationYaw = (float) (player.prevYaw + (this.targetYaw / 0.10) * tickDelta); float rotationYaw = (float) (player.prevYaw + (this.targetYaw / 0.10) * tickDelta);
float rotationPitch = (float) (player.prevPitch + (this.targetPitch / 0.10) * tickDelta); float rotationPitch = (float) (player.prevPitch + (this.targetPitch / 0.10) * tickDelta);
client.player.yaw = rotationYaw; client.player.setYaw(rotationYaw);
client.player.pitch = MathHelper.clamp(rotationPitch, -90.f, 90.f); client.player.setPitch(MathHelper.clamp(rotationPitch, -90.f, 90.f));
if (client.player.isRiding()) { if (client.player.isRiding()) {
client.player.getVehicle().onPassengerLookAround(client.player); client.player.getVehicle().onPassengerLookAround(client.player);
} }
@@ -208,9 +205,9 @@ public class LambdaInput {
/** /**
* This method is called when a Screen is opened. * This method is called when a Screen is opened.
* *
* @param client The client instance. * @param client the client instance
* @param windowWidth The window width. * @param windowWidth the window width
* @param windowHeight The window height. * @param windowHeight the window height
*/ */
public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight) { public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight) {
if (client.currentScreen == null) { if (client.currentScreen == null) {
@@ -232,12 +229,12 @@ public class LambdaInput {
} }
private void fetchButtonInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) { 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++) { for (int i = 0; i < buffer.limit(); i++) {
int btn = leftJoycon ? ButtonBinding.controller2Button(i) : i; int btn = leftJoycon ? ButtonBinding.controller2Button(i) : i;
boolean btnState = buffer.get() == (byte) 1; boolean btnState = buffer.get() == (byte) 1;
ButtonState state = ButtonState.NONE; var state = ButtonState.NONE;
ButtonState previousState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE); var previousState = InputManager.STATES.getOrDefault(btn, ButtonState.NONE);
if (btnState != previousState.isPressed()) { if (btnState != previousState.isPressed()) {
state = btnState ? ButtonState.PRESS : ButtonState.RELEASE; state = btnState ? ButtonState.PRESS : ButtonState.RELEASE;
@@ -257,7 +254,7 @@ public class LambdaInput {
} }
private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) { 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++) { for (int i = 0; i < buffer.limit(); i++) {
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i; int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
float value = buffer.get(); float value = buffer.get();
@@ -276,7 +273,7 @@ public class LambdaInput {
if (action == 0 && !this.controlsInput.currentButtons.contains(button)) { if (action == 0 && !this.controlsInput.currentButtons.contains(button)) {
this.controlsInput.currentButtons.add(button); this.controlsInput.currentButtons.add(button);
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++) for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
buttons[i] = this.controlsInput.currentButtons.get(i); buttons[i] = this.controlsInput.currentButtons.get(i);
this.controlsInput.focusedBinding.setButton(buttons); this.controlsInput.focusedBinding.setButton(buttons);
@@ -295,11 +292,7 @@ public class LambdaInput {
this.changeFocus(client.currentScreen, NavigationDirection.UP); this.changeFocus(client.currentScreen, NavigationDirection.UP);
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) { } else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) {
this.changeFocus(client.currentScreen, NavigationDirection.DOWN); this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT) { } else this.handleLeftRight(client.currentScreen, button != GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT);
this.handleLeftRight(client.currentScreen, false);
} else {
this.handleLeftRight(client.currentScreen, true);
}
} }
return; return;
} }
@@ -308,7 +301,7 @@ public class LambdaInput {
if (action == 1) { if (action == 1) {
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) { if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) {
if (this.actionGuiCooldown == 0) { if (this.actionGuiCooldown == 0) {
Element focused = client.currentScreen.getFocused(); var focused = client.currentScreen.getFocused();
if (focused != null && isScreenInteractive(client.currentScreen)) { if (focused != null && isScreenInteractive(client.currentScreen)) {
if (this.handleAButton(client.currentScreen, focused)) { if (this.handleAButton(client.currentScreen, focused)) {
this.actionGuiCooldown = 5; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. 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) { if (!this.ignoreNextARelease) {
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
@@ -354,9 +348,9 @@ public class LambdaInput {
/** /**
* Handles inventory interaction. * Handles inventory interaction.
* *
* @param client The client instance. * @param client the client instance
* @param button The button pressed. * @param button the button pressed
* @return True if an inventory interaction was done. * @return {@code true} if an inventory interaction was done
*/ */
private boolean handleInventory(@NotNull MinecraftClient client, int button) { private boolean handleInventory(@NotNull MinecraftClient client, int button) {
if (!(client.currentScreen instanceof HandledScreen)) 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 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(); double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
HandledScreen screen = (HandledScreen) client.currentScreen; var screen = (HandledScreen) client.currentScreen;
HandledScreenAccessor accessor = (HandledScreenAccessor) screen; var accessor = (HandledScreenAccessor) screen;
Slot slot = ((HandledScreenAccessor) client.currentScreen).lambdacontrols$getSlotAt(x, y); Slot slot = ((HandledScreenAccessor) client.currentScreen).lambdacontrols$getSlotAt(x, y);
int slotId; int slotId;
if (slot == null) { if (slot == null) {
if (client.player.inventory.getCursorStack().isEmpty()) if (client.player.currentScreenHandler.getCursorStack().isEmpty())
return false; return false;
slotId = accessor.lambdacontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1; slotId = accessor.lambdacontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1;
} else { } else {
slotId = slot.id; slotId = slot.id;
} }
SlotActionType actionType = SlotActionType.PICKUP; var actionType = SlotActionType.PICKUP;
int clickData = GLFW.GLFW_MOUSE_BUTTON_1; int clickData = GLFW.GLFW_MOUSE_BUTTON_1;
switch (button) { switch (button) {
case GLFW_GAMEPAD_BUTTON_A: case GLFW_GAMEPAD_BUTTON_A:
@@ -416,13 +410,13 @@ public class LambdaInput {
/** /**
* Tries to go back. * Tries to go back.
* *
* @param screen The current screen. * @param screen the current screen
* @return True if successful, else false. * @return true if successful, else false
*/ */
public boolean tryGoBack(@NotNull Screen screen) { public boolean tryGoBack(@NotNull Screen screen) {
ImmutableSet<String> set = ImmutableSet.of("gui.back", "gui.done", "gui.cancel", "gui.toTitle", "gui.toMenu"); var set = ImmutableSet.of("gui.back", "gui.done", "gui.cancel", "gui.toTitle", "gui.toMenu");
return screen.children().stream().filter(element -> element instanceof AbstractPressableButtonWidget) return screen.children().stream().filter(element -> element instanceof PressableWidget)
.map(element -> (AbstractPressableButtonWidget) element) .map(element -> (PressableWidget) element)
.filter(element -> element.getMessage() instanceof TranslatableText) .filter(element -> element.getMessage() instanceof TranslatableText)
.anyMatch(element -> { .anyMatch(element -> {
if (set.stream().anyMatch(key -> key.equals(((TranslatableText) element.getMessage()).getKey()))) { if (set.stream().anyMatch(key -> key.equals(((TranslatableText) element.getMessage()).getKey()))) {
@@ -450,8 +444,8 @@ public class LambdaInput {
{ {
boolean currentPlusState = asButtonState == 1; boolean currentPlusState = asButtonState == 1;
boolean currentMinusState = asButtonState == 2; boolean currentMinusState = asButtonState == 2;
ButtonState previousPlusState = InputManager.STATES.getOrDefault(axisAsButton(axis, true), ButtonState.NONE); var previousPlusState = InputManager.STATES.getOrDefault(axisAsButton(axis, true), ButtonState.NONE);
ButtonState previousMinusState = InputManager.STATES.getOrDefault(axisAsButton(axis, false), ButtonState.NONE); var previousMinusState = InputManager.STATES.getOrDefault(axisAsButton(axis, false), ButtonState.NONE);
if (currentPlusState != previousPlusState.isPressed()) { if (currentPlusState != previousPlusState.isPressed()) {
InputManager.STATES.put(axisAsButton(axis, true), currentPlusState ? ButtonState.PRESS : ButtonState.RELEASE); InputManager.STATES.put(axisAsButton(axis, true), currentPlusState ? ButtonState.PRESS : ButtonState.RELEASE);
@@ -505,20 +499,18 @@ public class LambdaInput {
this.controlsInput.waiting = false; this.controlsInput.waiting = false;
} }
return; return;
} else if (client.currentScreen instanceof CreativeInventoryScreen) { } else if (client.currentScreen instanceof CreativeInventoryScreen creativeInventoryScreen) {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
CreativeInventoryScreen screen = (CreativeInventoryScreen) client.currentScreen; var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen;
CreativeInventoryScreenAccessor accessor = (CreativeInventoryScreenAccessor) screen;
// @TODO allow rebinding to left stick // @TODO allow rebinding to left stick
if (accessor.lambdacontrols$hasScrollbar() && absValue >= deadZone) { if (accessor.lambdacontrols$hasScrollbar() && absValue >= deadZone) {
screen.mouseScrolled(0.0, 0.0, -value); creativeInventoryScreen.mouseScrolled(0.0, 0.0, -value);
} }
return; 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) { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X || axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
AdvancementsScreen screen = (AdvancementsScreen) client.currentScreen; var accessor = (AdvancementsScreenAccessor) advancementsScreen;
AdvancementsScreenAccessor accessor = (AdvancementsScreenAccessor) screen;
if (absValue >= deadZone) { if (absValue >= deadZone) {
AdvancementTab tab = accessor.getSelectedTab(); 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); 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) { private boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) {
if (focused instanceof AbstractPressableButtonWidget) { if (focused instanceof PressableWidget widget) {
AbstractPressableButtonWidget widget = (AbstractPressableButtonWidget) focused;
widget.playDownSound(MinecraftClient.getInstance().getSoundManager()); widget.playDownSound(MinecraftClient.getInstance().getSoundManager());
widget.onPress(); widget.onPress();
return true; return true;
} else if (focused instanceof AbstractSprucePressableButtonWidget) { } else if (focused instanceof AbstractSprucePressableButtonWidget widget) {
AbstractSprucePressableButtonWidget widget = (AbstractSprucePressableButtonWidget) focused;
widget.playDownSound(); widget.playDownSound();
widget.onPress(); widget.onPress();
return true; return true;
} else if (focused instanceof SpruceLabelWidget) { } else if (focused instanceof SpruceLabelWidget labelWidget) {
((SpruceLabelWidget) focused).onPress(); labelWidget.onPress();
return true; return true;
} else if (focused instanceof WorldListWidget) { } else if (focused instanceof WorldListWidget list) {
WorldListWidget list = (WorldListWidget) focused;
list.getSelectedAsOptional().ifPresent(WorldListWidget.Entry::play); list.getSelectedAsOptional().ifPresent(WorldListWidget.Entry::play);
return true; return true;
} else if (focused instanceof MultiplayerServerListWidget) { } else if (focused instanceof MultiplayerServerListWidget list) {
MultiplayerServerListWidget list = (MultiplayerServerListWidget) focused; var entry = list.getSelectedOrNull();
MultiplayerServerListWidget.Entry entry = list.getSelected();
if (entry instanceof MultiplayerServerListWidget.LanServerEntry || entry instanceof MultiplayerServerListWidget.ServerEntry) { if (entry instanceof MultiplayerServerListWidget.LanServerEntry || entry instanceof MultiplayerServerListWidget.ServerEntry) {
((MultiplayerScreen) screen).select(entry); ((MultiplayerScreen) screen).select(entry);
((MultiplayerScreen) screen).connect(); ((MultiplayerScreen) screen).connect();
} }
} else if (focused instanceof SpruceParentWidget) { } else if (focused instanceof SpruceParentWidget) {
Element childFocused = ((SpruceParentWidget<?>) focused).getFocused(); var childFocused = ((SpruceParentWidget<?>) focused).getFocused();
if (childFocused != null) if (childFocused != null)
return this.handleAButton(screen, childFocused); return this.handleAButton(screen, childFocused);
} else if (focused instanceof ParentElement) { } else if (focused instanceof ParentElement widget) {
Element childFocused = ((ParentElement) focused).getFocused(); var childFocused = widget.getFocused();
if (childFocused != null) if (childFocused != null)
return this.handleAButton(screen, childFocused); return this.handleAButton(screen, childFocused);
} }
@@ -634,16 +622,16 @@ public class LambdaInput {
/** /**
* Handles the left and right buttons. * Handles the left and right buttons.
* *
* @param screen The current screen. * @param screen the current screen
* @param right True if the right button is pressed, else false. * @param right true if the right button is pressed, else false
*/ */
private boolean handleLeftRight(@NotNull Screen screen, boolean right) { private boolean handleLeftRight(@NotNull Screen screen, boolean right) {
if (screen instanceof SpruceScreen) { if (screen instanceof SpruceScreen spruceScreen) {
((SpruceScreen) screen).onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false); spruceScreen.onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
this.actionGuiCooldown = 5; this.actionGuiCooldown = 5;
return false; return false;
} }
Element focused = screen.getFocused(); var focused = screen.getFocused();
if (focused != null) if (focused != null)
if (this.handleRightLeftElement(focused, right)) if (this.handleRightLeftElement(focused, right))
return this.changeFocus(screen, right ? NavigationDirection.RIGHT : NavigationDirection.LEFT); return this.changeFocus(screen, right ? NavigationDirection.RIGHT : NavigationDirection.LEFT);
@@ -651,22 +639,20 @@ public class LambdaInput {
} }
private boolean handleRightLeftElement(@NotNull Element element, boolean right) { private boolean handleRightLeftElement(@NotNull Element element, boolean right) {
if (element instanceof SpruceElement) { if (element instanceof SpruceElement spruceElement) {
if (((SpruceElement) element).requiresCursor()) if (spruceElement.requiresCursor())
return true; 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) { if (element instanceof SliderWidget slider) {
SliderWidget slider = (SliderWidget) element;
slider.keyPressed(right ? 262 : 263, 0, 0); slider.keyPressed(right ? 262 : 263, 0, 0);
this.actionGuiCooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. this.actionGuiCooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks.
return false; return false;
} else if (element instanceof AlwaysSelectedEntryListWidget) { } else if (element instanceof AlwaysSelectedEntryListWidget) {
((EntryListWidgetAccessor) element).lambdacontrols$moveSelection(right ? EntryListWidget.MoveDirection.UP : EntryListWidget.MoveDirection.DOWN); ((EntryListWidgetAccessor) element).lambdacontrols$moveSelection(right ? EntryListWidget.MoveDirection.UP : EntryListWidget.MoveDirection.DOWN);
return false; return false;
} else if (element instanceof ParentElement) { } else if (element instanceof ParentElement entryList) {
ParentElement entryList = (ParentElement) element; var focused = entryList.getFocused();
Element focused = entryList.getFocused();
if (focused == null) if (focused == null)
return true; return true;
return this.handleRightLeftElement(focused, right); return this.handleRightLeftElement(focused, right);
@@ -677,10 +663,10 @@ public class LambdaInput {
/** /**
* Handles the look direction input. * Handles the look direction input.
* *
* @param client The client instance. * @param client the client instance
* @param axis The axis to change. * @param axis the axis to change
* @param value The value of the look. * @param value the value of the look
* @param state The state. * @param state the state
*/ */
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) { public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) {
// Handles the look direction. // Handles the look direction.
@@ -704,8 +690,8 @@ public class LambdaInput {
} }
private boolean changeFocus(@NotNull Screen screen, NavigationDirection direction) { private boolean changeFocus(@NotNull Screen screen, NavigationDirection direction) {
if (screen instanceof SpruceScreen) { if (screen instanceof SpruceScreen spruceScreen) {
if (((SpruceScreen) screen).onNavigation(direction, false)) { if (spruceScreen.onNavigation(direction, false)) {
this.actionGuiCooldown = 5; this.actionGuiCooldown = 5;
} }
return false; 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. // 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) { private void moveMouseToClosestSlot(@NotNull MinecraftClient client, @Nullable Screen screen) {
// Makes the mouse attracted to slots. This helps with selecting items when using a controller. // Makes the mouse attracted to slots. This helps with selecting items when using a controller.
if (screen instanceof HandledScreen) { if (screen instanceof HandledScreen inventoryScreen) {
HandledScreen inventoryScreen = (HandledScreen) screen; var accessor = (HandledScreenAccessor) inventoryScreen;
HandledScreenAccessor accessor = (HandledScreenAccessor) inventoryScreen;
int guiLeft = accessor.getX(); int guiLeft = accessor.getX();
int guiTop = accessor.getY(); int guiTop = accessor.getY();
int mouseX = (int) (targetMouseX * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()); 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)); .min(Comparator.comparingDouble(p -> p.value));
if (closestSlot.isPresent()) { if (closestSlot.isPresent()) {
Slot slot = closestSlot.get().key; var slot = closestSlot.get().key;
if (slot.hasStack() || !client.player.inventory.getMainHandStack().isEmpty()) { if (slot.hasStack() || !client.player.getInventory().getMainHandStack().isEmpty()) {
int slotCenterXScaled = guiLeft + slot.x + 8; int slotCenterXScaled = guiLeft + slot.x + 8;
int slotCenterYScaled = guiTop + slot.y + 8; int slotCenterYScaled = guiTop + slot.y + 8;
int slotCenterX = (int) (slotCenterXScaled / ((double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth())); int slotCenterX = (int) (slotCenterXScaled / ((double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()));

View File

@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
/** /**
* Represents the reach-around API of LambdaControls. * Represents the reach-around API of LambdaControls.
* *
* @version 1.5.0 * @version 1.7.0
* @since 1.3.2 * @since 1.3.2
*/ */
public class LambdaReacharound { public class LambdaReacharound {
@@ -49,7 +49,7 @@ public class LambdaReacharound {
/** /**
* Returns the last reach around result. * Returns the last reach around result.
* *
* @return The last reach around result. * @return the last reach around result
*/ */
public @Nullable BlockHitResult getLastReacharoundResult() { public @Nullable BlockHitResult getLastReacharoundResult() {
return this.lastReacharoundResult; return this.lastReacharoundResult;
@@ -58,7 +58,7 @@ public class LambdaReacharound {
/** /**
* Returns whether the last reach around is vertical. * 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() { public boolean isLastReacharoundVertical() {
return this.lastReacharoundVertical; return this.lastReacharoundVertical;
@@ -67,7 +67,7 @@ public class LambdaReacharound {
/** /**
* Returns whether reacharound is available or not. * 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() { public boolean isReacharoundAvailable() {
return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable(); 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. * Returns a nullable block hit result if vertical reach-around is possible.
* *
* @param client The client instance. * @param client the client instance
* @return A block hit result if vertical reach-around is possible, else null. * @return a block hit result if vertical reach-around is possible, else {@code null}
*/ */
public @Nullable BlockHitResult tryVerticalReachAround(@NotNull MinecraftClient client) { public @Nullable BlockHitResult tryVerticalReachAround(@NotNull MinecraftClient client) {
if (!LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable()) if (!LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable())
return null; return null;
if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.MISS 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()) || client.player.isRiding())
return null; return null;
Vec3d pos = client.player.getCameraPosVec(1.0F); Vec3d pos = client.player.getCameraPosVec(1.0F);
Vec3d rotationVec = client.player.getRotationVec(1.0F); Vec3d rotationVec = client.player.getRotationVec(1.0F);
float range = getPlayerRange(client); float range = getPlayerRange(client);
Vec3d rayVec = pos.add(rotationVec.x * range, rotationVec.y * range, rotationVec.z * range).add(0, 0.75, 0); var 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 result = client.world.raycast(new RaycastContext(pos, rayVec, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, client.player));
if (result.getType() == HitResult.Type.BLOCK) { if (result.getType() == HitResult.Type.BLOCK) {
BlockPos blockPos = result.getBlockPos().down(); BlockPos blockPos = result.getBlockPos().down();
@@ -112,33 +112,34 @@ public class LambdaReacharound {
/** /**
* Returns a nullable block hit result if horizontal reach-around is possible. * Returns a nullable block hit result if horizontal reach-around is possible.
* *
* @param client The client instance. * @param client the client instance
* @return A block hit result if horizontal reach-around is possible. * @return a block hit result if horizontal reach-around is possible
*/ */
public @Nullable BlockHitResult tryHorizontalReachAround(@NotNull MinecraftClient client) { public @Nullable BlockHitResult tryHorizontalReachAround(@NotNull MinecraftClient client) {
if (!LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable()) if (!LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable())
return null; 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()) if (client.player.isRiding())
return null; return null;
BlockPos playerPos = client.player.getBlockPos().down(); var playerPos = client.player.getBlockPos().down();
if (client.player.getY() - playerPos.getY() - 1.0 >= 0.25) { if (client.player.getY() - playerPos.getY() - 1.0 >= 0.25) {
playerPos = playerPos.up(); playerPos = playerPos.up();
this.onSlab = true; this.onSlab = true;
} else { } else {
this.onSlab = false; this.onSlab = false;
} }
BlockPos targetPos = new BlockPos(client.crosshairTarget.getPos()).subtract(playerPos); var 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)); var vector = new BlockPos.Mutable(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1));
BlockPos blockPos = playerPos.add(vector); 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()) if (!state.isAir())
return null; 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)) { if (adjacentBlockState.isAir() || adjacentBlockState.getBlock() instanceof FluidBlock || (vector.getX() == 0 && vector.getZ() == 0)) {
return null; return null;
} }

View File

@@ -20,7 +20,7 @@ import java.util.Optional;
/** /**
* Represents the virtual mouse skins. * Represents the virtual mouse skins.
* *
* @version 1.4.0 * @version 1.7.0
* @since 1.2.0 * @since 1.2.0
*/ */
public enum VirtualMouseSkin implements Nameable { public enum VirtualMouseSkin implements Nameable {
@@ -40,10 +40,10 @@ public enum VirtualMouseSkin implements Nameable {
/** /**
* Returns the next virtual mouse skin available. * 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() { public @NotNull VirtualMouseSkin next() {
VirtualMouseSkin[] v = values(); var v = values();
if (v.length == this.ordinal() + 1) if (v.length == this.ordinal() + 1)
return v[0]; return v[0];
return v[this.ordinal() + 1]; return v[this.ordinal() + 1];
@@ -52,7 +52,7 @@ public enum VirtualMouseSkin implements Nameable {
/** /**
* Returns the translation key of this virtual mouse skin. * 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() { public @NotNull String getTranslationKey() {
return "lambdacontrols.virtual_mouse.skin." + this.getName(); 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. * 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() { public @NotNull Text getTranslatedText() {
return this.text; return this.text;
@@ -75,8 +75,8 @@ public enum VirtualMouseSkin implements Nameable {
/** /**
* Gets the virtual mouse skin from its identifier. * Gets the virtual mouse skin from its identifier.
* *
* @param id The identifier of the virtual mouse skin. * @param id the identifier of the virtual mouse skin
* @return The virtual mouse skin if found, else empty. * @return the virtual mouse skin if found, else empty
*/ */
public static @NotNull Optional<VirtualMouseSkin> byId(@NotNull String id) { public static @NotNull Optional<VirtualMouseSkin> byId(@NotNull String id) {
return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst(); return Arrays.stream(values()).filter(mode -> mode.getName().equalsIgnoreCase(id)).findFirst();

View File

@@ -15,7 +15,6 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -23,22 +22,22 @@ import org.jetbrains.annotations.Nullable;
* Represents a compatibility handler for a mod. * Represents a compatibility handler for a mod.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.5.0 * @version 1.7.0
* @since 1.1.0 * @since 1.1.0
*/ */
public interface CompatHandler { public interface CompatHandler {
/** /**
* Handles compatibility of a mod. * Handles compatibility of a mod.
* *
* @param mod This mod instance. * @param mod this mod instance
*/ */
void handle(@NotNull LambdaControlsClient mod); void handle(@NotNull LambdaControlsClient mod);
/** /**
* Returns whether the mouse is required on the specified screen. * Returns whether the mouse is required on the specified screen.
* *
* @param screen The screen. * @param screen the screen
* @return True if the mouse is required on the specified screen, else false. * @return true if the mouse is required on the specified screen, else false
*/ */
default boolean requireMouseOnScreen(Screen screen) { default boolean requireMouseOnScreen(Screen screen) {
return false; return false;
@@ -47,22 +46,22 @@ public interface CompatHandler {
/** /**
* Returns a slot at the specified location if possible. * Returns a slot at the specified location if possible.
* *
* @param screen The screen. * @param screen the screen
* @param mouseX The mouse X-coordinate. * @param mouseX the mouse X-coordinate
* @param mouseY The mouse Y-coordinate. * @param mouseY the mouse Y-coordinate
* @return A slot if present, else null. * @return a slot if present, else null
* @since 1.5.0 * @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; return null;
} }
/** /**
* Returns whether the current slot is a creative slot or not. * Returns whether the current slot is a creative slot or not.
* *
* @param screen The screen. * @param screen the screen
* @param slot The slot to check. * @param slot the slot to check
* @return True if the slot is a creative slot, else false. * @return true if the slot is a creative slot, else false
*/ */
default boolean isCreativeSlot(@NotNull HandledScreen screen, @NotNull Slot slot) { default boolean isCreativeSlot(@NotNull HandledScreen screen, @NotNull Slot slot) {
return false; return false;
@@ -71,9 +70,9 @@ public interface CompatHandler {
/** /**
* Returns a custom translation key to make custom attack action strings on the HUD. * Returns a custom translation key to make custom attack action strings on the HUD.
* *
* @param client The client instance. * @param client the client instance
* @param placeResult The last place block result. * @param placeResult the last place block result
* @return Null if untouched, else a translation key. * @return null if untouched, else a translation key
*/ */
default String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) { default String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
return null; return null;
@@ -82,9 +81,9 @@ public interface CompatHandler {
/** /**
* Returns a custom translation key to make custom use action strings on the HUD. * Returns a custom translation key to make custom use action strings on the HUD.
* *
* @param client The client instance. * @param client the client instance
* @param placeResult The last place block result. * @param placeResult the last place block result
* @return Null if untouched, else a translation key. * @return null if untouched, else a translation key
*/ */
default String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) { default String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
return null; return null;
@@ -93,11 +92,15 @@ public interface CompatHandler {
/** /**
* Handles the menu back button. * Handles the menu back button.
* *
* @param client The client instance. * @param client the client instance
* @param screen The screen. * @param screen the screen
* @return True if the handle was fired and succeed, else false. * @return true if the handle was fired and succeed, else false
*/ */
default boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) { default boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) {
return false; return false;
} }
record SlotPos(int x, int y) {
public static final SlotPos INVALID_SLOT = new SlotPos(-1, -1);
}
} }

View File

@@ -16,7 +16,6 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import org.aperlambda.lambdacommon.utils.LambdaReflection; import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -37,17 +36,17 @@ public class LambdaControlsCompat {
/** /**
* Initializes compatibility with other mods if needed. * Initializes compatibility with other mods if needed.
* *
* @param mod The mod instance. * @param mod the mod instance
*/ */
public static void init(@NotNull LambdaControlsClient mod) { public static void init(@NotNull LambdaControlsClient mod) {
if (FabricLoader.getInstance().isModLoaded("okzoomer")) { /*if (FabricLoader.getInstance().isModLoaded("okzoomer")) {
mod.log("Adding okzoomer compatibility..."); mod.log("Adding okzoomer compatibility...");
HANDLERS.add(new OkZoomerCompat()); HANDLERS.add(new OkZoomerCompat());
} }
if (isReiPresent()) { if (isReiPresent()) {
mod.log("Adding REI compatiblity..."); mod.log("Adding REI compatiblity...");
HANDLERS.add(new ReiCompat()); HANDLERS.add(new ReiCompat());
} }*/
if (FabricLoader.getInstance().isModLoaded("hardcorequesting") && LambdaReflection.doesClassExist(HQMCompat.GUI_BASE_CLASS_PATH)) { if (FabricLoader.getInstance().isModLoaded("hardcorequesting") && LambdaReflection.doesClassExist(HQMCompat.GUI_BASE_CLASS_PATH)) {
mod.log("Adding HQM compatibility..."); mod.log("Adding HQM compatibility...");
HANDLERS.add(new HQMCompat()); HANDLERS.add(new HQMCompat());
@@ -59,7 +58,7 @@ public class LambdaControlsCompat {
/** /**
* Registers a new compatibility handler. * 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) { public static void registerCompatHandler(@NotNull CompatHandler handler) {
HANDLERS.add(handler); HANDLERS.add(handler);
@@ -68,7 +67,7 @@ public class LambdaControlsCompat {
/** /**
* Streams through compatibility handlers. * Streams through compatibility handlers.
* *
* @return A stream of compatibility handlers. * @return a stream of compatibility handlers
*/ */
public static Stream<CompatHandler> streamCompatHandlers() { public static Stream<CompatHandler> streamCompatHandlers() {
return HANDLERS.stream(); return HANDLERS.stream();
@@ -77,8 +76,8 @@ public class LambdaControlsCompat {
/** /**
* Returns whether the mouse is required on the specified screen. * Returns whether the mouse is required on the specified screen.
* *
* @param screen The screen. * @param screen the screen
* @return True if the mouse is requried on the specified screen, else false. * @return true if the mouse is requried on the specified screen, else false
*/ */
public static boolean requireMouseOnScreen(Screen screen) { public static boolean requireMouseOnScreen(Screen screen) {
return HANDLERS.stream().anyMatch(handler -> handler.requireMouseOnScreen(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. * Returns a slot at the specified location if possible.
* *
* @param screen The screen. * @param screen the screen
* @param mouseX The mouse X-coordinate. * @param mouseX the mouse X-coordinate
* @param mouseY The mouse Y-coordinate. * @param mouseY the mouse Y-coordinate
* @return A slot if present, else null. * @return a slot if present, else null
*/ */
public static @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) { public static @Nullable CompatHandler.SlotPos getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
for (CompatHandler handler : HANDLERS) { for (var handler : HANDLERS) {
Pair<Integer, Integer> slot = handler.getSlotAt(screen, mouseX, mouseY); var slot = handler.getSlotAt(screen, mouseX, mouseY);
if (slot != null) if (slot != null)
return slot; return slot;
} }
@@ -104,9 +103,9 @@ public class LambdaControlsCompat {
/** /**
* Returns a custom translation key to make custom attack action strings on the HUD. * Returns a custom translation key to make custom attack action strings on the HUD.
* *
* @param client The client instance. * @param client the client instance
* @param placeResult The last place block result. * @param placeResult the last place block result
* @return Null if untouched, else a translation key. * @return null if untouched, else a translation key
*/ */
public static String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) { public static String getAttackActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
for (CompatHandler handler : HANDLERS) { 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. * Returns a custom translation key to make custom use action strings on the HUD.
* *
* @param client The client instance. * @param client the client instance
* @param placeResult The last place block result. * @param placeResult the last place block result
* @return Null if untouched, else a translation key. * @return null if untouched, else a translation key
*/ */
public static String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) { public static String getUseActionAt(@NotNull MinecraftClient client, @Nullable BlockHitResult placeResult) {
for (CompatHandler handler : HANDLERS) { for (CompatHandler handler : HANDLERS) {
@@ -138,9 +137,9 @@ public class LambdaControlsCompat {
/** /**
* Handles the menu back button. * Handles the menu back button.
* *
* @param client The client instance. * @param client the client instance
* @param screen The screen. * @param screen the screen
* @return True if the handle was fired and succeed, else false. * @return true if the handle was fired and succeed, else false
*/ */
public static boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) { public static boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) {
for (CompatHandler handler : HANDLERS) { for (CompatHandler handler : HANDLERS) {
@@ -153,7 +152,7 @@ public class LambdaControlsCompat {
/** /**
* Returns whether Roughly Enough Items is present. * 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() { public static boolean isReiPresent() {
return FabricLoader.getInstance().isModLoaded("roughlyenoughitems"); return FabricLoader.getInstance().isModLoaded("roughlyenoughitems");

View File

@@ -10,10 +10,7 @@
package dev.lambdaurora.lambdacontrols.client.compat; package dev.lambdaurora.lambdacontrols.client.compat;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; 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.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
/** /**
* Represents a compatibility handler for OkZoomer. * Represents a compatibility handler for OkZoomer.
@@ -25,7 +22,7 @@ import org.lwjgl.glfw.GLFW;
public class OkZoomerCompat implements CompatHandler { public class OkZoomerCompat implements CompatHandler {
@Override @Override
public void handle(@NotNull LambdaControlsClient mod) { 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) .buttons(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_X)
.onlyInGame() .onlyInGame()
.cooldown(true) .cooldown(true)
@@ -54,6 +51,6 @@ public class OkZoomerCompat implements CompatHandler {
.category(ButtonBinding.MISC_CATEGORY) .category(ButtonBinding.MISC_CATEGORY)
.linkKeybind(ZoomKeybinds.resetZoomKey) .linkKeybind(ZoomKeybinds.resetZoomKey)
.register(); .register();
} }*/
} }
} }

View File

@@ -11,48 +11,26 @@ package dev.lambdaurora.lambdacontrols.client.compat;
import dev.lambdaurora.lambdacontrols.client.ButtonState; import dev.lambdaurora.lambdacontrols.client.ButtonState;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; 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.ButtonBinding;
import dev.lambdaurora.lambdacontrols.client.controller.InputHandlers; import dev.lambdaurora.lambdacontrols.client.controller.InputHandlers;
import dev.lambdaurora.lambdacontrols.client.controller.PressAction; 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.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.Identifier; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Optional;
import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.glfw.GLFW.*;
/** /**
* Represents a compatibility handler for REI. * Represents a compatibility handler for REI.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.5.0 * @version 1.7.0
* @since 1.2.0 * @since 1.2.0
*/ */
public class ReiCompat implements CompatHandler { 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 @Override
public void handle(@NotNull LambdaControlsClient mod) { public void handle(@NotNull LambdaControlsClient mod) {
@@ -113,57 +91,57 @@ public class ReiCompat implements CompatHandler {
@Override @Override
public boolean requireMouseOnScreen(Screen screen) { public boolean requireMouseOnScreen(Screen screen) {
return isViewingScreen(screen) || screen instanceof PreRecipeViewingScreen; return isViewingScreen(screen) /*|| screen instanceof PreRecipeViewingScreen*/;
} }
@Override @Override
public @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) { public @Nullable SlotPos getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay(); /*var overlay = ScreenHelper.getOptionalOverlay();
if (overlay.isPresent() && overlay.get().isInside(mouseX, mouseY)) { if (overlay.isPresent() && overlay.get().isInside(mouseX, mouseY)) {
EntryListWidget widget = getEntryListWidget(); var widget = getEntryListWidget();
if (widget == null) if (widget == null)
return 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) if (slot != null && slot != INVALID_SLOT)
return slot; return slot;
} else if (isViewingScreen(screen)) { } else if (isViewingScreen(screen)) {
for (Element element : screen.children()) { for (var element : screen.children()) {
Pair<Integer, Integer> slot = this.getSlotAt(element, mouseX, mouseY, true); var slot = this.getSlotAt(element, mouseX, mouseY, true);
if (slot != null && slot != INVALID_SLOT) if (slot != null && slot != INVALID_SLOT)
return slot; return slot;
} }
} }*/
return null; return null;
} }
private @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Element element, int mouseX, int mouseY, boolean allowEmpty) { /*private @Nullable SlotPos getSlotAt(@NotNull Element element, int mouseX, int mouseY, boolean allowEmpty) {
if (element instanceof EntryWidget) { if (element instanceof EntryWidget entry) {
EntryWidget entry = (EntryWidget) element;
if (entry.containsMouse(mouseX, mouseY)) { if (entry.containsMouse(mouseX, mouseY)) {
if (!allowEmpty && entry.entries().isEmpty()) if (!allowEmpty && entry.entries().isEmpty())
return INVALID_SLOT; 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) { } else if (element instanceof EntryListWidget) {
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries(); List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries();
for (EntryListEntryWidget entry : entries) { 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) if (slot != null && slot != INVALID_SLOT)
return slot; return slot;
} }
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds) { } else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds widgetWithBounds) {
for (Element child : ((WidgetWithBounds) element).children()) { for (var child : widgetWithBounds.children()) {
Pair<Integer, Integer> slot = this.getSlotAt(child, mouseX, mouseY, allowEmpty); var slot = this.getSlotAt(child, mouseX, mouseY, allowEmpty);
if (slot != null && slot != INVALID_SLOT) if (slot != null && slot != INVALID_SLOT)
return slot; return slot;
} }
} }
return null; return null;
} }*/
private static boolean isViewingScreen(Screen screen) { private static boolean isViewingScreen(Screen screen) {
return screen instanceof RecipeViewingScreen || screen instanceof VillagerRecipeViewingScreen; return true;
//return screen instanceof DefaultDisplayViewingScreen || screen instanceof CompositeDisplayViewingScreen;
} }
@Override @Override
@@ -171,12 +149,12 @@ public class ReiCompat implements CompatHandler {
if (!isViewingScreen(screen)) if (!isViewingScreen(screen))
return false; return false;
MinecraftClient.getInstance().openScreen(REIHelper.getInstance().getPreviousContainerScreen()); /*MinecraftClient.getInstance().openScreen(REIRuntimeImpl.getInstance().getPreviousContainerScreen());
ScreenHelper.getLastOverlay().init(); ScreenHelper.getLastOverlay().init();*/
return true; return true;
} }
private static EntryListWidget getEntryListWidget() { /*private static EntryListWidget getEntryListWidget() {
if (ENTRY_LIST_WIDGET == null) { if (ENTRY_LIST_WIDGET == null) {
ENTRY_LIST_WIDGET = LambdaReflection.getFirstFieldOfType(ContainerScreenOverlay.class, EntryListWidget.class) ENTRY_LIST_WIDGET = LambdaReflection.getFirstFieldOfType(ContainerScreenOverlay.class, EntryListWidget.class)
.map(field -> (EntryListWidget) LambdaReflection.getFieldValue(null, field)) .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(); double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
if (isViewingScreen(client.currentScreen)) { if (isViewingScreen(client.currentScreen)) {
for (Element element : client.currentScreen.children()) { for (var element : client.currentScreen.children()) {
EntryStack stack = getCurrentStack(element, x, y); var stack = getCurrentStack(element, x, y);
if (stack != null) if (stack != null)
return stack; return stack;
} }
} }
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay(); var overlay = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent()) if (!overlay.isPresent())
return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen); return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
EntryListWidget widget = getEntryListWidget(); var widget = getEntryListWidget();
if (widget == null) if (widget == null)
return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen); 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) { private static @Nullable EntryStack getCurrentStack(@NotNull Element element, double mouseX, double mouseY) {
if (element instanceof EntryWidget) { if (element instanceof EntryWidget entry) {
EntryWidget entry = (EntryWidget) element;
if (entry.containsMouse(mouseX, mouseY)) if (entry.containsMouse(mouseX, mouseY))
return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry(); return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry();
} else if (element instanceof EntryListWidget) { } else if (element instanceof EntryListWidget) {
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries(); var entries = ((EntryListWidgetAccessor) element).getEntries();
for (EntryListEntryWidget entry : entries) { for (EntryListEntryWidget entry : entries) {
if (entry.containsMouse(mouseX, mouseY)) { if (entry.containsMouse(mouseX, mouseY)) {
return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry(); return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry();
} }
} }
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds) { } else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds widgetWithBounds) {
for (Element child : ((WidgetWithBounds) element).children()) { for (var child : widgetWithBounds.children()) {
EntryStack stack = getCurrentStack(child, mouseX, mouseY); var stack = getCurrentStack(child, mouseX, mouseY);
if (stack != null) if (stack != null)
return stack; return stack;
} }
} }
return null; return null;
} }*/
private static PressAction handleShowRecipeUsage(boolean usage) { private static PressAction handleShowRecipeUsage(boolean usage) {
return (client, button, value, action) -> { return (client, button, value, action) -> {
if (action.isUnpressed()) if (action.isUnpressed())
return false; return false;
EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen); /*EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
if (stack == null) { if (stack == null) {
stack = getCurrentStack(client); stack = getCurrentStack(client);
} }
@@ -246,7 +223,7 @@ public class ReiCompat implements CompatHandler {
} else { } else {
return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory()); return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory());
} }
} }*/
return false; return false;
}; };
@@ -257,11 +234,11 @@ public class ReiCompat implements CompatHandler {
if (action == ButtonState.RELEASE) if (action == ButtonState.RELEASE)
return false; return false;
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay(); /*Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent()) if (!overlay.isPresent())
return false; return false;
EntryListWidget widget = getEntryListWidget(); var widget = getEntryListWidget();
if (widget == null) if (widget == null)
return false; return false;
@@ -269,7 +246,7 @@ public class ReiCompat implements CompatHandler {
widget.nextPage(); widget.nextPage();
else else
widget.previousPage(); widget.previousPage();
widget.updateEntriesPosition(); widget.updateEntriesPosition();*/
return true; return true;
}; };
@@ -286,14 +263,14 @@ public class ReiCompat implements CompatHandler {
if (action != ButtonState.RELEASE) if (action != ButtonState.RELEASE)
return false; return false;
if (client.currentScreen instanceof RecipeViewingScreen) { /*if (client.currentScreen instanceof DefaultDisplayViewingScreen) {
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen; RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
if (next) if (next)
screen.getCategoryNext().onClick(); screen.getCategoryNext().onClick();
else else
screen.getCategoryBack().onClick(); screen.getCategoryBack().onClick();
return true; return true;
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) { } else if (client.currentScreen instanceof CompositeDisplayViewingScreen) {
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen; VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories(); List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex(); int currentTab = screen.getSelectedCategoryIndex();
@@ -301,7 +278,7 @@ public class ReiCompat implements CompatHandler {
screen.setSelectedRecipeIndex(0); screen.setSelectedRecipeIndex(0);
screen.lambdacontrols_init(); screen.lambdacontrols_init();
return true; return true;
} }*/
return false; return false;
}; };
} }
@@ -311,15 +288,13 @@ public class ReiCompat implements CompatHandler {
if (action.isUnpressed()) if (action.isUnpressed())
return false; return false;
if (client.currentScreen instanceof RecipeViewingScreen) { /*if (client.currentScreen instanceof RecipeViewingScreenAccessor screen) {
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
if (next) if (next)
screen.getRecipeNext().onClick(); screen.getRecipeNext().onClick();
else else
screen.getRecipeBack().onClick(); screen.getRecipeBack().onClick();
return true; return true;
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) { } else if (client.currentScreen instanceof VillagerRecipeViewingScreenAccessor screen) {
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories(); List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex(); int currentTab = screen.getSelectedCategoryIndex();
List<RecipeDisplay> recipes = screen.getCategoryMap().get(categories.get(currentTab)); List<RecipeDisplay> recipes = screen.getCategoryMap().get(categories.get(currentTab));
@@ -343,7 +318,7 @@ public class ReiCompat implements CompatHandler {
screen.lambdacontrols_init(); screen.lambdacontrols_init();
return true; return true;
} }*/
return false; return false;
}; };

View File

@@ -9,13 +9,6 @@
package dev.lambdaurora.lambdacontrols.client.compat.mixin; 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. * Represents an accessor to REI's EntryListWidget.
* *
@@ -23,8 +16,8 @@ import java.util.List;
* @version 1.5.0 * @version 1.5.0
* @since 1.5.0 * @since 1.5.0
*/ */
@Mixin(value = EntryListWidget.class, remap = false) //@Mixin(value = EntryListWidget.class, remap = false)
public interface EntryListWidgetAccessor { public interface EntryListWidgetAccessor {
@Accessor(value = "entries") /*@Accessor(value = "entries")
List<EntryListEntryWidget> getEntries(); List<EntryListEntryWidget> getEntries();*/
} }

View File

@@ -9,11 +9,6 @@
package dev.lambdaurora.lambdacontrols.client.compat.mixin; 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. * Represents an accessor to REI's EntryWidget.
* *
@@ -21,8 +16,8 @@ import org.spongepowered.asm.mixin.gen.Invoker;
* @version 1.5.0 * @version 1.5.0
* @since 1.5.0 * @since 1.5.0
*/ */
@Mixin(value = EntryWidget.class, remap = false) //@Mixin(value = EntryWidget.class, remap = false)
public interface EntryWidgetAccessor { public interface EntryWidgetAccessor {
@Invoker("getCurrentEntry") /*@Invoker("getCurrentEntry")
EntryStack lambdacontrols_getCurrentEntry(); EntryStack lambdacontrols_getCurrentEntry();*/
} }

View File

@@ -9,21 +9,16 @@
package dev.lambdaurora.lambdacontrols.client.compat.mixin; 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. * Represents an accessor to REI's RecipeViewingScreen.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.5.0 * @version 1.7.0
* @since 1.2.0 * @since 1.2.0
*/ */
@Mixin(value = RecipeViewingScreen.class, remap = false) //@Mixin(value = DefaultDisplayViewingScreen.class, remap = false)
public interface RecipeViewingScreenAccessor { public interface RecipeViewingScreenAccessor {
@Accessor("categoryBack") /*@Accessor("categoryBack")
Button getCategoryBack(); Button getCategoryBack();
@Accessor("categoryNext") @Accessor("categoryNext")
@@ -33,5 +28,5 @@ public interface RecipeViewingScreenAccessor {
Button getRecipeBack(); Button getRecipeBack();
@Accessor("recipeNext") @Accessor("recipeNext")
Button getRecipeNext(); Button getRecipeNext();*/
} }

View File

@@ -9,31 +9,20 @@
package dev.lambdaurora.lambdacontrols.client.compat.mixin; 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. * Represents an accessor to REI's VillagerRecipeViewingScreen.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.5.0 * @version 1.7.0
* @since 1.2.0 * @since 1.2.0
*/ */
@Mixin(VillagerRecipeViewingScreen.class) //@Mixin(CompositeDisplayViewingScreen.class)
public interface VillagerRecipeViewingScreenAccessor { public interface VillagerRecipeViewingScreenAccessor {
@Accessor(value = "categoryMap", remap = false) /*@Accessor(value = "categoryMap", remap = false)
Map<RecipeCategory<?>, List<RecipeDisplay>> getCategoryMap(); Map<DisplayCategory<?>, List<Display>> getCategoryMap();
@Accessor(value = "categories", remap = false) @Accessor(value = "categories", remap = false)
List<RecipeCategory<?>> getCategories(); List<DisplayCategory<?>> getCategories();
@Accessor(value = "selectedCategoryIndex", remap = false) @Accessor(value = "selectedCategoryIndex", remap = false)
int getSelectedCategoryIndex(); int getSelectedCategoryIndex();
@@ -51,5 +40,5 @@ public interface VillagerRecipeViewingScreenAccessor {
ScrollingContainer getScrolling(); ScrollingContainer getScrolling();
@Invoker("init") @Invoker("init")
void lambdacontrols_init(); void lambdacontrols_init();*/
} }

View File

@@ -11,8 +11,8 @@ package dev.lambdaurora.lambdacontrols.client.controller;
import dev.lambdaurora.lambdacontrols.client.ButtonState; import dev.lambdaurora.lambdacontrols.client.ButtonState;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.options.GameOptions; import net.minecraft.client.option.GameOptions;
import net.minecraft.client.options.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.Identifier; import org.aperlambda.lambdacommon.Identifier;
@@ -31,7 +31,7 @@ import static org.lwjgl.glfw.GLFW.*;
* Represents a button binding. * Represents a button binding.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.5.0 * @version 1.7.0
* @since 1.0.0 * @since 1.0.0
*/ */
public class ButtonBinding implements Nameable { public class ButtonBinding implements Nameable {
@@ -89,12 +89,12 @@ public class ButtonBinding implements Nameable {
private final Text text; private final Text text;
private KeyBinding mcKeyBinding = null; private KeyBinding mcKeyBinding = null;
protected PairPredicate<MinecraftClient, ButtonBinding> filter; 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 boolean hasCooldown;
private int cooldown = 0; private int cooldown = 0;
boolean pressed = false; 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.setButton(this.defaultButton = defaultButton);
this.key = key; this.key = key;
this.text = new TranslatableText(this.key); this.text = new TranslatableText(this.key);
@@ -103,14 +103,14 @@ public class ButtonBinding implements Nameable {
this.hasCooldown = hasCooldown; 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); this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown);
} }
/** /**
* Returns the button bound. * Returns the button bound.
* *
* @return The bound button. * @return the bound button
*/ */
public int[] getButton() { public int[] getButton() {
return this.button; return this.button;
@@ -119,7 +119,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets the bound button. * Sets the bound button.
* *
* @param button The bound button. * @param button the bound button
*/ */
public void setButton(int[] button) { public void setButton(int[] button) {
this.button = button; this.button = button;
@@ -131,8 +131,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns whether the bound button is the specified button or not. * Returns whether the bound button is the specified button or not.
* *
* @param button The button to check. * @param button the button to check
* @return True if the bound button is the specified button, else false. * @return true if the bound button is the specified button, else false
*/ */
public boolean isButton(int[] button) { public boolean isButton(int[] button) {
return InputManager.areButtonsEquivalent(button, this.button); return InputManager.areButtonsEquivalent(button, this.button);
@@ -141,7 +141,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns whether this button is down or not. * 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() { public boolean isButtonDown() {
return this.pressed; return this.pressed;
@@ -150,7 +150,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns whether this button binding is bound or not. * 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() { public boolean isNotBound() {
return this.button.length == 0 || this.button[0] == -1; 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. * Gets the default button assigned to this binding.
* *
* @return The default button. * @return the default button
*/ */
public int[] getDefaultButton() { public int[] getDefaultButton() {
return this.defaultButton; return this.defaultButton;
@@ -168,7 +168,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns whether the assigned button is the default button. * 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() { public boolean isDefault() {
return this.button.length == this.defaultButton.length && InputManager.areButtonsEquivalent(this.button, this.defaultButton); 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. * Returns the button code.
* *
* @return The button code. * @return the button code
*/ */
public @NotNull public String getButtonCode() {
String getButtonCode() {
return Arrays.stream(this.button) return Arrays.stream(this.button)
.mapToObj(btn -> Integer.valueOf(btn).toString()) .mapToObj(btn -> Integer.valueOf(btn).toString())
.collect(Collectors.joining("+")); .collect(Collectors.joining("+"));
@@ -189,7 +188,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets the key binding to emulate with this button binding. * 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) { public void setKeyBinding(@Nullable KeyBinding keyBinding) {
this.mcKeyBinding = keyBinding; this.mcKeyBinding = keyBinding;
@@ -198,8 +197,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns whether the button binding is available in the current context. * Returns whether the button binding is available in the current context.
* *
* @param client The client instance. * @param client the client instance
* @return True if the button binding is available, else false. * @return true if the button binding is available, else false
*/ */
public boolean isAvailable(@NotNull MinecraftClient client) { public boolean isAvailable(@NotNull MinecraftClient client) {
return this.filter.test(client, this); return this.filter.test(client, this);
@@ -216,8 +215,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Handles the button binding. * Handles the button binding.
* *
* @param client The client instance. * @param client the client instance
* @param state The state. * @param state the state
*/ */
public void handle(@NotNull MinecraftClient client, float value, @NotNull ButtonState state) { public void handle(@NotNull MinecraftClient client, float value, @NotNull ButtonState state) {
if (state == ButtonState.REPEAT && this.hasCooldown && this.cooldown != 0) 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. * Returns the translation key of this button binding.
* *
* @return The translation key. * @return the translation key
*/ */
public @NotNull String getTranslationKey() { public @NotNull String getTranslationKey() {
return "lambdacontrols.action." + this.getName(); return "lambdacontrols.action." + this.getName();
@@ -252,7 +251,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns the key binding equivalent of this button binding. * Returns the key binding equivalent of this button binding.
* *
* @return The key binding equivalent. * @return the key binding equivalent
*/ */
public @NotNull Optional<KeyBinding> asKeyBinding() { public @NotNull Optional<KeyBinding> asKeyBinding() {
return Optional.ofNullable(this.mcKeyBinding); return Optional.ofNullable(this.mcKeyBinding);
@@ -268,9 +267,9 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns the specified axis as a button. * Returns the specified axis as a button.
* *
* @param axis The axis. * @param axis the axis
* @param positive True if the axis part is positive, else false. * @param positive true if the axis part is positive, else false
* @return The axis as a button. * @return the axis as a button
*/ */
public static int axisAsButton(int axis, boolean positive) { public static int axisAsButton(int axis, boolean positive) {
return positive ? 100 + axis : 200 + axis; 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. * Returns whether the specified button is an axis or not.
* *
* @param button The button. * @param button the button
* @return True if the button is an axis, else false. * @return true if the button is an axis, else false
*/ */
public static boolean isAxis(int button) { public static boolean isAxis(int button) {
button %= 500; button %= 500;
@@ -290,8 +289,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns the second Joycon's specified button code. * Returns the second Joycon's specified button code.
* *
* @param button The raw button code. * @param button the raw button code
* @return The second Joycon's button code. * @return the second Joycon's button code
*/ */
public static int controller2Button(int button) { public static int controller2Button(int button) {
return 500 + button; return 500 + button;
@@ -321,66 +320,39 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns the localized name of the specified button. * Returns the localized name of the specified button.
* *
* @param button The button. * @param button the button
* @return The localized name of the button. * @return the localized name of the button
*/ */
public static @NotNull Text getLocalizedButtonName(int button) { public static @NotNull Text getLocalizedButtonName(int button) {
switch (button % 500) { return switch (button % 500) {
case -1: case -1 -> new TranslatableText("key.keyboard.unknown");
return new TranslatableText("key.keyboard.unknown"); case GLFW_GAMEPAD_BUTTON_A -> new TranslatableText("lambdacontrols.button.a");
case GLFW_GAMEPAD_BUTTON_A: case GLFW_GAMEPAD_BUTTON_B -> new TranslatableText("lambdacontrols.button.b");
return new TranslatableText("lambdacontrols.button.a"); case GLFW_GAMEPAD_BUTTON_X -> new TranslatableText("lambdacontrols.button.x");
case GLFW_GAMEPAD_BUTTON_B: case GLFW_GAMEPAD_BUTTON_Y -> new TranslatableText("lambdacontrols.button.y");
return new TranslatableText("lambdacontrols.button.b"); case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> new TranslatableText("lambdacontrols.button.left_bumper");
case GLFW_GAMEPAD_BUTTON_X: case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> new TranslatableText("lambdacontrols.button.right_bumper");
return new TranslatableText("lambdacontrols.button.x"); case GLFW_GAMEPAD_BUTTON_BACK -> new TranslatableText("lambdacontrols.button.back");
case GLFW_GAMEPAD_BUTTON_Y: case GLFW_GAMEPAD_BUTTON_START -> new TranslatableText("lambdacontrols.button.start");
return new TranslatableText("lambdacontrols.button.y"); case GLFW_GAMEPAD_BUTTON_GUIDE -> new TranslatableText("lambdacontrols.button.guide");
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: case GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> new TranslatableText("lambdacontrols.button.left_thumb");
return new TranslatableText("lambdacontrols.button.left_bumper"); case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> new TranslatableText("lambdacontrols.button.right_thumb");
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: case GLFW_GAMEPAD_BUTTON_DPAD_UP -> new TranslatableText("lambdacontrols.button.dpad_up");
return new TranslatableText("lambdacontrols.button.right_bumper"); case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> new TranslatableText("lambdacontrols.button.dpad_right");
case GLFW_GAMEPAD_BUTTON_BACK: case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> new TranslatableText("lambdacontrols.button.dpad_down");
return new TranslatableText("lambdacontrols.button.back"); case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> new TranslatableText("lambdacontrols.button.dpad_left");
case GLFW_GAMEPAD_BUTTON_START: case 100 -> new TranslatableText("lambdacontrols.axis.left_x+");
return new TranslatableText("lambdacontrols.button.start"); case 101 -> new TranslatableText("lambdacontrols.axis.left_y+");
case GLFW_GAMEPAD_BUTTON_GUIDE: case 102 -> new TranslatableText("lambdacontrols.axis.right_x+");
return new TranslatableText("lambdacontrols.button.guide"); case 103 -> new TranslatableText("lambdacontrols.axis.right_y+");
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB: case 104 -> new TranslatableText("lambdacontrols.axis.left_trigger");
return new TranslatableText("lambdacontrols.button.left_thumb"); case 105 -> new TranslatableText("lambdacontrols.axis.right_trigger");
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: case 200 -> new TranslatableText("lambdacontrols.axis.left_x-");
return new TranslatableText("lambdacontrols.button.right_thumb"); case 201 -> new TranslatableText("lambdacontrols.axis.left_y-");
case GLFW_GAMEPAD_BUTTON_DPAD_UP: case 202 -> new TranslatableText("lambdacontrols.axis.right_x-");
return new TranslatableText("lambdacontrols.button.dpad_up"); case 203 -> new TranslatableText("lambdacontrols.axis.right_y-");
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: default -> new TranslatableText("lambdacontrols.button.unknown", button);
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);
}
} }
static { static {
@@ -416,8 +388,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns a builder instance. * Returns a builder instance.
* *
* @param identifier The identifier of the button binding. * @param identifier the identifier of the button binding
* @return The builder instance * @return the builder instanc
* @since 1.5.0 * @since 1.5.0
*/ */
public static Builder builder(@NotNull Identifier identifier) { public static Builder builder(@NotNull Identifier identifier) {
@@ -427,8 +399,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Returns a builder instance. * Returns a builder instance.
* *
* @param identifier The identifier of the button binding. * @param identifier the identifier of the button binding
* @return The builder instance. * @return the builder instance
* @since 1.5.0 * @since 1.5.0
*/ */
public static Builder builder(@NotNull net.minecraft.util.Identifier identifier) { public static Builder builder(@NotNull net.minecraft.util.Identifier identifier) {
@@ -446,7 +418,7 @@ public class ButtonBinding implements Nameable {
public static class Builder { public static class Builder {
private final String key; private final String key;
private int[] buttons = new int[0]; 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 PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue();
private boolean cooldown = false; private boolean cooldown = false;
private ButtonCategory category = null; private ButtonCategory category = null;
@@ -455,7 +427,7 @@ public class ButtonBinding implements Nameable {
/** /**
* This constructor shouldn't be used for other mods. * 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) { public Builder(@NotNull String key) {
this.key = key; this.key = key;
@@ -473,8 +445,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Defines the default buttons of the {@link ButtonBinding}. * Defines the default buttons of the {@link ButtonBinding}.
* *
* @param buttons The default buttons. * @param buttons the default buttons
* @return The builder instance. * @return the builder instance
*/ */
public Builder buttons(int... buttons) { public Builder buttons(int... buttons) {
this.buttons = buttons; this.buttons = buttons;
@@ -484,7 +456,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets the {@link ButtonBinding} to unbound. * Sets the {@link ButtonBinding} to unbound.
* *
* @return The builder instance. * @return the builder instance
*/ */
public Builder unbound() { public Builder unbound() {
return this.buttons(-1); return this.buttons(-1);
@@ -493,8 +465,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Adds the actions to the {@link ButtonBinding}. * Adds the actions to the {@link ButtonBinding}.
* *
* @param actions The actions to add. * @param actions the actions to add
* @return The builder instance. * @return the builder instance
*/ */
public Builder actions(@NotNull PressAction... actions) { public Builder actions(@NotNull PressAction... actions) {
this.actions.addAll(Arrays.asList(actions)); this.actions.addAll(Arrays.asList(actions));
@@ -504,8 +476,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Adds an action to the {@link ButtonBinding}. * Adds an action to the {@link ButtonBinding}.
* *
* @param action The action to add. * @param action the action to add
* @return The builder instance. * @return the builder instance
*/ */
public Builder action(@NotNull PressAction action) { public Builder action(@NotNull PressAction action) {
this.actions.add(action); this.actions.add(action);
@@ -515,8 +487,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets a filter for the {@link ButtonBinding}. * Sets a filter for the {@link ButtonBinding}.
* *
* @param filter The filter. * @param filter the filter
* @return The builder instance. * @return the builder instance
*/ */
public Builder filter(@NotNull PairPredicate<MinecraftClient, ButtonBinding> filter) { public Builder filter(@NotNull PairPredicate<MinecraftClient, ButtonBinding> filter) {
this.filter = filter; this.filter = filter;
@@ -526,7 +498,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets the filter of {@link ButtonBinding} to only in game. * Sets the filter of {@link ButtonBinding} to only in game.
* *
* @return The builder instance. * @return the builder instance
* @see #filter(PairPredicate) * @see #filter(PairPredicate)
* @see InputHandlers#inGame(MinecraftClient, ButtonBinding) * @see InputHandlers#inGame(MinecraftClient, ButtonBinding)
*/ */
@@ -537,7 +509,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets the filter of {@link ButtonBinding} to only in inventory. * Sets the filter of {@link ButtonBinding} to only in inventory.
* *
* @return The builder instance. * @return the builder instance
* @see #filter(PairPredicate) * @see #filter(PairPredicate)
* @see InputHandlers#inInventory(MinecraftClient, ButtonBinding) * @see InputHandlers#inInventory(MinecraftClient, ButtonBinding)
*/ */
@@ -548,8 +520,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets whether the {@link ButtonBinding} has a cooldown or not. * Sets whether the {@link ButtonBinding} has a cooldown or not.
* *
* @param cooldown True if the {@link ButtonBinding} has a cooldown, else false. * @param cooldown true if the {@link ButtonBinding} has a cooldown, else false
* @return The builder instance. * @return the builder instance
*/ */
public Builder cooldown(boolean cooldown) { public Builder cooldown(boolean cooldown) {
this.cooldown = cooldown; this.cooldown = cooldown;
@@ -559,7 +531,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Puts a cooldown on the {@link ButtonBinding}. * Puts a cooldown on the {@link ButtonBinding}.
* *
* @return The builder instance. * @return the builder instance
* @since 1.5.0 * @since 1.5.0
*/ */
public Builder cooldown() { public Builder cooldown() {
@@ -569,8 +541,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets the category of the {@link ButtonBinding}. * Sets the category of the {@link ButtonBinding}.
* *
* @param category The category. * @param category the category
* @return The builder instance. * @return the builder instance
*/ */
public Builder category(@Nullable ButtonCategory category) { public Builder category(@Nullable ButtonCategory category) {
this.category = category; this.category = category;
@@ -580,8 +552,8 @@ public class ButtonBinding implements Nameable {
/** /**
* Sets the keybinding linked to the {@link ButtonBinding}. * Sets the keybinding linked to the {@link ButtonBinding}.
* *
* @param binding The keybinding to link. * @param binding the keybinding to link
* @return The builder instance. * @return the builder instance
*/ */
public Builder linkKeybind(@Nullable KeyBinding binding) { public Builder linkKeybind(@Nullable KeyBinding binding) {
this.mcBinding = binding; this.mcBinding = binding;
@@ -591,10 +563,10 @@ public class ButtonBinding implements Nameable {
/** /**
* Builds the {@link ButtonBinding}. * Builds the {@link ButtonBinding}.
* *
* @return The built {@link ButtonBinding}. * @return the built {@link ButtonBinding}
*/ */
public ButtonBinding build() { 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) if (this.category != null)
this.category.registerBinding(binding); this.category.registerBinding(binding);
if (this.mcBinding != null) if (this.mcBinding != null)
@@ -605,7 +577,7 @@ public class ButtonBinding implements Nameable {
/** /**
* Builds and registers the {@link ButtonBinding}. * Builds and registers the {@link ButtonBinding}.
* *
* @return The built {@link ButtonBinding}. * @return the built {@link ButtonBinding}
* @see #build() * @see #build()
*/ */
public ButtonBinding register() { public ButtonBinding register() {

View File

@@ -29,7 +29,7 @@ import java.util.List;
public class ButtonCategory implements Identifiable { public class ButtonCategory implements Identifiable {
private final List<ButtonBinding> bindings = new ArrayList<>(); private final List<ButtonBinding> bindings = new ArrayList<>();
private final Identifier id; private final Identifier id;
private int priority; private final int priority;
public ButtonCategory(@NotNull Identifier id, int priority) { public ButtonCategory(@NotNull Identifier id, int priority) {
this.id = id; this.id = id;
@@ -57,7 +57,7 @@ public class ButtonCategory implements Identifiable {
/** /**
* Gets the bindings assigned to this category. * 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() { public @NotNull List<ButtonBinding> getBindings() {
return Collections.unmodifiableList(this.bindings); return Collections.unmodifiableList(this.bindings);
@@ -68,7 +68,7 @@ public class ButtonCategory implements Identifiable {
* <p> * <p>
* The translation key should be `modid.identifier_name`. * The translation key should be `modid.identifier_name`.
* *
* @return The translated name. * @return the translated name
*/ */
public @NotNull String getTranslatedName() { public @NotNull String getTranslatedName() {
if (this.id.getNamespace().equals("minecraft")) if (this.id.getNamespace().equals("minecraft"))
@@ -81,7 +81,7 @@ public class ButtonCategory implements Identifiable {
* Gets the priority display of this category. * Gets the priority display of this category.
* It will defines in which order the categories will display on the controls screen. * 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() { public int getPriority() {
return this.priority; return this.priority;

View File

@@ -17,18 +17,14 @@ import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.Nameable; import org.aperlambda.lambdacommon.utils.Nameable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWGamepadState; import org.lwjgl.glfw.GLFWGamepadState;
import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import java.io.IOException; import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
@@ -41,30 +37,16 @@ import static org.lwjgl.BufferUtils.createByteBuffer;
* Represents a controller. * Represents a controller.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.4.3 * @version 1.7.0
* @since 1.0.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 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. * Gets the controller's globally unique identifier.
* *
* @return The controller's GUID. * @return the controller's GUID
*/ */
public String getGuid() { public String getGuid() {
String guid = GLFW.glfwGetJoystickGUID(this.id); String guid = GLFW.glfwGetJoystickGUID(this.id);
@@ -74,7 +56,7 @@ public class Controller implements Nameable {
/** /**
* Returns whether this controller is connected or not. * 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() { public boolean isConnected() {
return GLFW.glfwJoystickPresent(this.id); return GLFW.glfwJoystickPresent(this.id);
@@ -83,7 +65,7 @@ public class Controller implements Nameable {
/** /**
* Returns whether this controller is a gamepad or not. * 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() { public boolean isGamepad() {
return this.isConnected() && GLFW.glfwJoystickIsGamepad(this.id); return this.isConnected() && GLFW.glfwJoystickIsGamepad(this.id);
@@ -92,27 +74,27 @@ public class Controller implements Nameable {
/** /**
* Gets the name of the controller. * Gets the name of the controller.
* *
* @return The controller's name. * @return the controller's name
*/ */
@Override @Override
public @NotNull String getName() { public String getName() {
String name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id); var name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id);
return name == null ? String.valueOf(this.getId()) : name; return name == null ? String.valueOf(this.id()) : name;
} }
/** /**
* Gets the state of the controller. * Gets the state of the controller.
* *
* @return The state of the controller input. * @return the state of the controller input
*/ */
public GLFWGamepadState getState() { public GLFWGamepadState getState() {
GLFWGamepadState state = GLFWGamepadState.create(); var state = GLFWGamepadState.create();
if (this.isGamepad()) if (this.isGamepad())
GLFW.glfwGetGamepadState(this.id, state); GLFW.glfwGetGamepadState(this.id, state);
return state; return state;
} }
public static @NotNull Controller byId(int id) { public static Controller byId(int id) {
if (id > GLFW.GLFW_JOYSTICK_LAST) { if (id > GLFW.GLFW_JOYSTICK_LAST) {
LambdaControlsClient.get().log("Controller '" + id + "' doesn't exist."); LambdaControlsClient.get().log("Controller '" + id + "' doesn't exist.");
id = GLFW.GLFW_JOYSTICK_LAST; 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) return CONTROLLERS.values().stream().filter(Controller::isConnected)
.filter(controller -> controller.getGuid().equals(guid)) .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. * Reads the specified resource and returns the raw data as a ByteBuffer.
* *
* @param resource The resource to read. * @param resource the resource to read
* @param bufferSize The initial buffer size. * @param bufferSize the initial buffer size
* @return The resource data. * @return the resource data
* @throws IOException If an IO error occurs. * @throws IOException If an IO error occurs.
*/ */
private static ByteBuffer ioResourceToBuffer(String resource, int bufferSize) throws IOException { private static ByteBuffer ioResourceToBuffer(String resource, int bufferSize) throws IOException {
ByteBuffer buffer = null; ByteBuffer buffer = null;
Path path = Paths.get(resource); var path = Paths.get(resource);
if (Files.isReadable(path)) { if (Files.isReadable(path)) {
try (SeekableByteChannel fc = Files.newByteChannel(path)) { try (var fc = Files.newByteChannel(path)) {
buffer = createByteBuffer((int) fc.size() + 2); buffer = createByteBuffer((int) fc.size() + 2);
while (fc.read(buffer) != -1) ; while (fc.read(buffer) != -1) ;
buffer.put((byte) 0); buffer.put((byte) 0);
} }
} }
((Buffer) buffer).flip(); // Force Java 8 >.< buffer.flip(); // Force Java 8 >.<
return buffer; return buffer;
} }
@@ -165,20 +147,19 @@ public class Controller implements Nameable {
if (!LambdaControlsClient.MAPPINGS_FILE.exists()) if (!LambdaControlsClient.MAPPINGS_FILE.exists())
return; return;
LambdaControlsClient.get().log("Updating controller mappings..."); 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); GLFW.glfwUpdateGamepadMappings(buffer);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
MemoryStack memoryStack = MemoryStack.stackPush(); try (var memoryStack = MemoryStack.stackPush()) {
try { var pointerBuffer = memoryStack.mallocPointer(1);
PointerBuffer pointerBuffer = memoryStack.mallocPointer(1);
int i = GLFW.glfwGetError(pointerBuffer); int i = GLFW.glfwGetError(pointerBuffer);
if (i != 0) { if (i != 0) {
long l = pointerBuffer.get(); long l = pointerBuffer.get();
String string = l == 0L ? "" : MemoryUtil.memUTF8(l); var string = l == 0L ? "" : MemoryUtil.memUTF8(l);
MinecraftClient client = MinecraftClient.getInstance(); var client = MinecraftClient.getInstance();
if (client != null) { if (client != null) {
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT, client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT,
new TranslatableText("lambdacontrols.controller.mappings.error"), new LiteralText(string))); new TranslatableText("lambdacontrols.controller.mappings.error"), new LiteralText(string)));
@@ -186,13 +167,11 @@ public class Controller implements Nameable {
} }
} catch (Throwable e) { } catch (Throwable e) {
/* Ignored :concern: */ /* Ignored :concern: */
} finally {
memoryStack.close();
} }
if (LambdaControlsClient.get().config.hasDebug()) { if (LambdaControlsClient.get().config.hasDebug()) {
for (int i = GLFW.GLFW_JOYSTICK_1; i <= GLFW.GLFW_JOYSTICK_16; i++) { for (int i = GLFW.GLFW_JOYSTICK_1; i <= GLFW.GLFW_JOYSTICK_16; i++) {
Controller controller = byId(i); var controller = byId(i);
if (!controller.isConnected()) if (!controller.isConnected())
continue; continue;

View File

@@ -16,20 +16,16 @@ import dev.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccess
import dev.lambdaurora.lambdacontrols.client.mixin.RecipeBookWidgetAccessor; import dev.lambdaurora.lambdacontrols.client.mixin.RecipeBookWidgetAccessor;
import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor; import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
import net.minecraft.client.MinecraftClient; 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.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.HandledScreen;
import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import net.minecraft.client.util.ScreenshotRecorder;
import net.minecraft.client.util.ScreenshotUtils;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import org.aperlambda.lambdacommon.utils.Pair; import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -38,7 +34,7 @@ import java.util.stream.Collectors;
* Represents some input handlers. * Represents some input handlers.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.4.3 * @version 1.7.0
* @since 1.1.0 * @since 1.1.0
*/ */
public class InputHandlers { public class InputHandlers {
@@ -53,12 +49,11 @@ public class InputHandlers {
// When ingame // When ingame
if (client.currentScreen == null && client.player != null) { if (client.currentScreen == null && client.player != null) {
if (next) 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 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; return true;
} else if (client.currentScreen instanceof CreativeInventoryScreen) { } else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) {
CreativeInventoryScreenAccessor inventory = (CreativeInventoryScreenAccessor) client.currentScreen;
int currentTab = inventory.getSelectedTab(); int currentTab = inventory.getSelectedTab();
int nextTab = currentTab + (next ? 1 : -1); int nextTab = currentTab + (next ? 1 : -1);
if (nextTab < 0) if (nextTab < 0)
@@ -67,10 +62,10 @@ public class InputHandlers {
nextTab = 0; nextTab = 0;
inventory.lambdacontrols$setSelectedTab(ItemGroup.GROUPS[nextTab]); inventory.lambdacontrols$setSelectedTab(ItemGroup.GROUPS[nextTab]);
return true; return true;
} else if (client.currentScreen instanceof InventoryScreen) { } else if (client.currentScreen instanceof InventoryScreen inventoryScreen) {
RecipeBookWidgetAccessor recipeBook = (RecipeBookWidgetAccessor) ((InventoryScreen) client.currentScreen).getRecipeBookWidget(); var recipeBook = (RecipeBookWidgetAccessor) inventoryScreen.getRecipeBookWidget();
List<RecipeGroupButtonWidget> tabs = recipeBook.getTabButtons(); var tabs = recipeBook.getTabButtons();
RecipeGroupButtonWidget currentTab = recipeBook.getCurrentTab(); var currentTab = recipeBook.getCurrentTab();
if (currentTab == null) if (currentTab == null)
return false; return false;
int nextTab = tabs.indexOf(currentTab) + (next ? 1 : -1); int nextTab = tabs.indexOf(currentTab) + (next ? 1 : -1);
@@ -83,10 +78,9 @@ public class InputHandlers {
currentTab.setToggled(true); currentTab.setToggled(true);
recipeBook.lambdacontrols$refreshResults(true); recipeBook.lambdacontrols$refreshResults(true);
return true; return true;
} else if (client.currentScreen instanceof AdvancementsScreen) { } else if (client.currentScreen instanceof AdvancementsScreenAccessor screen) {
AdvancementsScreenAccessor screen = (AdvancementsScreenAccessor) client.currentScreen; var tabs = screen.getTabs().values().stream().distinct().collect(Collectors.toList());
List<AdvancementTab> tabs = screen.getTabs().values().stream().distinct().collect(Collectors.toList()); var tab = screen.getSelectedTab();
AdvancementTab tab = screen.getSelectedTab();
if (tab == null) if (tab == null)
return false; return false;
for (int i = 0; i < tabs.size(); i++) { for (int i = 0; i < tabs.size(); i++) {
@@ -122,14 +116,14 @@ public class InputHandlers {
/** /**
* Handles the screenshot action. * Handles the screenshot action.
* *
* @param client The client instance. * @param client the client instance
* @param binding The binding which fired the action. * @param binding the binding which fired the action
* @param action The action done on the binding. * @param action the action done on the binding
* @return True if handled, else false. * @return true if handled, else false
*/ */
public static boolean handleScreenshot(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, float value, @NotNull ButtonState action) { public static boolean handleScreenshot(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, float value, @NotNull ButtonState action) {
if (action == ButtonState.RELEASE) 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))); text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)));
return true; return true;
} }
@@ -137,10 +131,10 @@ public class InputHandlers {
public static boolean handleToggleSneak(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action) { public static boolean handleToggleSneak(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action) {
button.asKeyBinding().ifPresent(binding -> { button.asKeyBinding().ifPresent(binding -> {
boolean sneakToggled = client.options.sneakToggled; boolean sneakToggled = client.options.sneakToggled;
if (client.player.abilities.flying && sneakToggled) if (client.player.getAbilities().flying && sneakToggled)
client.options.sneakToggled = false; client.options.sneakToggled = false;
binding.setPressed(button.pressed); binding.setPressed(button.pressed);
if (client.player.abilities.flying && sneakToggled) if (client.player.getAbilities().flying && sneakToggled)
client.options.sneakToggled = true; client.options.sneakToggled = true;
}); });
return true; return true;
@@ -148,18 +142,17 @@ public class InputHandlers {
public static PressAction handleInventorySlotPad(int direction) { public static PressAction handleInventorySlotPad(int direction) {
return (client, binding, value, action) -> { return (client, binding, value, action) -> {
if (!(client.currentScreen instanceof HandledScreen && action != ButtonState.RELEASE)) if (!(client.currentScreen instanceof HandledScreen inventory && action != ButtonState.RELEASE))
return false; return false;
HandledScreen inventory = (HandledScreen) client.currentScreen; var accessor = (HandledScreenAccessor) inventory;
HandledScreenAccessor accessor = (HandledScreenAccessor) inventory;
int guiLeft = accessor.getX(); int guiLeft = accessor.getX();
int guiTop = accessor.getY(); int guiTop = accessor.getY();
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
// Finds the hovered slot. // 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. // Finds the closest slot in the GUI within 14 pixels.
Optional<Slot> closestSlot = inventory.getScreenHandler().slots.parallelStream() 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)); double distance = Math.sqrt(Math.pow(posX - otherPosX, 2) + Math.pow(posY - otherPosY, 2));
return Pair.of(slot, distance); return Pair.of(slot, distance);
}).filter(entry -> { }).filter(entry -> {
Slot slot = entry.key; var slot = entry.key;
int posX = guiLeft + slot.x + 8; int posX = guiLeft + slot.x + 8;
int posY = guiTop + slot.y + 8; int posY = guiTop + slot.y + 8;
int otherPosX = (int) mouseX; int otherPosX = (int) mouseX;
@@ -203,7 +196,7 @@ public class InputHandlers {
.map(p -> p.key); .map(p -> p.key);
if (closestSlot.isPresent()) { if (closestSlot.isPresent()) {
Slot slot = closestSlot.get(); var slot = closestSlot.get();
int x = guiLeft + slot.x + 8; int x = guiLeft + slot.x + 8;
int y = guiTop + slot.y + 8; int y = guiTop + slot.y + 8;
InputManager.queueMousePosition(x * (double) client.getWindow().getWidth() / (double) client.getWindow().getScaledWidth(), InputManager.queueMousePosition(x * (double) client.getWindow().getWidth() / (double) client.getWindow().getScaledWidth(),
@@ -217,9 +210,9 @@ public class InputHandlers {
/** /**
* Returns always true to the filter. * Returns always true to the filter.
* *
* @param client The client instance. * @param client the client instance
* @param binding The affected binding. * @param binding the affected binding
* @return True. * @return true
*/ */
public static boolean always(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { public static boolean always(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
return true; return true;
@@ -228,9 +221,9 @@ public class InputHandlers {
/** /**
* Returns whether the client is in game or not. * Returns whether the client is in game or not.
* *
* @param client The client instance. * @param client the client instance
* @param binding The affected binding. * @param binding the affected binding
* @return True if the client is in game, else false. * @return true if the client is in game, else false
*/ */
public static boolean inGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { public static boolean inGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
return client.currentScreen == null; return client.currentScreen == null;
@@ -239,9 +232,9 @@ public class InputHandlers {
/** /**
* Returns whether the client is in a non-interactive screen (which means require mouse input) or not. * Returns whether the client is in a non-interactive screen (which means require mouse input) or not.
* *
* @param client The client instance. * @param client the client instance
* @param binding The affected binding. * @param binding the affected binding
* @return True if the client is in a non-interactive screen, else false. * @return true if the client is in a non-interactive screen, else false
*/ */
public static boolean inNonInteractiveScreens(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { public static boolean inNonInteractiveScreens(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
if (client.currentScreen == null) if (client.currentScreen == null)
@@ -252,9 +245,9 @@ public class InputHandlers {
/** /**
* Returns whether the client is in an inventory or not. * Returns whether the client is in an inventory or not.
* *
* @param client The client instance. * @param client the client instance
* @param binding The affected binding. * @param binding the affected binding
* @return True if the client is in an inventory, else false. * @return true if the client is in an inventory, else false
*/ */
public static boolean inInventory(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { public static boolean inInventory(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
return client.currentScreen instanceof HandledScreen; return client.currentScreen instanceof HandledScreen;
@@ -263,9 +256,9 @@ public class InputHandlers {
/** /**
* Returns whether the client is in the advancements screen or not. * Returns whether the client is in the advancements screen or not.
* *
* @param client The client instance. * @param client the client instance
* @param binding The affected binding. * @param binding the affected binding
* @return True if the client is in the advancements screen, else false. * @return true if the client is in the advancements screen, else false
*/ */
public static boolean inAdvancements(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { public static boolean inAdvancements(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) {
return client.currentScreen instanceof AdvancementsScreen; return client.currentScreen instanceof AdvancementsScreen;

View File

@@ -14,12 +14,13 @@ import dev.lambdaurora.lambdacontrols.client.ButtonState;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig; import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig;
import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor; 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.MinecraftClient;
import net.minecraft.client.options.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil; import net.minecraft.client.util.InputUtil;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.aperlambda.lambdacommon.Identifier; import org.aperlambda.lambdacommon.Identifier;
import org.aperlambda.lambdacommon.utils.Pair;
import org.aperlambda.lambdacommon.utils.function.PairPredicate; import org.aperlambda.lambdacommon.utils.function.PairPredicate;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@@ -33,15 +34,15 @@ import java.util.stream.Stream;
* Represents an input manager for controllers. * Represents an input manager for controllers.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.4.0 * @version 1.7.0
* @since 1.1.0 * @since 1.1.0
*/ */
public class InputManager { public class InputManager {
public static final InputManager INPUT_MANAGER = new InputManager(); public static final InputManager INPUT_MANAGER = new InputManager();
private static final List<ButtonBinding> BINDINGS = new ArrayList<>(); private static final List<ButtonBinding> BINDINGS = new ArrayList<>();
private static final List<ButtonCategory> CATEGORIES = new ArrayList<>(); private static final List<ButtonCategory> CATEGORIES = new ArrayList<>();
public static final Map<Integer, ButtonState> STATES = new HashMap<>(); public static final Int2ObjectMap<ButtonState> STATES = new Int2ObjectOpenHashMap<>();
public static final Map<Integer, Float> BUTTON_VALUES = new HashMap<>(); public static final Int2FloatMap BUTTON_VALUES = new Int2FloatOpenHashMap();
private int prevTargetMouseX = 0; private int prevTargetMouseX = 0;
private int prevTargetMouseY = 0; private int prevTargetMouseY = 0;
private int targetMouseX = 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. * 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) { public void updateMousePosition(@NotNull MinecraftClient client) {
Objects.requireNonNull(client, "Client instance cannot be null."); Objects.requireNonNull(client, "Client instance cannot be null.");
@@ -80,8 +81,8 @@ public class InputManager {
/** /**
* Resets the mouse position. * Resets the mouse position.
* *
* @param windowWidth The window width. * @param windowWidth the window width
* @param windowHeight The window height. * @param windowHeight the window height
*/ */
public void resetMousePosition(int windowWidth, int windowHeight) { public void resetMousePosition(int windowWidth, int windowHeight) {
this.targetMouseX = this.prevTargetMouseX = (int) (windowWidth / 2.F); this.targetMouseX = this.prevTargetMouseX = (int) (windowWidth / 2.F);
@@ -98,8 +99,8 @@ public class InputManager {
/** /**
* Returns whether the specified binding is registered or not. * Returns whether the specified binding is registered or not.
* *
* @param binding The binding to check. * @param binding the binding to check
* @return True if the binding is registered, else false. * @return true if the binding is registered, else false
*/ */
public static boolean hasBinding(@NotNull ButtonBinding binding) { public static boolean hasBinding(@NotNull ButtonBinding binding) {
return BINDINGS.contains(binding); return BINDINGS.contains(binding);
@@ -108,8 +109,8 @@ public class InputManager {
/** /**
* Returns whether the specified binding is registered or not. * Returns whether the specified binding is registered or not.
* *
* @param name The name of the binding to check. * @param name the name of the binding to check
* @return True if the binding is registered, else false. * @return true if the binding is registered, else false
*/ */
public static boolean hasBinding(@NotNull String name) { public static boolean hasBinding(@NotNull String name) {
return BINDINGS.parallelStream().map(ButtonBinding::getName).anyMatch(binding -> binding.equalsIgnoreCase(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. * Returns whether the specified binding is registered or not.
* *
* @param identifier The identifier of the binding to check. * @param identifier the identifier of the binding to check
* @return True if the binding is registered, else false. * @return true if the binding is registered, else false
*/ */
public static boolean hasBinding(@NotNull Identifier identifier) { public static boolean hasBinding(@NotNull Identifier identifier) {
return hasBinding(identifier.getNamespace() + "." + identifier.getName()); return hasBinding(identifier.getNamespace() + "." + identifier.getName());
@@ -128,8 +129,8 @@ public class InputManager {
/** /**
* Registers a button binding. * Registers a button binding.
* *
* @param binding The binding to register. * @param binding the binding to register
* @return The registered binding. * @return the registered binding
*/ */
public static @NotNull ButtonBinding registerBinding(@NotNull ButtonBinding binding) { public static @NotNull ButtonBinding registerBinding(@NotNull ButtonBinding binding) {
if (hasBinding(binding)) if (hasBinding(binding))
@@ -159,7 +160,8 @@ public class InputManager {
*/ */
public static void sortBindings() { public static void sortBindings() {
synchronized (BINDINGS) { 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()); .collect(Collectors.toList());
BINDINGS.clear(); BINDINGS.clear();
BINDINGS.addAll(sorted); BINDINGS.addAll(sorted);
@@ -169,8 +171,8 @@ public class InputManager {
/** /**
* Registers a category of button bindings. * Registers a category of button bindings.
* *
* @param category The category to register. * @param category the category to register
* @return The registered category. * @return the registered category
*/ */
public static ButtonCategory registerCategory(@NotNull ButtonCategory category) { public static ButtonCategory registerCategory(@NotNull ButtonCategory category) {
CATEGORIES.add(category); CATEGORIES.add(category);
@@ -186,7 +188,7 @@ public class InputManager {
} }
protected static ButtonCategory registerDefaultCategory(@NotNull String key, @NotNull Consumer<ButtonCategory> keyAdder) { 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); keyAdder.accept(category);
return category; return category;
} }
@@ -194,23 +196,23 @@ public class InputManager {
/** /**
* Loads the button bindings from configuration. * Loads the button bindings from configuration.
* *
* @param config The configuration instance. * @param config the configuration instance
*/ */
public static void loadButtonBindings(@NotNull LambdaControlsConfig config) { public static void loadButtonBindings(@NotNull LambdaControlsConfig config) {
List<ButtonBinding> queue = new ArrayList<>(BINDINGS); var queue = new ArrayList<>(BINDINGS);
queue.forEach(config::loadButtonBinding); queue.forEach(config::loadButtonBinding);
} }
/** /**
* Returns the binding state. * Returns the binding state.
* *
* @param binding The binding. * @param binding the binding
* @return The current state of the binding. * @return the current state of the binding
*/ */
public static @NotNull ButtonState getBindingState(@NotNull ButtonBinding binding) { public static @NotNull ButtonState getBindingState(@NotNull ButtonBinding binding) {
ButtonState state = ButtonState.REPEAT; var state = ButtonState.REPEAT;
for (int btn : binding.getButton()) { 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) if (btnState == ButtonState.PRESS)
state = ButtonState.PRESS; state = ButtonState.PRESS;
else if (btnState == ButtonState.RELEASE) { else if (btnState == ButtonState.RELEASE) {
@@ -243,8 +245,8 @@ public class InputManager {
/** /**
* Returns whether the button has duplicated bindings. * Returns whether the button has duplicated bindings.
* *
* @param button The button to check. * @param button the button to check
* @return True if the button has duplicated bindings, else false. * @return true if the button has duplicated bindings, else false
*/ */
public static boolean hasDuplicatedBindings(int[] button) { public static boolean hasDuplicatedBindings(int[] button) {
return BINDINGS.parallelStream().filter(binding -> areButtonsEquivalent(binding.getButton(), button)).count() > 1; 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. * Returns whether the button has duplicated bindings.
* *
* @param binding The binding to check. * @param binding the binding to check
* @return True if the button has duplicated bindings, else false. * @return true if the button has duplicated bindings, else false
*/ */
public static boolean hasDuplicatedBindings(ButtonBinding binding) { public static boolean hasDuplicatedBindings(ButtonBinding binding) {
return BINDINGS.parallelStream().filter(other -> areButtonsEquivalent(other.getButton(), binding.getButton()) && other.filter.equals(binding.filter)).count() > 1; 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. * Returns whether the specified buttons are equivalent or not.
* *
* @param buttons1 First set of buttons. * @param buttons1 first set of buttons
* @param buttons2 Second set of buttons. * @param buttons2 second set of buttons
* @return True if the two sets of buttons are equivalent, else false. * @return true if the two sets of buttons are equivalent, else false
*/ */
public static boolean areButtonsEquivalent(int[] buttons1, int[] buttons2) { public static boolean areButtonsEquivalent(int[] buttons1, int[] buttons2) {
if (buttons1.length != buttons2.length) if (buttons1.length != buttons2.length)
@@ -285,9 +287,9 @@ public class InputManager {
/** /**
* Returns whether the button set contains the specified button or not. * Returns whether the button set contains the specified button or not.
* *
* @param buttons The button set. * @param buttons the button set
* @param button The button to check. * @param button the button to check
* @return True if the button set contains the specified button, else false. * @return true if the button set contains the specified button, else false
*/ */
public static boolean containsButton(int[] buttons, int button) { public static boolean containsButton(int[] buttons, int button) {
return Arrays.stream(buttons).anyMatch(btn -> btn == button); return Arrays.stream(buttons).anyMatch(btn -> btn == button);
@@ -297,19 +299,21 @@ public class InputManager {
* Updates the button states. * Updates the button states.
*/ */
public static void updateStates() { public static void updateStates() {
STATES.forEach((btn, state) -> { for (var entry : STATES.int2ObjectEntrySet()) {
if (state == ButtonState.PRESS) if (entry.getValue() == ButtonState.PRESS)
STATES.put(btn, ButtonState.REPEAT); STATES.put(entry.getIntKey(), ButtonState.REPEAT);
else if (state == ButtonState.RELEASE) else if (entry.getValue() == ButtonState.RELEASE)
STATES.put(btn, ButtonState.NONE); STATES.put(entry.getIntKey(), ButtonState.NONE);
}); }
} }
public static void updateBindings(@NotNull MinecraftClient client) { public static void updateBindings(@NotNull MinecraftClient client) {
List<Integer> skipButtons = new ArrayList<>(); var skipButtons = new IntArrayList();
Map<ButtonBinding, Pair<ButtonState, Float>> states = new HashMap<>(); record ButtonStateValue(ButtonState state, float value) {
for (ButtonBinding binding : BINDINGS) { }
ButtonState state = binding.isAvailable(client) ? getBindingState(binding) : ButtonState.NONE; 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 (skipButtons.stream().anyMatch(btn -> containsButton(binding.getButton(), btn))) {
if (binding.pressed) if (binding.pressed)
state = ButtonState.RELEASE; state = ButtonState.RELEASE;
@@ -328,12 +332,12 @@ public class InputManager {
float value = getBindingValue(binding, state); float value = getBindingValue(binding, state);
states.put(binding, Pair.of(state, value)); states.put(binding, new ButtonStateValue(state, value));
} }
states.forEach((binding, state) -> { states.forEach((binding, state) -> {
if (state.key != ButtonState.NONE) { if (state.state() != ButtonState.NONE) {
binding.handle(client, state.value, state.key); binding.handle(client, state.value(), state.state());
} }
}); });
} }
@@ -358,11 +362,11 @@ public class InputManager {
/** /**
* Returns a new key binding instance. * Returns a new key binding instance.
* *
* @param id The identifier of the key binding. * @param id the identifier of the key binding
* @param type The type. * @param type the type
* @param code The code. * @param code the code
* @param category The category of the key binding. * @param category the category of the key binding
* @return The key binding. * @return the key binding
* @see #makeKeyBinding(Identifier, InputUtil.Type, int, String) * @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) { 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. * Returns a new key binding instance.
* *
* @param id The identifier of the key binding. * @param id the identifier of the key binding
* @param type The type. * @param type the type
* @param code The code. * @param code the code
* @param category The category of the key binding. * @param category the category of the key binding
* @return The key binding. * @return the key binding
* @see #makeKeyBinding(net.minecraft.util.Identifier, InputUtil.Type, int, String) * @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) { public static @NotNull KeyBinding makeKeyBinding(@NotNull Identifier id, InputUtil.Type type, int code, @NotNull String category) {

View File

@@ -12,14 +12,14 @@ package dev.lambdaurora.lambdacontrols.client.controller;
import dev.lambdaurora.lambdacontrols.client.ButtonState; import dev.lambdaurora.lambdacontrols.client.ButtonState;
import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.options.StickyKeyBinding; import net.minecraft.client.option.StickyKeyBinding;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Represents a press action callback. * Represents a press action callback.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.4.3 * @version 1.7.0
* @since 1.0.0 * @since 1.0.0
*/ */
@FunctionalInterface @FunctionalInterface
@@ -31,7 +31,7 @@ public interface PressAction {
if (binding instanceof StickyKeyBinding) if (binding instanceof StickyKeyBinding)
binding.setPressed(button.pressed); binding.setPressed(button.pressed);
else else
((KeyBindingAccessor) binding).lambdacontrols_handlePressState(button.isButtonDown()); ((KeyBindingAccessor) binding).lambdacontrols$handlePressState(button.isButtonDown());
}); });
return true; return true;
}; };
@@ -39,8 +39,8 @@ public interface PressAction {
/** /**
* Handles when there is a press action. * Handles when there is a press action.
* *
* @param client The client instance. * @param client the client instance
* @param action The action done. * @param action the action done
*/ */
boolean press(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action); boolean press(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action);
} }

View File

@@ -15,10 +15,9 @@ import dev.lambdaurora.lambdacontrols.client.HudSide;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; import dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat;
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; 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.MinecraftClient;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.Window;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -32,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
* Represents the LambdaControls HUD. * Represents the LambdaControls HUD.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.3.2 * @version 1.7.0
* @since 1.0.0 * @since 1.0.0
*/ */
public class LambdaControlsHud extends Hud { public class LambdaControlsHud extends Hud {
@@ -87,8 +86,8 @@ public class LambdaControlsHud extends Hud {
if (this.mod.reacharound.isLastReacharoundVertical()) { if (this.mod.reacharound.isLastReacharoundVertical()) {
// Render crosshair indicator. // Render crosshair indicator.
Window window = this.client.getWindow(); var window = this.client.getWindow();
String text = "[ ]"; var text = "[ ]";
float scale = Math.min(5, this.ticksDisplayedCrosshair + tickDelta) / 5F; float scale = Math.min(5, this.ticksDisplayedCrosshair + tickDelta) / 5F;
scale *= scale; scale *= scale;
@@ -203,7 +202,7 @@ public class LambdaControlsHud extends Hud {
this.ticksDisplayedCrosshair = 0; this.ticksDisplayedCrosshair = 0;
} }
String customAttackAction = LambdaControlsCompat.getAttackActionAt(this.client, this.placeHitResult); var customAttackAction = LambdaControlsCompat.getAttackActionAt(this.client, this.placeHitResult);
if (customAttackAction != null) { if (customAttackAction != null) {
this.attackAction = customAttackAction; this.attackAction = customAttackAction;
this.attackWidth = this.width(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) if (customUseAction != null)
placeAction = customUseAction; 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) { private void drawTip(MatrixStack matrices, int x, int y, @NotNull String action, boolean display) {
if (!display) if (!display)
return; return;
String translatedAction = I18n.translate(action); var translatedAction = I18n.translate(action);
int textY = (LambdaControlsRenderer.ICON_SIZE / 2 - this.client.textRenderer.fontHeight / 2) + 1; int textY = (LambdaControlsRenderer.ICON_SIZE / 2 - this.client.textRenderer.fontHeight / 2) + 1;
this.client.textRenderer.draw(matrices, translatedAction, (float) x, (float) (y + textY), 14737632); this.client.textRenderer.draw(matrices, translatedAction, (float) x, (float) (y + textY), 14737632);
} }

View File

@@ -18,11 +18,9 @@ import dev.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@@ -30,7 +28,7 @@ import org.lwjgl.glfw.GLFW;
* Represents the LambdaControls renderer. * Represents the LambdaControls renderer.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.5.0 * @version 1.7.0
* @since 1.2.0 * @since 1.2.0
*/ */
public class LambdaControlsRenderer { public class LambdaControlsRenderer {
@@ -39,28 +37,21 @@ public class LambdaControlsRenderer {
private static final int AXIS_SIZE = 18; private static final int AXIS_SIZE = 18;
public static int getButtonSize(int button) { public static int getButtonSize(int button) {
switch (button) { return switch (button) {
case -1: case -1 -> 0;
return 0; case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200,
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100: GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200,
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200: GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200,
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100: GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200 -> AXIS_SIZE;
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200: default -> BUTTON_SIZE;
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;
}
} }
/** /**
* Gets the binding icon width. * Gets the binding icon width.
* *
* @param binding The binding. * @param binding the binding
* @return The width. * @return the width
*/ */
public static int getBindingIconWidth(@NotNull ButtonBinding binding) { public static int getBindingIconWidth(@NotNull ButtonBinding binding) {
return getBindingIconWidth(binding.getButton()); return getBindingIconWidth(binding.getButton());
@@ -69,8 +60,8 @@ public class LambdaControlsRenderer {
/** /**
* Gets the binding icon width. * Gets the binding icon width.
* *
* @param buttons The buttons. * @param buttons the buttons
* @return The width. * @return the width
*/ */
public static int getBindingIconWidth(int[] buttons) { public static int getBindingIconWidth(int[] buttons) {
int width = 0; int width = 0;
@@ -83,11 +74,11 @@ public class LambdaControlsRenderer {
return width; 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); 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 height = 0;
int length = 0; int length = 0;
int currentX = x; int currentX = x;
@@ -102,7 +93,7 @@ public class LambdaControlsRenderer {
currentX = x + length; currentX = x + length;
} }
} }
return Pair.of(length, height); return new ButtonSize(length, height);
} }
@SuppressWarnings("deprecated") @SuppressWarnings("deprecated")
@@ -119,75 +110,55 @@ public class LambdaControlsRenderer {
boolean axis = false; boolean axis = false;
int buttonOffset = button * 15; int buttonOffset = button * 15;
switch (button) { switch (button) {
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> buttonOffset = 7 * 15;
buttonOffset = 7 * 15; case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> buttonOffset = 8 * 15;
break; case GLFW.GLFW_GAMEPAD_BUTTON_BACK -> buttonOffset = 4 * 15;
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: case GLFW.GLFW_GAMEPAD_BUTTON_START -> buttonOffset = 6 * 15;
buttonOffset = 8 * 15; case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE -> buttonOffset = 5 * 15;
break; case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> buttonOffset = 15 * 15;
case GLFW.GLFW_GAMEPAD_BUTTON_BACK: case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> buttonOffset = 16 * 15;
buttonOffset = 4 * 15; case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100 -> {
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:
buttonOffset = 0; buttonOffset = 0;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100: case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100 -> {
buttonOffset = 18; buttonOffset = 18;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100: case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100 -> {
buttonOffset = 2 * 18; buttonOffset = 2 * 18;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100: case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100 -> {
buttonOffset = 3 * 18; buttonOffset = 3 * 18;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200: case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200 -> {
buttonOffset = 4 * 18; buttonOffset = 4 * 18;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200: case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200 -> {
buttonOffset = 5 * 18; buttonOffset = 5 * 18;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200: case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200 -> {
buttonOffset = 6 * 18; buttonOffset = 6 * 18;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200: case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200 -> {
buttonOffset = 7 * 18; buttonOffset = 7 * 18;
axis = true; axis = true;
break; }
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100: case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200 -> buttonOffset = 9 * 15;
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200: case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200 -> buttonOffset = 10 * 15;
buttonOffset = 9 * 15;
break;
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100:
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200:
buttonOffset = 10 * 15;
break;
} }
client.getTextureManager().bindTexture(axis ? LambdaControlsClient.CONTROLLER_AXIS : LambdaControlsClient.CONTROLLER_BUTTONS); RenderSystem.setShaderTexture(0, axis ? LambdaControlsClient.CONTROLLER_AXIS : LambdaControlsClient.CONTROLLER_BUTTONS);
RenderSystem.disableDepthTest(); RenderSystem.disableDepthTest();
int assetSize = axis ? AXIS_SIZE : BUTTON_SIZE; 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), DrawableHelper.drawTexture(matrices, x + (ICON_SIZE / 2 - assetSize / 2), y + (ICON_SIZE / 2 - assetSize / 2),
(float) buttonOffset, (float) (controllerType * (axis ? AXIS_SIZE : BUTTON_SIZE)), (float) buttonOffset, (float) (controllerType * (axis ? AXIS_SIZE : BUTTON_SIZE)),
assetSize, assetSize, 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) { public static int drawButtonTip(MatrixStack matrices, int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client) {
if (display) { if (display) {
int buttonWidth = drawButton(matrices, x, y, button, client).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; 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); 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) { 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; return;
int mouseX = (int) (client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()); int mouseX = (int) (client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth());
@@ -227,8 +199,7 @@ public class LambdaControlsRenderer {
boolean hoverSlot = false; boolean hoverSlot = false;
if (client.currentScreen instanceof HandledScreen) { if (client.currentScreen instanceof HandledScreenAccessor inventoryScreen) {
HandledScreenAccessor inventoryScreen = (HandledScreenAccessor) client.currentScreen;
int guiLeft = inventoryScreen.getX(); int guiLeft = inventoryScreen.getX();
int guiTop = inventoryScreen.getY(); int guiTop = inventoryScreen.getY();
@@ -242,11 +213,11 @@ public class LambdaControlsRenderer {
} }
if (!hoverSlot) { if (!hoverSlot) {
Pair<Integer, Integer> slot = LambdaControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY); var slot = LambdaControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY);
if (slot != null) { if (slot != null) {
mouseX = slot.getFirst(); mouseX = slot.x();
mouseY = slot.getSecond(); mouseY = slot.y();
hoverSlot = true; hoverSlot = true;
} }
} }
@@ -262,19 +233,23 @@ public class LambdaControlsRenderer {
/** /**
* Draws the virtual cursor. * Draws the virtual cursor.
* *
* @param matrices The matrix stack. * @param matrices the matrix stack
* @param x X coordinate. * @param x x coordinate
* @param y Y coordinate. * @param y y coordinate
* @param hoverSlot True if hovering a slot, else false. * @param hoverSlot true if hovering a slot, else false
* @param client The client instance. * @param client the client instance
*/ */
public static void drawCursor(@NotNull MatrixStack matrices, int x, int y, boolean hoverSlot, @NotNull MinecraftClient client) { public static void drawCursor(@NotNull MatrixStack matrices, int x, int y, boolean hoverSlot, @NotNull MinecraftClient client) {
client.getTextureManager().bindTexture(LambdaControlsClient.CURSOR_TEXTURE);
RenderSystem.disableDepthTest(); RenderSystem.disableDepthTest();
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
DrawableHelper.drawTexture(matrices, x, y, hoverSlot ? 16.F : 0.F, LambdaControlsClient.get().config.getVirtualMouseSkin().ordinal() * 16.F, 16, 16, 32, 64); 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(); RenderSystem.enableDepthTest();
} }
public record ButtonSize(int length, int height) {
}
} }

View File

@@ -9,21 +9,20 @@
package dev.lambdaurora.lambdacontrols.client.gui; package dev.lambdaurora.lambdacontrols.client.gui;
import dev.lambdaurora.lambdacontrols.ControlsMode;
import dev.lambdaurora.lambdacontrols.LambdaControls; import dev.lambdaurora.lambdacontrols.LambdaControls;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig; import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig;
import dev.lambdaurora.lambdacontrols.client.controller.Controller; import dev.lambdaurora.lambdacontrols.client.controller.Controller;
import dev.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget; import dev.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget;
import me.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.option.*; import dev.lambdaurora.spruceui.option.*;
import me.lambdaurora.spruceui.screen.SpruceScreen; import dev.lambdaurora.spruceui.screen.SpruceScreen;
import me.lambdaurora.spruceui.widget.AbstractSpruceWidget; import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
import me.lambdaurora.spruceui.widget.SpruceLabelWidget; import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import me.lambdaurora.spruceui.widget.container.SpruceOptionListWidget; import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
import me.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget; import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
@@ -71,7 +70,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
private final SpruceOption controllerOption = private final SpruceOption controllerOption =
new SpruceCyclingOption("lambdacontrols.menu.controller", new SpruceCyclingOption("lambdacontrols.menu.controller",
amount -> { amount -> {
int id = this.config.getController().getId(); int id = this.config.getController().id();
id += amount; id += amount;
if (id > GLFW.GLFW_JOYSTICK_LAST) if (id > GLFW.GLFW_JOYSTICK_LAST)
id = GLFW.GLFW_JOYSTICK_1; id = GLFW.GLFW_JOYSTICK_1;
@@ -79,8 +78,8 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
this.config.setController(Controller.byId(id)); this.config.setController(Controller.byId(id));
}, },
option -> { option -> {
Controller controller = this.config.getController(); var controller = this.config.getController();
String controllerName = controller.getName(); var controllerName = controller.getName();
if (!controller.isConnected()) if (!controller.isConnected())
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED)); return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED));
else if (!controller.isGamepad()) else if (!controller.isGamepad())
@@ -90,7 +89,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
}, null); }, null);
private final SpruceOption secondControllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller2", private final SpruceOption secondControllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller2",
amount -> { amount -> {
int id = this.config.getSecondController().map(Controller::getId).orElse(-1); int id = this.config.getSecondController().map(Controller::id).orElse(-1);
id += amount; id += amount;
if (id > GLFW.GLFW_JOYSTICK_LAST) if (id > GLFW.GLFW_JOYSTICK_LAST)
id = -1; id = -1;
@@ -98,7 +97,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
this.config.setSecondController(id == -1 ? null : Controller.byId(id)); this.config.setSecondController(id == -1 ? null : Controller.byId(id));
}, },
option -> this.config.getSecondController().map(controller -> { option -> this.config.getSecondController().map(controller -> {
String controllerName = controller.getName(); var controllerName = controller.getName();
if (!controller.isConnected()) if (!controller.isConnected())
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED)); return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED));
else if (!controller.isGamepad()) else if (!controller.isGamepad())
@@ -152,7 +151,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
// General options // General options
this.inputModeOption = new SpruceCyclingOption("lambdacontrols.menu.controls_mode", this.inputModeOption = new SpruceCyclingOption("lambdacontrols.menu.controls_mode",
amount -> { amount -> {
ControlsMode next = this.config.getControlsMode().next(); var next = this.config.getControlsMode().next();
this.config.setControlsMode(next); this.config.setControlsMode(next);
this.config.save(); this.config.save();
@@ -181,7 +180,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
new TranslatableText("lambdacontrols.tooltip.mouse_speed")); new TranslatableText("lambdacontrols.tooltip.mouse_speed"));
this.resetOption = SpruceSimpleActionOption.reset(btn -> { this.resetOption = SpruceSimpleActionOption.reset(btn -> {
this.config.reset(); this.config.reset();
MinecraftClient client = MinecraftClient.getInstance(); var client = MinecraftClient.getInstance();
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
}); });
// Gameplay options // Gameplay options
@@ -225,7 +224,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
this.config.setRightDeadZone(newValue); this.config.setRightDeadZone(newValue);
} }
}, option -> { }, 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)))); return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5))));
}, new TranslatableText("lambdacontrols.tooltip.right_dead_zone")); }, new TranslatableText("lambdacontrols.tooltip.right_dead_zone"));
this.leftDeadZoneOption = new SpruceDoubleOption("lambdacontrols.menu.left_dead_zone", 0.05, 1.0, .05f, 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); this.config.setLeftDeadZone(newValue);
} }
}, option -> { }, 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)))); return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5))));
}, new TranslatableText("lambdacontrols.tooltip.left_dead_zone")); }, new TranslatableText("lambdacontrols.tooltip.left_dead_zone"));
this.invertsRightXAxis = new SpruceToggleBooleanOption("lambdacontrols.menu.invert_right_x_axis", this.config::doesInvertRightXAxis, 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.buildTabs();
this.addChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150)); this.addDrawableChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE, this.addDrawableChild(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
btn -> this.client.openScreen(this.parent))); btn -> this.client.openScreen(this.parent)));
} }
public void buildTabs() { 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, null,
Math.max(116, this.width / 8), 0); Math.max(116, this.width / 8), 0);
this.addChild(tabs); this.addDrawableChild(tabs);
tabs.addSeparatorEntry(new TranslatableText("lambdacontrols.menu.separator.general")); tabs.addSeparatorEntry(new TranslatableText("lambdacontrols.menu.separator.general"));
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.general"), null, 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) { 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.inputModeOption);
list.addSingleOptionEntry(this.autoSwitchModeOption); list.addSingleOptionEntry(this.autoSwitchModeOption);
list.addSingleOptionEntry(this.rotationSpeedOption); list.addSingleOptionEntry(this.rotationSpeedOption);
@@ -319,7 +318,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
} }
public SpruceOptionListWidget buildGameplayTab(int width, int height) { 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.analogMovementOption);
list.addSingleOptionEntry(this.fastBlockPlacingOption); list.addSingleOptionEntry(this.fastBlockPlacingOption);
list.addSingleOptionEntry(this.frontBlockPlacingOption); list.addSingleOptionEntry(this.frontBlockPlacingOption);
@@ -331,7 +330,7 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
} }
public SpruceOptionListWidget buildVisualTab(int width, int height) { 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.controllerTypeOption);
list.addSingleOptionEntry(this.virtualMouseSkinOption); list.addSingleOptionEntry(this.virtualMouseSkinOption);
list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null)); 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) { 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), new TranslatableText("lambdacontrols.controller.mappings.1", SDL2_GAMEPAD_TOOL),
width, true); 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, this.controllerMappingsUrlText, width,
label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true); label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true);
gamepadToolUrlLabel.setTooltip(new TranslatableText("chat.link.open")); 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), aboutMappings1.getHeight() + gamepadToolUrlLabel.getHeight() + 6),
new TranslatableText("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), new TranslatableText("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()),
width, true); width, true);
int listHeight = height - 8 - aboutMappings1.getHeight() - aboutMappings3.getHeight() - gamepadToolUrlLabel.getHeight(); 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), listHeight),
width, height - listHeight); width, height - listHeight);
labels.addChild(aboutMappings1); labels.addChild(aboutMappings1);
labels.addChild(gamepadToolUrlLabel); labels.addChild(gamepadToolUrlLabel);
labels.addChild(aboutMappings3); 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.controllerOption);
list.addSingleOptionEntry(this.secondControllerOption); list.addSingleOptionEntry(this.secondControllerOption);
list.addSingleOptionEntry(this.unfocusedInputOption); list.addSingleOptionEntry(this.unfocusedInputOption);
list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis); list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis);
list.addSingleOptionEntry(this.rightDeadZoneOption); list.addSingleOptionEntry(this.rightDeadZoneOption);
list.addSingleOptionEntry(this.leftDeadZoneOption); list.addSingleOptionEntry(this.leftDeadZoneOption);
for (SpruceOption option : this.maxAnalogValueOptions) { for (var option : this.maxAnalogValueOptions) {
list.addSingleOptionEntry(option); list.addSingleOptionEntry(option);
} }
@@ -391,6 +390,6 @@ public class LambdaControlsSettingsScreen extends SpruceScreen {
@Override @Override
public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) { 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);
} }
} }

View File

@@ -11,10 +11,10 @@ package dev.lambdaurora.lambdacontrols.client.gui;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.controller.Controller; import dev.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.option.SpruceOption; import dev.lambdaurora.spruceui.option.SpruceOption;
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import me.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget; import dev.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget;
import net.minecraft.client.toast.SystemToast; import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
@@ -27,7 +27,7 @@ import java.nio.file.Files;
* Represents the controller mappings file editor screen. * Represents the controller mappings file editor screen.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.4.3 * @version 1.7.0
* @since 1.4.3 * @since 1.4.3
*/ */
public class MappingsStringInputWidget extends SpruceContainerWidget { public class MappingsStringInputWidget extends SpruceContainerWidget {
@@ -59,7 +59,7 @@ public class MappingsStringInputWidget extends SpruceContainerWidget {
if (this.textArea != null) { if (this.textArea != null) {
this.mappings = this.textArea.getText(); this.mappings = this.textArea.getText();
try { try {
FileWriter fw = new FileWriter(LambdaControlsClient.MAPPINGS_FILE, false); var fw = new FileWriter(LambdaControlsClient.MAPPINGS_FILE, false);
fw.write(this.mappings); fw.write(this.mappings);
fw.close(); fw.close();
} catch (IOException e) { } catch (IOException e) {
@@ -76,7 +76,7 @@ public class MappingsStringInputWidget extends SpruceContainerWidget {
this.mappings = this.textArea.getText(); this.mappings = this.textArea.getText();
} }
String mappings = ""; var mappings = "";
if (this.mappings != null) if (this.mappings != null)
mappings = this.mappings; mappings = this.mappings;

View File

@@ -10,8 +10,8 @@
package dev.lambdaurora.lambdacontrols.client.gui; package dev.lambdaurora.lambdacontrols.client.gui;
import dev.lambdaurora.lambdacontrols.client.controller.Controller; import dev.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.option.SpruceSimpleActionOption; import dev.lambdaurora.spruceui.option.SpruceSimpleActionOption;
import me.lambdaurora.spruceui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.toast.SystemToast; import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
@@ -28,7 +28,7 @@ public class ReloadControllerMappingsOption {
public static SpruceSimpleActionOption newOption(@Nullable Consumer<SpruceButtonWidget> before) { public static SpruceSimpleActionOption newOption(@Nullable Consumer<SpruceButtonWidget> before) {
return SpruceSimpleActionOption.of(KEY, btn -> { return SpruceSimpleActionOption.of(KEY, btn -> {
MinecraftClient client = MinecraftClient.getInstance(); var client = MinecraftClient.getInstance();
if (before != null) if (before != null)
before.accept(btn); before.accept(btn);
Controller.updateMappings(); Controller.updateMappings();

View File

@@ -11,14 +11,13 @@ package dev.lambdaurora.lambdacontrols.client.gui.widget;
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer; import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer;
import me.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget; import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@@ -52,8 +51,8 @@ public class ControllerButtonWidget extends AbstractSpruceIconButtonWidget {
if (this.binding.getButton().length > 1) { if (this.binding.getButton().length > 1) {
x += (this.width / 2 - this.iconWidth / 2) - 4; x += (this.width / 2 - this.iconWidth / 2) - 4;
} }
Pair<Integer, Integer> size = LambdaControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance()); var size = LambdaControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance());
this.iconWidth = size.key; this.iconWidth = size.length();
return size.value; return size.height();
} }
} }

View File

@@ -12,11 +12,11 @@ package dev.lambdaurora.lambdacontrols.client.gui.widget;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import dev.lambdaurora.lambdacontrols.client.controller.InputManager; import dev.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.function.Predicates; 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))); this.resetButton.setActive(InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault)));
super.renderWidget(matrices, mouseX, mouseY, delta); 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;
}
} }

View File

@@ -13,22 +13,20 @@ import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding; import dev.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import dev.lambdaurora.lambdacontrols.client.controller.ButtonCategory; import dev.lambdaurora.lambdacontrols.client.controller.ButtonCategory;
import dev.lambdaurora.lambdacontrols.client.controller.InputManager; import dev.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.spruceui.Position; import dev.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.navigation.NavigationDirection; import dev.lambdaurora.spruceui.navigation.NavigationDirection;
import me.lambdaurora.spruceui.navigation.NavigationUtils; import dev.lambdaurora.spruceui.navigation.NavigationUtils;
import me.lambdaurora.spruceui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import me.lambdaurora.spruceui.widget.SpruceSeparatorWidget; import dev.lambdaurora.spruceui.widget.SpruceSeparatorWidget;
import me.lambdaurora.spruceui.widget.SpruceWidget; import dev.lambdaurora.spruceui.widget.SpruceWidget;
import me.lambdaurora.spruceui.widget.container.SpruceEntryListWidget; import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
import me.lambdaurora.spruceui.widget.container.SpruceParentWidget; import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
@@ -36,7 +34,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.*; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/** /**
* Represents a control list widget. * Represents a control list widget.
@@ -91,8 +91,9 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
gui.focusedBinding = binding; gui.focusedBinding = binding;
LambdaControlsClient.get().input.beginControlsInput(gui); LambdaControlsClient.get().input.beginControlsInput(gui);
}) { }) {
protected Optional<Text> getNarrationMessage() { protected Text getNarrationMessage() {
return Optional.of(binding.isNotBound() ? new TranslatableText("narrator.controls.unbound", bindingName) : new TranslatableText("narrator.controls.bound", bindingName, super.getNarrationMessage())); return binding.isNotBound() ? new TranslatableText("narrator.controls.unbound", bindingName)
: new TranslatableText("narrator.controls.bound", bindingName, super.getNarrationMessage());
} }
}; };
this.children.add(editButton); this.children.add(editButton);
@@ -100,8 +101,8 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
this.editButton.getPosition().getRelativeX() + this.editButton.getWidth() + 2, 0), this.editButton.getPosition().getRelativeX() + this.editButton.getWidth() + 2, 0),
44, 20, new TranslatableText("controls.reset"), 44, 20, new TranslatableText("controls.reset"),
btn -> LambdaControlsClient.get().config.setButtonBinding(binding, binding.getDefaultButton())) { btn -> LambdaControlsClient.get().config.setButtonBinding(binding, binding.getDefaultButton())) {
protected Optional<Text> getNarrationMessage() { protected Text getNarrationMessage() {
return Optional.of(new TranslatableText("narrator.controls.reset", bindingName)); return new TranslatableText("narrator.controls.reset", bindingName);
} }
}; };
this.children.add(this.resetButton); this.children.add(this.resetButton);
@@ -113,8 +114,8 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
gui.focusedBinding = null; gui.focusedBinding = null;
LambdaControlsClient.get().input.beginControlsInput(null); LambdaControlsClient.get().input.beginControlsInput(null);
}) { }) {
protected Optional<Text> getNarrationMessage() { protected Text getNarrationMessage() {
return Optional.of(new TranslatableText("lambdacontrols.narrator.unbound", bindingName)); return new TranslatableText("lambdacontrols.narrator.unbound", bindingName);
} }
}; };
this.children.add(this.unbindButton); this.children.add(this.unbindButton);
@@ -151,7 +152,7 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
@Override @Override
protected boolean onMouseClick(double mouseX, double mouseY, int button) { protected boolean onMouseClick(double mouseX, double mouseY, int button) {
Iterator<SpruceWidget> it = this.children().iterator(); var it = this.children().iterator();
SpruceWidget element; SpruceWidget element;
do { do {
@@ -229,12 +230,11 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) { protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) {
boolean focused = gui.focusedBinding == this.binding; boolean focused = gui.focusedBinding == this.binding;
TextRenderer textRenderer = ControlsListWidget.this.client.textRenderer; var textRenderer = ControlsListWidget.this.client.textRenderer;
String bindingName = this.bindingName;
int height = this.getHeight(); int height = this.getHeight();
//float textX = (float) (this.getX() + 70 - ControlsListWidget.this.maxTextLength); //float textX = (float) (this.getX() + 70 - ControlsListWidget.this.maxTextLength);
int textY = this.getY() + height / 2; int textY = this.getY() + height / 2;
textRenderer.draw(matrices, 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.resetButton.setVisible(!focused);
this.unbindButton.setVisible(focused); this.unbindButton.setVisible(focused);
@@ -242,14 +242,14 @@ public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget
this.editButton.update(); this.editButton.update();
if (focused) { 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)); text.append(this.editButton.getMessage().copy().formatted(Formatting.YELLOW));
this.editButton.setMessage(text.append(new LiteralText(" <").formatted(Formatting.WHITE))); this.editButton.setMessage(text.append(new LiteralText(" <").formatted(Formatting.WHITE)));
} else if (!this.binding.isNotBound() && InputManager.hasDuplicatedBindings(this.binding)) { } 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)); this.editButton.setMessage(text.formatted(Formatting.RED));
} else if (this.binding.isNotBound()) { } else if (this.binding.isNotBound()) {
MutableText text = this.editButton.getMessage().copy(); var text = this.editButton.getMessage().copy();
this.editButton.setMessage(text.formatted(Formatting.GOLD)); this.editButton.setMessage(text.formatted(Formatting.GOLD));
} }

View File

@@ -9,12 +9,12 @@
package dev.lambdaurora.lambdacontrols.client.mixin; 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.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AbstractButtonWidget.class) @Mixin(ClickableWidget.class)
public interface AbstractButtonWidgetAccessor { public interface ClickableWidgetAccessor {
@Accessor("height") @Accessor("height")
int getHeight(); int getHeight();
} }

View File

@@ -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")) @Inject(method = "move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V"))
public void onMove(MovementType type, Vec3d movement, CallbackInfo ci) { public void onMove(MovementType type, Vec3d movement, CallbackInfo ci) {
LambdaControlsClient mod = LambdaControlsClient.get(); var mod = LambdaControlsClient.get();
if (type == MovementType.SELF) { 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.hasMovementInput()) {
if (!this.lambdacontrols$driftingPrevented) { if (!this.lambdacontrols$driftingPrevented) {
if (!mod.config.hasFlyDrifting()) 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")) @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z"))
public void onTickMovement(CallbackInfo ci) { public void onTickMovement(CallbackInfo ci) {
if (this.abilities.flying && this.isCamera()) { if (this.getAbilities().flying && this.isCamera()) {
if (LambdaControlsClient.get().config.hasFlyVerticalDrifting()) if (LambdaControlsClient.get().config.hasFlyVerticalDrifting())
return; return;
int moving = 0; int moving = 0;

View File

@@ -10,12 +10,15 @@
package dev.lambdaurora.lambdacontrols.client.mixin; package dev.lambdaurora.lambdacontrols.client.mixin;
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen; 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.Screen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
import net.minecraft.client.gui.screen.options.GameOptionsScreen; import net.minecraft.client.gui.screen.option.GameOptionsScreen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ButtonWidget; 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.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -31,12 +34,25 @@ public class ControlsOptionsScreenMixin extends GameOptionsScreen {
super(parent, gameOptions, text); super(parent, gameOptions, text);
} }
@Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/options/ControlsOptionsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 1)) @SuppressWarnings("unchecked")
private AbstractButtonWidget onInit(ControlsOptionsScreen screen, AbstractButtonWidget btn) { @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) /*if (this.parent instanceof ControllerControlsWidget)
return this.addButton(btn); return this.addButton(btn);
else*/ else*/
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).getHeight(), new TranslatableText("menu.options"), if (element instanceof CyclingButtonWidget btn) {
b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, true)))); 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);
}
} }
} }

View File

@@ -26,7 +26,7 @@ public interface CreativeInventoryScreenAccessor {
/** /**
* Gets the selected tab. * Gets the selected tab.
* *
* @return The selected tab index. * @return the selected tab index
*/ */
@Accessor("selectedTab") @Accessor("selectedTab")
int getSelectedTab(); int getSelectedTab();
@@ -34,7 +34,7 @@ public interface CreativeInventoryScreenAccessor {
/** /**
* Sets the selected tab. * Sets the selected tab.
* *
* @param group The tab's item group. * @param group the tab's item group
*/ */
@Invoker("setSelectedTab") @Invoker("setSelectedTab")
void lambdacontrols$setSelectedTab(@NotNull ItemGroup group); void lambdacontrols$setSelectedTab(@NotNull ItemGroup group);
@@ -42,8 +42,8 @@ public interface CreativeInventoryScreenAccessor {
/** /**
* Returns whether the slot belongs to the creative inventory or not. * Returns whether the slot belongs to the creative inventory or not.
* *
* @param slot The slot to check. * @param slot the slot to check
* @return True if the slot is from the creative inventory, else false. * @return true if the slot is from the creative inventory, else false
*/ */
@Invoker("isCreativeInventorySlot") @Invoker("isCreativeInventorySlot")
boolean lambdacontrols$isCreativeInventorySlot(@Nullable Slot slot); boolean lambdacontrols$isCreativeInventorySlot(@Nullable Slot slot);
@@ -51,7 +51,7 @@ public interface CreativeInventoryScreenAccessor {
/** /**
* Returns whether the current tab has a scrollbar or not. * 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") @Invoker("hasScrollbar")
boolean lambdacontrols$hasScrollbar(); boolean lambdacontrols$hasScrollbar();

View File

@@ -9,7 +9,7 @@
package dev.lambdaurora.lambdacontrols.client.mixin; 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.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;

View File

@@ -51,7 +51,7 @@ public abstract class HandledScreenMixin implements HandledScreenAccessor {
@Inject(method = "render", at = @At("RETURN")) @Inject(method = "render", at = @At("RETURN"))
public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) { 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; int x = 2, y = client.getWindow().getScaledHeight() - 2 - LambdaControlsRenderer.ICON_SIZE;
x = LambdaControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 2; x = LambdaControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 2;

View File

@@ -10,7 +10,7 @@
package dev.lambdaurora.lambdacontrols.client.mixin; package dev.lambdaurora.lambdacontrols.client.mixin;
import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; 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.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;

View File

@@ -13,7 +13,6 @@ import dev.lambdaurora.lambdacontrols.LambdaControlsFeature;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer; import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.GameRenderer;
@@ -83,10 +82,10 @@ public abstract class MinecraftClientMixin {
int cooldown = this.itemUseCooldown; int cooldown = this.itemUseCooldown;
BlockHitResult hitResult; 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; hitResult = (BlockHitResult) this.crosshairTarget;
BlockPos targetPos = hitResult.getBlockPos(); var targetPos = hitResult.getBlockPos();
Direction side = hitResult.getSide(); var side = hitResult.getSide();
boolean sidewaysBlockPlacing = this.lambdacontrols$lastTargetPos == null || !targetPos.equals(this.lambdacontrols$lastTargetPos.offset(this.lambdacontrols$lastTargetSide)); boolean sidewaysBlockPlacing = this.lambdacontrols$lastTargetPos == null || !targetPos.equals(this.lambdacontrols$lastTargetPos.offset(this.lambdacontrols$lastTargetSide));
boolean backwardsBlockPlacing = this.player.input.movementForward < 0.0f && (this.lambdacontrols$lastTargetPos == null || targetPos.equals(this.lambdacontrols$lastTargetPos.offset(this.lambdacontrols$lastTargetSide))); boolean 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) @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) { private void onItemUse(CallbackInfo ci, Hand[] hands, int handCount, int handIndex, Hand hand, ItemStack stackInHand) {
LambdaControlsClient mod = LambdaControlsClient.get(); var mod = LambdaControlsClient.get();
if (!stackInHand.isEmpty() && this.player.pitch > 35.0F && mod.reacharound.isReacharoundAvailable()) { 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 (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.MISS && this.player.isOnGround()) {
if (!stackInHand.isEmpty() && stackInHand.getItem() instanceof BlockItem) { if (!stackInHand.isEmpty() && stackInHand.getItem() instanceof BlockItem) {
BlockHitResult hitResult = mod.reacharound.getLastReacharoundResult(); var hitResult = mod.reacharound.getLastReacharoundResult();
if (hitResult == null) if (hitResult == null)
return; return;
@@ -135,7 +134,7 @@ public abstract class MinecraftClientMixin {
hitResult = mod.reacharound.withSideForReacharound(hitResult, stackInHand); hitResult = mod.reacharound.withSideForReacharound(hitResult, stackInHand);
int previousStackCount = stackInHand.getCount(); 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.isAccepted()) {
if (result.shouldSwingHand()) { if (result.shouldSwingHand()) {
this.player.swingHand(hand); this.player.swingHand(hand);

View File

@@ -15,6 +15,7 @@ import dev.lambdaurora.lambdacontrols.client.LambdaControlsConfig;
import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor; import dev.lambdaurora.lambdacontrols.client.util.MouseAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.Mouse; import net.minecraft.client.Mouse;
import net.minecraft.client.gui.screen.Screen;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -29,8 +30,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
* Adds extra access to the mouse. * Adds extra access to the mouse.
*/ */
@Mixin(Mouse.class) @Mixin(Mouse.class)
public abstract class MouseMixin implements MouseAccessor public abstract class MouseMixin implements MouseAccessor {
{
@Shadow @Shadow
@Final @Final
private MinecraftClient client; private MinecraftClient client;
@@ -39,20 +39,18 @@ public abstract class MouseMixin implements MouseAccessor
public abstract void lambdacontrols$onCursorPos(long window, double x, double y); 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")) @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) 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 (!result[0] && button == GLFW.GLFW_MOUSE_BUTTON_4 && this.client.currentScreen != null) { if (LambdaControlsClient.get().input.tryGoBack(screen)) {
if (LambdaControlsClient.get().input.tryGoBack(this.client.currentScreen)) {
result[0] = true; result[0] = true;
} }
} }
} }
@Inject(method = "isCursorLocked", at = @At("HEAD"), cancellable = 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) { if (this.client.currentScreen == null) {
LambdaControlsConfig config = LambdaControlsClient.get().config; var config = LambdaControlsClient.get().config;
if (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()) { if (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()) {
ci.setReturnValue(true); ci.setReturnValue(true);
ci.cancel(); ci.cancel();
@@ -61,11 +59,10 @@ public abstract class MouseMixin implements MouseAccessor
} }
@Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true) @Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true)
private void onCursorLocked(CallbackInfo ci) private void onCursorLocked(CallbackInfo ci) {
{
LambdaControlsConfig config = LambdaControlsClient.get().config; LambdaControlsConfig config = LambdaControlsClient.get().config;
if (config.getControlsMode() == ControlsMode.TOUCHSCREEN if (/*config.getControlsMode() == ControlsMode.TOUCHSCREEN
|| (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse())) ||*/ (config.getControlsMode() == ControlsMode.CONTROLLER && config.hasVirtualMouse()))
ci.cancel(); ci.cancel();
} }
} }

View File

@@ -12,9 +12,11 @@ package dev.lambdaurora.lambdacontrols.client.mixin;
import dev.lambdaurora.lambdacontrols.ControlsMode; import dev.lambdaurora.lambdacontrols.ControlsMode;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import dev.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen; 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.Screen;
import net.minecraft.client.gui.screen.options.OptionsScreen; import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -30,13 +32,22 @@ public class OptionsScreenMixin extends Screen {
super(title); 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)) @SuppressWarnings("unchecked")
private AbstractButtonWidget lambdacontrols$onInit(OptionsScreen screen, AbstractButtonWidget btn) { @Redirect(
if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) { method = "init",
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).getHeight(), btn.getMessage(), 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)))); b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, false))));
} else { } else {
return this.addButton(btn); return this.addDrawableChild(element);
} }
} }
} }

View File

@@ -10,8 +10,6 @@
package dev.lambdaurora.lambdacontrols.client.mixin; package dev.lambdaurora.lambdacontrols.client.mixin;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext; import net.minecraft.block.ShapeContext;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
@@ -19,14 +17,10 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext; import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult; import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -70,30 +64,30 @@ public abstract class WorldRendererMixin {
LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) { LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !LambdaControlsClient.get().config.shouldRenderReacharoundOutline()) if (this.client.crosshairTarget == null || this.client.crosshairTarget.getType() != HitResult.Type.MISS || !LambdaControlsClient.get().config.shouldRenderReacharoundOutline())
return; return;
BlockHitResult result = LambdaControlsClient.get().reacharound.getLastReacharoundResult(); var result = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
if (result == null) if (result == null)
return; return;
BlockPos blockPos = result.getBlockPos(); var blockPos = result.getBlockPos();
if (this.world.getWorldBorder().contains(blockPos)) { 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)) if (stack == null || !(stack.getItem() instanceof BlockItem))
return; 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); 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) if (placementState == null)
return; 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(); 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, drawShapeOutline(matrices, vertexConsumer, outlineShape,
(double) blockPos.getX() - pos.getX(), (double) blockPos.getY() - pos.getY(), (double) blockPos.getZ() - pos.getZ(), (double) blockPos.getX() - pos.getX(), (double) blockPos.getY() - pos.getY(), (double) blockPos.getZ() - pos.getZ(),
color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f); color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f);

View File

@@ -31,6 +31,6 @@ public class DummyRingAction extends RingAction {
@Override @Override
public void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered) { 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);
} }
} }

View File

@@ -13,7 +13,7 @@ import com.electronwill.nightconfig.core.Config;
import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; import dev.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen; 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.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -39,14 +39,11 @@ public class KeyBindingRingAction extends RingAction {
public void onAction(@NotNull RingButtonMode mode) { public void onAction(@NotNull RingButtonMode mode) {
KeyBindingAccessor accessor = (KeyBindingAccessor) this.binding; KeyBindingAccessor accessor = (KeyBindingAccessor) this.binding;
switch (mode) { switch (mode) {
case PRESS: case PRESS, HOLD -> accessor.lambdacontrols$handlePressState(this.activated);
case HOLD: case TOGGLE -> {
accessor.lambdacontrols_handlePressState(this.activated); accessor.lambdacontrols$handlePressState(!this.binding.isPressed());
break;
case TOGGLE:
accessor.lambdacontrols_handlePressState(!this.binding.isPressed());
this.activated = !this.binding.isPressed(); this.activated = !this.binding.isPressed();
break; }
} }
} }

View File

@@ -11,25 +11,25 @@ package dev.lambdaurora.lambdacontrols.client.ring;
import com.electronwill.nightconfig.core.Config; import com.electronwill.nightconfig.core.Config;
import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient; import dev.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Represents a key binding ring. * Represents a key binding ring.
* *
* @author LambdAurora * @author LambdAurora
* @version 1.5.0 * @version 1.7.0
* @since 1.4.0 * @since 1.4.0
*/ */
public final class LambdaRing { public final class LambdaRing {
public static final int ELEMENT_SIZE = 50; 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 List<RingPage> pages = new ArrayList<>(Collections.singletonList(RingPage.DEFAULT));
private final LambdaControlsClient mod; private final LambdaControlsClient mod;
private int currentPage = 0; private int currentPage = 0;
@@ -49,13 +49,13 @@ public final class LambdaRing {
/** /**
* Loads the ring from configuration. * Loads the ring from configuration.
* *
* @param config The configuration. * @param config the configuration
*/ */
public void load(@NotNull Config config) { public void load(@NotNull Config config) {
List<Config> configPages = config.get("ring.pages"); List<Config> configPages = config.get("ring.pages");
if (configPages != null) { if (configPages != null) {
this.pages.clear(); this.pages.clear();
for (Config configPage : configPages) { for (var configPage : configPages) {
RingPage.parseRingPage(configPage).ifPresent(this.pages::add); RingPage.parseRingPage(configPage).ifPresent(this.pages::add);
} }
} }

View File

@@ -40,7 +40,7 @@ public abstract class RingAction extends DrawableHelper implements Nameable {
/** /**
* Gets the text name of the ring action. * Gets the text name of the ring action.
* *
* @return The text name. * @return the text name
*/ */
public Text getTextName() { public Text getTextName() {
return new TranslatableText(this.getName()); 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. * 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() { public boolean isActivated() {
return this.activated; return this.activated;

View File

@@ -37,10 +37,10 @@ public enum RingButtonMode implements Nameable {
/** /**
* Returns the next ring button mode available. * Returns the next ring button mode available.
* *
* @return The next ring button mode. * @return the next ring button mode
*/ */
public @NotNull RingButtonMode next() { public @NotNull RingButtonMode next() {
RingButtonMode[] v = values(); var v = values();
if (v.length == this.ordinal() + 1) if (v.length == this.ordinal() + 1)
return v[0]; return v[0];
return v[this.ordinal() + 1]; return v[this.ordinal() + 1];
@@ -49,7 +49,7 @@ public enum RingButtonMode implements Nameable {
/** /**
* Returns the translation key of this ring button mode. * 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() { public @NotNull String getTranslationKey() {
return "lambdacontrols.ring.button_mode." + this.getName(); 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. * 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() { public @NotNull Text getTranslatedText() {
return this.text; return this.text;

View File

@@ -41,12 +41,12 @@ public class RingPage extends DrawableHelper {
/** /**
* Renders the ring page. * Renders the ring page.
* *
* @param matrices The matrices. * @param matrices the matrices
* @param width The screen width. * @param width the screen width
* @param height The screen height. * @param height the screen height
* @param mouseX The mouse X-coordinate. * @param mouseX the mouse X-coordinate
* @param mouseY The mouse Y-coordinate. * @param mouseY the mouse Y-coordinate
* @param tickDelta The tick delta. * @param tickDelta the tick delta
*/ */
public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int width, int height, int mouseX, int mouseY, float tickDelta) { public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int width, int height, int mouseX, int mouseY, float tickDelta) {
int centerX = width / 2; int centerX = width / 2;
@@ -57,7 +57,7 @@ public class RingPage extends DrawableHelper {
int y = centerY - offset; int y = centerY - offset;
int x = centerX - offset; int x = centerX - offset;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
RingAction ringAction = this.actions[i]; var ringAction = this.actions[i];
if (ringAction != null) if (ringAction != null)
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY)); ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
x += 55; x += 55;
@@ -65,7 +65,7 @@ public class RingPage extends DrawableHelper {
y += 55; y += 55;
x = centerX - offset; x = centerX - offset;
for (int i = 3; i < 5; i++) { for (int i = 3; i < 5; i++) {
RingAction ringAction = this.actions[i]; var ringAction = this.actions[i];
if (ringAction != null) if (ringAction != null)
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY)); ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
x += 55 * 2; x += 55 * 2;
@@ -73,7 +73,7 @@ public class RingPage extends DrawableHelper {
y += 55; y += 55;
x = centerX - offset; x = centerX - offset;
for (int i = 5; i < 8; i++) { for (int i = 5; i < 8; i++) {
RingAction ringAction = this.actions[i]; var ringAction = this.actions[i];
if (ringAction != null) if (ringAction != null)
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY)); ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
x += 55; x += 55;
@@ -87,15 +87,15 @@ public class RingPage extends DrawableHelper {
/** /**
* Tries to parse a ring page configuration. * Tries to parse a ring page configuration.
* *
* @param config The configuration. * @param config the configuration
* @return An optional ring page. * @return an optional ring page
*/ */
public static @NotNull Optional<RingPage> parseRingPage(@NotNull Config config) { public static @NotNull Optional<RingPage> parseRingPage(@NotNull Config config) {
String name = config.get("name"); String name = config.get("name");
if (name == null) if (name == null)
return Optional.empty(); return Optional.empty();
RingPage page = new RingPage(name); var page = new RingPage(name);
List<Config> actionConfigs = config.get("actions"); List<Config> actionConfigs = config.get("actions");

View File

@@ -20,35 +20,35 @@ public interface HandledScreenAccessor {
/** /**
* Gets the left coordinate of the GUI. * Gets the left coordinate of the GUI.
* *
* @return The left coordinate of the GUI. * @return the left coordinate of the GUI
*/ */
int getX(); int getX();
/** /**
* Gets the top coordinate of the GUI. * Gets the top coordinate of the GUI.
* *
* @return The top coordinate of the GUI. * @return the top coordinate of the GUI
*/ */
int getY(); int getY();
/** /**
* Gets the slot at position. * Gets the slot at position.
* *
* @param pos_x The X position to check. * @param posX the X position to check
* @param pos_y The Y position to check. * @param posY the Y position to check
* @return The slot at the specified position. * @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); boolean lambdacontrols$isClickOutsideBounds(double mouseX, double mouseY, int x, int y, int button);
/** /**
* Handles a mouse click on the specified slot. * Handles a mouse click on the specified slot.
* *
* @param slot The slot instance. * @param slot the slot instance
* @param slotId The slot id. * @param slotId the slot id
* @param clickData The click data. * @param clickData the click data
* @param actionType The action type. * @param actionType the action type
*/ */
void lambdacontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType); void lambdacontrols$onMouseClick(@Nullable Slot slot, int slotId, int clickData, SlotActionType actionType);
} }

View File

@@ -17,7 +17,7 @@ public interface KeyBindingAccessor {
boolean lambdacontrols$unpress(); boolean lambdacontrols$unpress();
default boolean lambdacontrols_handlePressState(boolean pressed) { default boolean lambdacontrols$handlePressState(boolean pressed) {
if (pressed) if (pressed)
return this.lambdacontrols$press(); return this.lambdacontrols$press();
else else

View File

@@ -3,12 +3,12 @@
"id": "lambdacontrols", "id": "lambdacontrols",
"name": "LambdaControls", "name": "LambdaControls",
"version": "${version}", "version": "${version}",
"description": "Adds better controls: controller and touchscreen support.", "description": "Adds better controls, and controller support.",
"authors": [ "authors": [
"LambdAurora" "LambdAurora"
], ],
"contact": { "contact": {
"homepage": "https://www.curseforge.com/minecraft/mc-mods/lambdacontrols", "homepage": "https://modrinth.com/mod/lambdacontrols",
"sources": "https://github.com/LambdAurora/LambdaControls.git", "sources": "https://github.com/LambdAurora/LambdaControls.git",
"issues": "https://github.com/LambdAurora/LambdaControls/issues" "issues": "https://github.com/LambdAurora/LambdaControls/issues"
}, },
@@ -26,23 +26,23 @@
"dev.lambdaurora.lambdacontrols.client.LambdaControlsModMenu" "dev.lambdaurora.lambdacontrols.client.LambdaControlsModMenu"
] ]
}, },
"accessWidener": "lambdacontrols.accesswidener",
"mixins": [ "mixins": [
"lambdacontrols.mixins.json", "lambdacontrols.mixins.json",
"lambdacontrols_compat.mixins.json" "lambdacontrols_compat.mixins.json"
], ],
"depends": { "depends": {
"fabricloader": ">=0.11.1", "fabricloader": ">=0.11.3",
"fabric": ">=0.29.3", "fabric": ">=0.36.0",
"minecraft": ">=1.16.2", "minecraft": ">=1.7",
"spruceui": ">=1.6.3" "spruceui": ">=3.1.0",
"java": ">=16"
}, },
"recommends": { "recommends": {
"modmenu": ">=1.12.2" "modmenu": ">=1.12.2"
}, },
"suggests": { "suggests": {
"flamingo": "*", "flamingo": "*"
"roughlyenoughitems": ">=4.5.5",
"okzoomer": ">=4.0.0"
}, },
"breaks": { "breaks": {
"modmenu": "<1.12.2", "modmenu": "<1.12.2",

View File

@@ -0,0 +1,3 @@
accessWidener v1 named
accessible class net/minecraft/client/gui/widget/EntryListWidget$MoveDirection

View File

@@ -1,9 +1,9 @@
{ {
"required": true, "required": true,
"package": "dev.lambdaurora.lambdacontrols.client.mixin", "package": "dev.lambdaurora.lambdacontrols.client.mixin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_16",
"client": [ "client": [
"AbstractButtonWidgetAccessor", "ClickableWidgetAccessor",
"AdvancementsScreenAccessor", "AdvancementsScreenAccessor",
"ClientPlayerEntityMixin", "ClientPlayerEntityMixin",
"ControlsOptionsScreenMixin", "ControlsOptionsScreenMixin",

View File

@@ -2,12 +2,8 @@
"required": true, "required": true,
"package": "dev.lambdaurora.lambdacontrols.client.compat.mixin", "package": "dev.lambdaurora.lambdacontrols.client.compat.mixin",
"plugin": "dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsMixinPlugin", "plugin": "dev.lambdaurora.lambdacontrols.client.compat.LambdaControlsMixinPlugin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_16",
"client": [ "client": [
"EntryListWidgetAccessor",
"EntryWidgetAccessor",
"RecipeViewingScreenAccessor",
"VillagerRecipeViewingScreenAccessor"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1