diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java index 70247fa..1985abc 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java @@ -131,6 +131,18 @@ public class LambdaControlsConfig this.config.remove("gameplay.front_block_placing"); this.config.set("gameplay.front_block_placing.enabled", DEFAULT_FRONT_BLOCK_PLACING); } + + this.renamed("controller.controls.tab_left", "controller.controls.tab_back"); + this.renamed("controller.controls.tab_right", "controller.controls.tab_next"); + } + + private void renamed(String oldPath, String newPath) + { + if (!this.config.contains(oldPath)) + return; + Object raw = this.config.getRaw(oldPath); + this.config.remove(oldPath); + this.config.set(newPath, raw); } /** diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java index d8f0a6c..42fafd0 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsCompat.java @@ -41,7 +41,7 @@ public class LambdaControlsCompat mod.log("Adding okzoomer compatibility..."); HANDLERS.add(new OkZoomerCompat()); } - if (FabricLoader.getInstance().isModLoaded("roughlyenoughitems")) { + if (isReiPresent()) { mod.log("Adding REI compatiblity..."); HANDLERS.add(new ReiCompat()); } @@ -59,4 +59,14 @@ public class LambdaControlsCompat { return HANDLERS.stream().anyMatch(handler -> handler.requireMouseOnScreen(screen)); } + + /** + * Returns whether Roughly Enough Items is present. + * + * @return True if Roughly Enough Items is present, else false. + */ + public static boolean isReiPresent() + { + return FabricLoader.getInstance().isModLoaded("roughlyenoughitems"); + } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsMixinPlugin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsMixinPlugin.java new file mode 100644 index 0000000..1836797 --- /dev/null +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/LambdaControlsMixinPlugin.java @@ -0,0 +1,73 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols.client.compat; + +import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +/** + * This plugin is only present for the conditional mixins. + * + * @author LambdAurora + * @version 1.2.0 + * @since 1.2.0 + */ +public class LambdaControlsMixinPlugin implements IMixinConfigPlugin +{ + private final HashMap conditionalMixins = new HashMap<>(); + + public LambdaControlsMixinPlugin() + { + this.conditionalMixins.put("me.lambdaurora.lambdacontrols.client.compat.mixin.RecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent()); + } + + @Override + public void onLoad(String mixinPackage) + { + } + + @Override + public String getRefMapperConfig() + { + return null; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) + { + return this.conditionalMixins.getOrDefault(mixinClassName, Boolean.TRUE); + } + + @Override + public void acceptTargets(Set myTargets, Set otherTargets) + { + } + + @Override + public List getMixins() + { + return null; + } + + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) + { + } + + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) + { + } +} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/ReiCompat.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/ReiCompat.java index 434bd6f..b4c4f1c 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/ReiCompat.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/ReiCompat.java @@ -11,6 +11,7 @@ package me.lambdaurora.lambdacontrols.client.compat; import me.lambdaurora.lambdacontrols.client.ButtonState; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import me.lambdaurora.lambdacontrols.client.compat.mixin.RecipeViewingScreenAccessor; import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding; import me.lambdaurora.lambdacontrols.client.controller.InputManager; import me.lambdaurora.lambdacontrols.client.controller.PressAction; @@ -35,18 +36,19 @@ public class ReiCompat implements CompatHandler @Override public void handle(@NotNull LambdaControlsClient mod) { - InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "tab_right")) - .buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) - .filter((client, binding) -> isViewingScreen(client.currentScreen)) - .action(tabAction(true)) - .cooldown(true) - .build()); - InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "tab_left")) + InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "tab_back")) .buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) .filter((client, binding) -> isViewingScreen(client.currentScreen)) .action(tabAction(false)) .cooldown(true) .build()); + + InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "tab_next")) + .buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) + .filter((client, binding) -> isViewingScreen(client.currentScreen)) + .action(tabAction(true)) + .cooldown(true) + .build()); } @Override @@ -60,14 +62,18 @@ public class ReiCompat implements CompatHandler return screen instanceof RecipeViewingScreen || screen instanceof VillagerRecipeViewingScreen; } - private static PressAction tabAction(boolean right) + private static PressAction tabAction(boolean next) { return (client, button, action) -> { if (action == ButtonState.RELEASE) return false; if (client.currentScreen instanceof RecipeViewingScreen) { - RecipeViewingScreen screen = (RecipeViewingScreen) client.currentScreen; + RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen; + if (next) + screen.getCategoryNext().onPressed(); + else + screen.getCategoryBack().onPressed(); } return false; }; diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/mixin/RecipeViewingScreenAccessor.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/mixin/RecipeViewingScreenAccessor.java new file mode 100644 index 0000000..5d7d87f --- /dev/null +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/compat/mixin/RecipeViewingScreenAccessor.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols.client.compat.mixin; + +import me.shedaniel.rei.gui.RecipeViewingScreen; +import me.shedaniel.rei.gui.widget.ButtonWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +/** + * Represents an accessor to REI's RecipeViewingScreen. + * + * @author LambdAurora + * @version 1.2.0 + * @since 1.2.0 + */ +@Mixin(RecipeViewingScreen.class) +public interface RecipeViewingScreenAccessor +{ + @Accessor("categoryBack") + ButtonWidget getCategoryBack(); + + @Accessor("categoryNext") + ButtonWidget getCategoryNext(); +} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java index 72988e2..57b11ce 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java @@ -73,9 +73,9 @@ public class ButtonBinding implements Nameable .actions(PressAction.DEFAULT_ACTION, InputHandlers::handleToggleSneak).onlyInGame().cooldown(true).register(); public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).register(); public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).cooldown(true).register(); - public static final ButtonBinding TAB_LEFT = new Builder("tab_left").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)).cooldown(true).register(); - public static final ButtonBinding TAB_RIGHT = new Builder("tab_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) + public static final ButtonBinding TAB_RIGHT = new Builder("tab_next").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) .action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown(true).register(); public static final ButtonBinding TOGGLE_PERSPECTIVE = new Builder("toggle_perspective").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_Y).cooldown(true).register(); public static final ButtonBinding USE = new Builder("use").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)).register(); diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ContainerScreenMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ContainerScreenMixin.java index 561ef10..f1707ae 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ContainerScreenMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ContainerScreenMixin.java @@ -11,6 +11,7 @@ package me.lambdaurora.lambdacontrols.client.mixin; import me.lambdaurora.lambdacontrols.ControlsMode; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; +import me.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat; import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer; import me.lambdaurora.lambdacontrols.client.util.ContainerScreenAccessor; import net.fabricmc.loader.api.FabricLoader; @@ -49,7 +50,7 @@ public abstract class ContainerScreenMixin implements ContainerScreenAccessor x = LambdaControlsRenderer.drawButtonTip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 2; x = LambdaControlsRenderer.drawButtonTip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "lambdacontrols.action.exit", true, client) + 2; - if (FabricLoader.getInstance().isModLoaded("roughlyenoughitems")) { + if (LambdaControlsCompat.isReiPresent()) { x = 2; y -= 24; } diff --git a/fabric/src/main/resources/config.toml b/fabric/src/main/resources/config.toml index 7057723..4ac0d55 100644 --- a/fabric/src/main/resources/config.toml +++ b/fabric/src/main/resources/config.toml @@ -95,10 +95,10 @@ auto_switch_mode = false sprint = "9" # Swap hands control. swap_hands = "2" - # Switch to left tab control. - tab_left = "4" - # Switch to right tab control. - tab_right = "5" + # Switch to back tab control. + tab_back = "4" + # Switch to next tab control. + tab_next = "5" # Toggle perspective control. toggle_perspective = "11+3" # Toggle smooth camera control. diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 91f34dd..dd8b126 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -27,7 +27,8 @@ ] }, "mixins": [ - "lambdacontrols.mixins.json" + "lambdacontrols.mixins.json", + "lambdacontrols_compat.mixins.json" ], "depends": { "fabricloader": ">=0.4.0", @@ -40,7 +41,8 @@ "okzoomer": ">=1.0.4" }, "suggests": { - "flamingo": "*" + "flamingo": "*", + "roughlyenoughitems": ">=3.4.5" }, "breaks": { "modmenu": "<1.9.0" diff --git a/fabric/src/main/resources/lambdacontrols_compat.mixins.json b/fabric/src/main/resources/lambdacontrols_compat.mixins.json new file mode 100644 index 0000000..4fdee98 --- /dev/null +++ b/fabric/src/main/resources/lambdacontrols_compat.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "package": "me.lambdaurora.lambdacontrols.client.compat.mixin", + "plugin": "me.lambdaurora.lambdacontrols.client.compat.LambdaControlsMixinPlugin", + "compatibilityLevel": "JAVA_8", + "client": [ + "RecipeViewingScreenAccessor" + ], + "injectors": { + "defaultRequire": 1 + } +}