Compare commits

..

4 Commits
1.21 ... 1.20

Author SHA1 Message Date
Martin Prokoph
aabb728303 Use EMI version for 1.20.1 2024-02-14 10:52:28 +01:00
Martin Prokoph
3b93a52568 Merge pull request #262 from TeamMidnightDust/1.20.4
Backport fixes to 1.20.1
2024-02-14 10:51:00 +01:00
Martin Prokoph
797ab519de Rebase on 1.20.1 2024-02-03 14:17:28 +01:00
Martin Prokoph
18df94c4e4 Merge pull request #259 from TeamMidnightDust/1.20.4
Backport changes from 1.9.0+
2024-02-03 13:16:41 +01:00
50 changed files with 467 additions and 524 deletions

View File

@@ -1,7 +1,7 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: 'Bug: TITLE HERE' title: ''
labels: bug labels: bug
assignees: '' assignees: ''
@@ -21,17 +21,15 @@ Steps to reproduce the behavior:
A clear and concise description of what you expected to happen. A clear and concise description of what you expected to happen.
**Screenshots** **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):** **Desktop (please complete the following information):**
- OS: [e.g. Windows / Linux / MacOS] - OS: [e.g. Linux]
- Minecraft [e.g. 1.20.4] - Minecraft [e.g. 1.14.4]
- Modloader [e.g. Fabric Loader 0.15.6] - Fabric [e.g. fabric 0.7.2+build.174]
- Fabric/Quilt Libraries [e.g. Fabric Api 0.96.1+1.20.4] - Mods [e.g. aurora_keystrokes v1.0.0, modmenu v1.7.15]
- Mods [e.g. Puzzle v1.6.1, LilTaterReloaded v1.1.15]
- Version [e.g. 1.0.0] - Version [e.g. 1.0.0]
- Remove this line if you actually completed it - Branch [e.g. dev]
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.
In case of a crash, please provide the crash log.

View File

@@ -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.

View File

@@ -1,7 +1,7 @@
--- ---
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: 'Feature: TITLE HERE' title: ''
labels: enhancement labels: enhancement
assignees: '' 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. A clear and concise description of any alternative solutions or features you've considered.
**Additional context** **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.

View File

@@ -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.

View File

@@ -64,7 +64,11 @@ After this is done, everything should be built just fine!
## FAQ: ## FAQ:
### The controller does not work, and it's name appears in orange, what can I do? ### 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 [Quilt]: https://quiltmc.org

View File

@@ -1,22 +1,53 @@
plugins { plugins {
id 'fabric-loom' version '1.6-SNAPSHOT' id 'fabric-loom' version '1.1-SNAPSHOT'
id 'java-library' id 'java-library'
id 'maven-publish' id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '7.0.0' id 'com.github.johnrengelman.shadow' version '7.0.0'
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 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. // This field defines the Java version your mod target.
def targetJavaVersion = 21 def targetJavaVersion = 17
boolean isMCVersionNonRelease() { boolean isMCVersionNonRelease() {
return project.minecraft_version.matches('^\\d\\dw\\d\\d[a-z]$') return project.minecraft_version.matches('^\\d\\dw\\d\\d[a-z]$')
|| project.minecraft_version.matches('\\d+\\.\\d+-(pre|rc)(\\d+)') || 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 { repositories {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
@@ -52,7 +83,10 @@ dependencies {
// Fabric API. This is technically optional, but you probably want it anyway. // Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
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') { api('org.aperlambda:lambdajcommon:1.8.1') {
exclude group: 'com.google.code.gson' exclude group: 'com.google.code.gson'
exclude group: 'com.google.guava' exclude group: 'com.google.guava'
@@ -114,55 +148,39 @@ processResources {
expand 'version': project.version expand 'version': project.version
} }
} }
modrinth {
ext { 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!
releaseChangelog = { projectId = project.archives_base_name // This can be the project ID or the slug. Either will work!
def changes = new StringBuilder() versionNumber = project.version // You don't need to set this manually. Will fail if Modrinth has this version already
changes << "## MidnightControls v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/TeamMidnightDust/MidnightControls/commits/)" versionName = "MidnightControls " + project.mod_version + " - " + project.minecraft_version
def proc = "git log --max-count=1 --pretty=format:%s".execute() versionType = isMCVersionNonRelease() ? "beta" : "release" // Can also be `beta` or `alpha`
proc.in.eachLine { line -> uploadFile = remapJar // With Loom, this MUST be set to `remapJar` instead of `jar`!
def processedLine = line.toString() gameVersions = [(String) project.minecraft_version] // Must be an array, even with only one version
if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) { loaders = ["fabric","quilt"] // Must also be an array - no need to specify this if you're using Loom or ForgeGradle
changes << "\n- ${processedLine.capitalize()}" dependencies { // A special DSL for creating dependencies
} // scope.type
} // The scope can be `required`, `optional`, `incompatible`, or `embedded`
proc.waitFor() // The type can either be `project` or `version`
return changes.toString() required.project "midnightlib" // Creates a new required dependency on MidnightLib
} }
changelog = project.changelog
} }
tasks.register('publishCurseForge', TaskPublishCurseForge) {
unifiedPublishing { // This token is used to authenticate with CurseForge. It should be handled
project { // with the same level of care and security as your actual password. You
displayName = "MidnightControls v$project.version - Fabric $project.minecraft_version" // should never share your token with an untrusted source or publish it
releaseType = "$project.release_type" // publicly to GitHub or embed it within a project. The best practice is to
changelog = releaseChangelog() // store this token in an environment variable or a build secret.
gameVersions = [] apiToken = System.getenv("CURSEFORGE_TOKEN")
gameLoaders = ["fabric","quilt"]
mainPublication remapJar
relations {
includes {
curseforge = "midnightlib"
modrinth = "midnightlib"
}
}
var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN") // Tells CurseForgeGradle to publish the output of the jar task. This will
if (CURSEFORGE_TOKEN != null) { // return a UploadArtifact object that can be used to further configure the
curseforge { // file.
token = CURSEFORGE_TOKEN def mainFile = upload(project.curseforge_id, remapJar)
id = rootProject.curseforge_id mainFile.changelog = project.changelog
gameVersions.addAll "Java 21", project.minecraft_version mainFile.displayName = "MidnightControls " + project.mod_version + " - " + project.minecraft_version
} mainFile.addModLoader("Fabric", "Quilt")
} mainFile.addRequirement("midnightlib")
mainFile.releaseType = "release"
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
}
}
}
} }

View File

@@ -3,28 +3,28 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/use # check these on https://fabricmc.net/use
minecraft_version=1.21 minecraft_version=1.20.1
yarn_mappings=1.21+build.1 yarn_mappings=1.20.1+build.10
loader_version=0.15.11 loader_version=0.15.6
# Mod Properties # Mod Properties
mod_version = 1.9.7 mod_version = 1.9.4
maven_group = eu.midnightdust maven_group = eu.midnightdust
archives_base_name = midnightcontrols archives_base_name = midnightcontrols
release_type=beta
modrinth_id = bXX9h73M modrinth_id = bXX9h73M
curseforge_id = 621768 curseforge_id = 621768
changelog = See changes at: https://github.com/TeamMidnightDust/MidnightControls/commits/
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.100.1+1.21 fabric_version=0.91.0+1.20.1
sodium_version=mc1.19.2-0.4.4 sodium_version=mc1.19.2-0.4.4
obsidianui_version=0.2.6+mc1.21-fabric spruceui_version=5.0.0+1.20
midnightlib_version=1.5.7-fabric midnightlib_version=1.4.1-fabric
modmenu_version=10.0.0-beta.1 modmenu_version=7.0.0
emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric
bendylib_version=2.0.+ bendylib_version=2.0.+
emi_version=1.1.1+1.20.4+fabric emi_version=1.1.1+1.20.1+fabric
libgui_version=6.0.0+1.19 libgui_version=6.0.0+1.19
inventorytabs_version=inventorytabs-0.9.beta-1.19.x inventorytabs_version=inventorytabs-0.9.beta-1.19.x
clothconfig_version=7.0.72 clothconfig_version=7.0.72

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -4,7 +4,6 @@ pluginManagement {
name 'Fabric' name 'Fabric'
url 'https://maven.fabricmc.net/' url 'https://maven.fabricmc.net/'
} }
maven { url "https://maven.architectury.dev/" }
gradlePluginPortal() gradlePluginPortal()
} }
} }

