mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-13 15:25:08 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aabb728303 | ||
|
|
3b93a52568 | ||
|
|
797ab519de | ||
|
|
18df94c4e4 |
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: 'Bug: TITLE HERE'
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
@@ -21,17 +21,15 @@ Steps to reproduce the behavior:
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots or videos to help explain your problem.
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. Windows / Linux / MacOS]
|
||||
- Minecraft [e.g. 1.20.4]
|
||||
- Modloader [e.g. Fabric Loader 0.15.6]
|
||||
- Fabric/Quilt Libraries [e.g. Fabric Api 0.96.1+1.20.4]
|
||||
- Mods [e.g. Puzzle v1.6.1, LilTaterReloaded v1.1.15]
|
||||
- OS: [e.g. Linux]
|
||||
- Minecraft [e.g. 1.14.4]
|
||||
- Fabric [e.g. fabric 0.7.2+build.174]
|
||||
- Mods [e.g. aurora_keystrokes v1.0.0, modmenu v1.7.15]
|
||||
- Version [e.g. 1.0.0]
|
||||
- Remove this line if you actually completed it
|
||||
- Branch [e.g. dev]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
In case of a crash, please provide the crash log.
|
||||
|
||||
40
.github/ISSUE_TEMPLATE/controller_support.md
vendored
40
.github/ISSUE_TEMPLATE/controller_support.md
vendored
@@ -1,40 +0,0 @@
|
||||
---
|
||||
name: Controller support
|
||||
about: Report a problem related to a specific controller
|
||||
title: 'Controller Issues: CONTROLLER NAME HERE'
|
||||
labels: controller
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the current state**
|
||||
A clear and concise description of current state of support for the controller and the issues.
|
||||
|
||||
**To Reproduce**
|
||||
If needed, specify steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots or videos to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- Have you checked #263 for your controller? [e.g. Yes/No]
|
||||
- Connection method [e.g. Wired / Bluetooth]
|
||||
|
||||
- OS: [e.g. Windows / Linux / MacOS]
|
||||
- Minecraft [e.g. 1.20.4]
|
||||
- Modloader [e.g. Fabric Loader 0.15.6]
|
||||
- Fabric/Quilt Libraries [e.g. Fabric Api 0.96.1+1.20.4]
|
||||
- Mods [e.g. Puzzle v1.6.1, LilTaterReloaded v1.1.15]
|
||||
- Version [e.g. 1.0.0]
|
||||
- Remove this line if you actually completed it
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
In case of a crash, please provide the crash log.
|
||||
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: 'Feature: TITLE HERE'
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
@@ -17,4 +17,4 @@ A clear and concise description of what you want to happen.
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots/videos about the feature request here.
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
20
.github/ISSUE_TEMPLATE/mod_support.md
vendored
20
.github/ISSUE_TEMPLATE/mod_support.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Mod Support
|
||||
about: Compatibility improvements with a specific mod (not for crashes)
|
||||
title: 'Mod Support: MOD NAME HERE'
|
||||
labels: mod compatibility
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your compatibility request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I've always wanted to [...]
|
||||
|
||||
**Describe the way of compatibility you'd imagine**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative mods or workarounds you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots/videos about the compatibility request here.
|
||||
@@ -64,7 +64,11 @@ After this is done, everything should be built just fine!
|
||||
|
||||
## FAQ:
|
||||
### The controller does not work, and it's name appears in orange, what can I do?
|
||||
Create a custom mapping as pointed out in the [wiki](https://midnightdust.eu/wiki/midnightcontrols/)
|
||||
Orange controller names indicate a missing controller mapping.
|
||||
Download [GamepadTool](https://generalarcade.com/gamepadtool/), create and copy a mapping, go to MidnightControls' Mappings File Editor and paste the string.
|
||||
Alternatively, you can use [AntiMicroX](https://github.com/AntiMicroX/antimicroX) to create the mappings, in case the Gamepad Tool is not working for you.
|
||||
If that works, you might as well consider submitting the mapping by opening a PR in this repo: https://github.com/gabomdq/SDL_GameControllerDB
|
||||
That will make sure other people using the same controller as you don't have to use gamepad-tool anymore.
|
||||
|
||||
[Quilt]: https://quiltmc.org
|
||||
|
||||
|
||||
122
build.gradle
122
build.gradle
@@ -1,22 +1,53 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.6-SNAPSHOT'
|
||||
id 'fabric-loom' version '1.1-SNAPSHOT'
|
||||
id 'java-library'
|
||||
id 'maven-publish'
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
id "me.shedaniel.unified-publishing" version "0.1.+"
|
||||
id 'com.modrinth.minotaur' version '2.+'
|
||||
id 'net.darkhax.curseforgegradle' version '1.+'
|
||||
}
|
||||
|
||||
import net.darkhax.curseforgegradle.TaskPublishCurseForge
|
||||
|
||||
group = project.maven_group
|
||||
version = "${project.mod_version}+${project.minecraft_version}"
|
||||
version = "${project.mod_version}+${getMCVersionString()}"
|
||||
|
||||
// This field defines the Java version your mod target.
|
||||
def targetJavaVersion = 21
|
||||
def targetJavaVersion = 17
|
||||
|
||||
boolean isMCVersionNonRelease() {
|
||||
return project.minecraft_version.matches('^\\d\\dw\\d\\d[a-z]$')
|
||||
|| project.minecraft_version.matches('\\d+\\.\\d+-(pre|rc)(\\d+)')
|
||||
}
|
||||
|
||||
String getMCVersionString() {
|
||||
if (isMCVersionNonRelease() || project.minecraft_version == "1.20.4") {
|
||||
return project.minecraft_version
|
||||
}
|
||||
def version = project.minecraft_version.split('\\.')
|
||||
return version[0] + '.' + version[1]
|
||||
}
|
||||
|
||||
boolean pingUrl(String address) {
|
||||
try {
|
||||
def conn = (HttpURLConnection) new URL(address).openConnection()
|
||||
int responseCode = conn.getResponseCode()
|
||||
return (200 <= responseCode && responseCode <= 399)
|
||||
} catch (IOException ignored) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
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, '')
|
||||
return readme
|
||||
}
|
||||
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
@@ -52,7 +83,10 @@ dependencies {
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
include modImplementation ("maven.modrinth:obsidianui:${project.obsidianui_version}") {}
|
||||
modImplementation ("dev.lambdaurora:spruceui:${project.spruceui_version}") {
|
||||
exclude(group: "net.fabricmc.fabric-api")
|
||||
}
|
||||
include "dev.lambdaurora:spruceui:${project.spruceui_version}"
|
||||
api('org.aperlambda:lambdajcommon:1.8.1') {
|
||||
exclude group: 'com.google.code.gson'
|
||||
exclude group: 'com.google.guava'
|
||||
@@ -114,55 +148,39 @@ processResources {
|
||||
expand 'version': project.version
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
releaseChangelog = {
|
||||
def changes = new StringBuilder()
|
||||
changes << "## MidnightControls v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/TeamMidnightDust/MidnightControls/commits/)"
|
||||
def proc = "git log --max-count=1 --pretty=format:%s".execute()
|
||||
proc.in.eachLine { line ->
|
||||
def processedLine = line.toString()
|
||||
if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) {
|
||||
changes << "\n- ${processedLine.capitalize()}"
|
||||
}
|
||||
}
|
||||
proc.waitFor()
|
||||
return changes.toString()
|
||||
modrinth {
|
||||
token = System.getenv("MODRINTH_TOKEN") // Remember to have the MODRINTH_TOKEN environment variable set or else this will fail - just make sure it stays private!
|
||||
projectId = project.archives_base_name // This can be the project ID or the slug. Either will work!
|
||||
versionNumber = project.version // You don't need to set this manually. Will fail if Modrinth has this version already
|
||||
versionName = "MidnightControls " + project.mod_version + " - " + project.minecraft_version
|
||||
versionType = isMCVersionNonRelease() ? "beta" : "release" // Can also be `beta` or `alpha`
|
||||
uploadFile = remapJar // With Loom, this MUST be set to `remapJar` instead of `jar`!
|
||||
gameVersions = [(String) project.minecraft_version] // Must be an array, even with only one version
|
||||
loaders = ["fabric","quilt"] // Must also be an array - no need to specify this if you're using Loom or ForgeGradle
|
||||
dependencies { // A special DSL for creating dependencies
|
||||
// scope.type
|
||||
// The scope can be `required`, `optional`, `incompatible`, or `embedded`
|
||||
// The type can either be `project` or `version`
|
||||
required.project "midnightlib" // Creates a new required dependency on MidnightLib
|
||||
}
|
||||
changelog = project.changelog
|
||||
}
|
||||
tasks.register('publishCurseForge', TaskPublishCurseForge) {
|
||||
|
||||
unifiedPublishing {
|
||||
project {
|
||||
displayName = "MidnightControls v$project.version - Fabric $project.minecraft_version"
|
||||
releaseType = "$project.release_type"
|
||||
changelog = releaseChangelog()
|
||||
gameVersions = []
|
||||
gameLoaders = ["fabric","quilt"]
|
||||
mainPublication remapJar
|
||||
relations {
|
||||
includes {
|
||||
curseforge = "midnightlib"
|
||||
modrinth = "midnightlib"
|
||||
}
|
||||
}
|
||||
// This token is used to authenticate with CurseForge. It should be handled
|
||||
// with the same level of care and security as your actual password. You
|
||||
// should never share your token with an untrusted source or publish it
|
||||
// publicly to GitHub or embed it within a project. The best practice is to
|
||||
// store this token in an environment variable or a build secret.
|
||||
apiToken = System.getenv("CURSEFORGE_TOKEN")
|
||||
|
||||
var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN")
|
||||
if (CURSEFORGE_TOKEN != null) {
|
||||
curseforge {
|
||||
token = CURSEFORGE_TOKEN
|
||||
id = rootProject.curseforge_id
|
||||
gameVersions.addAll "Java 21", project.minecraft_version
|
||||
}
|
||||
}
|
||||
|
||||
var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN")
|
||||
if (MODRINTH_TOKEN != null) {
|
||||
modrinth {
|
||||
token = MODRINTH_TOKEN
|
||||
id = rootProject.modrinth_id
|
||||
version = "$project.version"
|
||||
gameVersions.addAll project.minecraft_version
|
||||
}
|
||||
}
|
||||
}
|
||||
// Tells CurseForgeGradle to publish the output of the jar task. This will
|
||||
// return a UploadArtifact object that can be used to further configure the
|
||||
// file.
|
||||
def mainFile = upload(project.curseforge_id, remapJar)
|
||||
mainFile.changelog = project.changelog
|
||||
mainFile.displayName = "MidnightControls " + project.mod_version + " - " + project.minecraft_version
|
||||
mainFile.addModLoader("Fabric", "Quilt")
|
||||
mainFile.addRequirement("midnightlib")
|
||||
mainFile.releaseType = "release"
|
||||
}
|
||||
|
||||
@@ -3,28 +3,28 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version=1.21
|
||||
yarn_mappings=1.21+build.1
|
||||
loader_version=0.15.11
|
||||
minecraft_version=1.20.1
|
||||
yarn_mappings=1.20.1+build.10
|
||||
loader_version=0.15.6
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.9.7
|
||||
mod_version = 1.9.4
|
||||
maven_group = eu.midnightdust
|
||||
archives_base_name = midnightcontrols
|
||||
release_type=beta
|
||||
modrinth_id = bXX9h73M
|
||||
curseforge_id = 621768
|
||||
changelog = See changes at: https://github.com/TeamMidnightDust/MidnightControls/commits/
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.100.1+1.21
|
||||
fabric_version=0.91.0+1.20.1
|
||||
sodium_version=mc1.19.2-0.4.4
|
||||
obsidianui_version=0.2.6+mc1.21-fabric
|
||||
midnightlib_version=1.5.7-fabric
|
||||
modmenu_version=10.0.0-beta.1
|
||||
spruceui_version=5.0.0+1.20
|
||||
midnightlib_version=1.4.1-fabric
|
||||
modmenu_version=7.0.0
|
||||
emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric
|
||||
bendylib_version=2.0.+
|
||||
emi_version=1.1.1+1.20.4+fabric
|
||||
emi_version=1.1.1+1.20.1+fabric
|
||||
libgui_version=6.0.0+1.19
|
||||
inventorytabs_version=inventorytabs-0.9.beta-1.19.x
|
||||
clothconfig_version=7.0.72
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -4,7 +4,6 @@ pluginManagement {
|
||||
name 'Fabric'
|
||||
url 'https://maven.fabricmc.net/'
|
||||
}
|
||||
maven { url "https://maven.architectury.dev/" }
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols;
|
||||
|
||||
import dev.lambdaurora.spruceui.util.Nameable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.thinkingstudio.obsidianui.util.Nameable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -9,17 +9,21 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback;
|
||||
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket;
|
||||
import eu.midnightdust.midnightcontrols.packet.FeaturePacket;
|
||||
import eu.midnightdust.midnightcontrols.packet.HelloPacket;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents the MidnightControls mod.
|
||||
@@ -30,9 +34,9 @@ import org.apache.logging.log4j.Logger;
|
||||
*/
|
||||
public class MidnightControls implements ModInitializer {
|
||||
private static MidnightControls INSTANCE;
|
||||
public static final CustomPayload.Id<CustomPayload> CONTROLS_MODE_CHANNEL = new CustomPayload.Id<>(MidnightControlsConstants.CONTROLS_MODE_CHANNEL);
|
||||
public static final CustomPayload.Id<CustomPayload> FEATURE_CHANNEL = new CustomPayload.Id<>(MidnightControlsConstants.FEATURE_CHANNEL);
|
||||
public static final CustomPayload.Id<CustomPayload> HELLO_CHANNEL = new CustomPayload.Id<>(MidnightControlsConstants.HELLO_CHANNEL);
|
||||
public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString());
|
||||
public static final Identifier FEATURE_CHANNEL = new Identifier(MidnightControlsConstants.FEATURE_CHANNEL.toString());
|
||||
public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString());
|
||||
public static boolean isExtrasLoaded;
|
||||
|
||||
public final Logger logger = LogManager.getLogger("MidnightControls");
|
||||
@@ -43,19 +47,19 @@ public class MidnightControls implements ModInitializer {
|
||||
isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra");
|
||||
this.log("Initializing MidnightControls...");
|
||||
|
||||
PayloadTypeRegistry.playC2S().register(HelloPacket.PACKET_ID, HelloPacket.codec);
|
||||
PayloadTypeRegistry.playC2S().register(ControlsModePacket.PACKET_ID, ControlsModePacket.codec);
|
||||
PayloadTypeRegistry.playS2C().register(ControlsModePacket.PACKET_ID, ControlsModePacket.codec);
|
||||
PayloadTypeRegistry.playS2C().register(FeaturePacket.PACKET_ID, FeaturePacket.codec);
|
||||
|
||||
ServerPlayNetworking.registerGlobalReceiver(HelloPacket.PACKET_ID, (payload, context) -> {
|
||||
ControlsMode.byId(payload.controlsMode())
|
||||
.ifPresent(controlsMode -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.player(), controlsMode));
|
||||
context.responseSender().sendPacket(new FeaturePacket(MidnightControlsFeature.HORIZONTAL_REACHAROUND));
|
||||
ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> {
|
||||
String version = buf.readString(32);
|
||||
ControlsMode.byId(buf.readString(32))
|
||||
.ifPresent(controlsMode -> server
|
||||
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode)));
|
||||
server.execute(() -> {
|
||||
ServerPlayNetworking.send(player, FEATURE_CHANNEL, this.makeFeatureBuffer(MidnightControlsFeature.HORIZONTAL_REACHAROUND));
|
||||
});
|
||||
});
|
||||
ServerPlayNetworking.registerGlobalReceiver(ControlsModePacket.PACKET_ID,
|
||||
(payload, context) -> ControlsMode.byId(payload.controlsMode())
|
||||
.ifPresent(controlsMode -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.player(), controlsMode)));
|
||||
ServerPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL,
|
||||
(server, player, handler, buf, responseSender) -> ControlsMode.byId(buf.readString(32))
|
||||
.ifPresent(controlsMode -> server
|
||||
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,6 +80,44 @@ public class MidnightControls implements ModInitializer {
|
||||
this.logger.info("[MidnightControls] " + warning);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a packet byte buffer made for the midnightcontrols:controls_mode plugin message.
|
||||
*
|
||||
* @param controlsMode the controls mode to send
|
||||
* @return the packet byte buffer
|
||||
*/
|
||||
public PacketByteBuf makeControlsModeBuffer(@NotNull ControlsMode controlsMode) {
|
||||
Objects.requireNonNull(controlsMode, "Controls mode cannot be null.");
|
||||
return new PacketByteBuf(Unpooled.buffer()).writeString(controlsMode.getName(), 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a packet byte buffer made for the midnightcontrols:feature plugin message.
|
||||
*
|
||||
* @param features the features data to send
|
||||
* @return the packet byte buffer
|
||||
*/
|
||||
public PacketByteBuf makeFeatureBuffer(MidnightControlsFeature... features) {
|
||||
if (features.length == 0)
|
||||
throw new IllegalArgumentException("At least one feature must be provided.");
|
||||
var buffer = new PacketByteBuf(Unpooled.buffer());
|
||||
buffer.writeVarInt(features.length);
|
||||
for (var feature : features) {
|
||||
buffer.writeString(feature.getName(), 64);
|
||||
buffer.writeBoolean(feature.isAllowed());
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public PacketByteBuf makeHello(@NotNull ControlsMode controlsMode) {
|
||||
var version = "";
|
||||
Optional<ModContainer> container;
|
||||
if ((container = FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE)).isPresent()) {
|
||||
version = container.get().getMetadata().getVersion().getFriendlyString();
|
||||
}
|
||||
return new PacketByteBuf(Unpooled.buffer()).writeString(version, 32).writeString(controlsMode.getName(), 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MidnightControls instance.
|
||||
*
|
||||
|
||||
@@ -21,7 +21,7 @@ import net.minecraft.util.Identifier;
|
||||
*/
|
||||
public class MidnightControlsConstants {
|
||||
public static final String NAMESPACE = "midnightcontrols";
|
||||
public static final Identifier CONTROLS_MODE_CHANNEL = Identifier.of(NAMESPACE, "controls_mode");
|
||||
public static final Identifier FEATURE_CHANNEL = Identifier.of(NAMESPACE, "feature");
|
||||
public static final Identifier HELLO_CHANNEL = Identifier.of(NAMESPACE, "hello");
|
||||
public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(NAMESPACE, "controls_mode");
|
||||
public static final Identifier FEATURE_CHANNEL = new Identifier(NAMESPACE, "feature");
|
||||
public static final Identifier HELLO_CHANNEL = new Identifier("lambdacontrols", "hello");
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols;
|
||||
|
||||
import org.thinkingstudio.obsidianui.util.Nameable;
|
||||
import dev.lambdaurora.spruceui.util.Nameable;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client;
|
||||
|
||||
import dev.lambdaurora.spruceui.event.OpenScreenCallback;
|
||||
import eu.midnightdust.lib.util.PlatformFunctions;
|
||||
import eu.midnightdust.midnightcontrols.ControlsMode;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControls;
|
||||
@@ -25,13 +26,8 @@ import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
|
||||
import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingIDAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.ring.ButtonBindingRingAction;
|
||||
import eu.midnightdust.midnightcontrols.client.ring.MidnightRing;
|
||||
import org.thinkingstudio.obsidianui.fabric.event.OpenScreenCallback;
|
||||
import org.thinkingstudio.obsidianui.hud.HudManager;
|
||||
import dev.lambdaurora.spruceui.hud.HudManager;
|
||||
import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
|
||||
import eu.midnightdust.midnightcontrols.client.util.RainbowColor;
|
||||
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket;
|
||||
import eu.midnightdust.midnightcontrols.packet.FeaturePacket;
|
||||
import eu.midnightdust.midnightcontrols.packet.HelloPacket;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
@@ -40,7 +36,6 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
@@ -52,7 +47,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.Objects;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Represents the midnightcontrols client mod.
|
||||
@@ -64,20 +61,20 @@ import java.util.*;
|
||||
public class MidnightControlsClient extends MidnightControls implements ClientModInitializer {
|
||||
public static boolean lateInitDone = false;
|
||||
private static MidnightControlsClient INSTANCE;
|
||||
public static final KeyBinding BINDING_LOOK_UP = InputManager.makeKeyBinding(Identifier.of(MidnightControlsConstants.NAMESPACE, "look_up"),
|
||||
public static final KeyBinding BINDING_LOOK_UP = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_up"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_8, "key.categories.movement");
|
||||
public static final KeyBinding BINDING_LOOK_RIGHT = InputManager.makeKeyBinding(Identifier.of(MidnightControlsConstants.NAMESPACE, "look_right"),
|
||||
public static final KeyBinding BINDING_LOOK_RIGHT = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_right"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_6, "key.categories.movement");
|
||||
public static final KeyBinding BINDING_LOOK_DOWN = InputManager.makeKeyBinding(Identifier.of(MidnightControlsConstants.NAMESPACE, "look_down"),
|
||||
public static final KeyBinding BINDING_LOOK_DOWN = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_down"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement");
|
||||
public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(Identifier.of(MidnightControlsConstants.NAMESPACE, "look_left"),
|
||||
public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_left"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement");
|
||||
public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(Identifier.of(MidnightControlsConstants.NAMESPACE, "ring"),
|
||||
public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "ring"),
|
||||
InputUtil.Type.KEYSYM, InputUtil.UNKNOWN_KEY.getCode(), "key.categories.misc");
|
||||
public static final Identifier CONTROLLER_BUTTONS = Identifier.of(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_buttons.png");
|
||||
public static final Identifier CONTROLLER_EXPANDED = Identifier.of(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_expanded.png");
|
||||
public static final Identifier CONTROLLER_AXIS = Identifier.of(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_axis.png");
|
||||
public static final Identifier CURSOR_TEXTURE = Identifier.of(MidnightControlsConstants.NAMESPACE, "textures/gui/cursor.png");
|
||||
public static final Identifier CONTROLLER_BUTTONS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_buttons.png");
|
||||
public static final Identifier CONTROLLER_EXPANDED = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_expanded.png");
|
||||
public static final Identifier CONTROLLER_AXIS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_axis.png");
|
||||
public static final Identifier CURSOR_TEXTURE = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/cursor.png");
|
||||
public final static File MAPPINGS_FILE = new File("config/gamecontrollercustommappings.txt");
|
||||
public final MidnightInput input = new MidnightInput();
|
||||
public final MidnightRing ring = new MidnightRing(this);
|
||||
@@ -96,26 +93,26 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
|
||||
|
||||
this.ring.registerAction("buttonbinding", ButtonBindingRingAction.FACTORY);
|
||||
|
||||
ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (payload, context) ->
|
||||
context.responseSender().sendPacket(new ControlsModePacket(MidnightControlsConfig.controlsMode.getName())));
|
||||
ClientPlayNetworking.registerGlobalReceiver(FeaturePacket.PACKET_ID, ((payload, context) -> {}));
|
||||
|
||||
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
|
||||
var version = "";
|
||||
Optional<ModContainer> container;
|
||||
if ((container = FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE)).isPresent()) {
|
||||
version = container.get().getMetadata().getVersion().getFriendlyString();
|
||||
ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) ->
|
||||
responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)));
|
||||
ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> {
|
||||
int features = buf.readVarInt();
|
||||
for (int i = 0; i < features; i++) {
|
||||
var name = buf.readString(64);
|
||||
boolean allowed = buf.readBoolean();
|
||||
MidnightControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed)));
|
||||
}
|
||||
var controlsMode = MidnightControlsConfig.controlsMode.getName();
|
||||
sender.sendPacket(new HelloPacket(version, controlsMode));
|
||||
sender.sendPacket(new ControlsModePacket(controlsMode));
|
||||
});
|
||||
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
|
||||
sender.sendPacket(HELLO_CHANNEL, this.makeHello(MidnightControlsConfig.controlsMode));
|
||||
sender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode));
|
||||
});
|
||||
ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave);
|
||||
|
||||
ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick);
|
||||
ClientTickEvents.START_CLIENT_TICK.register(this::onTick);
|
||||
|
||||
OpenScreenCallback.POST.register((client, screen) -> {
|
||||
OpenScreenCallback.EVENT.register((client, screen) -> {
|
||||
if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) {
|
||||
screen = new TouchscreenOverlay(this);
|
||||
screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
@@ -137,8 +134,8 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
|
||||
|
||||
HudManager.register(this.hud = new MidnightControlsHud(this));
|
||||
FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> {
|
||||
ResourceManagerHelper.registerBuiltinResourcePack(Identifier.of("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL);
|
||||
ResourceManagerHelper.registerBuiltinResourcePack(Identifier.of("midnightcontrols","legacy"), modContainer, ResourcePackActivationType.NORMAL);
|
||||
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL);
|
||||
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","legacy"), modContainer, ResourcePackActivationType.NORMAL);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -231,7 +228,6 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
|
||||
MidnightControlsConfig.enableHints = false;
|
||||
MidnightControlsConfig.save();
|
||||
}
|
||||
RainbowColor.tick();
|
||||
TouchInput.tick();
|
||||
}
|
||||
|
||||
@@ -257,7 +253,6 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
|
||||
|
||||
MidnightControlsConfig.controlsMode = this.previousControlsMode;
|
||||
}
|
||||
ClientPlayNetworking.getSender().sendPacket(new ControlsModePacket(MidnightControlsConfig.controlsMode.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
package eu.midnightdust.midnightcontrols.client;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.thinkingstudio.obsidianui.widget.AbstractSpruceWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceEntryListWidget;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControls;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.*;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
@@ -25,12 +25,12 @@ import eu.midnightdust.midnightcontrols.client.mixin.*;
|
||||
import eu.midnightdust.midnightcontrols.client.ring.RingPage;
|
||||
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
|
||||
import org.thinkingstudio.obsidianui.navigation.NavigationDirection;
|
||||
import org.thinkingstudio.obsidianui.screen.SpruceScreen;
|
||||
import org.thinkingstudio.obsidianui.widget.AbstractSprucePressableButtonWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceElement;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceLabelWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceParentWidget;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
import dev.lambdaurora.spruceui.screen.SpruceScreen;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceElement;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
|
||||
import eu.midnightdust.midnightcontrols.client.enums.ButtonState;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -489,7 +489,7 @@ public class MidnightInput {
|
||||
state = 1;
|
||||
asButtonState = 1;
|
||||
}
|
||||
//if (MidnightControlsConfig.debug) System.out.println(axis + " "+ value + " " + absValue + " " + state);
|
||||
if (MidnightControlsConfig.debug) System.out.println(axis + " "+ value + " " + absValue + " " + state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +565,7 @@ public class MidnightInput {
|
||||
var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen;
|
||||
// @TODO allow rebinding to left stick
|
||||
if (accessor.midnightcontrols$hasScrollbar() && absValue >= deadZone) {
|
||||
creativeInventoryScreen.mouseScrolled(0.0, 0.0, 0, -value);
|
||||
creativeInventoryScreen.mouseScrolled(0.0, 0.0, -value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -573,7 +573,7 @@ public class MidnightInput {
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
|
||||
// @TODO allow rebinding to left stick
|
||||
if (absValue >= deadZone) {
|
||||
merchantScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f));
|
||||
merchantScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -581,7 +581,7 @@ public class MidnightInput {
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
|
||||
// @TODO allow rebinding to left stick
|
||||
if (absValue >= deadZone) {
|
||||
stonecutterScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f));
|
||||
stonecutterScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -600,7 +600,7 @@ public class MidnightInput {
|
||||
.map(element -> (SpruceEntryListWidget<?>) element)
|
||||
.filter(AbstractSpruceWidget::isFocusedOrHovered)
|
||||
.noneMatch(element -> {
|
||||
element.mouseScrolled(0.0, 0.0, 0, -finalValue);
|
||||
element.mouseScrolled(0.0, 0.0, -finalValue);
|
||||
return true;
|
||||
})
|
||||
&&
|
||||
@@ -608,11 +608,11 @@ public class MidnightInput {
|
||||
.map(element -> (EntryListWidget<?>) element)
|
||||
.filter(element -> element.getType().isFocused())
|
||||
.noneMatch(element -> {
|
||||
element.mouseScrolled(0.0, 0.0, 0, -finalValue);
|
||||
element.mouseScrolled(0.0, 0.0, -finalValue);
|
||||
return true;
|
||||
}))
|
||||
{
|
||||
client.currentScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f));
|
||||
client.currentScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f));
|
||||
}
|
||||
else if (isScreenInteractive(client.currentScreen) && absValue >= deadZone) {
|
||||
if (value > 0 && joystickCooldown == 0) {
|
||||
|
||||
@@ -15,7 +15,6 @@ import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FluidBlock;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
@@ -75,7 +74,7 @@ public class MidnightReacharound {
|
||||
}
|
||||
|
||||
public static float getPlayerRange(@NotNull MinecraftClient client) {
|
||||
return client.player != null ? Double.valueOf(client.player.getAttributeValue(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE)).floatValue() : 0.f;
|
||||
return client.interactionManager != null ? client.interactionManager.getReachDistance() : 0.f;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.compat;
|
||||
|
||||
import eu.midnightdust.lib.util.PlatformFunctions;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
@@ -23,16 +22,23 @@ import java.util.Set;
|
||||
/**
|
||||
* This plugin is only present for the conditional mixins.
|
||||
*
|
||||
* @author LambdAurora & Motschen
|
||||
* @version 1.6.0
|
||||
* @author LambdAurora
|
||||
* @version 1.5.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class MidnightControlsMixinPlugin implements IMixinConfigPlugin {
|
||||
private String mixinPackage;
|
||||
private final HashMap<String, Boolean> conditionalMixins = new HashMap<>();
|
||||
|
||||
public MidnightControlsMixinPlugin() {
|
||||
//this.putConditionalMixin("SodiumOptionsGUIAccessor", FabricLoader.getInstance().isModLoaded("sodium"));
|
||||
}
|
||||
|
||||
private void putConditionalMixin(@NotNull String path, boolean condition) {
|
||||
this.conditionalMixins.put("eu.midnightdust.midnightcontrols.client.compat.mixin." + path, condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
this.mixinPackage = mixinPackage + ".";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,13 +48,7 @@ public class MidnightControlsMixinPlugin implements IMixinConfigPlugin {
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
final String mixinName = mixinClassName.substring(this.mixinPackage.length());
|
||||
final String packageName = mixinName.substring(0, mixinName.lastIndexOf('.'));
|
||||
|
||||
if (packageName.startsWith("sodium") && !PlatformFunctions.isModLoaded("sodium"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return this.conditionalMixins.getOrDefault(mixinClassName, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,7 +2,7 @@ package eu.midnightdust.midnightcontrols.client.compat;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.MidnightControls;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.mixin.sodium.SodiumOptionsGUIAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.mixin.SodiumOptionsGUIAccessor;
|
||||
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package eu.midnightdust.midnightcontrols.client.compat.mixin.sodium;
|
||||
package eu.midnightdust.midnightcontrols.client.compat.mixin;
|
||||
|
||||
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
|
||||
import me.jellysquid.mods.sodium.client.gui.options.OptionPage;
|
||||
@@ -76,7 +76,7 @@ public class ButtonBinding {
|
||||
public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A)
|
||||
.action(InputHandlers::handleScreenshot).cooldown().register();
|
||||
public static final ButtonBinding DEBUG_SCREEN = new Builder("debug_screen").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_B)
|
||||
.action((client,binding,value,action) -> {if (action == ButtonState.PRESS) client.inGameHud.getDebugHud().toggleDebugHud(); return true;}).cooldown().register();
|
||||
.action((client,binding,value,action) -> {if (action == ButtonState.PRESS) client.options.debugEnabled = !client.options.debugEnabled; return true;}).cooldown().register();
|
||||
public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
|
||||
.action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register();
|
||||
public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)
|
||||
@@ -88,7 +88,7 @@ public class ButtonBinding {
|
||||
public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
|
||||
.actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register();
|
||||
public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB)
|
||||
.actions(InputHandlers::handleToggleSprint).onlyInGame().cooldown().register();
|
||||
.actions(InputHandlers::handleToggleSprint).onlyInGame().register();
|
||||
public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register();
|
||||
public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
|
||||
.action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null)).cooldown().register();
|
||||
|
||||
@@ -151,17 +151,25 @@ public record Controller(int id) implements Nameable {
|
||||
private static boolean updateMappingsSync() {
|
||||
try {
|
||||
MidnightControlsClient.get().log("Updating controller mappings...");
|
||||
Optional<File> databaseFile = getDatabaseFile();
|
||||
if (databaseFile.isPresent()) {
|
||||
var database = ioResourceToBuffer(databaseFile.get().getPath(), 1024);
|
||||
if (database != null) GLFW.glfwUpdateGamepadMappings(database);
|
||||
}
|
||||
File databaseFile = new File("config/gamecontrollerdatabase.txt");
|
||||
try {
|
||||
BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream());
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile));
|
||||
byte[] dataBuffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||
out.write(dataBuffer, 0, bytesRead);
|
||||
}
|
||||
out.close();
|
||||
} catch (Exception ignored) {/* Just continue when internet connection is not available */}
|
||||
var database = ioResourceToBuffer(databaseFile.getPath(), 1024);
|
||||
if (database != null) GLFW.glfwUpdateGamepadMappings(database);
|
||||
if (!MidnightControlsClient.MAPPINGS_FILE.exists())
|
||||
return false;
|
||||
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
|
||||
if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
|
||||
} catch (IOException e) {
|
||||
e.fillInStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try (var memoryStack = MemoryStack.stackPush()) {
|
||||
@@ -174,8 +182,8 @@ public record Controller(int id) implements Nameable {
|
||||
if (client != null) {
|
||||
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.PERIODIC_NOTIFICATION,
|
||||
Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string)));
|
||||
MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string);
|
||||
}
|
||||
MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
/* Ignored :concern: */
|
||||
@@ -197,19 +205,4 @@ public record Controller(int id) implements Nameable {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Optional<File> getDatabaseFile() {
|
||||
File databaseFile = new File("config/gamecontrollerdatabase.txt");
|
||||
try {
|
||||
BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream());
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile));
|
||||
byte[] dataBuffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||
out.write(dataBuffer, 0, bytesRead);
|
||||
}
|
||||
out.close();
|
||||
} catch (Exception e) {return Optional.empty();}
|
||||
return Optional.of(databaseFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
|
||||
import eu.midnightdust.midnightcontrols.client.mixin.*;
|
||||
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
|
||||
import net.fabricmc.fabric.impl.client.itemgroup.CreativeGuiExtensions;
|
||||
import net.fabricmc.fabric.impl.client.itemgroup.FabricCreativeGuiComponents;
|
||||
import net.fabricmc.fabric.impl.itemgroup.FabricItemGroup;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
@@ -61,7 +64,11 @@ public class InputHandlers {
|
||||
private InputHandlers() {
|
||||
}
|
||||
private static List<ItemGroup> getVisibleGroups(CreativeInventoryScreen screen) {
|
||||
return (screen.getItemGroupsOnPage(screen.getCurrentPage()));
|
||||
return ItemGroups.getGroups().stream()
|
||||
.filter(itemGroup -> {
|
||||
if (FabricCreativeGuiComponents.COMMON_GROUPS.contains(itemGroup)) return true;
|
||||
return ((CreativeGuiExtensions)screen).fabric_currentPage() == ((FabricItemGroup)itemGroup).getPage() && itemGroup.shouldDisplay();
|
||||
}).toList();
|
||||
}
|
||||
|
||||
public static PressAction handleHotbar(boolean next) {
|
||||
@@ -150,7 +157,7 @@ public class InputHandlers {
|
||||
nextTab = tabs.size() - 1;
|
||||
else if (nextTab >= tabs.size())
|
||||
nextTab = 0;
|
||||
screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot().getAdvancementEntry(), true);
|
||||
screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot(), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -269,7 +276,7 @@ public class InputHandlers {
|
||||
if (action == ButtonState.PRESS) {
|
||||
// If in game, then pause the game.
|
||||
if (client.currentScreen == null || client.currentScreen instanceof RingScreen)
|
||||
client.openGameMenu(false);
|
||||
client.openPauseMenu(false);
|
||||
else if (client.currentScreen instanceof HandledScreen && client.player != null) // If the current screen is a container then close it.
|
||||
client.player.closeHandledScreen();
|
||||
else // Else just close the current screen.
|
||||
@@ -313,12 +320,12 @@ public class InputHandlers {
|
||||
boolean sprintToggled = client.options.getSprintToggled().getValue();
|
||||
if (client.player.getAbilities().flying && sprintToggled)
|
||||
client.options.getSprintToggled().setValue(false);
|
||||
else if (MidnightControlsConfig.controllerToggleSprint != sprintToggled)
|
||||
else if (MidnightControlsConfig.controllerToggleSneak != sprintToggled)
|
||||
client.options.getSprintToggled().setValue(!sprintToggled);
|
||||
binding.setPressed(button.pressed);
|
||||
if (client.player.getAbilities().flying && sprintToggled)
|
||||
client.options.getSprintToggled().setValue(true);
|
||||
else if (MidnightControlsConfig.controllerToggleSprint != sprintToggled)
|
||||
else if (MidnightControlsConfig.controllerToggleSneak != sprintToggled)
|
||||
client.options.getSprintToggled().setValue(sprintToggled);
|
||||
});
|
||||
return true;
|
||||
|
||||
@@ -73,8 +73,8 @@ public class InputManager {
|
||||
public void updateMousePosition(@NotNull MinecraftClient client) {
|
||||
Objects.requireNonNull(client, "Client instance cannot be null.");
|
||||
if (this.prevTargetMouseX != this.targetMouseX || this.prevTargetMouseY != this.targetMouseY) {
|
||||
double mouseX = this.prevTargetMouseX + (this.targetMouseX - this.prevTargetMouseX) * client.getRenderTickCounter().getTickDelta(true) + 0.5;
|
||||
double mouseY = this.prevTargetMouseY + (this.targetMouseY - this.prevTargetMouseY) * client.getRenderTickCounter().getTickDelta(true) + 0.5;
|
||||
double mouseX = this.prevTargetMouseX + (this.targetMouseX - this.prevTargetMouseX) * client.getTickDelta() + 0.5;
|
||||
double mouseY = this.prevTargetMouseY + (this.targetMouseY - this.prevTargetMouseY) * client.getTickDelta() + 0.5;
|
||||
if (!MidnightControlsConfig.virtualMouse)
|
||||
GLFW.glfwSetCursorPos(client.getWindow().getHandle(), mouseX, mouseY);
|
||||
((MouseAccessor) client.mouse).midnightcontrols$onCursorPos(client.getWindow().getHandle(), mouseX, mouseY);
|
||||
|
||||
@@ -14,18 +14,9 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.predicate.entity.MovementPredicate;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.apache.commons.lang3.mutable.MutableFloat;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
/**
|
||||
* Represents the movement handler.
|
||||
@@ -44,7 +35,7 @@ public final class MovementHandler implements PressAction {
|
||||
private float slowdownFactor = 1.f;
|
||||
private float movementForward = 0.f;
|
||||
private float movementSideways = 0.f;
|
||||
private final MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil();
|
||||
private MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil();
|
||||
|
||||
private MovementHandler() {
|
||||
}
|
||||
@@ -90,7 +81,7 @@ public final class MovementHandler implements PressAction {
|
||||
}
|
||||
|
||||
this.slowdownFactor = client.player.shouldSlowDown() ? (MathHelper.clamp(
|
||||
0.3F + (float) client.player.getAttributeValue(EntityAttributes.PLAYER_SNEAKING_SPEED),
|
||||
0.3F + EnchantmentHelper.getSwiftSneakSpeedBoost(client.player),
|
||||
0.0F,
|
||||
1.0F
|
||||
)) : 1.f;
|
||||
|
||||
@@ -11,10 +11,10 @@ package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.Controller;
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.option.SpruceOption;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceContainerWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.text.SpruceTextAreaWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.option.SpruceOption;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import dev.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import org.thinkingstudio.obsidianui.hud.Hud;
|
||||
import dev.lambdaurora.spruceui.hud.Hud;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
@@ -57,7 +57,7 @@ public class MidnightControlsHud extends Hud {
|
||||
private static boolean isCrammed = false;
|
||||
|
||||
public MidnightControlsHud(@NotNull MidnightControlsClient mod) {
|
||||
super(Identifier.of(MidnightControlsConstants.NAMESPACE, "hud/button_indicator"));
|
||||
super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator"));
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,24 +10,23 @@
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import org.thinkingstudio.obsidianui.background.Background;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceWidget;
|
||||
import dev.lambdaurora.spruceui.background.Background;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceWidget;
|
||||
import eu.midnightdust.lib.util.MidnightColorUtil;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControls;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.Controller;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget;
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.SpruceTexts;
|
||||
import org.thinkingstudio.obsidianui.option.*;
|
||||
import org.thinkingstudio.obsidianui.screen.SpruceScreen;
|
||||
import org.thinkingstudio.obsidianui.widget.AbstractSpruceWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceLabelWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceContainerWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceOptionListWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.tabbed.SpruceTabbedWidget;
|
||||
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.option.*;
|
||||
import dev.lambdaurora.spruceui.screen.SpruceScreen;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
@@ -93,7 +92,6 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
|
||||
id = GLFW.GLFW_JOYSTICK_1;
|
||||
id = searchNextAvailableController(id, false);
|
||||
MidnightControlsConfig.setController(Controller.byId(id));
|
||||
if (MidnightControlsConfig.debug) System.out.println(Controller.byId(id).getName() + "'s Controller GUID: " + Controller.byId(id).getGuid());
|
||||
},
|
||||
option -> {
|
||||
var controller = MidnightControlsConfig.getController();
|
||||
@@ -184,7 +182,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
|
||||
MidnightControlsConfig.save();
|
||||
|
||||
if (this.client != null && this.client.player != null) {
|
||||
ClientPlayNetworking.getSender().sendPacket(new ControlsModePacket(next.getName()));
|
||||
ClientPlayNetworking.getSender().sendPacket(MidnightControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next));
|
||||
}
|
||||
}, option -> option.getDisplayText(Text.translatable(MidnightControlsConfig.controlsMode.getTranslationKey())),
|
||||
Text.translatable("midnightcontrols.menu.controls_mode.tooltip"));
|
||||
@@ -509,14 +507,15 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
|
||||
float g = (float)(color.getGreen()) / 255.0F;
|
||||
float b = (float)(color.getBlue()) / 255.0F;
|
||||
float t = (float)(transparency) / 255.0F;
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorProgram);
|
||||
bufferBuilder.vertex(matrix, (float)x1, (float)y2, 0.0F).color(r, g, b, t);
|
||||
bufferBuilder.vertex(matrix, (float)x2, (float)y2, 0.0F).color(r, g, b, t);
|
||||
bufferBuilder.vertex(matrix, (float)x2, (float)y1, 0.0F).color(r, g, b, t);
|
||||
bufferBuilder.vertex(matrix, (float)x1, (float)y1, 0.0F).color(r, g, b, t);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
|
||||
bufferBuilder.vertex(matrix, (float)x1, (float)y2, 0.0F).color(r, g, b, t).next();
|
||||
bufferBuilder.vertex(matrix, (float)x2, (float)y2, 0.0F).color(r, g, b, t).next();
|
||||
bufferBuilder.vertex(matrix, (float)x2, (float)y1, 0.0F).color(r, g, b, t).next();
|
||||
bufferBuilder.vertex(matrix, (float)x1, (float)y1, 0.0F).color(r, g, b, t).next();
|
||||
BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
|
||||
RenderSystem.disableBlend();
|
||||
matrixStack.pop();
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.controller.Controller;
|
||||
import org.thinkingstudio.obsidianui.option.SpruceSimpleActionOption;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.option.SpruceSimpleActionOption;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import eu.midnightdust.lib.util.PlatformFunctions;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
|
||||
import eu.midnightdust.midnightcontrols.client.enums.ButtonState;
|
||||
@@ -20,6 +20,7 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.EmotecraftCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.widget.TextIconButtonWidget;
|
||||
import eu.midnightdust.midnightcontrols.client.touch.gui.ItemUseButtonWidget;
|
||||
import eu.midnightdust.midnightcontrols.client.touch.gui.SilentTexturedButtonWidget;
|
||||
import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
|
||||
@@ -27,10 +28,7 @@ import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.*;
|
||||
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
|
||||
import net.minecraft.client.gui.widget.TextIconButtonWidget;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.texture.MissingSprite;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.item.*;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
@@ -51,7 +49,7 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
|
||||
* Represents the touchscreen overlay
|
||||
*/
|
||||
public class TouchscreenOverlay extends Screen {
|
||||
public static final Identifier WIDGETS_LOCATION = Identifier.of("midnightcontrols", "textures/gui/widgets.png");
|
||||
public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png");
|
||||
private final MidnightControlsClient mod;
|
||||
private SilentTexturedButtonWidget inventoryButton;
|
||||
private SilentTexturedButtonWidget swapHandsButton;
|
||||
@@ -84,10 +82,7 @@ public class TouchscreenOverlay extends Screen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderInGameBackground(DrawContext context) {}
|
||||
|
||||
@Override
|
||||
protected void applyBlur(float delta) {}
|
||||
public void renderBackground(DrawContext context) {}
|
||||
|
||||
private void pauseGame() {
|
||||
assert this.client != null;
|
||||
@@ -168,15 +163,15 @@ public class TouchscreenOverlay extends Screen {
|
||||
int emoteOffset = 0;
|
||||
if (PlatformFunctions.isModLoaded("emotecraft")) {
|
||||
emoteOffset = 10;
|
||||
TextIconButtonWidget emoteButton = TextIconButtonWidget.builder(Text.empty(), btn -> EmotecraftCompat.openEmotecraftScreen(this), true).width(20).texture(Identifier.of(MidnightControlsConstants.NAMESPACE, "touch/emote"), 20, 20).build();
|
||||
TextIconButtonWidget emoteButton = TextIconButtonWidget.builder(Text.empty(), btn -> EmotecraftCompat.openEmotecraftScreen(this), true).width(20).texture(new Identifier(MidnightControlsConstants.NAMESPACE, "touch/emote"), 20, 20).build();
|
||||
emoteButton.setPosition(scaledWidth / 2 - 30, 0);
|
||||
this.addDrawableChild(emoteButton);
|
||||
}
|
||||
|
||||
TextIconButtonWidget chatButton = TextIconButtonWidget.builder(Text.empty(), btn -> this.client.setScreen(new ChatScreen("")), true).width(20).texture(Identifier.of(MidnightControlsConstants.NAMESPACE, "touch/chat"), 20, 20).build();
|
||||
TextIconButtonWidget chatButton = TextIconButtonWidget.builder(Text.empty(), btn -> this.client.setScreen(new ChatScreen("")), true).width(20).texture(new Identifier(MidnightControlsConstants.NAMESPACE, "touch/chat"), 20, 20).build();
|
||||
chatButton.setPosition(scaledWidth / 2 - 20 + emoteOffset, 0);
|
||||
this.addDrawableChild(chatButton);
|
||||
TextIconButtonWidget pauseButton = TextIconButtonWidget.builder(Text.empty(), btn -> this.pauseGame(), true).width(20).texture(Identifier.of(MidnightControlsConstants.NAMESPACE, "touch/pause"), 20, 20).build();
|
||||
TextIconButtonWidget pauseButton = TextIconButtonWidget.builder(Text.empty(), btn -> this.pauseGame(), true).width(20).texture(new Identifier(MidnightControlsConstants.NAMESPACE, "touch/pause"), 20, 20).build();
|
||||
pauseButton.setPosition(scaledWidth / 2 + emoteOffset, 0);
|
||||
this.addDrawableChild(pauseButton);
|
||||
// Inventory buttons.
|
||||
@@ -291,17 +286,16 @@ public class TouchscreenOverlay extends Screen {
|
||||
}
|
||||
private void initCustomButtons(boolean left) {
|
||||
assert client != null;
|
||||
Identifier emptySprite = Identifier.of(MidnightControlsConstants.NAMESPACE, "touch/empty");
|
||||
Identifier emptySprite = new Identifier(MidnightControlsConstants.NAMESPACE, "touch/empty");
|
||||
List<String> list = left ? MidnightControlsConfig.leftTouchBinds : MidnightControlsConfig.rightTouchBinds;
|
||||
Sprite missingSprite = client.getGuiAtlasManager().getSprite(MissingSprite.getMissingSpriteId());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
String bindName = list.get(i);
|
||||
ButtonBinding binding = InputManager.getBinding(bindName);
|
||||
if (binding == null) continue;
|
||||
boolean hasTexture = client.getGuiAtlasManager().getSprite(Identifier.of(MidnightControlsConstants.NAMESPACE, "binding/"+bindName)) != missingSprite;
|
||||
if (MidnightControlsConfig.debug) System.out.println(left +" "+Identifier.of(MidnightControlsConstants.NAMESPACE, "binding/"+bindName)+" "+ hasTexture);
|
||||
boolean hasTexture = client.getTextureManager().getOrDefault(new Identifier(MidnightControlsConstants.NAMESPACE, "binding/"+bindName), null) != null;
|
||||
if (MidnightControlsConfig.debug) System.out.println(left +" "+new Identifier(MidnightControlsConstants.NAMESPACE, "binding/"+bindName)+" "+ hasTexture);
|
||||
var button = TextIconButtonWidget.builder(Text.translatable(binding.getTranslationKey()), b -> binding.handle(client, 1, ButtonState.PRESS), hasTexture)
|
||||
.texture(hasTexture ? Identifier.of(MidnightControlsConstants.NAMESPACE, "binding/"+bindName) : emptySprite, 20, 20).dimension(20, 20).build();
|
||||
.texture(hasTexture ? new Identifier(MidnightControlsConstants.NAMESPACE, "binding/"+bindName) : emptySprite, 20, 20).dimension(20, 20).build();
|
||||
button.setPosition(left ? (3+(i*23)) : this.width-(23+(i*23)), 3);
|
||||
button.setAlpha(MidnightControlsConfig.touchTransparency / 100f);
|
||||
this.addDrawableChild(button);
|
||||
|
||||
@@ -11,9 +11,9 @@ package eu.midnightdust.midnightcontrols.client.gui.widget;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer;
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.SpruceTexts;
|
||||
import org.thinkingstudio.obsidianui.widget.AbstractSpruceIconButtonWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
@@ -13,10 +13,10 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.SpruceTexts;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceContainerWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
|
||||
|
||||
@@ -14,19 +14,20 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.SpruceTexts;
|
||||
import org.thinkingstudio.obsidianui.navigation.NavigationDirection;
|
||||
import org.thinkingstudio.obsidianui.navigation.NavigationUtils;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceSeparatorWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceEntryListWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceParentWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationUtils;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceSeparatorWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package eu.midnightdust.midnightcontrols.client.gui.widget;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class TextIconButtonWidget extends net.minecraft.client.gui.widget.ButtonWidget {
|
||||
protected final Identifier texture;
|
||||
protected final int textureWidth;
|
||||
protected final int textureHeight;
|
||||
|
||||
TextIconButtonWidget(int width, int height, Text message, int textureWidth, int textureHeight, Identifier texture, net.minecraft.client.gui.widget.ButtonWidget.PressAction onPress) {
|
||||
super(0, 0, width, height, message, onPress, DEFAULT_NARRATION_SUPPLIER);
|
||||
this.textureWidth = textureWidth;
|
||||
this.textureHeight = textureHeight;
|
||||
this.texture = new Identifier(texture.getNamespace(), "textures/gui/sprites/"+texture.getPath()+".png");
|
||||
}
|
||||
|
||||
public static Builder builder(Text text, net.minecraft.client.gui.widget.ButtonWidget.PressAction onPress, boolean hideLabel) {
|
||||
return new Builder(text, onPress, hideLabel);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Builder {
|
||||
private final Text text;
|
||||
private final net.minecraft.client.gui.widget.ButtonWidget.PressAction onPress;
|
||||
private final boolean hideText;
|
||||
private int width = 150;
|
||||
private int height = 20;
|
||||
@Nullable
|
||||
private Identifier texture;
|
||||
private int textureWidth;
|
||||
private int textureHeight;
|
||||
|
||||
public Builder(Text text, net.minecraft.client.gui.widget.ButtonWidget.PressAction onPress, boolean hideText) {
|
||||
this.text = text;
|
||||
this.onPress = onPress;
|
||||
this.hideText = hideText;
|
||||
}
|
||||
|
||||
public Builder width(int width) {
|
||||
this.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder dimension(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder texture(Identifier texture, int width, int height) {
|
||||
this.texture = texture;
|
||||
this.textureWidth = width;
|
||||
this.textureHeight = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextIconButtonWidget build() {
|
||||
if (this.texture == null) {
|
||||
throw new IllegalStateException("Sprite not set");
|
||||
} else {
|
||||
return this.hideText ? new IconOnly(this.width, this.height, this.text, this.textureWidth, this.textureHeight, this.texture, this.onPress) : new WithText(this.width, this.height, this.text, this.textureWidth, this.textureHeight, this.texture, this.onPress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class WithText extends TextIconButtonWidget {
|
||||
protected WithText(int i, int j, Text text, int k, int l, Identifier identifier, net.minecraft.client.gui.widget.ButtonWidget.PressAction pressAction) {
|
||||
super(i, j, text, k, l, identifier, pressAction);
|
||||
}
|
||||
|
||||
public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
super.renderButton(context, mouseX, mouseY, delta);
|
||||
int i = this.getX() + this.getWidth() - this.textureWidth - 2;
|
||||
int j = this.getY() + this.getHeight() / 2 - this.textureHeight / 2;
|
||||
context.drawTexture(this.texture, i, j, 0, 0, this.getWidth(), this.getHeight(), this.textureWidth, this.textureHeight);
|
||||
}
|
||||
|
||||
public void drawMessage(DrawContext context, TextRenderer textRenderer, int color) {
|
||||
int i = this.getX() + 2;
|
||||
int j = this.getX() + this.getWidth() - this.textureWidth - 4;
|
||||
int k = this.getX() + this.getWidth() / 2;
|
||||
drawScrollableText(context, textRenderer, this.getMessage(), k, i, this.getY(), j, color);
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class IconOnly extends TextIconButtonWidget {
|
||||
protected IconOnly(int i, int j, Text text, int k, int l, Identifier identifier, ButtonWidget.PressAction pressAction) {
|
||||
super(i, j, text, k, l, identifier, pressAction);
|
||||
}
|
||||
|
||||
public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
super.renderButton(context, mouseX, mouseY, delta);
|
||||
int i = this.getX() + this.getWidth() / 2 - this.textureWidth / 2;
|
||||
int j = this.getY() + this.getHeight() / 2 - this.textureHeight / 2;
|
||||
context.drawTexture(this.texture, i, j, 0, 0, this.getWidth(), this.getHeight(), this.textureWidth, this.textureHeight);
|
||||
}
|
||||
|
||||
public void drawMessage(DrawContext context, TextRenderer textRenderer, int color) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,16 +10,14 @@
|
||||
package eu.midnightdust.midnightcontrols.client.mixin;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.widget.TextIconButtonWidget;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
|
||||
import net.minecraft.client.gui.screen.option.GameOptionsScreen;
|
||||
import net.minecraft.client.gui.widget.TextIconButtonWidget;
|
||||
import net.minecraft.client.option.GameOptions;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -29,28 +27,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
*/
|
||||
@Mixin(ControlsOptionsScreen.class)
|
||||
public abstract class ControlsOptionsScreenMixin extends GameOptionsScreen {
|
||||
|
||||
public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text title) {
|
||||
super(parent, gameOptions, title);
|
||||
public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) {
|
||||
super(parent, gameOptions, text);
|
||||
}
|
||||
@Unique TextIconButtonWidget button = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
|
||||
.dimension(20,20).texture(Identifier.of("midnightcontrols", "icon/controller"), 20, 20).build();
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
this.midnightcontrols$setupButton();
|
||||
this.addDrawableChild(button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(MinecraftClient client, int width, int height) {
|
||||
super.resize(client, width, height);
|
||||
this.midnightcontrols$setupButton();
|
||||
}
|
||||
@Unique
|
||||
public void midnightcontrols$setupButton() {
|
||||
assert body != null;
|
||||
button.setPosition(body.getWidth() / 2 + 158, body.getY() + 4);
|
||||
@Inject(method = "init", at = @At(value = "INVOKE", ordinal = 1, shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/screen/option/ControlsOptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;"))
|
||||
private void addControllerButton(CallbackInfo ci) {
|
||||
TextIconButtonWidget iconWidget = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
|
||||
.dimension(20,20).texture(new Identifier("midnightcontrols", "icon/controller"), 20, 20).build();
|
||||
iconWidget.setPosition(this.width / 2 + 158, this.height / 6 - 12);
|
||||
this.addDrawableChild(iconWidget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import eu.midnightdust.midnightcontrols.ControlsMode;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
@@ -19,14 +18,14 @@ import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
import org.joml.Matrix4f;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(GameRenderer.class)
|
||||
public abstract class GameRendererMixin {
|
||||
@@ -35,20 +34,19 @@ public abstract class GameRendererMixin {
|
||||
MinecraftClient client;
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Mouse;getX()D", shift = At.Shift.BEFORE))
|
||||
private void onRender(RenderTickCounter tickCounter, boolean tick, CallbackInfo ci) {
|
||||
private void onRender(float tickDelta, long startTime, boolean fullRender, CallbackInfo ci) {
|
||||
if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER)
|
||||
MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen);
|
||||
}
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE))
|
||||
private void renderVirtualCursor(RenderTickCounter tickCounter, boolean tick, CallbackInfo ci, @Local DrawContext drawContext) {
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILSOFT)
|
||||
private void renderVirtualCursor(float tickDelta, long startTime, boolean tick, CallbackInfo ci, MatrixStack matrixStack, DrawContext drawContext) {
|
||||
MidnightControlsRenderer.renderVirtualCursor(drawContext, client);
|
||||
drawContext.draw();
|
||||
}
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z"), method = "renderWorld")
|
||||
private void captureProjAndModMatrix(RenderTickCounter tickCounter, CallbackInfo ci, @Local(ordinal = 1) Matrix4f matrices) {
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z", ordinal = 0), method = "renderWorld")
|
||||
private void postWorldRender(float tickDelta, long limitTime, MatrixStack matrix, CallbackInfo ci) {
|
||||
TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix());
|
||||
TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix());
|
||||
TouchUtils.lastWorldSpaceMatrix.set(matrices);
|
||||
TouchUtils.lastWorldSpaceMatrix.set(matrix.peek().getPositionMatrix());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,11 @@ import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.Mouse;
|
||||
import net.minecraft.client.util.GlfwUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ThrowablePotionItem;
|
||||
import net.minecraft.util.UseAction;
|
||||
import net.minecraft.util.math.Smoother;
|
||||
import net.minecraft.client.util.SmoothUtil;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -55,11 +51,11 @@ public abstract class MouseMixin implements MouseAccessor {
|
||||
|
||||
@Shadow private boolean hasResolutionChanged;
|
||||
|
||||
@Shadow private double glfwTime;
|
||||
@Shadow private double lastMouseUpdateTime;
|
||||
|
||||
@Shadow @Final private Smoother cursorXSmoother;
|
||||
@Shadow @Final private SmoothUtil cursorXSmoother;
|
||||
|
||||
@Shadow @Final private Smoother cursorYSmoother;
|
||||
@Shadow @Final private SmoothUtil cursorYSmoother;
|
||||
|
||||
@Shadow private boolean leftButtonClicked;
|
||||
|
||||
@@ -120,8 +116,8 @@ public abstract class MouseMixin implements MouseAccessor {
|
||||
cursorYSmoother.clear();
|
||||
}
|
||||
EyeTrackerHandler.updateMouseWithEyeTracking(x + cursorDeltaX, y + cursorDeltaY, client,
|
||||
glfwTime, leftButtonClicked, isUsingLongRangedTool(), cursorXSmoother, cursorYSmoother);
|
||||
glfwTime = GlfwUtil.getTime();
|
||||
lastMouseUpdateTime, leftButtonClicked, cursorXSmoother, cursorYSmoother);
|
||||
lastMouseUpdateTime = GlfwUtil.getTime();
|
||||
cursorDeltaX = 0.0;
|
||||
cursorDeltaY = 0.0;
|
||||
ci.cancel();
|
||||
@@ -131,14 +127,6 @@ public abstract class MouseMixin implements MouseAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private boolean isUsingLongRangedTool() {
|
||||
if (client.player == null) return false;
|
||||
ItemStack stack = client.player.getActiveItem();
|
||||
return (leftButtonClicked && (stack.getUseAction() == UseAction.BOW || stack.getUseAction() == UseAction.CROSSBOW ||
|
||||
stack.getUseAction() == UseAction.SPEAR || stack.getItem() instanceof ThrowablePotionItem));
|
||||
}
|
||||
|
||||
@Inject(method = "lockCursor", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/InputUtil;setCursorParameters(JIDD)V",shift = At.Shift.BEFORE), cancellable = true)
|
||||
private void midnightcontrols$lockCursor(CallbackInfo ci) {
|
||||
if ((doMixedInput() || MidnightControlsConfig.eyeTrackerAsMouse)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package eu.midnightdust.midnightcontrols.client.mixin;
|
||||
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import eu.midnightdust.midnightcontrols.ControlsMode;
|
||||
import eu.midnightdust.midnightcontrols.client.enums.ButtonState;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
|
||||
@@ -9,14 +9,12 @@
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import eu.midnightdust.lib.util.MidnightColorUtil;
|
||||
import eu.midnightdust.midnightcontrols.ControlsMode;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
|
||||
import eu.midnightdust.midnightcontrols.client.enums.TouchMode;
|
||||
import eu.midnightdust.midnightcontrols.client.util.RainbowColor;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.*;
|
||||
@@ -62,7 +60,6 @@ public abstract class WorldRendererMixin {
|
||||
@Shadow
|
||||
private static void drawCuboidShapeOutline(MatrixStack matrices, VertexConsumer vertexConsumer, VoxelShape shape, double offsetX, double offsetY, double offsetZ, float red, float green, float blue, float alpha) {
|
||||
}
|
||||
|
||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"))
|
||||
private HitResult.Type dontRenderOutline(HitResult instance) {
|
||||
if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
|
||||
@@ -80,7 +77,8 @@ public abstract class WorldRendererMixin {
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
private void onOutlineRender(RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci, @Local MatrixStack matrices) {
|
||||
private void onOutlineRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer,
|
||||
LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
if (((MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.touchInControllerMode) || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN)
|
||||
&& MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
|
||||
this.renderFingerOutline(matrices, camera);
|
||||
@@ -96,7 +94,7 @@ public abstract class WorldRendererMixin {
|
||||
if (this.world.getWorldBorder().contains(blockPos) && this.client.player != null) {
|
||||
var outlineShape = this.world.getBlockState(blockPos).getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
|
||||
Color rgb = MidnightColorUtil.hex2Rgb(MidnightControlsConfig.touchOutlineColorHex);
|
||||
if (MidnightControlsConfig.touchOutlineColorHex.isEmpty()) rgb = RainbowColor.radialRainbow(1,1);
|
||||
if (MidnightControlsConfig.touchOutlineColorHex.isEmpty()) rgb = MidnightColorUtil.radialRainbow(1,1);
|
||||
var pos = camera.getPos();
|
||||
matrices.push();
|
||||
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
|
||||
@@ -131,7 +129,7 @@ public abstract class WorldRendererMixin {
|
||||
|
||||
var outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
|
||||
Color rgb = MidnightColorUtil.hex2Rgb(MidnightControlsConfig.reacharoundOutlineColorHex);
|
||||
if (MidnightControlsConfig.reacharoundOutlineColorHex.isEmpty()) rgb = RainbowColor.radialRainbow(1,1);
|
||||
if (MidnightControlsConfig.reacharoundOutlineColorHex.isEmpty()) rgb = MidnightColorUtil.radialRainbow(1,1);
|
||||
matrices.push();
|
||||
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
|
||||
drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape,
|
||||
|
||||
@@ -2,8 +2,8 @@ package eu.midnightdust.midnightcontrols.client.mouse;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.util.GlfwUtil;
|
||||
import net.minecraft.client.util.SmoothUtil;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import net.minecraft.util.math.Smoother;
|
||||
|
||||
public class EyeTrackerHandler {
|
||||
|
||||
@@ -15,9 +15,8 @@ public class EyeTrackerHandler {
|
||||
MinecraftClient client,
|
||||
double lastMouseUpdateTime,
|
||||
boolean holdingLeftMouseButton,
|
||||
boolean usingLongRangedTool,
|
||||
Smoother smoothX,
|
||||
Smoother smoothY
|
||||
SmoothUtil smoothX,
|
||||
SmoothUtil smoothY
|
||||
) {
|
||||
// The player wants objects of interest to be moved under the crosshair that is always center of screen.
|
||||
// Normal mouse controls operate with the delta values from the direction of mouse movement,
|
||||
@@ -46,7 +45,7 @@ public class EyeTrackerHandler {
|
||||
} else {
|
||||
frameScalar = moveScalar;
|
||||
}
|
||||
if(holdingLeftMouseButton && !usingLongRangedTool) {
|
||||
if(holdingLeftMouseButton){
|
||||
frameScalar *= 0.5; //Don't move the camera so much while mining. It's annoying.
|
||||
}
|
||||
|
||||
@@ -69,8 +68,7 @@ public class EyeTrackerHandler {
|
||||
if (client.options.getInvertYMouse().getValue()) {
|
||||
invertY = -1.0;
|
||||
}
|
||||
boolean notInDeadzone = (moveMagnitude > MidnightControlsConfig.eyeTrackerDeadzone) && !usingLongRangedTool;
|
||||
if (client.player != null && notInDeadzone) {
|
||||
if (client.player != null && moveMagnitude > MidnightControlsConfig.eyeTrackerDeadzone) {
|
||||
client.player.changeLookDirection(moveX, moveY * invertY);
|
||||
client.getTutorialManager().onUpdateMouse(moveX, moveY);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package eu.midnightdust.midnightcontrols.client.touch.gui;
|
||||
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.PotionItem;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.UseAction;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package eu.midnightdust.midnightcontrols.client.touch.gui;
|
||||
|
||||
import org.thinkingstudio.obsidianui.Position;
|
||||
import org.thinkingstudio.obsidianui.widget.SpruceTexturedButtonWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package eu.midnightdust.midnightcontrols.client.util;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class RainbowColor {
|
||||
public static float hue;
|
||||
public static void tick() {
|
||||
if (hue > 1) hue = 0f;
|
||||
hue = hue + 0.01f;
|
||||
}
|
||||
|
||||
public static Color radialRainbow(float saturation, float brightness) {
|
||||
return Color.getHSBColor(hue, saturation, brightness);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package eu.midnightdust.midnightcontrols.packet;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.RegistryByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodec;
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public record ControlsModePacket(String controlsMode) implements CustomPayload {
|
||||
public static final Id<ControlsModePacket> PACKET_ID = new Id<>(MidnightControlsConstants.CONTROLS_MODE_CHANNEL);
|
||||
public static final PacketCodec<RegistryByteBuf, ControlsModePacket> codec = PacketCodec.of(ControlsModePacket::write, ControlsModePacket::read);
|
||||
|
||||
public static ControlsModePacket read(RegistryByteBuf buf) {
|
||||
return new ControlsModePacket(buf.readString(32));
|
||||
}
|
||||
|
||||
public void write(RegistryByteBuf buf) {
|
||||
Objects.requireNonNull(controlsMode, "Controls mode cannot be null.");
|
||||
buf.writeString(controlsMode, 32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id<? extends CustomPayload> getId() {
|
||||
return PACKET_ID;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package eu.midnightdust.midnightcontrols.packet;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControlsFeature;
|
||||
import net.minecraft.network.RegistryByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodec;
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
|
||||
public record FeaturePacket(MidnightControlsFeature... features) implements CustomPayload {
|
||||
public static final Id<FeaturePacket> PACKET_ID = new Id<>(MidnightControlsConstants.FEATURE_CHANNEL);
|
||||
public static final PacketCodec<RegistryByteBuf, FeaturePacket> codec = PacketCodec.of(FeaturePacket::write, FeaturePacket::read);
|
||||
|
||||
public static FeaturePacket read(RegistryByteBuf buf) {
|
||||
int featureLength = buf.readVarInt();
|
||||
MidnightControlsFeature[] receivedFeatures = new MidnightControlsFeature[featureLength];
|
||||
for (int i = 0; i < featureLength; i++) {
|
||||
var name = buf.readString(64);
|
||||
boolean allowed = buf.readBoolean();
|
||||
var feature = MidnightControlsFeature.fromName(name);
|
||||
if (feature.isPresent()) {
|
||||
feature.get().setAllowed(allowed);
|
||||
receivedFeatures[i] = feature.get();
|
||||
}
|
||||
}
|
||||
return new FeaturePacket(receivedFeatures);
|
||||
}
|
||||
|
||||
public void write(RegistryByteBuf buf) {
|
||||
if (features.length == 0)
|
||||
throw new IllegalArgumentException("At least one feature must be provided.");
|
||||
|
||||
buf.writeVarInt(features.length);
|
||||
for (var feature : features) {
|
||||
buf.writeString(feature.getName(), 64);
|
||||
buf.writeBoolean(feature.isAllowed());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id<? extends CustomPayload> getId() {
|
||||
return PACKET_ID;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package eu.midnightdust.midnightcontrols.packet;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
|
||||
import net.minecraft.network.RegistryByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodec;
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
|
||||
public record HelloPacket(String version, String controlsMode) implements CustomPayload {
|
||||
public static final CustomPayload.Id<HelloPacket> PACKET_ID = new CustomPayload.Id<>(MidnightControlsConstants.HELLO_CHANNEL);
|
||||
public static final PacketCodec<RegistryByteBuf, HelloPacket> codec = PacketCodec.of(HelloPacket::write, HelloPacket::read);
|
||||
|
||||
public static HelloPacket read(RegistryByteBuf buf) {
|
||||
return new HelloPacket(buf.readString(32), buf.readString(32));
|
||||
}
|
||||
|
||||
public void write(RegistryByteBuf buf) {
|
||||
buf.writeString(version, 32).writeString(controlsMode, 32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id<? extends CustomPayload> getId() {
|
||||
return PACKET_ID;
|
||||
}
|
||||
}
|
||||
@@ -53,10 +53,13 @@
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.3",
|
||||
"fabric": ">=0.71.0",
|
||||
"minecraft": ">=1.20.5",
|
||||
"obsidianui": ">=0.2.5",
|
||||
"minecraft": "~1.20",
|
||||
"spruceui": ">=3.2.0",
|
||||
"java": ">=17"
|
||||
},
|
||||
"recommends": {
|
||||
"modmenu": ">=1.12.2"
|
||||
},
|
||||
"suggests": {
|
||||
"kontrolo": "*"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
accessWidener v1 named
|
||||
|
||||
#accessible class net/minecraft/client/gui/widget/EntryListWidget$MoveDirection
|
||||
accessible method net/minecraft/util/Identifier <init> (Ljava/lang/String;Ljava/lang/String;)V
|
||||
#accessible class net/minecraft/client/gui/widget/EntryListWidget$MoveDirection
|
||||
@@ -4,7 +4,7 @@
|
||||
"plugin": "eu.midnightdust.midnightcontrols.client.compat.MidnightControlsMixinPlugin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"client": [
|
||||
"sodium.SodiumOptionsGUIAccessor"
|
||||
"SodiumOptionsGUIAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"pack": {
|
||||
"pack_format": 15,
|
||||
"supported_formats": [15, 999],
|
||||
"pack_format": 13,
|
||||
"description": "Makes controller tooltips use similar icons to Bedrock Edition"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"pack": {
|
||||
"pack_format": 15,
|
||||
"supported_formats": [15, 999],
|
||||
"pack_format": 13,
|
||||
"description": "Makes controller icons look similar to Legacy Console Edit."
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user