diff --git a/changelog.md b/changelog.md index 49999fc20..83a718e9a 100644 --- a/changelog.md +++ b/changelog.md @@ -7,8 +7,6 @@ This version has the following targets: **By donating on my [Patreon](https://patreon.com/isxander), you will gain access to builds of Controlify for splitscreen support and snapshot versions** -## Bug fixes +## Compatibilities -- Fix the temporarily disabling of the enhanced steam deck driver causing a Decky popup -- Fix crash on some NeoForge targets due to NeoForge patching vanilla methods like a good mod loader -- Fix missing texture on custom radial menu icons on NeoForge +- Add a screen processor for NeoForge's mod list screen to improve GUI interactions. diff --git a/src/main/java/dev/isxander/controlify/platform/neoforge/mixins/ModListScreenAccessor.java b/src/main/java/dev/isxander/controlify/platform/neoforge/mixins/ModListScreenAccessor.java new file mode 100644 index 000000000..856d2c24a --- /dev/null +++ b/src/main/java/dev/isxander/controlify/platform/neoforge/mixins/ModListScreenAccessor.java @@ -0,0 +1,24 @@ +//? if neoforge { +/*package dev.isxander.controlify.platform.neoforge.mixins; + +import net.minecraft.client.gui.components.Button; +import net.neoforged.neoforge.client.gui.ModListScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(ModListScreen.class) +public interface ModListScreenAccessor { + @Accessor + Button getConfigButton(); + + @Accessor + Button getOpenModsFolderButton(); + + @Accessor + Button getDoneButton(); + + @Invoker + void invokeDisplayModConfig(); +}*/ +//?} diff --git a/src/main/java/dev/isxander/controlify/platform/neoforge/mixins/ModListScreenMixin.java b/src/main/java/dev/isxander/controlify/platform/neoforge/mixins/ModListScreenMixin.java new file mode 100644 index 000000000..3073bd185 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/platform/neoforge/mixins/ModListScreenMixin.java @@ -0,0 +1,22 @@ +//? if neoforge { +/*package dev.isxander.controlify.platform.neoforge.mixins; + +import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.screenop.compat.neoforge.ModListScreenProcessor; +import net.neoforged.neoforge.client.gui.ModListScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(ModListScreen.class) +public class ModListScreenMixin implements ScreenProcessorProvider { + @Unique + private final ScreenProcessor processor = + new ModListScreenProcessor((ModListScreen) (Object) this); + + @Override + public ScreenProcessor screenProcessor() { + return this.processor; + } +}*/ +//?} diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/neoforge/ModListScreenProcessor.java b/src/main/java/dev/isxander/controlify/screenop/compat/neoforge/ModListScreenProcessor.java new file mode 100644 index 000000000..b40ffc247 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/screenop/compat/neoforge/ModListScreenProcessor.java @@ -0,0 +1,68 @@ +//? if neoforge { +/*package dev.isxander.controlify.screenop.compat.neoforge; + +import dev.isxander.controlify.api.bind.InputBindingSupplier; +import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; +import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; +import dev.isxander.controlify.bindings.ControlifyBindings; +import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.platform.neoforge.mixins.ModListScreenAccessor; +import dev.isxander.controlify.screenop.ScreenProcessor; +import net.minecraft.Util; +import net.neoforged.fml.loading.FMLPaths; +import net.neoforged.neoforge.client.gui.ModListScreen; + +public class ModListScreenProcessor extends ScreenProcessor { + public ModListScreenProcessor(ModListScreen screen) { + super(screen); + } + + final InputBindingSupplier OPEN_MOD_CONFIG = ControlifyBindings.GUI_PRESS; + final InputBindingSupplier OPEN_MODS_FOLDER = ControlifyBindings.GUI_ABSTRACT_ACTION_1; + final InputBindingSupplier NAVIGATE_BACK = ControlifyBindings.GUI_BACK; + + @Override + protected void handleButtons(ControllerEntity controller) { + super.handleButtons(controller); + + if (OPEN_MOD_CONFIG.on(controller).guiPressed().get()) { + getAccessor().invokeDisplayModConfig(); + playClackSound(); + } + if (OPEN_MODS_FOLDER.on(controller).guiPressed().get()) { + openModsFolder(); + playClackSound(); + } + } + + private ModListScreenAccessor getAccessor() { + return ((ModListScreenAccessor) (Object) this.screen); + } + + private void openModsFolder() { + Util.getPlatform().openFile(FMLPaths.MODSDIR.get().toFile()); + } + + @Override + public void onWidgetRebuild() { + super.onWidgetRebuild(); + final ModListScreenAccessor accessor = getAccessor(); + + ButtonGuideApi.addGuideToButton( + accessor.getConfigButton(), + OPEN_MOD_CONFIG, + ButtonGuidePredicate.always() + ); + ButtonGuideApi.addGuideToButton( + accessor.getOpenModsFolderButton(), + OPEN_MODS_FOLDER, + ButtonGuidePredicate.always() + ); + ButtonGuideApi.addGuideToButton( + accessor.getDoneButton(), + NAVIGATE_BACK, + ButtonGuidePredicate.always() + ); + } +}*/ +//?} diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/neoforge/NeoForgeTitleScreenProcessorCompat.java b/src/main/java/dev/isxander/controlify/screenop/compat/neoforge/NeoForgeTitleScreenProcessorCompat.java new file mode 100644 index 000000000..5e79918c6 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/screenop/compat/neoforge/NeoForgeTitleScreenProcessorCompat.java @@ -0,0 +1,50 @@ +//? if neoforge { +/*package dev.isxander.controlify.screenop.compat.neoforge; + +import dev.isxander.controlify.api.bind.InputBindingSupplier; +import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; +import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; +import dev.isxander.controlify.bindings.ControlifyBindings; +import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.screenop.ScreenProcessor; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.screens.TitleScreen; +import org.jetbrains.annotations.NotNull; +import net.neoforged.neoforge.client.gui.ModListScreen; + +import java.util.function.Function; + +public final class NeoForgeTitleScreenProcessorCompat { + private final @NotNull Function getButtonByTranslationKey; + private final ScreenProcessor screenProcessor; + + public NeoForgeTitleScreenProcessorCompat(@NotNull Function getButtonByTranslationKey, ScreenProcessor screenProcessor) { + this.getButtonByTranslationKey = getButtonByTranslationKey; + this.screenProcessor = screenProcessor; + } + + private static final String FORGE_MODS_BUTTON_KEY = "fml.menu.mods"; + + private AbstractButton getForgeModsButton() { + return getButtonByTranslationKey.apply(FORGE_MODS_BUTTON_KEY); + } + + private static final InputBindingSupplier OPEN_MOD_LIST_BINDING = ControlifyBindings.GUI_ABSTRACT_ACTION_2; + + public void onHandleButtons(@NotNull ControllerEntity controller) { + if (OPEN_MOD_LIST_BINDING.on(controller).guiPressed().get()) { + Minecraft.getInstance().setScreen(new ModListScreen(this.screenProcessor.screen)); + ScreenProcessor.playClackSound(); + } + } + + public void onAddGuides() { + ButtonGuideApi.addGuideToButton( + getForgeModsButton(), + OPEN_MOD_LIST_BINDING, + ButtonGuidePredicate.always() + ); + } +} +*///?} diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/TitleScreenProcessor.java b/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/TitleScreenProcessor.java index 27c8722cd..226721c88 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/TitleScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/TitleScreenProcessor.java @@ -6,12 +6,24 @@ import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.screenop.ScreenProcessor; import net.minecraft.client.gui.components.AbstractButton; -import net.minecraft.client.gui.screens.options.OptionsScreen; import net.minecraft.client.gui.screens.TitleScreen; +import net.minecraft.client.gui.screens.options.OptionsScreen; +//? if neoforge { +/*import dev.isxander.controlify.screenop.compat.neoforge.NeoForgeTitleScreenProcessorCompat;*/ +//?} public class TitleScreenProcessor extends ScreenProcessor { + //? if neoforge { + /*private final NeoForgeTitleScreenProcessorCompat neoForgeCompat;*/ + //?} public TitleScreenProcessor(TitleScreen screen) { super(screen); + //? if neoforge { + /*this.neoForgeCompat = new NeoForgeTitleScreenProcessorCompat( + key -> (AbstractButton) getWidget(key).orElseThrow(), + this + );*/ + //?} } @Override @@ -27,6 +39,9 @@ protected void handleButtons(ControllerEntity controller) { minecraft.setScreen(new OptionsScreen(screen, minecraft.options)); playClackSound(); } + //? if neoforge { + /*neoForgeCompat.onHandleButtons(controller);*/ + //?} } @Override @@ -44,5 +59,8 @@ public void onWidgetRebuild() { ControlifyBindings.GUI_ABSTRACT_ACTION_1, ButtonGuidePredicate.always() ); + //? if neoforge { + /*neoForgeCompat.onAddGuides();*/ + //?} } } diff --git a/src/main/resources/controlify-platform.neoforge.mixins.json b/src/main/resources/controlify-platform.neoforge.mixins.json index c74266bf2..ffa7aff2f 100644 --- a/src/main/resources/controlify-platform.neoforge.mixins.json +++ b/src/main/resources/controlify-platform.neoforge.mixins.json @@ -12,6 +12,8 @@ "compatibilityLevel": "JAVA_21", "client": [ "CreativeModeInventoryScreenAccessor", - "OptionsMixin" + "OptionsMixin", + "ModListScreenAccessor", + "ModListScreenMixin" ] }