View File

@@ -9,8 +9,8 @@
package eu.midnightdust.midnightcontrols; package eu.midnightdust.midnightcontrols;
import dev.lambdaurora.spruceui.util.Nameable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.thinkingstudio.obsidianui.util.Nameable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;

View File

@@ -9,17 +9,21 @@
package eu.midnightdust.midnightcontrols; package eu.midnightdust.midnightcontrols;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback; import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback;
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket; import io.netty.buffer.Unpooled;
import eu.midnightdust.midnightcontrols.packet.FeaturePacket;
import eu.midnightdust.midnightcontrols.packet.HelloPacket;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader; 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.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.Optional;
/** /**
* Represents the MidnightControls mod. * Represents the MidnightControls mod.
@@ -30,9 +34,9 @@ import org.apache.logging.log4j.Logger;
*/ */
public class MidnightControls implements ModInitializer { public class MidnightControls implements ModInitializer {
private static MidnightControls INSTANCE; private static MidnightControls INSTANCE;
public static final CustomPayload.Id<CustomPayload> CONTROLS_MODE_CHANNEL = new CustomPayload.Id<>(MidnightControlsConstants.CONTROLS_MODE_CHANNEL); public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString());
public static final CustomPayload.Id<CustomPayload> FEATURE_CHANNEL = new CustomPayload.Id<>(MidnightControlsConstants.FEATURE_CHANNEL); public static final Identifier FEATURE_CHANNEL = new Identifier(MidnightControlsConstants.FEATURE_CHANNEL.toString());
public static final CustomPayload.Id<CustomPayload> HELLO_CHANNEL = new CustomPayload.Id<>(MidnightControlsConstants.HELLO_CHANNEL); public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString());
public static boolean isExtrasLoaded; public static boolean isExtrasLoaded;
public final Logger logger = LogManager.getLogger("MidnightControls"); public final Logger logger = LogManager.getLogger("MidnightControls");
@@ -43,19 +47,19 @@ public class MidnightControls implements ModInitializer {
isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra"); isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra");
this.log("Initializing MidnightControls..."); this.log("Initializing MidnightControls...");
PayloadTypeRegistry.playC2S().register(HelloPacket.PACKET_ID, HelloPacket.codec); ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> {
PayloadTypeRegistry.playC2S().register(ControlsModePacket.PACKET_ID, ControlsModePacket.codec); String version = buf.readString(32);
PayloadTypeRegistry.playS2C().register(ControlsModePacket.PACKET_ID, ControlsModePacket.codec); ControlsMode.byId(buf.readString(32))
PayloadTypeRegistry.playS2C().register(FeaturePacket.PACKET_ID, FeaturePacket.codec); .ifPresent(controlsMode -> server
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode)));
ServerPlayNetworking.registerGlobalReceiver(HelloPacket.PACKET_ID, (payload, context) -> { server.execute(() -> {
ControlsMode.byId(payload.controlsMode()) ServerPlayNetworking.send(player, FEATURE_CHANNEL, this.makeFeatureBuffer(MidnightControlsFeature.HORIZONTAL_REACHAROUND));
.ifPresent(controlsMode -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.player(), controlsMode));
context.responseSender().sendPacket(new FeaturePacket(MidnightControlsFeature.HORIZONTAL_REACHAROUND));
}); });
ServerPlayNetworking.registerGlobalReceiver(ControlsModePacket.PACKET_ID, });
(payload, context) -> ControlsMode.byId(payload.controlsMode()) ServerPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL,
.ifPresent(controlsMode -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.player(), controlsMode))); (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); 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. * Gets the MidnightControls instance.
* *

View File

@@ -21,7 +21,7 @@ import net.minecraft.util.Identifier;
*/ */
public class MidnightControlsConstants { public class MidnightControlsConstants {
public static final String NAMESPACE = "midnightcontrols"; public static final String NAMESPACE = "midnightcontrols";
public static final Identifier CONTROLS_MODE_CHANNEL = Identifier.of(NAMESPACE, "controls_mode"); public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(NAMESPACE, "controls_mode");
public static final Identifier FEATURE_CHANNEL = Identifier.of(NAMESPACE, "feature"); public static final Identifier FEATURE_CHANNEL = new Identifier(NAMESPACE, "feature");
public static final Identifier HELLO_CHANNEL = Identifier.of(NAMESPACE, "hello"); public static final Identifier HELLO_CHANNEL = new Identifier("lambdacontrols", "hello");
} }

View File

