🚧 More WIP on REI as hooking into it is quite difficult.

This commit is contained in:
LambdAurora
2020-02-18 18:09:50 +01:00
parent d56126c680
commit f8cc1fcc20
7 changed files with 159 additions and 19 deletions

View File

@@ -35,7 +35,7 @@ public interface CompatHandler
* @param screen The screen.
* @return True if the mouse is requried on the specified screen, else false.
*/
default boolean requireMouseOnScreen(@NotNull Screen screen)
default boolean requireMouseOnScreen(Screen screen)
{
return false;
}

View File

@@ -55,7 +55,7 @@ public class LambdaControlsCompat
* @param screen The screen.
* @return True if the mouse is requried on the specified screen, else false.
*/
public static boolean requireMouseOnScreen(@NotNull Screen screen)
public static boolean requireMouseOnScreen(Screen screen)
{
return HANDLERS.stream().anyMatch(handler -> handler.requireMouseOnScreen(screen));
}

View File

@@ -31,6 +31,7 @@ public class LambdaControlsMixinPlugin implements IMixinConfigPlugin
public LambdaControlsMixinPlugin()
{
this.conditionalMixins.put("me.lambdaurora.lambdacontrols.client.compat.mixin.RecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent());
this.conditionalMixins.put("me.lambdaurora.lambdacontrols.client.compat.mixin.VillagerRecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent());
}
@Override

View File

@@ -12,17 +12,26 @@ 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.compat.mixin.VillagerRecipeViewingScreenAccessor;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.InputHandlers;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.lambdacontrols.client.controller.PressAction;
import me.shedaniel.rei.api.RecipeCategory;
import me.shedaniel.rei.gui.ContainerScreenOverlay;
import me.shedaniel.rei.gui.RecipeViewingScreen;
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
import me.shedaniel.rei.gui.widget.EntryListWidget;
import me.shedaniel.rei.impl.ScreenHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.Identifier;
import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.jetbrains.annotations.NotNull;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER;
import java.util.List;
import java.util.Optional;
import static org.lwjgl.glfw.GLFW.*;
/**
* Represents a compatibility handler for REI.
@@ -33,47 +42,135 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER;
*/
public class ReiCompat implements CompatHandler
{
private static EntryListWidget ENTRY_LIST_WIDGET;
public static ButtonBinding TAB_BACK;
@Override
public void handle(@NotNull LambdaControlsClient mod)
{
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "tab_back"))
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "category_back"))
.buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(tabAction(false))
.action(handleTab(false))
.cooldown(true)
.build());
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "category_next"))
.buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleTab(true))
.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))
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "page_back"))
.buttons(ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_X, false))
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handlePage(false))
.cooldown(true)
.build());
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "page_next"))
.buttons(ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_X, true))
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handlePage(true))
.cooldown(true)
.build());
// For some reasons this is broken.
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "show_usage"))
.buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action((client, button, action) -> {
if (action != ButtonState.RELEASE)
return false;
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent())
return false;
double mouseX = client.mouse.getX();
double mouseY = client.mouse.getY();
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return false;
return widget.mouseClicked(mouseX, mouseY, GLFW_MOUSE_BUTTON_2);
})
.cooldown(true)
.build());
}
@Override
public boolean requireMouseOnScreen(@NotNull Screen screen)
public boolean requireMouseOnScreen(Screen screen)
{
return isViewingScreen(screen);
}
private static boolean isViewingScreen(@NotNull Screen screen)
private static boolean isViewingScreen(Screen screen)
{
return screen instanceof RecipeViewingScreen || screen instanceof VillagerRecipeViewingScreen;
}
private static PressAction tabAction(boolean next)
private static EntryListWidget getEntryListWidget()
{
if (ENTRY_LIST_WIDGET == null) {
ENTRY_LIST_WIDGET = LambdaReflection.getFirstFieldOfType(ContainerScreenOverlay.class, EntryListWidget.class)
.map(field -> (EntryListWidget) LambdaReflection.getFieldValue(null, field))
.orElse(null);
}
return ENTRY_LIST_WIDGET;
}
private static PressAction handlePage(boolean next)
{
return (client, button, action) -> {
if (action == ButtonState.RELEASE)
return false;
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent())
return false;
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return false;
if (next)
widget.nextPage();
else
widget.previousPage();
widget.updateEntriesPosition();
return true;
};
}
/**
* Returns the handler for category tabs buttons.
*
* @param next True if the action is to switch to the next tab.
* @return The handler.
*/
private static PressAction handleTab(boolean next)
{
return (client, button, action) -> {
if (action != ButtonState.RELEASE)
return false;
if (client.currentScreen instanceof RecipeViewingScreen) {
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
if (next)
screen.getCategoryNext().onPressed();
else
screen.getCategoryBack().onPressed();
return true;
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) {
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex();
int nextTab = currentTab + (next ? 1 : -1);
if (nextTab < 0)
nextTab = categories.size() - 1;
else if (nextTab >= categories.size())
nextTab = 0;
screen.setSelectedCategoryIndex(nextTab);
screen.lambdacontrols_init();
return true;
}
return false;
};

View File

@@ -0,0 +1,41 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* 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.api.RecipeCategory;
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.util.List;
/**
* Represents an accessor to REI's VillagerRecipeViewingScreen.
*
* @author LambdAurora
* @version 1.2.0
* @since 1.2.0
*/
@Mixin(VillagerRecipeViewingScreen.class)
public interface VillagerRecipeViewingScreenAccessor
{
@Accessor("categories")
List<RecipeCategory<?>> getCategories();
@Accessor("selectedCategoryIndex")
int getSelectedCategoryIndex();
@Accessor("selectedCategoryIndex")
void setSelectedCategoryIndex(int selectedCategoryIndex);
@Invoker("init")
void lambdacontrols_init();
}

View File

@@ -47,7 +47,7 @@ public class InputHandlers
{
}
public static PressAction handleHotbar(boolean right)
public static PressAction handleHotbar(boolean next)
{
return (client, button, action) -> {
if (action == ButtonState.RELEASE)
@@ -55,7 +55,7 @@ public class InputHandlers
// When ingame
if (client.currentScreen == null && client.player != null) {
if (right)
if (next)
client.player.inventory.selectedSlot = client.player.inventory.selectedSlot == 8 ? 0 : client.player.inventory.selectedSlot + 1;
else
client.player.inventory.selectedSlot = client.player.inventory.selectedSlot == 0 ? 8 : client.player.inventory.selectedSlot - 1;
@@ -63,7 +63,7 @@ public class InputHandlers
} else if (client.currentScreen instanceof CreativeInventoryScreen) {
CreativeInventoryScreenAccessor inventory = (CreativeInventoryScreenAccessor) client.currentScreen;
int currentTab = inventory.getSelectedTab();
int nextTab = currentTab + (right ? 1 : -1);
int nextTab = currentTab + (next ? 1 : -1);
if (nextTab < 0)
nextTab = ItemGroup.GROUPS.length - 1;
else if (nextTab >= ItemGroup.GROUPS.length)
@@ -74,7 +74,7 @@ public class InputHandlers
RecipeBookWidgetAccessor recipeBook = (RecipeBookWidgetAccessor) ((InventoryScreen) client.currentScreen).getRecipeBookWidget();
List<RecipeGroupButtonWidget> tabs = recipeBook.getTabButtons();
RecipeGroupButtonWidget currentTab = recipeBook.getCurrentTab();
int nextTab = tabs.indexOf(currentTab) + (right ? 1 : -1);
int nextTab = tabs.indexOf(currentTab) + (next ? 1 : -1);
if (nextTab < 0)
nextTab = tabs.size() - 1;
else if (nextTab >= tabs.size())
@@ -89,7 +89,7 @@ public class InputHandlers
AdvancementTab tab = screen.getSelectedTab();
for (int i = 0; i < tabs.size(); i++) {
if (tabs.get(i).equals(tab)) {
int nextTab = i + (right ? 1 : -1);
int nextTab = i + (next ? 1 : -1);
if (nextTab < 0)
nextTab = tabs.size() - 1;
else if (nextTab >= tabs.size())

View File

@@ -4,7 +4,8 @@
"plugin": "me.lambdaurora.lambdacontrols.client.compat.LambdaControlsMixinPlugin",
"compatibilityLevel": "JAVA_8",
"client": [
"RecipeViewingScreenAccessor"
"RecipeViewingScreenAccessor",
"VillagerRecipeViewingScreenAccessor"
],
"injectors": {
"defaultRequire": 1