Compare commits
3 Commits
449ee5b435
...
9217852c0b
Author | SHA1 | Date |
---|---|---|
chylex | 9217852c0b | |
chylex | 21dcd60b91 | |
chylex | 9922828f09 |
|
@ -1,18 +1,20 @@
|
||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "bettercontrols",
|
"id": "bettercontrols",
|
||||||
"version": "${version}",
|
|
||||||
|
|
||||||
"name": "${name}",
|
"name": "${name}",
|
||||||
"description": "Adds many powerful key bindings and options to control your movement.\nThe features complement vanilla mechanics without giving unfair advantages, so server use should be fine.",
|
"description": "${description}",
|
||||||
"icon": "assets/bettercontrols/icon.png",
|
"version": "${version}",
|
||||||
"license": "MPL-2.0",
|
"license": "${license}",
|
||||||
|
|
||||||
|
"icon": "assets/bettercontrols/icon.png",
|
||||||
|
|
||||||
|
"authors": [
|
||||||
|
"${author}"
|
||||||
|
],
|
||||||
|
|
||||||
"authors": [ "chylex" ],
|
|
||||||
"contact": {
|
"contact": {
|
||||||
"homepage": "",
|
"issues": "${issuesURL}",
|
||||||
"sources": "https://github.com/chylex/Better-Controls",
|
"sources": "${sourcesURL}"
|
||||||
"issues": "https://github.com/chylex/Better-Controls/issues"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"environment": "client",
|
"environment": "client",
|
||||||
|
|
|
@ -4,20 +4,20 @@ import chylex.bettercontrols.gui.BetterControlsScreen;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.client.ConfigGuiHandler.ConfigGuiFactory;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import net.minecraftforge.fml.IExtensionPoint.DisplayTest;
|
import net.minecraftforge.fml.IExtensionPoint.DisplayTest;
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.loading.FMLPaths;
|
import net.minecraftforge.fml.loading.FMLPaths;
|
||||||
import net.minecraftforge.fmlclient.ConfigGuiHandler.ConfigGuiFactory;
|
import net.minecraftforge.network.NetworkConstants;
|
||||||
import net.minecraftforge.fmllegacy.network.FMLNetworkConstants;
|
|
||||||
|
|
||||||
@Mod("bettercontrols")
|
@Mod("bettercontrols")
|
||||||
public final class BetterControlsMod {
|
public final class BetterControlsMod {
|
||||||
public BetterControlsMod() {
|
public BetterControlsMod() {
|
||||||
BetterControlsCommon.setConfig(DistExecutor.safeCallWhenOn(Dist.CLIENT, () -> ClientLoader::loadConfig));
|
BetterControlsCommon.setConfig(DistExecutor.safeCallWhenOn(Dist.CLIENT, () -> ClientLoader::loadConfig));
|
||||||
ModLoadingContext.get().registerExtensionPoint(ConfigGuiFactory.class, () -> new ConfigGuiFactory(ClientLoader::createScreen));
|
ModLoadingContext.get().registerExtensionPoint(ConfigGuiFactory.class, () -> new ConfigGuiFactory(ClientLoader::createScreen));
|
||||||
ModLoadingContext.get().registerExtensionPoint(DisplayTest.class, () -> new DisplayTest(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true));
|
ModLoadingContext.get().registerExtensionPoint(DisplayTest.class, () -> new DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (a, b) -> true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ClientLoader {
|
private static final class ClientLoader {
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
modLoader = "javafml"
|
modLoader = "javafml"
|
||||||
loaderVersion = "[37,)"
|
loaderVersion = "[37,)"
|
||||||
|
|
||||||
authors = "chylex"
|
authors = "${author}"
|
||||||
license = "MPL-2.0"
|
license = "${license}"
|
||||||
issueTrackerURL = "https://github.com/chylex/Better-Controls/issues"
|
issueTrackerURL = "${issuesURL}"
|
||||||
|
|
||||||
[[mods]]
|
[[mods]]
|
||||||
modId = "bettercontrols"
|
modId = "bettercontrols"
|
||||||
version = "${version}"
|
version = "${version}"
|
||||||
displayName = "${name}"
|
displayName = "${name}"
|
||||||
|
description = "${description}"
|
||||||
logoFile = "icon.png"
|
logoFile = "icon.png"
|
||||||
description = '''
|
|
||||||
Adds many powerful key bindings and options to control your movement.
|
|
||||||
The features complement vanilla mechanics without giving unfair advantages, so server use should be fine.
|
|
||||||
'''
|
|
||||||
|
|
||||||
[[dependencies.bettercontrols]]
|
[[dependencies.bettercontrols]]
|
||||||
modId = "minecraft"
|
modId = "minecraft"
|
||||||
|
|
|
@ -4,8 +4,13 @@ import java.util.Date
|
||||||
|
|
||||||
val modId: String by project
|
val modId: String by project
|
||||||
val modName: String by project
|
val modName: String by project
|
||||||
|
val modDescription: String by project
|
||||||
val modAuthor: String by project
|
val modAuthor: String by project
|
||||||
val modVersion: String by project
|
val modVersion: String by project
|
||||||
|
val modLicense: String by project
|
||||||
|
val modSourcesURL: String by project
|
||||||
|
val modIssuesURL: String by project
|
||||||
|
|
||||||
val minecraftVersion: String by project
|
val minecraftVersion: String by project
|
||||||
val mixinVersion: String by project
|
val mixinVersion: String by project
|
||||||
|
|
||||||
|
@ -26,7 +31,16 @@ plugins {
|
||||||
|
|
||||||
idea {
|
idea {
|
||||||
module {
|
module {
|
||||||
excludeDirs.add(project.file("run"))
|
excludeDirs.add(file("gradle"))
|
||||||
|
excludeDirs.add(file("run"))
|
||||||
|
|
||||||
|
if (findProject(":Forge") == null) {
|
||||||
|
excludeDirs.add(file("Forge"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findProject(":Fabric") == null) {
|
||||||
|
excludeDirs.add(file("Fabric"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +74,12 @@ allprojects {
|
||||||
}
|
}
|
||||||
|
|
||||||
extensions.getByType<JavaPluginExtension>().apply {
|
extensions.getByType<JavaPluginExtension>().apply {
|
||||||
toolchain.languageVersion.set(JavaLanguageVersion.of(16))
|
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<JavaCompile> {
|
tasks.withType<JavaCompile> {
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
options.release.set(16)
|
options.release.set(17)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +104,12 @@ subprojects {
|
||||||
from(rootProject.sourceSets.main.get().resources)
|
from(rootProject.sourceSets.main.get().resources)
|
||||||
|
|
||||||
inputs.property("name", modName)
|
inputs.property("name", modName)
|
||||||
|
inputs.property("description", modDescription)
|
||||||
inputs.property("version", modVersion)
|
inputs.property("version", modVersion)
|
||||||
|
inputs.property("author", modAuthor)
|
||||||
|
inputs.property("license", modLicense)
|
||||||
|
inputs.property("sourcesURL", modSourcesURL)
|
||||||
|
inputs.property("issuesURL", modIssuesURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.jar {
|
tasks.jar {
|
||||||
|
@ -111,19 +130,40 @@ subprojects {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
onlyIf { false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("setupIdea") {
|
||||||
|
group = "mod"
|
||||||
|
|
||||||
|
dependsOn(tasks.findByName("decompile"))
|
||||||
|
|
||||||
|
val forge = findProject(":Forge")
|
||||||
|
if (forge != null) {
|
||||||
|
dependsOn(forge.tasks.getByName("genIntellijRuns"))
|
||||||
|
}
|
||||||
|
|
||||||
|
val fabric = findProject(":Fabric")
|
||||||
|
if (fabric != null) {
|
||||||
|
dependsOn(fabric.tasks.getByName("genSources"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val copyJars = tasks.register<Copy>("copyJars") {
|
val copyJars = tasks.register<Copy>("copyJars") {
|
||||||
|
group = "build"
|
||||||
duplicatesStrategy = EXCLUDE
|
duplicatesStrategy = EXCLUDE
|
||||||
|
|
||||||
for (subproject in subprojects) {
|
for (subproject in subprojects) {
|
||||||
dependsOn(subproject.tasks.build)
|
dependsOn(subproject.tasks.assemble)
|
||||||
from(subproject.base.libsDirectory.file("${subproject.base.archivesName.get()}-$jarVersion.jar"))
|
from(subproject.base.libsDirectory.file("${subproject.base.archivesName.get()}-$jarVersion.jar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
into(file("${project.buildDir}/dist"))
|
into(file("${project.buildDir}/dist"))
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.build {
|
tasks.assemble {
|
||||||
finalizedBy(copyJars)
|
finalizedBy(copyJars)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
# Mod
|
# Mod
|
||||||
modId=bettercontrols
|
modId=bettercontrols
|
||||||
modName=Better Controls
|
modName=Better Controls
|
||||||
|
modDescription=Adds many powerful key bindings and options to control your movement.\\n\\nThe features complement vanilla mechanics without giving unfair advantages, so server use should be fine.
|
||||||
modAuthor=chylex
|
modAuthor=chylex
|
||||||
modVersion=1.2.1
|
modVersion=1.2.2
|
||||||
|
modLicense=MPL-2.0
|
||||||
|
modSourcesURL=https://github.com/chylex/Better-Controls
|
||||||
|
modIssuesURL=https://github.com/chylex/Better-Controls/issues
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
minecraftVersion=1.17.1
|
minecraftVersion=1.18
|
||||||
forgeVersion=37.0.75
|
forgeVersion=38.0.8
|
||||||
fabricVersion=0.11.7
|
fabricVersion=0.12.8
|
||||||
mixinVersion=0.8.4
|
mixinVersion=0.8.4
|
||||||
|
|
||||||
# Gradle
|
# Gradle
|
||||||
|
|
|
@ -4,14 +4,14 @@ import net.minecraft.client.KeyMapping;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.Options;
|
import net.minecraft.client.Options;
|
||||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||||
import net.minecraft.client.gui.screens.controls.ControlList;
|
import net.minecraft.client.gui.screens.controls.KeyBindsList;
|
||||||
import net.minecraft.client.gui.screens.controls.ControlList.Entry;
|
import net.minecraft.client.gui.screens.controls.KeyBindsList.Entry;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
@Mixin(ControlList.class)
|
@Mixin(KeyBindsList.class)
|
||||||
public abstract class HookControlsListWidget extends ContainerObjectSelectionList<Entry> {
|
public abstract class HookControlsListWidget extends ContainerObjectSelectionList<Entry> {
|
||||||
public HookControlsListWidget(final Minecraft client, final int width, final int height, final int top, final int bottom, final int itemHeight) {
|
public HookControlsListWidget(final Minecraft client, final int width, final int height, final int top, final int bottom, final int itemHeight) {
|
||||||
super(client, width, height, top, bottom, itemHeight);
|
super(client, width, height, top, bottom, itemHeight);
|
||||||
|
|
|
@ -1,28 +1,61 @@
|
||||||
package chylex.bettercontrols.mixin;
|
package chylex.bettercontrols.mixin;
|
||||||
|
|
||||||
import chylex.bettercontrols.gui.BetterControlsScreen;
|
import chylex.bettercontrols.gui.BetterControlsScreen;
|
||||||
import net.minecraft.client.CycleOption;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.Option;
|
|
||||||
import net.minecraft.client.Options;
|
import net.minecraft.client.Options;
|
||||||
import net.minecraft.client.gui.components.AbstractWidget;
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.screens.OptionsSubScreen;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.client.gui.screens.controls.ControlsScreen;
|
import net.minecraft.client.gui.screens.controls.ControlsScreen;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(ControlsScreen.class)
|
@Mixin(ControlsScreen.class)
|
||||||
public abstract class HookControlsScreen {
|
public abstract class HookControlsScreen extends OptionsSubScreen {
|
||||||
@Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/CycleOption;createButton(Lnet/minecraft/client/Options;III)Lnet/minecraft/client/gui/components/AbstractWidget;"))
|
public HookControlsScreen(final Screen parentScreen, final Options options, final Component title) {
|
||||||
private AbstractWidget replaceAutoJumpButton(final CycleOption<?> option, final Options options, final int x, final int y, final int width) {
|
super(parentScreen, options, title);
|
||||||
if (option == Option.AUTO_JUMP && !Screen.hasAltDown()) {
|
}
|
||||||
@SuppressWarnings("ConstantConditions")
|
|
||||||
final ControlsScreen screen = (ControlsScreen)(Object)this;
|
@Inject(method = "init", at = @At("RETURN"))
|
||||||
return new Button(x, y, width, 20, BetterControlsScreen.TITLE.plainCopy().append("..."), btn -> Minecraft.getInstance().setScreen(new BetterControlsScreen(screen)));
|
public void afterInit(final CallbackInfo ci) {
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
final ControlsScreen screen = (ControlsScreen)(Object)this;
|
||||||
|
final int center = width / 2;
|
||||||
|
|
||||||
|
int leftBottomY = 0;
|
||||||
|
int rightBottomY = 0;
|
||||||
|
|
||||||
|
for (final GuiEventListener child : children()) {
|
||||||
|
if (!(child instanceof AbstractWidget widget)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int bottomY = widget.y + widget.getHeight();
|
||||||
|
|
||||||
|
if (widget.x + widget.getWidth() < center) {
|
||||||
|
leftBottomY = Math.max(leftBottomY, bottomY);
|
||||||
|
}
|
||||||
|
if (widget.x >= center) {
|
||||||
|
rightBottomY = Math.max(rightBottomY, bottomY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return option.createButton(options, x, y, width);
|
final int x, y;
|
||||||
|
|
||||||
|
if (leftBottomY < rightBottomY) {
|
||||||
|
x = center - 155;
|
||||||
|
y = leftBottomY + 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = center + 5;
|
||||||
|
y = rightBottomY + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
addRenderableWidget(new Button(x, y, 150, 20, BetterControlsScreen.TITLE.plainCopy().append("..."), btn -> Minecraft.getInstance().setScreen(new BetterControlsScreen(screen))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "chylex.bettercontrols.mixin",
|
"package": "chylex.bettercontrols.mixin",
|
||||||
"refmap": "bettercontrols.refmap.json",
|
"refmap": "bettercontrols.refmap.json",
|
||||||
"compatibilityLevel": "JAVA_16",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"client": [
|
"client": [
|
||||||
"AccessCameraFields",
|
"AccessCameraFields",
|
||||||
"AccessClientPlayerFields",
|
"AccessClientPlayerFields",
|
||||||
|
|
Loading…
Reference in New Issue