@@ -9,7 +9,7 @@
package eu.midnightdust.midnightcontrols; package eu.midnightdust.midnightcontrols;
import org.thinkingstudio.obsidianui.util.Nameable; import dev.lambdaurora.spruceui.util.Nameable;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@@ -9,6 +9,7 @@
package eu.midnightdust.midnightcontrols.client; package eu.midnightdust.midnightcontrols.client;
import dev.lambdaurora.spruceui.event.OpenScreenCallback;
import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.lib.util.PlatformFunctions;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.MidnightControls;
@@ -25,13 +26,8 @@ import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingIDAccessor; import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingIDAccessor;
import eu.midnightdust.midnightcontrols.client.ring.ButtonBindingRingAction; import eu.midnightdust.midnightcontrols.client.ring.ButtonBindingRingAction;
import eu.midnightdust.midnightcontrols.client.ring.MidnightRing; import eu.midnightdust.midnightcontrols.client.ring.MidnightRing;
import org.thinkingstudio.obsidianui.fabric.event.OpenScreenCallback; import dev.lambdaurora.spruceui.hud.HudManager;
import org.thinkingstudio.obsidianui.hud.HudManager;
import eu.midnightdust.midnightcontrols.client.touch.TouchInput; 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.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
@@ -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.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.ResourcePackActivationType; import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
@@ -52,7 +47,9 @@ import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.io.File; import java.io.File;
import java.util.*; import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
/** /**
* Represents the midnightcontrols client mod. * Represents the midnightcontrols client mod.
@@ -64,20 +61,20 @@ import java.util.*;
public class MidnightControlsClient extends MidnightControls implements ClientModInitializer { public class MidnightControlsClient extends MidnightControls implements ClientModInitializer {
public static boolean lateInitDone = false; public static boolean lateInitDone = false;
private static MidnightControlsClient INSTANCE; 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"); 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"); 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"); 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"); 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"); 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_BUTTONS = new Identifier(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_EXPANDED = new Identifier(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 CONTROLLER_AXIS = new Identifier(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 CURSOR_TEXTURE = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/cursor.png");
public final static File MAPPINGS_FILE = new File("config/gamecontrollercustommappings.txt"); public final static File MAPPINGS_FILE = new File("config/gamecontrollercustommappings.txt");
public final MidnightInput input = new MidnightInput(); public final MidnightInput input = new MidnightInput();
public final MidnightRing ring = new MidnightRing(this); public final MidnightRing ring = new MidnightRing(this);
@@ -96,26 +93,26 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
this.ring.registerAction("buttonbinding", ButtonBindingRingAction.FACTORY); this.ring.registerAction("buttonbinding", ButtonBindingRingAction.FACTORY);
ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (payload, context) -> ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) ->
context.responseSender().sendPacket(new ControlsModePacket(MidnightControlsConfig.controlsMode.getName()))); responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)));
ClientPlayNetworking.registerGlobalReceiver(FeaturePacket.PACKET_ID, ((payload, context) -> {})); ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> {
int features = buf.readVarInt();
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> { for (int i = 0; i < features; i++) {
var version = ""; var name = buf.readString(64);
Optional<ModContainer> container; boolean allowed = buf.readBoolean();
if ((container = FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE)).isPresent()) { MidnightControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed)));
version = container.get().getMetadata().getVersion().getFriendlyString();
} }
var controlsMode = MidnightControlsConfig.controlsMode.getName(); });
sender.sendPacket(new HelloPacket(version, controlsMode)); ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
sender.sendPacket(new ControlsModePacket(controlsMode)); sender.sendPacket(HELLO_CHANNEL, this.makeHello(MidnightControlsConfig.controlsMode));
sender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode));
}); });
ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave); ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave);
ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick); ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick);
ClientTickEvents.START_CLIENT_TICK.register(this::onTick); ClientTickEvents.START_CLIENT_TICK.register(this::onTick);
OpenScreenCallback.POST.register((client, screen) -> { OpenScreenCallback.EVENT.register((client, screen) -> {
if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) { if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) {
screen = new TouchscreenOverlay(this); screen = new TouchscreenOverlay(this);
screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
@@ -137,8 +134,8 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
HudManager.register(this.hud = new MidnightControlsHud(this)); HudManager.register(this.hud = new MidnightControlsHud(this));
FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> { FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> {
ResourceManagerHelper.registerBuiltinResourcePack(Identifier.of("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL); ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL);
ResourceManagerHelper.registerBuiltinResourcePack(Identifier.of("midnightcontrols","legacy"), 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.enableHints = false;
MidnightControlsConfig.save(); MidnightControlsConfig.save();
} }
RainbowColor.tick();
TouchInput.tick(); TouchInput.tick();
} }
@@ -257,7 +253,6 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
MidnightControlsConfig.controlsMode = this.previousControlsMode; MidnightControlsConfig.controlsMode = this.previousControlsMode;
} }
ClientPlayNetworking.getSender().sendPacket(new ControlsModePacket(MidnightControlsConfig.controlsMode.getName()));
} }
} }

View File

@@ -10,8 +10,8 @@
package eu.midnightdust.midnightcontrols.client; package eu.midnightdust.midnightcontrols.client;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.thinkingstudio.obsidianui.widget.AbstractSpruceWidget; import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceEntryListWidget; import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.compat.*; import eu.midnightdust.midnightcontrols.client.compat.*;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; 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.ring.RingPage;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import eu.midnightdust.midnightcontrols.client.util.MathUtil; import eu.midnightdust.midnightcontrols.client.util.MathUtil;
import org.thinkingstudio.obsidianui.navigation.NavigationDirection; import dev.lambdaurora.spruceui.navigation.NavigationDirection;
import org.thinkingstudio.obsidianui.screen.SpruceScreen; import dev.lambdaurora.spruceui.screen.SpruceScreen;
import org.thinkingstudio.obsidianui.widget.AbstractSprucePressableButtonWidget; import dev.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget;
import org.thinkingstudio.obsidianui.widget.SpruceElement; import dev.lambdaurora.spruceui.widget.SpruceElement;
import org.thinkingstudio.obsidianui.widget.SpruceLabelWidget; import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceParentWidget; import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import eu.midnightdust.midnightcontrols.client.enums.ButtonState; import eu.midnightdust.midnightcontrols.client.enums.ButtonState;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
@@ -489,7 +489,7 @@ public class MidnightInput {
state = 1; state = 1;
asButtonState = 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; var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen;
// @TODO allow rebinding to left stick // @TODO allow rebinding to left stick
if (accessor.midnightcontrols$hasScrollbar() && absValue >= deadZone) { if (accessor.midnightcontrols$hasScrollbar() && absValue >= deadZone) {
creativeInventoryScreen.mouseScrolled(0.0, 0.0, 0, -value); creativeInventoryScreen.mouseScrolled(0.0, 0.0, -value);
} }
return; return;
} }
@@ -573,7 +573,7 @@ public class MidnightInput {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
// @TODO allow rebinding to left stick // @TODO allow rebinding to left stick
if (absValue >= deadZone) { if (absValue >= deadZone) {
merchantScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f)); merchantScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f));
} }
return; return;
} }
@@ -581,7 +581,7 @@ public class MidnightInput {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
// @TODO allow rebinding to left stick // @TODO allow rebinding to left stick
if (absValue >= deadZone) { if (absValue >= deadZone) {
stonecutterScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f)); stonecutterScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f));
} }
return; return;
} }
@@ -600,7 +600,7 @@ public class MidnightInput {
.map(element -> (SpruceEntryListWidget<?>) element) .map(element -> (SpruceEntryListWidget<?>) element)
.filter(AbstractSpruceWidget::isFocusedOrHovered) .filter(AbstractSpruceWidget::isFocusedOrHovered)
.noneMatch(element -> { .noneMatch(element -> {
element.mouseScrolled(0.0, 0.0, 0, -finalValue); element.mouseScrolled(0.0, 0.0, -finalValue);
return true; return true;
}) })
&& &&
@@ -608,11 +608,11 @@ public class MidnightInput {
.map(element -> (EntryListWidget<?>) element) .map(element -> (EntryListWidget<?>) element)
.filter(element -> element.getType().isFocused()) .filter(element -> element.getType().isFocused())
.noneMatch(element -> { .noneMatch(element -> {
element.mouseScrolled(0.0, 0.0, 0, -finalValue); element.mouseScrolled(0.0, 0.0, -finalValue);
return true; 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) { else if (isScreenInteractive(client.currentScreen) && absValue >= deadZone) {
if (value > 0 && joystickCooldown == 0) { if (value > 0 && joystickCooldown == 0) {

View File

@@ -15,7 +15,6 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.FluidBlock; import net.minecraft.block.FluidBlock;
import net.minecraft.block.SlabBlock; import net.minecraft.block.SlabBlock;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
@@ -75,7 +74,7 @@ public class MidnightReacharound {
} }
public static float getPlayerRange(@NotNull MinecraftClient client) { 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;
} }
/** /**

View File

@@ -9,7 +9,6 @@
package eu.midnightdust.midnightcontrols.client.compat; package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
@@ -23,16 +22,23 @@ import java.util.Set;
/** /**
* This plugin is only present for the conditional mixins. * This plugin is only present for the conditional mixins.
* *
* @author LambdAurora & Motschen * @author LambdAurora
* @version 1.6.0 * @version 1.5.0
* @since 1.2.0 * @since 1.2.0
*/ */
public class MidnightControlsMixinPlugin implements IMixinConfigPlugin { 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 @Override
public void onLoad(String mixinPackage) { public void onLoad(String mixinPackage) {
this.mixinPackage = mixinPackage + ".";
} }
@Override @Override
@@ -42,13 +48,7 @@ public class MidnightControlsMixinPlugin implements IMixinConfigPlugin {
@Override @Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
final String mixinName = mixinClassName.substring(this.mixinPackage.length()); return this.conditionalMixins.getOrDefault(mixinClassName, Boolean.TRUE);
final String packageName = mixinName.substring(0, mixinName.lastIndexOf('.'));
if (packageName.startsWith("sodium") && !PlatformFunctions.isModLoaded("sodium"))
return false;
return true;
} }
@Override @Override

