forked from Clones/Controlify
refactor button guide, bindings and controller identification
This commit is contained in:
@ -38,11 +38,12 @@ public class ControllerBinding<T extends ControllerState> {
|
||||
this(controller, defaultBind, id, null, () -> false);
|
||||
}
|
||||
|
||||
public ControllerBinding(Controller<T, ?> controller, GamepadBind defaultBind, ResourceLocation id, KeyMapping override, BooleanSupplier toggleOverride) {
|
||||
this(controller, controller instanceof GamepadController ? (IBind<T>) defaultBind : new EmptyBind<>(), id, override, toggleOverride);
|
||||
@SuppressWarnings("unchecked")
|
||||
public ControllerBinding(Controller<T, ?> controller, GamepadBinds defaultBind, ResourceLocation id, KeyMapping override, BooleanSupplier toggleOverride) {
|
||||
this(controller, controller instanceof GamepadController gamepad ? (IBind<T>) defaultBind.forGamepad(gamepad) : new EmptyBind<>(), id, override, toggleOverride);
|
||||
}
|
||||
|
||||
public ControllerBinding(Controller<T, ?> controller, GamepadBind defaultBind, ResourceLocation id) {
|
||||
public ControllerBinding(Controller<T, ?> controller, GamepadBinds defaultBind, ResourceLocation id) {
|
||||
this(controller, defaultBind, id, null, () -> false);
|
||||
}
|
||||
|
||||
@ -55,11 +56,11 @@ public class ControllerBinding<T extends ControllerState> {
|
||||
}
|
||||
|
||||
public boolean held() {
|
||||
return bind.held(controller.state(), controller);
|
||||
return bind.held(controller.state());
|
||||
}
|
||||
|
||||
public boolean prevHeld() {
|
||||
return bind.held(controller.prevState(), controller);
|
||||
return bind.held(controller.prevState());
|
||||
}
|
||||
|
||||
public boolean justPressed() {
|
||||
@ -108,6 +109,10 @@ public class ControllerBinding<T extends ControllerState> {
|
||||
return description;
|
||||
}
|
||||
|
||||
public boolean unbound() {
|
||||
return bind instanceof EmptyBind;
|
||||
}
|
||||
|
||||
public KeyMappingOverride override() {
|
||||
return override;
|
||||
}
|
||||
|
@ -48,52 +48,52 @@ public class ControllerBindings<T extends ControllerState> {
|
||||
this.controller = controller;
|
||||
var options = Minecraft.getInstance().options;
|
||||
|
||||
register(WALK_FORWARD = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_FORWARD, new ResourceLocation("controlify", "walk_forward")));
|
||||
register(WALK_BACKWARD = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "walk_backward")));
|
||||
register(WALK_LEFT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_LEFT, new ResourceLocation("controlify", "strafe_left")));
|
||||
register(WALK_RIGHT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "strafe_right")));
|
||||
register(LOOK_UP = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_FORWARD, new ResourceLocation("controlify", "look_up")));
|
||||
register(LOOK_DOWN = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_BACKWARD, new ResourceLocation("controlify", "look_down")));
|
||||
register(LOOK_LEFT = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "look_left")));
|
||||
register(LOOK_RIGHT = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "look_right")));
|
||||
register(JUMP = new ControllerBinding<>(controller, GamepadBind.A_BUTTON, new ResourceLocation("controlify", "jump"), options.keyJump, () -> false));
|
||||
register(SNEAK = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_PRESS, new ResourceLocation("controlify", "sneak"), options.keyShift, () -> controller.config().toggleSneak));
|
||||
register(ATTACK = new ControllerBinding<>(controller, GamepadBind.RIGHT_TRIGGER, new ResourceLocation("controlify", "attack"), options.keyAttack, () -> false));
|
||||
register(USE = new ControllerBinding<>(controller, GamepadBind.LEFT_TRIGGER, new ResourceLocation("controlify", "use"), options.keyUse, () -> false));
|
||||
register(SPRINT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_PRESS, new ResourceLocation("controlify", "sprint"), options.keySprint, () -> controller.config().toggleSprint));
|
||||
register(DROP = new ControllerBinding<>(controller, GamepadBind.DPAD_DOWN, new ResourceLocation("controlify", "drop"), options.keyDrop, () -> false));
|
||||
register(NEXT_SLOT = new ControllerBinding<>(controller, GamepadBind.RIGHT_BUMPER, new ResourceLocation("controlify", "next_slot")));
|
||||
register(PREV_SLOT = new ControllerBinding<>(controller, GamepadBind.LEFT_BUMPER, new ResourceLocation("controlify", "prev_slot")));
|
||||
register(PAUSE = new ControllerBinding<>(controller, GamepadBind.START, new ResourceLocation("controlify", "pause")));
|
||||
register(INVENTORY = new ControllerBinding<>(controller, GamepadBind.Y_BUTTON, new ResourceLocation("controlify", "inventory"), options.keyInventory, () -> false));
|
||||
register(CHANGE_PERSPECTIVE = new ControllerBinding<>(controller, GamepadBind.BACK, new ResourceLocation("controlify", "change_perspective"), options.keyTogglePerspective, () -> false));
|
||||
register(SWAP_HANDS = new ControllerBinding<>(controller, GamepadBind.X_BUTTON, new ResourceLocation("controlify", "swap_hands"), options.keySwapOffhand, () -> false));
|
||||
register(OPEN_CHAT = new ControllerBinding<>(controller, GamepadBind.DPAD_UP, new ResourceLocation("controlify", "open_chat"), options.keyChat, () -> false));
|
||||
register(GUI_PRESS = new ControllerBinding<>(controller, GamepadBind.A_BUTTON, new ResourceLocation("controlify", "gui_press")));
|
||||
register(GUI_BACK = new ControllerBinding<>(controller, GamepadBind.B_BUTTON, new ResourceLocation("controlify", "gui_back")));
|
||||
register(GUI_NEXT_TAB = new ControllerBinding<>(controller, GamepadBind.RIGHT_BUMPER, new ResourceLocation("controlify", "gui_next_tab")));
|
||||
register(GUI_PREV_TAB = new ControllerBinding<>(controller, GamepadBind.LEFT_BUMPER, new ResourceLocation("controlify", "gui_prev_tab")));
|
||||
register(PICK_BLOCK = new ControllerBinding<>(controller, GamepadBind.DPAD_LEFT, new ResourceLocation("controlify", "pick_block"), options.keyPickItem, () -> false));
|
||||
register(WALK_FORWARD = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_FORWARD, new ResourceLocation("controlify", "walk_forward")));
|
||||
register(WALK_BACKWARD = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "walk_backward")));
|
||||
register(WALK_LEFT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_LEFT, new ResourceLocation("controlify", "strafe_left")));
|
||||
register(WALK_RIGHT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "strafe_right")));
|
||||
register(LOOK_UP = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_FORWARD, new ResourceLocation("controlify", "look_up")));
|
||||
register(LOOK_DOWN = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_BACKWARD, new ResourceLocation("controlify", "look_down")));
|
||||
register(LOOK_LEFT = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "look_left")));
|
||||
register(LOOK_RIGHT = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "look_right")));
|
||||
register(JUMP = new ControllerBinding<>(controller, GamepadBinds.A_BUTTON, new ResourceLocation("controlify", "jump"), options.keyJump, () -> false));
|
||||
register(SNEAK = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_PRESS, new ResourceLocation("controlify", "sneak"), options.keyShift, () -> controller.config().toggleSneak));
|
||||
register(ATTACK = new ControllerBinding<>(controller, GamepadBinds.RIGHT_TRIGGER, new ResourceLocation("controlify", "attack"), options.keyAttack, () -> false));
|
||||
register(USE = new ControllerBinding<>(controller, GamepadBinds.LEFT_TRIGGER, new ResourceLocation("controlify", "use"), options.keyUse, () -> false));
|
||||
register(SPRINT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_PRESS, new ResourceLocation("controlify", "sprint"), options.keySprint, () -> controller.config().toggleSprint));
|
||||
register(DROP = new ControllerBinding<>(controller, GamepadBinds.DPAD_DOWN, new ResourceLocation("controlify", "drop"), options.keyDrop, () -> false));
|
||||
register(NEXT_SLOT = new ControllerBinding<>(controller, GamepadBinds.RIGHT_BUMPER, new ResourceLocation("controlify", "next_slot")));
|
||||
register(PREV_SLOT = new ControllerBinding<>(controller, GamepadBinds.LEFT_BUMPER, new ResourceLocation("controlify", "prev_slot")));
|
||||
register(PAUSE = new ControllerBinding<>(controller, GamepadBinds.START, new ResourceLocation("controlify", "pause")));
|
||||
register(INVENTORY = new ControllerBinding<>(controller, GamepadBinds.Y_BUTTON, new ResourceLocation("controlify", "inventory"), options.keyInventory, () -> false));
|
||||
register(CHANGE_PERSPECTIVE = new ControllerBinding<>(controller, GamepadBinds.BACK, new ResourceLocation("controlify", "change_perspective"), options.keyTogglePerspective, () -> false));
|
||||
register(SWAP_HANDS = new ControllerBinding<>(controller, GamepadBinds.X_BUTTON, new ResourceLocation("controlify", "swap_hands"), options.keySwapOffhand, () -> false));
|
||||
register(OPEN_CHAT = new ControllerBinding<>(controller, GamepadBinds.DPAD_UP, new ResourceLocation("controlify", "open_chat"), options.keyChat, () -> false));
|
||||
register(GUI_PRESS = new ControllerBinding<>(controller, GamepadBinds.A_BUTTON, new ResourceLocation("controlify", "gui_press")));
|
||||
register(GUI_BACK = new ControllerBinding<>(controller, GamepadBinds.B_BUTTON, new ResourceLocation("controlify", "gui_back")));
|
||||
register(GUI_NEXT_TAB = new ControllerBinding<>(controller, GamepadBinds.RIGHT_BUMPER, new ResourceLocation("controlify", "gui_next_tab")));
|
||||
register(GUI_PREV_TAB = new ControllerBinding<>(controller, GamepadBinds.LEFT_BUMPER, new ResourceLocation("controlify", "gui_prev_tab")));
|
||||
register(PICK_BLOCK = new ControllerBinding<>(controller, GamepadBinds.DPAD_LEFT, new ResourceLocation("controlify", "pick_block"), options.keyPickItem, () -> false));
|
||||
register(TOGGLE_HUD_VISIBILITY = new ControllerBinding<>(controller, new EmptyBind<>(), new ResourceLocation("controlify", "toggle_hud_visibility")));
|
||||
register(SHOW_PLAYER_LIST = new ControllerBinding<>(controller, GamepadBind.DPAD_RIGHT, new ResourceLocation("controlify", "show_player_list"), options.keyPlayerList, () -> false));
|
||||
register(VMOUSE_MOVE_UP = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_FORWARD, new ResourceLocation("controlify", "vmouse_move_up")));
|
||||
register(VMOUSE_MOVE_DOWN = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "vmouse_move_down")));
|
||||
register(VMOUSE_MOVE_LEFT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_LEFT, new ResourceLocation("controlify", "vmouse_move_left")));
|
||||
register(VMOUSE_MOVE_RIGHT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "vmouse_move_right")));
|
||||
register(VMOUSE_LCLICK = new ControllerBinding<>(controller, GamepadBind.A_BUTTON, new ResourceLocation("controlify", "vmouse_lclick")));
|
||||
register(VMOUSE_RCLICK = new ControllerBinding<>(controller, GamepadBind.X_BUTTON, new ResourceLocation("controlify", "vmouse_rclick")));
|
||||
register(VMOUSE_SHIFT_CLICK = new ControllerBinding<>(controller, GamepadBind.Y_BUTTON, new ResourceLocation("controlify", "vmouse_shift_click")));
|
||||
register(VMOUSE_SCROLL_UP = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_FORWARD, new ResourceLocation("controlify", "vmouse_scroll_up")));
|
||||
register(VMOUSE_SCROLL_DOWN = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_BACKWARD, new ResourceLocation("controlify", "vmouse_scroll_down")));
|
||||
register(VMOUSE_ESCAPE = new ControllerBinding<>(controller, GamepadBind.B_BUTTON, new ResourceLocation("controlify", "vmouse_escape")));
|
||||
register(VMOUSE_SHIFT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_PRESS, new ResourceLocation("controlify", "vmouse_shift")));
|
||||
register(VMOUSE_TOGGLE = new ControllerBinding<>(controller, GamepadBind.BACK, new ResourceLocation("controlify", "vmouse_toggle")));
|
||||
register(GUI_NAVI_UP = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_FORWARD, new ResourceLocation("controlify", "gui_navi_up")));
|
||||
register(GUI_NAVI_DOWN = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "gui_navi_down")));
|
||||
register(GUI_NAVI_LEFT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_LEFT, new ResourceLocation("controlify", "gui_navi_left")));
|
||||
register(GUI_NAVI_RIGHT = new ControllerBinding<>(controller, GamepadBind.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "gui_navi_right")));
|
||||
register(YACL_CYCLE_OPT_FORWARD = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "yacl_cycle_opt_forward")));
|
||||
register(YACL_CYCLE_OPT_BACKWARD = new ControllerBinding<>(controller, GamepadBind.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "yacl_cycle_opt_backward")));
|
||||
register(SHOW_PLAYER_LIST = new ControllerBinding<>(controller, GamepadBinds.DPAD_RIGHT, new ResourceLocation("controlify", "show_player_list"), options.keyPlayerList, () -> false));
|
||||
register(VMOUSE_MOVE_UP = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_FORWARD, new ResourceLocation("controlify", "vmouse_move_up")));
|
||||
register(VMOUSE_MOVE_DOWN = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "vmouse_move_down")));
|
||||
register(VMOUSE_MOVE_LEFT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_LEFT, new ResourceLocation("controlify", "vmouse_move_left")));
|
||||
register(VMOUSE_MOVE_RIGHT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "vmouse_move_right")));
|
||||
register(VMOUSE_LCLICK = new ControllerBinding<>(controller, GamepadBinds.A_BUTTON, new ResourceLocation("controlify", "vmouse_lclick")));
|
||||
register(VMOUSE_RCLICK = new ControllerBinding<>(controller, GamepadBinds.X_BUTTON, new ResourceLocation("controlify", "vmouse_rclick")));
|
||||
register(VMOUSE_SHIFT_CLICK = new ControllerBinding<>(controller, GamepadBinds.Y_BUTTON, new ResourceLocation("controlify", "vmouse_shift_click")));
|
||||
register(VMOUSE_SCROLL_UP = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_FORWARD, new ResourceLocation("controlify", "vmouse_scroll_up")));
|
||||
register(VMOUSE_SCROLL_DOWN = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_BACKWARD, new ResourceLocation("controlify", "vmouse_scroll_down")));
|
||||
register(VMOUSE_ESCAPE = new ControllerBinding<>(controller, GamepadBinds.B_BUTTON, new ResourceLocation("controlify", "vmouse_escape")));
|
||||
register(VMOUSE_SHIFT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_PRESS, new ResourceLocation("controlify", "vmouse_shift")));
|
||||
register(VMOUSE_TOGGLE = new ControllerBinding<>(controller, GamepadBinds.BACK, new ResourceLocation("controlify", "vmouse_toggle")));
|
||||
register(GUI_NAVI_UP = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_FORWARD, new ResourceLocation("controlify", "gui_navi_up")));
|
||||
register(GUI_NAVI_DOWN = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "gui_navi_down")));
|
||||
register(GUI_NAVI_LEFT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_LEFT, new ResourceLocation("controlify", "gui_navi_left")));
|
||||
register(GUI_NAVI_RIGHT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "gui_navi_right")));
|
||||
register(YACL_CYCLE_OPT_FORWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "yacl_cycle_opt_forward")));
|
||||
register(YACL_CYCLE_OPT_BACKWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "yacl_cycle_opt_backward")));
|
||||
|
||||
ControlifyEvents.CONTROLLER_BIND_REGISTRY.invoker().onRegisterControllerBinds(this, controller);
|
||||
|
||||
|
@ -15,7 +15,12 @@ public class EmptyBind<T extends ControllerState> implements IBind<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack matrices, int x, int centerY, Controller<T, ?> controller) {
|
||||
public boolean held(T state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack matrices, int x, int centerY) {
|
||||
|
||||
}
|
||||
|
||||
@ -31,6 +36,11 @@ public class EmptyBind<T extends ControllerState> implements IBind<T> {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Controller<T, ?> controller() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof EmptyBind;
|
||||
|
@ -4,78 +4,37 @@ import com.google.gson.JsonObject;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadConfig;
|
||||
import dev.isxander.controlify.controller.gamepad.BuiltinGamepadTheme;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadConfig;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadController;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadState;
|
||||
import dev.isxander.controlify.gui.DrawSize;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public enum GamepadBind implements IBind<GamepadState> {
|
||||
A_BUTTON(state -> state.gamepadButtons().a(), "a_button"),
|
||||
B_BUTTON(state -> state.gamepadButtons().b(), "b_button"),
|
||||
X_BUTTON(state -> state.gamepadButtons().x(), "x_button"),
|
||||
Y_BUTTON(state -> state.gamepadButtons().y(), "y_button"),
|
||||
LEFT_BUMPER(state -> state.gamepadButtons().leftBumper(), "left_bumper"),
|
||||
RIGHT_BUMPER(state -> state.gamepadButtons().rightBumper(), "right_bumper"),
|
||||
LEFT_STICK_PRESS(state -> state.gamepadButtons().leftStick(), "left_stick_press"),
|
||||
RIGHT_STICK_PRESS(state -> state.gamepadButtons().rightStick(), "right_stick_press"),
|
||||
START(state -> state.gamepadButtons().start(), "start"),
|
||||
BACK(state -> state.gamepadButtons().back(), "back"),
|
||||
GUIDE(state -> state.gamepadButtons().guide(), "guide"), // the middle button
|
||||
DPAD_UP(state -> state.gamepadButtons().dpadUp(), "dpad_up"),
|
||||
DPAD_DOWN(state -> state.gamepadButtons().dpadDown(), "dpad_down"),
|
||||
DPAD_LEFT(state -> state.gamepadButtons().dpadLeft(), "dpad_left"),
|
||||
DPAD_RIGHT(state -> state.gamepadButtons().dpadRight(), "dpad_right"),
|
||||
LEFT_TRIGGER(state -> state.gamepadAxes().leftTrigger(), "left_trigger", true),
|
||||
RIGHT_TRIGGER(state -> state.gamepadAxes().rightTrigger(), "right_trigger", true),
|
||||
LEFT_STICK_FORWARD(state -> -Math.min(0, state.gamepadAxes().leftStickY()), "left_stick_up", true),
|
||||
LEFT_STICK_BACKWARD(state -> Math.max(0, state.gamepadAxes().leftStickY()), "left_stick_down", true),
|
||||
LEFT_STICK_LEFT(state -> -Math.min(0, state.gamepadAxes().leftStickX()), "left_stick_left", true),
|
||||
LEFT_STICK_RIGHT(state -> Math.max(0, state.gamepadAxes().leftStickX()), "left_stick_right", true),
|
||||
RIGHT_STICK_FORWARD(state -> -Math.min(0, state.gamepadAxes().rightStickY()), "right_stick_up", true),
|
||||
RIGHT_STICK_BACKWARD(state -> Math.max(0, state.gamepadAxes().rightStickY()), "right_stick_down", true),
|
||||
RIGHT_STICK_LEFT(state -> -Math.min(0, state.gamepadAxes().rightStickX()), "right_stick_left", true),
|
||||
RIGHT_STICK_RIGHT(state -> Math.max(0, state.gamepadAxes().rightStickX()), "right_stick_right", true);
|
||||
|
||||
public static final String BIND_ID = "gamepad";
|
||||
|
||||
private final Function<GamepadState, Float> state;
|
||||
public class GamepadBind implements IBind<GamepadState> {
|
||||
private final Function<GamepadState, Float> stateSupplier;
|
||||
private final String identifier;
|
||||
private final Map<BuiltinGamepadTheme, ResourceLocation> textureLocations;
|
||||
private final GamepadController gamepad;
|
||||
private final ResourceLocation defaultTexture;
|
||||
|
||||
GamepadBind(Function<GamepadState, Float> state, String identifier, boolean jvmIsBad) {
|
||||
this.state = state;
|
||||
public GamepadBind(Function<GamepadState, Float> stateSupplier, String identifier, GamepadController gamepad) {
|
||||
this.stateSupplier = stateSupplier;
|
||||
this.identifier = identifier;
|
||||
|
||||
this.textureLocations = new HashMap<>();
|
||||
for (BuiltinGamepadTheme theme : BuiltinGamepadTheme.values()) {
|
||||
if (theme == BuiltinGamepadTheme.DEFAULT) continue;
|
||||
textureLocations.put(theme, new ResourceLocation("controlify", "textures/gui/gamepad_buttons/" + theme.id() + "/" + identifier + ".png"));
|
||||
}
|
||||
}
|
||||
|
||||
GamepadBind(Function<GamepadState, Boolean> state, String identifier) {
|
||||
this(state1 -> state.apply(state1) ? 1f : 0f, identifier, true);
|
||||
this.gamepad = gamepad;
|
||||
this.defaultTexture = new ResourceLocation("controlify", "textures/gui/gamepad_buttons/" + gamepad.config().theme.id() + "/" + identifier + ".png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public float state(GamepadState state) {
|
||||
return this.state.apply(state);
|
||||
return stateSupplier.apply(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack matrices, int x, int centerY, Controller<GamepadState, ?> controller) {
|
||||
ResourceLocation texture;
|
||||
if (((GamepadConfig)controller.config()).theme == BuiltinGamepadTheme.DEFAULT) {
|
||||
texture = new ResourceLocation("controlify", "textures/gui/gamepad/" + controller.type().identifier() + "/" + identifier + ".png");
|
||||
} else {
|
||||
texture = textureLocations.get(((GamepadConfig)controller.config()).theme);
|
||||
}
|
||||
public void draw(PoseStack matrices, int x, int centerY) {
|
||||
ResourceLocation texture = getTexture(gamepad.config().theme);
|
||||
|
||||
RenderSystem.setShaderTexture(0, texture);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
@ -92,19 +51,22 @@ public enum GamepadBind implements IBind<GamepadState> {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Controller<GamepadState, ?> controller() {
|
||||
return this.gamepad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("type", BIND_ID);
|
||||
object.addProperty("type", GamepadBinds.BIND_ID);
|
||||
object.addProperty("bind", identifier);
|
||||
return object;
|
||||
}
|
||||
|
||||
public static GamepadBind fromJson(JsonObject object) {
|
||||
String name = object.get("bind").getAsString();
|
||||
for (GamepadBind bind : values()) {
|
||||
if (bind.identifier.equals(name)) return bind;
|
||||
}
|
||||
return null;
|
||||
private ResourceLocation getTexture(BuiltinGamepadTheme theme) {
|
||||
if (theme == BuiltinGamepadTheme.DEFAULT)
|
||||
return defaultTexture;
|
||||
return new ResourceLocation("controlify", "textures/gui/gamepad_buttons/" + theme.id() + "/" + identifier + ".png");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
package dev.isxander.controlify.bindings;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadController;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadState;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public enum GamepadBinds {
|
||||
A_BUTTON(state -> state.gamepadButtons().a(), "a_button"),
|
||||
B_BUTTON(state -> state.gamepadButtons().b(), "b_button"),
|
||||
X_BUTTON(state -> state.gamepadButtons().x(), "x_button"),
|
||||
Y_BUTTON(state -> state.gamepadButtons().y(), "y_button"),
|
||||
LEFT_BUMPER(state -> state.gamepadButtons().leftBumper(), "left_bumper"),
|
||||
RIGHT_BUMPER(state -> state.gamepadButtons().rightBumper(), "right_bumper"),
|
||||
LEFT_STICK_PRESS(state -> state.gamepadButtons().leftStick(), "left_stick_press"),
|
||||
RIGHT_STICK_PRESS(state -> state.gamepadButtons().rightStick(), "right_stick_press"),
|
||||
START(state -> state.gamepadButtons().start(), "start"),
|
||||
BACK(state -> state.gamepadButtons().back(), "back"),
|
||||
GUIDE(state -> state.gamepadButtons().guide(), "guide"), // the middle button
|
||||
DPAD_UP(state -> state.gamepadButtons().dpadUp(), "dpad_up"),
|
||||
DPAD_DOWN(state -> state.gamepadButtons().dpadDown(), "dpad_down"),
|
||||
DPAD_LEFT(state -> state.gamepadButtons().dpadLeft(), "dpad_left"),
|
||||
DPAD_RIGHT(state -> state.gamepadButtons().dpadRight(), "dpad_right"),
|
||||
LEFT_TRIGGER(state -> state.gamepadAxes().leftTrigger(), "left_trigger", true),
|
||||
RIGHT_TRIGGER(state -> state.gamepadAxes().rightTrigger(), "right_trigger", true),
|
||||
LEFT_STICK_FORWARD(state -> -Math.min(0, state.gamepadAxes().leftStickY()), "left_stick_up", true),
|
||||
LEFT_STICK_BACKWARD(state -> Math.max(0, state.gamepadAxes().leftStickY()), "left_stick_down", true),
|
||||
LEFT_STICK_LEFT(state -> -Math.min(0, state.gamepadAxes().leftStickX()), "left_stick_left", true),
|
||||
LEFT_STICK_RIGHT(state -> Math.max(0, state.gamepadAxes().leftStickX()), "left_stick_right", true),
|
||||
RIGHT_STICK_FORWARD(state -> -Math.min(0, state.gamepadAxes().rightStickY()), "right_stick_up", true),
|
||||
RIGHT_STICK_BACKWARD(state -> Math.max(0, state.gamepadAxes().rightStickY()), "right_stick_down", true),
|
||||
RIGHT_STICK_LEFT(state -> -Math.min(0, state.gamepadAxes().rightStickX()), "right_stick_left", true),
|
||||
RIGHT_STICK_RIGHT(state -> Math.max(0, state.gamepadAxes().rightStickX()), "right_stick_right", true);
|
||||
|
||||
public static final String BIND_ID = "gamepad";
|
||||
|
||||
private final Function<GamepadState, Float> state;
|
||||
private final String identifier;
|
||||
|
||||
GamepadBinds(Function<GamepadState, Float> state, String identifier, boolean jvmIsBad) {
|
||||
this.state = state;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
GamepadBinds(Function<GamepadState, Boolean> state, String identifier) {
|
||||
this(state1 -> state.apply(state1) ? 1f : 0f, identifier, true);
|
||||
}
|
||||
|
||||
public GamepadBind forGamepad(GamepadController gamepad) {
|
||||
return new GamepadBind(state, identifier, gamepad);
|
||||
}
|
||||
|
||||
public static Optional<GamepadBinds> fromJson(JsonObject object) {
|
||||
String name = object.get("bind").getAsString();
|
||||
for (GamepadBinds bind : values()) {
|
||||
if (bind.identifier.equals(name)) return Optional.of(bind);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
@ -10,23 +10,25 @@ import dev.isxander.controlify.gui.DrawSize;
|
||||
|
||||
public interface IBind<S extends ControllerState> {
|
||||
float state(S state);
|
||||
default boolean held(S state, Controller<S, ?> controller) {
|
||||
return state(state) > controller.config().buttonActivationThreshold;
|
||||
default boolean held(S state) {
|
||||
return state(state) > controller().config().buttonActivationThreshold;
|
||||
}
|
||||
|
||||
void draw(PoseStack matrices, int x, int centerY, Controller<S, ?> controller);
|
||||
void draw(PoseStack matrices, int x, int centerY);
|
||||
DrawSize drawSize();
|
||||
|
||||
JsonObject toJson();
|
||||
|
||||
Controller<S, ?> controller();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends ControllerState> IBind<T> fromJson(JsonObject json, Controller<T, ?> controller) {
|
||||
var type = json.get("type").getAsString();
|
||||
if (type.equals(EmptyBind.BIND_ID))
|
||||
return new EmptyBind<>();
|
||||
|
||||
if (controller instanceof GamepadController && type.equals(GamepadBind.BIND_ID)) {
|
||||
return (IBind<T>) GamepadBind.fromJson(json);
|
||||
if (controller instanceof GamepadController gamepad && type.equals(GamepadBinds.BIND_ID)) {
|
||||
return GamepadBinds.fromJson(json).map(bind -> (IBind<T>) bind.forGamepad(gamepad)).orElse(new EmptyBind<>());
|
||||
} else if (controller instanceof JoystickController joystick) {
|
||||
return (IBind<T>) switch (type) {
|
||||
case JoystickButtonBind.BIND_ID -> JoystickButtonBind.fromJson(json, joystick);
|
||||
|
@ -39,8 +39,7 @@ public class JoystickAxisBind implements IBind<JoystickState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack matrices, int x, int centerY, Controller<JoystickState, ?> controller) {
|
||||
if (controller != joystick) return;
|
||||
public void draw(PoseStack matrices, int x, int centerY) {
|
||||
JoystickMapping mapping = joystick.mapping();
|
||||
|
||||
String type = joystick.type().identifier();
|
||||
@ -77,6 +76,11 @@ public class JoystickAxisBind implements IBind<JoystickState> {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Controller<JoystickState, ?> controller() {
|
||||
return joystick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
@ -31,9 +31,7 @@ public class JoystickButtonBind implements IBind<JoystickState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack matrices, int x, int centerY, Controller<JoystickState, ?> controller) {
|
||||
if (controller != joystick) return;
|
||||
|
||||
public void draw(PoseStack matrices, int x, int centerY) {
|
||||
String type = joystick.type().identifier();
|
||||
String button = joystick.mapping().button(buttonIndex).identifier();
|
||||
var texture = new ResourceLocation("controlify", "textures/gui/joystick/" + type + "/button_" + button + ".png");
|
||||
@ -56,6 +54,11 @@ public class JoystickButtonBind implements IBind<JoystickState> {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Controller<JoystickState, ?> controller() {
|
||||
return joystick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
@ -33,9 +33,7 @@ public class JoystickHatBind implements IBind<JoystickState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack matrices, int x, int centerY, Controller<JoystickState, ?> controller) {
|
||||
if (controller != joystick) return;
|
||||
|
||||
public void draw(PoseStack matrices, int x, int centerY) {
|
||||
String type = joystick.type().identifier();
|
||||
String button = joystick.mapping().button(hatIndex).identifier();
|
||||
String direction = "centered";
|
||||
@ -69,6 +67,11 @@ public class JoystickHatBind implements IBind<JoystickState> {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Controller<JoystickState, ?> controller() {
|
||||
return joystick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
@ -2,6 +2,7 @@ package dev.isxander.controlify.config.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import dev.isxander.controlify.bindings.GamepadBind;
|
||||
import dev.isxander.controlify.bindings.GamepadBinds;
|
||||
import dev.isxander.controlify.bindings.IBind;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadController;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadState;
|
||||
@ -56,7 +57,7 @@ public class GamepadBindController implements Controller<IBind<GamepadState>> {
|
||||
textRenderer.drawShadow(matrices, awaitingText, getDimension().xLimit() - textRenderer.width(awaitingText) - getXPadding(), getDimension().centerY() - textRenderer.lineHeight / 2f, 0xFFFFFF);
|
||||
} else {
|
||||
var bind = control.option().pendingValue();
|
||||
bind.draw(matrices, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY(), control.controller);
|
||||
bind.draw(matrices, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY());
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,8 +98,9 @@ public class GamepadBindController implements Controller<IBind<GamepadState>> {
|
||||
|
||||
var gamepad = control.controller;
|
||||
|
||||
for (var bind : GamepadBind.values()) {
|
||||
if (bind.held(gamepad.state(), gamepad) && !bind.held(gamepad.prevState(), gamepad)) {
|
||||
for (var bindType : GamepadBinds.values()) {
|
||||
GamepadBind bind = bindType.forGamepad(gamepad);
|
||||
if (bind.held(gamepad.state()) && !bind.held(gamepad.prevState())) {
|
||||
control.option().requestSet(bind);
|
||||
awaitingControllerInput = false;
|
||||
gamepad.consumeButtonState();
|
||||
|
@ -59,7 +59,7 @@ public class JoystickBindController implements Controller<IBind<JoystickState>>
|
||||
textRenderer.drawShadow(matrices, awaitingText, getDimension().xLimit() - textRenderer.width(awaitingText) - getXPadding(), getDimension().centerY() - textRenderer.lineHeight / 2f, 0xFFFFFF);
|
||||
} else {
|
||||
var bind = control.option().pendingValue();
|
||||
bind.draw(matrices, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY(), control.controller);
|
||||
bind.draw(matrices, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import dev.isxander.controlify.controller.gamepad.GamepadState;
|
||||
import dev.isxander.controlify.controller.gamepad.BuiltinGamepadTheme;
|
||||
import dev.isxander.controlify.controller.joystick.JoystickController;
|
||||
import dev.isxander.controlify.controller.joystick.JoystickState;
|
||||
import dev.isxander.controlify.controller.joystick.mapping.UnmappedJoystickMapping;
|
||||
import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen;
|
||||
import dev.isxander.yacl.api.*;
|
||||
import dev.isxander.yacl.gui.controllers.ActionController;
|
||||
@ -66,6 +67,10 @@ public class YACLHelper {
|
||||
yacl.category(globalCategory.build());
|
||||
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
// if (controller instanceof JoystickController joystick && joystick.mapping() instanceof UnmappedJoystickMapping) {
|
||||
// // PlaceholderCategory for onboarding
|
||||
// }
|
||||
|
||||
var category = ConfigCategory.createBuilder();
|
||||
|
||||
category.name(Component.literal(controller.name()));
|
||||
|
@ -3,19 +3,20 @@ package dev.isxander.controlify.controller;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.controller.hid.HIDIdentifier;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackResources;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.server.packs.resources.IoSupplier;
|
||||
import org.apache.commons.io.function.IOSupplier;
|
||||
import org.quiltmc.json5.JsonReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
public class ControllerType {
|
||||
public static final ControllerType UNKNOWN = new ControllerType("Unknown", "unknown");
|
||||
@ -45,27 +46,60 @@ public class ControllerType {
|
||||
|
||||
typeMap = new HashMap<>();
|
||||
try {
|
||||
List<IoSupplier<InputStream>> dbs = Minecraft.getInstance().getResourceManager().listPacks()
|
||||
.map(pack -> pack.getResource(PackType.CLIENT_RESOURCES, hidDbLocation))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
List<PackResources> packs = Minecraft.getInstance().getResourceManager().listPacks().toList();
|
||||
|
||||
for (var supplier : dbs) {
|
||||
try (var hidDb = supplier.get()) {
|
||||
var json = GSON.fromJson(new InputStreamReader(hidDb), JsonArray.class);
|
||||
for (var typeElement : json) {
|
||||
var typeObject = typeElement.getAsJsonObject();
|
||||
for (var pack : packs) {
|
||||
String packName = pack.packId();
|
||||
IoSupplier<InputStream> isSupplier = pack.getResource(PackType.CLIENT_RESOURCES, hidDbLocation);
|
||||
if (isSupplier == null) continue;
|
||||
Controlify.LOGGER.info("Loading controller HID DB from pack " + packName);
|
||||
|
||||
ControllerType type = new ControllerType(typeObject.get("name").getAsString(), typeObject.get("identifier").getAsString());
|
||||
try (var hidDb = isSupplier.get()) {
|
||||
JsonReader reader = JsonReader.json5(new InputStreamReader(hidDb));
|
||||
|
||||
int vendorId = typeObject.get("vendor").getAsInt();
|
||||
for (var productIdEntry : typeObject.getAsJsonArray("product")) {
|
||||
int productId = productIdEntry.getAsInt();
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
String friendlyName = null;
|
||||
String identifier = null;
|
||||
int vendorId = -1;
|
||||
Set<Integer> productIds = new HashSet<>();
|
||||
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String name = reader.nextName();
|
||||
|
||||
switch (name) {
|
||||
case "name" -> friendlyName = reader.nextString();
|
||||
case "identifier" -> identifier = reader.nextString();
|
||||
case "vendor" -> vendorId = reader.nextInt();
|
||||
case "product" -> {
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
productIds.add(reader.nextInt());
|
||||
}
|
||||
reader.endArray();
|
||||
}
|
||||
default -> {
|
||||
Controlify.LOGGER.warn("Unknown key in HID DB: " + name + ". Skipping...");
|
||||
reader.skipValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
reader.endObject();
|
||||
|
||||
if (friendlyName == null || identifier == null || vendorId == -1 || productIds.isEmpty()) {
|
||||
Controlify.LOGGER.warn("Invalid entry in HID DB. Skipping...");
|
||||
continue;
|
||||
}
|
||||
|
||||
var type = new ControllerType(friendlyName, identifier);
|
||||
for (int productId : productIds) {
|
||||
typeMap.put(new HIDIdentifier(vendorId, productId), type);
|
||||
}
|
||||
}
|
||||
reader.endArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Controlify.LOGGER.error("Failed to load HID DB from pack " + packName, e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -26,9 +26,9 @@ public class ControlifyEvents {
|
||||
}
|
||||
});
|
||||
|
||||
public static final Event<ButtonGuideRegistryEvent> BUTTON_GUIDE_REGISTRY = EventFactory.createArrayBacked(ButtonGuideRegistryEvent.class, callbacks -> registry -> {
|
||||
public static final Event<ButtonGuideRegistryEvent> BUTTON_GUIDE_REGISTRY = EventFactory.createArrayBacked(ButtonGuideRegistryEvent.class, callbacks -> (bindings, registry) -> {
|
||||
for (ButtonGuideRegistryEvent callback : callbacks) {
|
||||
callback.onRegisterButtonGuide(registry);
|
||||
callback.onRegisterButtonGuide(bindings, registry);
|
||||
}
|
||||
});
|
||||
|
||||
@ -55,7 +55,7 @@ public class ControlifyEvents {
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ButtonGuideRegistryEvent {
|
||||
void onRegisterButtonGuide(ButtonGuideRegistry registry);
|
||||
void onRegisterButtonGuide(ControllerBindings<?> bindings, ButtonGuideRegistry registry);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dev.isxander.controlify.ingame.guide;
|
||||
|
||||
import dev.isxander.controlify.bindings.ControllerBinding;
|
||||
|
||||
public interface ButtonGuideRegistry {
|
||||
void registerGuideAction(ButtonActionSupplier supplier);
|
||||
void registerGuideAction(ControllerBinding<?> binding, ActionLocation location, GuideActionNameSupplier supplier);
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import dev.isxander.controlify.bindings.ControllerBinding;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record GuideAction(ControllerBinding binding, Component name, ActionLocation location,
|
||||
public record GuideAction(ControllerBinding<?> binding, Component name, ActionLocation location,
|
||||
ActionPriority priority) implements Comparable<GuideAction> {
|
||||
public GuideAction(ControllerBinding binding, Component name, ActionLocation location) {
|
||||
public GuideAction(ControllerBinding<?> binding, Component name, ActionLocation location) {
|
||||
this(binding, name, location, ActionPriority.NORMAL);
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,12 @@ import dev.isxander.controlify.controller.Controller;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ButtonActionSupplier {
|
||||
Optional<GuideAction> supply(Minecraft client, LocalPlayer player, ClientLevel level, HitResult hitResult, Controller<?, ?> controller);
|
||||
public interface GuideActionNameSupplier {
|
||||
Optional<Component> supply(Minecraft client, LocalPlayer player, ClientLevel level, HitResult hitResult, Controller<?, ?> controller);
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
package dev.isxander.controlify.ingame.guide;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import dev.isxander.controlify.bindings.ControllerBinding;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.event.ControlifyEvents;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
@ -21,7 +23,7 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
|
||||
private final LocalPlayer player;
|
||||
private final Minecraft minecraft = Minecraft.getInstance();
|
||||
|
||||
private final List<ButtonActionSupplier> guidePredicates = new ArrayList<>();
|
||||
private final List<GuideActionSupplier> guidePredicates = new ArrayList<>();
|
||||
|
||||
private final List<GuideAction> leftGuides = new ArrayList<>();
|
||||
private final List<GuideAction> rightGuides = new ArrayList<>();
|
||||
@ -31,7 +33,7 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
|
||||
this.player = localPlayer;
|
||||
|
||||
registerDefaultActions();
|
||||
ControlifyEvents.BUTTON_GUIDE_REGISTRY.invoker().onRegisterButtonGuide(this);
|
||||
ControlifyEvents.BUTTON_GUIDE_REGISTRY.invoker().onRegisterButtonGuide(controller.bindings(), this);
|
||||
}
|
||||
|
||||
public void renderHud(PoseStack poseStack, float tickDelta, int width, int height) {
|
||||
@ -49,7 +51,7 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
|
||||
int x = 4;
|
||||
int y = 3 + offset;
|
||||
|
||||
bind.draw(poseStack, x, y, controller);
|
||||
bind.draw(poseStack, x, y);
|
||||
|
||||
int textX = x + drawSize.width() + 2;
|
||||
int textY = y - minecraft.font.lineHeight / 2;
|
||||
@ -71,7 +73,7 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
|
||||
int x = width - 4 - drawSize.width();
|
||||
int y = 3 + offset;
|
||||
|
||||
bind.draw(poseStack, x, y, controller);
|
||||
bind.draw(poseStack, x, y);
|
||||
|
||||
int textX = x - minecraft.font.width(action.name()) - 2;
|
||||
int textY = y - minecraft.font.lineHeight / 2;
|
||||
@ -92,7 +94,11 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
|
||||
|
||||
for (var actionPredicate : guidePredicates) {
|
||||
var action = actionPredicate.supply(Minecraft.getInstance(), player, minecraft.level, calculateHitResult(), controller);
|
||||
if (action.isPresent()) {
|
||||
if (action.isEmpty())
|
||||
continue;
|
||||
|
||||
GuideAction guideAction = action.get();
|
||||
if (!guideAction.binding().unbound()) {
|
||||
if (action.get().location() == ActionLocation.LEFT)
|
||||
leftGuides.add(action.get());
|
||||
else
|
||||
@ -105,94 +111,97 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerGuideAction(ButtonActionSupplier supplier) {
|
||||
guidePredicates.add(supplier);
|
||||
public void registerGuideAction(ControllerBinding<?> binding, ActionLocation location, GuideActionNameSupplier supplier) {
|
||||
guidePredicates.add(new GuideActionSupplier(binding, location, supplier));
|
||||
}
|
||||
|
||||
private void registerDefaultActions() {
|
||||
var options = Minecraft.getInstance().options;
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().JUMP, ActionLocation.LEFT, (client, player, level, hitResult, controller) -> {
|
||||
if (player.getAbilities().flying)
|
||||
return Optional.of(new GuideAction(controller.bindings().JUMP, Component.translatable("controlify.guide.fly_up"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.fly_up"));
|
||||
|
||||
if (player.isOnGround())
|
||||
return Optional.of(new GuideAction(controller.bindings().JUMP, Component.translatable("key.jump"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("key.jump"));
|
||||
|
||||
if (player.isInWater())
|
||||
return Optional.of(new GuideAction(controller.bindings().JUMP, Component.translatable("controlify.guide.swim_up"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.swim_up"));
|
||||
|
||||
if (!player.isOnGround() && !player.isFallFlying() && !player.isInWater() && !player.hasEffect(MobEffects.LEVITATION)) {
|
||||
var chestStack = player.getItemBySlot(EquipmentSlot.CHEST);
|
||||
if (chestStack.is(Items.ELYTRA) && ElytraItem.isFlyEnabled(chestStack))
|
||||
return Optional.of(new GuideAction(controller.bindings().JUMP, Component.translatable("controlify.guide.start_elytra"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.start_elytra"));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().SNEAK, ActionLocation.LEFT, (client, player, level, hitResult, controller) -> {
|
||||
if (player.getVehicle() != null)
|
||||
return Optional.of(new GuideAction(controller.bindings().SNEAK, Component.translatable("controlify.guide.dismount"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.dismount"));
|
||||
if (player.getAbilities().flying)
|
||||
return Optional.of(new GuideAction(controller.bindings().SNEAK, Component.translatable("controlify.guide.fly_down"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.fly_down"));
|
||||
if (player.isInWater())
|
||||
return Optional.of(new GuideAction(controller.bindings().SNEAK, Component.translatable("controlify.guide.swim_down"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.swim_down"));
|
||||
if (controller.config().toggleSneak) {
|
||||
if (player.input.shiftKeyDown)
|
||||
return Optional.of(new GuideAction(controller.bindings().SNEAK, Component.translatable("controlify.guide.stop_sneaking"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.stop_sneaking"));
|
||||
else
|
||||
return Optional.of(new GuideAction(controller.bindings().SNEAK, Component.translatable("controlify.guide.start_sneaking"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.start_sneaking"));
|
||||
} else {
|
||||
if (!player.input.shiftKeyDown)
|
||||
return Optional.of(new GuideAction(controller.bindings().SNEAK, Component.translatable("controlify.guide.sneak"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.sneak"));
|
||||
}
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().SPRINT, ActionLocation.LEFT, (client, player, level, hitResult, controller) -> {
|
||||
if (!options.keySprint.isDown()) {
|
||||
if (!player.input.getMoveVector().equals(Vec2.ZERO)) {
|
||||
if (player.isUnderWater())
|
||||
return Optional.of(new GuideAction(controller.bindings().SPRINT, Component.translatable("controlify.guide.start_swimming"), ActionLocation.LEFT));
|
||||
return Optional.of(new GuideAction(controller.bindings().SPRINT, Component.translatable("controlify.guide.start_sprinting"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.start_swimming"));
|
||||
return Optional.of(Component.translatable("controlify.guide.start_sprinting"));
|
||||
}
|
||||
} else if (controller.config().toggleSprint) {
|
||||
if (player.isUnderWater())
|
||||
return Optional.of(new GuideAction(controller.bindings().SPRINT, Component.translatable("controlify.guide.stop_swimming"), ActionLocation.LEFT));
|
||||
return Optional.of(new GuideAction(controller.bindings().SPRINT, Component.translatable("controlify.guide.stop_sprinting"), ActionLocation.LEFT));
|
||||
return Optional.of(Component.translatable("controlify.guide.stop_swimming"));
|
||||
return Optional.of(Component.translatable("controlify.guide.stop_sprinting"));
|
||||
}
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().INVENTORY, ActionLocation.RIGHT, (client, player, level, hitResult, controller) -> {
|
||||
if (client.screen == null)
|
||||
return Optional.of(new GuideAction(controller.bindings().INVENTORY, Component.translatable("controlify.guide.inventory"), ActionLocation.RIGHT));
|
||||
return Optional.of(Component.translatable("controlify.guide.inventory"));
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().ATTACK, ActionLocation.RIGHT, (client, player, level, hitResult, controller) -> {
|
||||
if (hitResult.getType() == HitResult.Type.ENTITY)
|
||||
return Optional.of(new GuideAction(controller.bindings().ATTACK, Component.translatable("controlify.guide.attack"), ActionLocation.RIGHT));
|
||||
return Optional.of(Component.translatable("controlify.guide.attack"));
|
||||
if (hitResult.getType() == HitResult.Type.BLOCK)
|
||||
return Optional.of(new GuideAction(controller.bindings().ATTACK, Component.translatable("controlify.guide.break"), ActionLocation.RIGHT));
|
||||
return Optional.of(Component.translatable("controlify.guide.break"));
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().USE, ActionLocation.RIGHT, (client, player, level, hitResult, controller) -> {
|
||||
if (hitResult.getType() == HitResult.Type.ENTITY)
|
||||
return Optional.of(new GuideAction(controller.bindings().USE, Component.translatable("controlify.guide.interact"), ActionLocation.RIGHT));
|
||||
if (player.isSpectator())
|
||||
return Optional.of(Component.translatable("controlify.guide.spectate"));
|
||||
else
|
||||
return Optional.of(Component.translatable("controlify.guide.interact"));
|
||||
if (hitResult.getType() == HitResult.Type.BLOCK || player.hasItemInSlot(EquipmentSlot.MAINHAND) || player.hasItemInSlot(EquipmentSlot.OFFHAND))
|
||||
return Optional.of(new GuideAction(controller.bindings().USE, Component.translatable("controlify.guide.use"), ActionLocation.RIGHT));
|
||||
return Optional.of(Component.translatable("controlify.guide.use"));
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().DROP, ActionLocation.RIGHT, (client, player, level, hitResult, controller) -> {
|
||||
if (player.hasItemInSlot(EquipmentSlot.MAINHAND) || player.hasItemInSlot(EquipmentSlot.OFFHAND))
|
||||
return Optional.of(new GuideAction(controller.bindings().DROP, Component.translatable("controlify.guide.drop"), ActionLocation.RIGHT));
|
||||
return Optional.of(Component.translatable("controlify.guide.drop"));
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().SWAP_HANDS, ActionLocation.RIGHT, (client, player, level, hitResult, controller) -> {
|
||||
if (player.hasItemInSlot(EquipmentSlot.MAINHAND) || player.hasItemInSlot(EquipmentSlot.OFFHAND))
|
||||
return Optional.of(new GuideAction(controller.bindings().SWAP_HANDS, Component.translatable("controlify.guide.swap_hands"), ActionLocation.RIGHT));
|
||||
return Optional.of(Component.translatable("controlify.guide.swap_hands"));
|
||||
return Optional.empty();
|
||||
});
|
||||
registerGuideAction((client, player, level, hitResult, controller) -> {
|
||||
registerGuideAction(controller.bindings().PICK_BLOCK, ActionLocation.RIGHT, (client, player, level, hitResult, controller) -> {
|
||||
if (hitResult.getType() == HitResult.Type.BLOCK && player.isCreative())
|
||||
return Optional.of(new GuideAction(controller.bindings().PICK_BLOCK, Component.translatable("controlify.guide.pick_block"), ActionLocation.RIGHT));
|
||||
return Optional.of(Component.translatable("controlify.guide.pick_block"));
|
||||
return Optional.empty();
|
||||
});
|
||||
}
|
||||
@ -223,4 +232,10 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
private record GuideActionSupplier(ControllerBinding<?> binding, ActionLocation location, GuideActionNameSupplier nameSupplier) {
|
||||
public Optional<GuideAction> supply(Minecraft client, LocalPlayer player, ClientLevel level, HitResult hitResult, Controller<?, ?> controller) {
|
||||
return nameSupplier.supply(client, player, level, hitResult, controller)
|
||||
.map(name -> new GuideAction(binding, name, location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user