View File

@@ -2,7 +2,7 @@ package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; 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 me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;

View File

@@ -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.SodiumOptionsGUI;
import me.jellysquid.mods.sodium.client.gui.options.OptionPage; import me.jellysquid.mods.sodium.client.gui.options.OptionPage;

View File

@@ -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) public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A)
.action(InputHandlers::handleScreenshot).cooldown().register(); .action(InputHandlers::handleScreenshot).cooldown().register();
public static final ButtonBinding DEBUG_SCREEN = new Builder("debug_screen").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_B) 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) public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
.action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register(); .action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT) public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)
@@ -88,7 +88,7 @@ public class ButtonBinding {
public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB) public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register(); .actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register();
public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB) 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 SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register();
public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null)).cooldown().register(); .action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null)).cooldown().register();

View File

@@ -151,17 +151,25 @@ public record Controller(int id) implements Nameable {
private static boolean updateMappingsSync() { private static boolean updateMappingsSync() {
try { try {
MidnightControlsClient.get().log("Updating controller mappings..."); MidnightControlsClient.get().log("Updating controller mappings...");
Optional<File> databaseFile = getDatabaseFile(); File databaseFile = new File("config/gamecontrollerdatabase.txt");
if (databaseFile.isPresent()) { try {
var database = ioResourceToBuffer(databaseFile.get().getPath(), 1024); BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream());
if (database != null) GLFW.glfwUpdateGamepadMappings(database); 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()) if (!MidnightControlsClient.MAPPINGS_FILE.exists())
return false; return false;
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024); var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer); if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
} catch (IOException e) { } catch (IOException e) {
e.fillInStackTrace(); e.printStackTrace();
} }
try (var memoryStack = MemoryStack.stackPush()) { try (var memoryStack = MemoryStack.stackPush()) {
@@ -174,9 +182,9 @@ public record Controller(int id) implements Nameable {
if (client != null) { if (client != null) {
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.PERIODIC_NOTIFICATION, client.getToastManager().add(SystemToast.create(client, SystemToast.Type.PERIODIC_NOTIFICATION,
Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string))); Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string)));
}
MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string); MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string);
} }
}
} catch (Throwable e) { } catch (Throwable e) {
/* Ignored :concern: */ /* Ignored :concern: */
} }
@@ -197,19 +205,4 @@ public record Controller(int id) implements Nameable {
} }
return true; 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);
}
} }

View File

@@ -23,6 +23,9 @@ import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import eu.midnightdust.midnightcontrols.client.mixin.*; import eu.midnightdust.midnightcontrols.client.mixin.*;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; 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.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.gui.screen.TitleScreen;
@@ -61,7 +64,11 @@ public class InputHandlers {
private InputHandlers() { private InputHandlers() {
} }
private static List<ItemGroup> getVisibleGroups(CreativeInventoryScreen screen) { 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) { public static PressAction handleHotbar(boolean next) {
@@ -150,7 +157,7 @@ public class InputHandlers {
nextTab = tabs.size() - 1; nextTab = tabs.size() - 1;
else if (nextTab >= tabs.size()) else if (nextTab >= tabs.size())
nextTab = 0; nextTab = 0;
screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot().getAdvancementEntry(), true); screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot(), true);
break; break;
} }
} }
@@ -269,7 +276,7 @@ public class InputHandlers {
if (action == ButtonState.PRESS) { if (action == ButtonState.PRESS) {
// If in game, then pause the game. // If in game, then pause the game.
if (client.currentScreen == null || client.currentScreen instanceof RingScreen) 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. else if (client.currentScreen instanceof HandledScreen && client.player != null) // If the current screen is a container then close it.
client.player.closeHandledScreen(); client.player.closeHandledScreen();
else // Else just close the current screen. else // Else just close the current screen.
@@ -313,12 +320,12 @@ public class InputHandlers {
boolean sprintToggled = client.options.getSprintToggled().getValue(); boolean sprintToggled = client.options.getSprintToggled().getValue();
if (client.player.getAbilities().flying && sprintToggled) if (client.player.getAbilities().flying && sprintToggled)
client.options.getSprintToggled().setValue(false); client.options.getSprintToggled().setValue(false);
else if (MidnightControlsConfig.controllerToggleSprint != sprintToggled) else if (MidnightControlsConfig.controllerToggleSneak != sprintToggled)
client.options.getSprintToggled().setValue(!sprintToggled); client.options.getSprintToggled().setValue(!sprintToggled);
binding.setPressed(button.pressed); binding.setPressed(button.pressed);
if (client.player.getAbilities().flying && sprintToggled) if (client.player.getAbilities().flying && sprintToggled)
client.options.getSprintToggled().setValue(true); client.options.getSprintToggled().setValue(true);
else if (MidnightControlsConfig.controllerToggleSprint != sprintToggled) else if (MidnightControlsConfig.controllerToggleSneak != sprintToggled)
client.options.getSprintToggled().setValue(sprintToggled); client.options.getSprintToggled().setValue(sprintToggled);
}); });
return true; return true;

View File

@@ -73,8 +73,8 @@ public class InputManager {
public void updateMousePosition(@NotNull MinecraftClient client) { public void updateMousePosition(@NotNull MinecraftClient client) {
Objects.requireNonNull(client, "Client instance cannot be null."); Objects.requireNonNull(client, "Client instance cannot be null.");
if (this.prevTargetMouseX != this.targetMouseX || this.prevTargetMouseY != this.targetMouseY) { if (this.prevTargetMouseX != this.targetMouseX || this.prevTargetMouseY != this.targetMouseY) {
double mouseX = this.prevTargetMouseX + (this.targetMouseX - this.prevTargetMouseX) * 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.getRenderTickCounter().getTickDelta(true) + 0.5; double mouseY = this.prevTargetMouseY + (this.targetMouseY - this.prevTargetMouseY) * client.getTickDelta() + 0.5;
if (!MidnightControlsConfig.virtualMouse) if (!MidnightControlsConfig.virtualMouse)
GLFW.glfwSetCursorPos(client.getWindow().getHandle(), mouseX, mouseY); GLFW.glfwSetCursorPos(client.getWindow().getHandle(), mouseX, mouseY);
((MouseAccessor) client.mouse).midnightcontrols$onCursorPos(client.getWindow().getHandle(), mouseX, mouseY); ((MouseAccessor) client.mouse).midnightcontrols$onCursorPos(client.getWindow().getHandle(), mouseX, mouseY);

View File

@@ -14,18 +14,9 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.util.MathUtil; import eu.midnightdust.midnightcontrols.client.util.MathUtil;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper; 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 net.minecraft.util.math.MathHelper;
import org.apache.commons.lang3.mutable.MutableFloat;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Unique;
/** /**
* Represents the movement handler. * Represents the movement handler.
@@ -44,7 +35,7 @@ public final class MovementHandler implements PressAction {
private float slowdownFactor = 1.f; private float slowdownFactor = 1.f;
private float movementForward = 0.f; private float movementForward = 0.f;
private float movementSideways = 0.f; private float movementSideways = 0.f;
private final MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil(); private MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil();
private MovementHandler() { private MovementHandler() {
} }
@@ -90,7 +81,7 @@ public final class MovementHandler implements PressAction {
} }
this.slowdownFactor = client.player.shouldSlowDown() ? (MathHelper.clamp( 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, 0.0F,
1.0F 1.0F
)) : 1.f; )) : 1.f;

View File

@@ -11,10 +11,10 @@ package eu.midnightdust.midnightcontrols.client.gui;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.Controller;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.option.SpruceOption; import dev.lambdaurora.spruceui.option.SpruceOption;
import org.thinkingstudio.obsidianui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import org.thinkingstudio.obsidianui.widget.text.SpruceTextAreaWidget; import dev.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget;
import net.minecraft.client.toast.SystemToast; import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.Text; import net.minecraft.text.Text;

View File

@@ -16,7 +16,7 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import org.thinkingstudio.obsidianui.hud.Hud; import dev.lambdaurora.spruceui.hud.Hud;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
@@ -57,7 +57,7 @@ public class MidnightControlsHud extends Hud {
private static boolean isCrammed = false; private static boolean isCrammed = false;
public MidnightControlsHud(@NotNull MidnightControlsClient mod) { public MidnightControlsHud(@NotNull MidnightControlsClient mod) {
super(Identifier.of(MidnightControlsConstants.NAMESPACE, "hud/button_indicator")); super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator"));
this.mod = mod; this.mod = mod;
} }

View File

@@ -10,24 +10,23 @@
package eu.midnightdust.midnightcontrols.client.gui; package eu.midnightdust.midnightcontrols.client.gui;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import org.thinkingstudio.obsidianui.background.Background; import dev.lambdaurora.spruceui.background.Background;
import org.thinkingstudio.obsidianui.widget.SpruceWidget; import dev.lambdaurora.spruceui.widget.SpruceWidget;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.Controller;
import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget; import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import org.thinkingstudio.obsidianui.option.*; import dev.lambdaurora.spruceui.option.*;
import org.thinkingstudio.obsidianui.screen.SpruceScreen; import dev.lambdaurora.spruceui.screen.SpruceScreen;
import org.thinkingstudio.obsidianui.widget.AbstractSpruceWidget; import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
import org.thinkingstudio.obsidianui.widget.SpruceLabelWidget; import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceOptionListWidget; import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
import org.thinkingstudio.obsidianui.widget.container.tabbed.SpruceTabbedWidget; import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
@@ -93,7 +92,6 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
id = GLFW.GLFW_JOYSTICK_1; id = GLFW.GLFW_JOYSTICK_1;
id = searchNextAvailableController(id, false); id = searchNextAvailableController(id, false);
MidnightControlsConfig.setController(Controller.byId(id)); MidnightControlsConfig.setController(Controller.byId(id));
if (MidnightControlsConfig.debug) System.out.println(Controller.byId(id).getName() + "'s Controller GUID: " + Controller.byId(id).getGuid());
}, },
option -> { option -> {
var controller = MidnightControlsConfig.getController(); var controller = MidnightControlsConfig.getController();
@@ -184,7 +182,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
MidnightControlsConfig.save(); MidnightControlsConfig.save();
if (this.client != null && this.client.player != null) { 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())), }, option -> option.getDisplayText(Text.translatable(MidnightControlsConfig.controlsMode.getTranslationKey())),
Text.translatable("midnightcontrols.menu.controls_mode.tooltip")); Text.translatable("midnightcontrols.menu.controls_mode.tooltip"));
@@ -509,14 +507,15 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
float g = (float)(color.getGreen()) / 255.0F; float g = (float)(color.getGreen()) / 255.0F;
float b = (float)(color.getBlue()) / 255.0F; float b = (float)(color.getBlue()) / 255.0F;
float t = (float)(transparency) / 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.enableBlend();
RenderSystem.defaultBlendFunc(); RenderSystem.defaultBlendFunc();
RenderSystem.setShader(GameRenderer::getPositionColorProgram); RenderSystem.setShader(GameRenderer::getPositionColorProgram);
bufferBuilder.vertex(matrix, (float)x1, (float)y2, 0.0F).color(r, g, b, t); bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
bufferBuilder.vertex(matrix, (float)x2, (float)y2, 0.0F).color(r, g, b, t); bufferBuilder.vertex(matrix, (float)x1, (float)y2, 0.0F).color(r, g, b, t).next();
bufferBuilder.vertex(matrix, (float)x2, (float)y1, 0.0F).color(r, g, b, t); bufferBuilder.vertex(matrix, (float)x2, (float)y2, 0.0F).color(r, g, b, t).next();
bufferBuilder.vertex(matrix, (float)x1, (float)y1, 0.0F).color(r, g, b, t); 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()); BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
RenderSystem.disableBlend(); RenderSystem.disableBlend();
matrixStack.pop(); matrixStack.pop();

View File

@@ -10,8 +10,8 @@
package eu.midnightdust.midnightcontrols.client.gui; package eu.midnightdust.midnightcontrols.client.gui;
import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.Controller;
import org.thinkingstudio.obsidianui.option.SpruceSimpleActionOption; import dev.lambdaurora.spruceui.option.SpruceSimpleActionOption;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.toast.SystemToast; import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.Text; import net.minecraft.text.Text;

View File

@@ -9,8 +9,8 @@
package eu.midnightdust.midnightcontrols.client.gui; package eu.midnightdust.midnightcontrols.client.gui;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.lib.util.PlatformFunctions;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants; import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.enums.ButtonState; 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.compat.EmotecraftCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.InputManager; 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.ItemUseButtonWidget;
import eu.midnightdust.midnightcontrols.client.touch.gui.SilentTexturedButtonWidget; import eu.midnightdust.midnightcontrols.client.touch.gui.SilentTexturedButtonWidget;
import eu.midnightdust.midnightcontrols.client.touch.TouchUtils; 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.DrawContext;
import net.minecraft.client.gui.screen.*; import net.minecraft.client.gui.screen.*;
import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.widget.TextIconButtonWidget;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.texture.MissingSprite;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.InputUtil; import net.minecraft.client.util.InputUtil;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; 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 * Represents the touchscreen overlay
*/ */
public class TouchscreenOverlay extends Screen { 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 final MidnightControlsClient mod;
private SilentTexturedButtonWidget inventoryButton; private SilentTexturedButtonWidget inventoryButton;
private SilentTexturedButtonWidget swapHandsButton; private SilentTexturedButtonWidget swapHandsButton;
@@ -84,10 +82,7 @@ public class TouchscreenOverlay extends Screen {
} }
@Override @Override
public void renderInGameBackground(DrawContext context) {} public void renderBackground(DrawContext context) {}
@Override
protected void applyBlur(float delta) {}
private void pauseGame() { private void pauseGame() {
assert this.client != null; assert this.client != null;
@@ -168,15 +163,15 @@ public class TouchscreenOverlay extends Screen {
int emoteOffset = 0; int emoteOffset = 0;
if (PlatformFunctions.isModLoaded("emotecraft")) { if (PlatformFunctions.isModLoaded("emotecraft")) {
emoteOffset = 10; 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); emoteButton.setPosition(scaledWidth / 2 - 30, 0);
this.addDrawableChild(emoteButton); 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); chatButton.setPosition(scaledWidth / 2 - 20 + emoteOffset, 0);
this.addDrawableChild(chatButton); 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); pauseButton.setPosition(scaledWidth / 2 + emoteOffset, 0);
this.addDrawableChild(pauseButton); this.addDrawableChild(pauseButton);
// Inventory buttons. // Inventory buttons.
@@ -291,17 +286,16 @@ public class TouchscreenOverlay extends Screen {
} }
private void initCustomButtons(boolean left) { private void initCustomButtons(boolean left) {
assert client != null; 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; List<String> list = left ? MidnightControlsConfig.leftTouchBinds : MidnightControlsConfig.rightTouchBinds;
Sprite missingSprite = client.getGuiAtlasManager().getSprite(MissingSprite.getMissingSpriteId());
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
String bindName = list.get(i); String bindName = list.get(i);
ButtonBinding binding = InputManager.getBinding(bindName); ButtonBinding binding = InputManager.getBinding(bindName);
if (binding == null) continue; if (binding == null) continue;
boolean hasTexture = client.getGuiAtlasManager().getSprite(Identifier.of(MidnightControlsConstants.NAMESPACE, "binding/"+bindName)) != missingSprite; boolean hasTexture = client.getTextureManager().getOrDefault(new Identifier(MidnightControlsConstants.NAMESPACE, "binding/"+bindName), null) != null;
if (MidnightControlsConfig.debug) System.out.println(left +" "+Identifier.of(MidnightControlsConstants.NAMESPACE, "binding/"+bindName)+" "+ hasTexture); 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) 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.setPosition(left ? (3+(i*23)) : this.width-(23+(i*23)), 3);
button.setAlpha(MidnightControlsConfig.touchTransparency / 100f); button.setAlpha(MidnightControlsConfig.touchTransparency / 100f);
this.addDrawableChild(button); this.addDrawableChild(button);

View File

@@ -11,9 +11,9 @@ package eu.midnightdust.midnightcontrols.client.gui.widget;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import org.thinkingstudio.obsidianui.widget.AbstractSpruceIconButtonWidget; import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text; import net.minecraft.text.Text;

View File

@@ -13,10 +13,10 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;

View File

@@ -14,19 +14,20 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory; import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory;
import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.SpruceTexts; import dev.lambdaurora.spruceui.SpruceTexts;
import org.thinkingstudio.obsidianui.navigation.NavigationDirection; import dev.lambdaurora.spruceui.navigation.NavigationDirection;
import org.thinkingstudio.obsidianui.navigation.NavigationUtils; import dev.lambdaurora.spruceui.navigation.NavigationUtils;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import org.thinkingstudio.obsidianui.widget.SpruceSeparatorWidget; import dev.lambdaurora.spruceui.widget.SpruceSeparatorWidget;
import org.thinkingstudio.obsidianui.widget.SpruceWidget; import dev.lambdaurora.spruceui.widget.SpruceWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceEntryListWidget; import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceParentWidget; import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@@ -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) {
}
}
}

View File

@@ -10,16 +10,14 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen; 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.Screen;
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
import net.minecraft.client.gui.screen.option.GameOptionsScreen; import net.minecraft.client.gui.screen.option.GameOptionsScreen;
import net.minecraft.client.gui.widget.TextIconButtonWidget;
import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.GameOptions;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -29,28 +27,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
*/ */
@Mixin(ControlsOptionsScreen.class) @Mixin(ControlsOptionsScreen.class)
public abstract class ControlsOptionsScreenMixin extends GameOptionsScreen { public abstract class ControlsOptionsScreenMixin extends GameOptionsScreen {
public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) {
public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text title) { super(parent, gameOptions, text);
super(parent, gameOptions, title);
} }
@Unique TextIconButtonWidget button = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true) @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;"))
.dimension(20,20).texture(Identifier.of("midnightcontrols", "icon/controller"), 20, 20).build(); private void addControllerButton(CallbackInfo ci) {
TextIconButtonWidget iconWidget = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
@Override .dimension(20,20).texture(new Identifier("midnightcontrols", "icon/controller"), 20, 20).build();
public void init() { iconWidget.setPosition(this.width / 2 + 158, this.height / 6 - 12);
super.init(); this.addDrawableChild(iconWidget);
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);
} }
} }

View File

@@ -9,7 +9,6 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
@@ -19,14 +18,14 @@ import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.RenderTickCounter; import net.minecraft.client.util.math.MatrixStack;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(GameRenderer.class) @Mixin(GameRenderer.class)
public abstract class GameRendererMixin { public abstract class GameRendererMixin {
@@ -35,20 +34,19 @@ public abstract class GameRendererMixin {
MinecraftClient client; MinecraftClient client;
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Mouse;getX()D", shift = At.Shift.BEFORE)) @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) if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER)
MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen); MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen);
} }
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE)) @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(RenderTickCounter tickCounter, boolean tick, CallbackInfo ci, @Local DrawContext drawContext) { private void renderVirtualCursor(float tickDelta, long startTime, boolean tick, CallbackInfo ci, MatrixStack matrixStack, DrawContext drawContext) {
MidnightControlsRenderer.renderVirtualCursor(drawContext, client); MidnightControlsRenderer.renderVirtualCursor(drawContext, client);
drawContext.draw(); drawContext.draw();
} }
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z"), method = "renderWorld") @Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z", ordinal = 0), method = "renderWorld")
private void captureProjAndModMatrix(RenderTickCounter tickCounter, CallbackInfo ci, @Local(ordinal = 1) Matrix4f matrices) { private void postWorldRender(float tickDelta, long limitTime, MatrixStack matrix, CallbackInfo ci) {
TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix()); TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix());
TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix()); TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix());
TouchUtils.lastWorldSpaceMatrix.set(matrices); TouchUtils.lastWorldSpaceMatrix.set(matrix.peek().getPositionMatrix());
} }
} }

View File

@@ -18,15 +18,11 @@ import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.Mouse; import net.minecraft.client.Mouse;
import net.minecraft.client.util.GlfwUtil; import net.minecraft.client.util.GlfwUtil;
import net.minecraft.item.ItemStack; import net.minecraft.client.util.SmoothUtil;
import net.minecraft.item.ThrowablePotionItem;
import net.minecraft.util.UseAction;
import net.minecraft.util.math.Smoother;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -55,11 +51,11 @@ public abstract class MouseMixin implements MouseAccessor {
@Shadow private boolean hasResolutionChanged; @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; @Shadow private boolean leftButtonClicked;
@@ -120,8 +116,8 @@ public abstract class MouseMixin implements MouseAccessor {
cursorYSmoother.clear(); cursorYSmoother.clear();
} }
EyeTrackerHandler.updateMouseWithEyeTracking(x + cursorDeltaX, y + cursorDeltaY, client, EyeTrackerHandler.updateMouseWithEyeTracking(x + cursorDeltaX, y + cursorDeltaY, client,
glfwTime, leftButtonClicked, isUsingLongRangedTool(), cursorXSmoother, cursorYSmoother); lastMouseUpdateTime, leftButtonClicked, cursorXSmoother, cursorYSmoother);
glfwTime = GlfwUtil.getTime(); lastMouseUpdateTime = GlfwUtil.getTime();
cursorDeltaX = 0.0; cursorDeltaX = 0.0;
cursorDeltaY = 0.0; cursorDeltaY = 0.0;
ci.cancel(); 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) @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) { private void midnightcontrols$lockCursor(CallbackInfo ci) {
if ((doMixedInput() || MidnightControlsConfig.eyeTrackerAsMouse)) { if ((doMixedInput() || MidnightControlsConfig.eyeTrackerAsMouse)) {

View File

@@ -1,6 +1,6 @@
package eu.midnightdust.midnightcontrols.client.mixin; 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.ControlsMode;
import eu.midnightdust.midnightcontrols.client.enums.ButtonState; import eu.midnightdust.midnightcontrols.client.enums.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;

View File

@@ -9,14 +9,12 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.touch.TouchInput; import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
import eu.midnightdust.midnightcontrols.client.enums.TouchMode; import eu.midnightdust.midnightcontrols.client.enums.TouchMode;
import eu.midnightdust.midnightcontrols.client.util.RainbowColor;
import net.minecraft.block.ShapeContext; import net.minecraft.block.ShapeContext;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
@@ -62,7 +60,6 @@ public abstract class WorldRendererMixin {
@Shadow @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) { 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;")) @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) { private HitResult.Type dontRenderOutline(HitResult instance) {
if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) { if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
@@ -80,7 +77,8 @@ public abstract class WorldRendererMixin {
shift = At.Shift.AFTER 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) if (((MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.touchInControllerMode) || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN)
&& MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) { && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
this.renderFingerOutline(matrices, camera); this.renderFingerOutline(matrices, camera);
@@ -96,7 +94,7 @@ public abstract class WorldRendererMixin {
if (this.world.getWorldBorder().contains(blockPos) && this.client.player != null) { 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())); var outlineShape = this.world.getBlockState(blockPos).getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
Color rgb = MidnightColorUtil.hex2Rgb(MidnightControlsConfig.touchOutlineColorHex); 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(); var pos = camera.getPos();
matrices.push(); matrices.push();
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines()); 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())); var outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
Color rgb = MidnightColorUtil.hex2Rgb(MidnightControlsConfig.reacharoundOutlineColorHex); 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(); matrices.push();
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines()); var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape, drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape,

View File

@@ -2,8 +2,8 @@ package eu.midnightdust.midnightcontrols.client.mouse;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.GlfwUtil; import net.minecraft.client.util.GlfwUtil;
import net.minecraft.client.util.SmoothUtil;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.util.math.Smoother;
public class EyeTrackerHandler { public class EyeTrackerHandler {
@@ -15,9 +15,8 @@ public class EyeTrackerHandler {
MinecraftClient client, MinecraftClient client,
double lastMouseUpdateTime, double lastMouseUpdateTime,
boolean holdingLeftMouseButton, boolean holdingLeftMouseButton,
boolean usingLongRangedTool, SmoothUtil smoothX,
Smoother smoothX, SmoothUtil smoothY
Smoother smoothY
) { ) {
// The player wants objects of interest to be moved under the crosshair that is always center of screen. // 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, // Normal mouse controls operate with the delta values from the direction of mouse movement,
@@ -46,7 +45,7 @@ public class EyeTrackerHandler {
} else { } else {
frameScalar = moveScalar; frameScalar = moveScalar;
} }
if(holdingLeftMouseButton && !usingLongRangedTool) { if(holdingLeftMouseButton){
frameScalar *= 0.5; //Don't move the camera so much while mining. It's annoying. 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()) { if (client.options.getInvertYMouse().getValue()) {
invertY = -1.0; invertY = -1.0;
} }
boolean notInDeadzone = (moveMagnitude > MidnightControlsConfig.eyeTrackerDeadzone) && !usingLongRangedTool; if (client.player != null && moveMagnitude > MidnightControlsConfig.eyeTrackerDeadzone) {
if (client.player != null && notInDeadzone) {
client.player.changeLookDirection(moveX, moveY * invertY); client.player.changeLookDirection(moveX, moveY * invertY);
client.getTutorialManager().onUpdateMouse(moveX, moveY); client.getTutorialManager().onUpdateMouse(moveX, moveY);
} }

View File

@@ -1,10 +1,11 @@
package eu.midnightdust.midnightcontrols.client.touch.gui; package eu.midnightdust.midnightcontrols.client.touch.gui;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants; import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.item.ArmorItem; import net.minecraft.item.ArmorItem;
import net.minecraft.item.PotionItem;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.UseAction; import net.minecraft.util.UseAction;

View File

@@ -1,7 +1,7 @@
package eu.midnightdust.midnightcontrols.client.touch.gui; package eu.midnightdust.midnightcontrols.client.touch.gui;
import org.thinkingstudio.obsidianui.Position; import dev.lambdaurora.spruceui.Position;
import org.thinkingstudio.obsidianui.widget.SpruceTexturedButtonWidget; import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -53,10 +53,13 @@
"depends": { "depends": {
"fabricloader": ">=0.11.3", "fabricloader": ">=0.11.3",
"fabric": ">=0.71.0", "fabric": ">=0.71.0",
"minecraft": ">=1.20.5", "minecraft": "~1.20",
"obsidianui": ">=0.2.5", "spruceui": ">=3.2.0",
"java": ">=17" "java": ">=17"
}, },
"recommends": {
"modmenu": ">=1.12.2"
},
"suggests": { "suggests": {
"kontrolo": "*" "kontrolo": "*"
}, },

View File

@@ -1,4 +1,3 @@
accessWidener v1 named accessWidener v1 named
#accessible class net/minecraft/client/gui/widget/EntryListWidget$MoveDirection #accessible class net/minecraft/client/gui/widget/EntryListWidget$MoveDirection
accessible method net/minecraft/util/Identifier <init> (Ljava/lang/String;Ljava/lang/String;)V

View File

@@ -4,7 +4,7 @@
"plugin": "eu.midnightdust.midnightcontrols.client.compat.MidnightControlsMixinPlugin", "plugin": "eu.midnightdust.midnightcontrols.client.compat.MidnightControlsMixinPlugin",
"compatibilityLevel": "JAVA_16", "compatibilityLevel": "JAVA_16",
"client": [ "client": [
"sodium.SodiumOptionsGUIAccessor" "SodiumOptionsGUIAccessor"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1

View File

@@ -1,7 +1,6 @@
{ {
"pack": { "pack": {
"pack_format": 15, "pack_format": 13,
"supported_formats": [15, 999],
"description": "Makes controller tooltips use similar icons to Bedrock Edition" "description": "Makes controller tooltips use similar icons to Bedrock Edition"
} }
} }

View File

@@ -1,7 +1,6 @@
{ {
"pack": { "pack": {
"pack_format": 15, "pack_format": 13,
"supported_formats": [15, 999],
"description": "Makes controller icons look similar to Legacy Console Edit." "description": "Makes controller icons look similar to Legacy Console Edit."
} }
} }