forked from Clones/Controlify
vanilla keybind override and config system
This commit is contained in:
@ -1,37 +1,60 @@
|
||||
package dev.isxander.controlify.bindings;
|
||||
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.ControllerState;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Bind {
|
||||
boolean state(ControllerState controllerState);
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
Bind A_BUTTON = state -> state.buttons().a();
|
||||
Bind B_BUTTON = state -> state.buttons().b();
|
||||
Bind X_BUTTON = state -> state.buttons().x();
|
||||
Bind Y_BUTTON = state -> state.buttons().y();
|
||||
Bind LEFT_BUMPER = state -> state.buttons().leftBumper();
|
||||
Bind RIGHT_BUMPER = state -> state.buttons().rightBumper();
|
||||
Bind LEFT_STICK = state -> state.buttons().leftStick();
|
||||
Bind RIGHT_STICK = state -> state.buttons().rightStick();
|
||||
Bind START = state -> state.buttons().start();
|
||||
Bind BACK = state -> state.buttons().back();
|
||||
Bind LEFT_TRIGGER = leftTrigger(0.5f);
|
||||
Bind RIGHT_TRIGGER = rightTrigger(0.5f);
|
||||
public enum Bind {
|
||||
A_BUTTON(state -> state.buttons().a(), "a_button"),
|
||||
B_BUTTON(state -> state.buttons().b(), "b_button"),
|
||||
X_BUTTON(state -> state.buttons().x(), "x_button"),
|
||||
Y_BUTTON(state -> state.buttons().y(), "y_button"),
|
||||
LEFT_BUMPER(state -> state.buttons().leftBumper(), "left_bumper"),
|
||||
RIGHT_BUMPER(state -> state.buttons().rightBumper(), "right_bumper"),
|
||||
LEFT_STICK(state -> state.buttons().leftStick(), "left_stick"),
|
||||
RIGHT_STICK(state -> state.buttons().rightStick(), "right_stick"),
|
||||
START(state -> state.buttons().start(), "start"),
|
||||
BACK(state -> state.buttons().back(), "back"),
|
||||
DPAD_UP(state -> state.buttons().dpadUp(), "dpad_up"),
|
||||
DPAD_DOWN(state -> state.buttons().dpadDown(), "dpad_down"),
|
||||
DPAD_LEFT(state -> state.buttons().dpadLeft(), "dpad_left"),
|
||||
DPAD_RIGHT(state -> state.buttons().dpadRight(), "dpad_right"),
|
||||
LEFT_TRIGGER((state, controller) -> state.axes().leftTrigger() >= controller.config().leftTriggerActivationThreshold, "left_trigger"),
|
||||
RIGHT_TRIGGER((state, controller) -> state.axes().rightTrigger() >= controller.config().rightTriggerActivationThreshold, "right_trigger");
|
||||
|
||||
Bind[] ALL = {
|
||||
A_BUTTON, B_BUTTON, X_BUTTON, Y_BUTTON,
|
||||
LEFT_BUMPER, RIGHT_BUMPER,
|
||||
LEFT_STICK, RIGHT_STICK,
|
||||
START, BACK,
|
||||
LEFT_TRIGGER, RIGHT_TRIGGER
|
||||
};
|
||||
private final BiFunction<ControllerState, Controller, Boolean> state;
|
||||
private final String identifier;
|
||||
private final ResourceLocation textureLocation;
|
||||
|
||||
static Bind leftTrigger(float threshold) {
|
||||
return state -> state.axes().leftTrigger() > threshold;
|
||||
Bind(BiFunction<ControllerState, Controller, Boolean> state, String identifier) {
|
||||
this.state = state;
|
||||
this.identifier = identifier;
|
||||
this.textureLocation = new ResourceLocation("controlify", "textures/gui/buttons/" + identifier + ".png");
|
||||
}
|
||||
|
||||
static Bind rightTrigger(float threshold) {
|
||||
return state -> state.axes().rightTrigger() > threshold;
|
||||
Bind(Function<ControllerState, Boolean> state, String identifier) {
|
||||
this((state1, controller) -> state.apply(state1), identifier);
|
||||
}
|
||||
|
||||
public boolean state(ControllerState controllerState, Controller controller) {
|
||||
return state.apply(controllerState, controller);
|
||||
}
|
||||
|
||||
public String identifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public ResourceLocation textureLocation() {
|
||||
return textureLocation;
|
||||
}
|
||||
|
||||
public static Bind fromIdentifier(String identifier) {
|
||||
for (Bind bind : values()) {
|
||||
if (bind.identifier.equals(identifier)) return bind;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,56 @@
|
||||
package dev.isxander.controlify.bindings;
|
||||
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public class ControllerBinding {
|
||||
private final Controller controller;
|
||||
private final Bind bind;
|
||||
private Bind bind;
|
||||
private final Bind defaultBind;
|
||||
private final String id;
|
||||
private final Component name, description;
|
||||
private final KeyMapping override;
|
||||
|
||||
public ControllerBinding(Controller controller, Bind defaultBind, String id, Component description) {
|
||||
public ControllerBinding(Controller controller, Bind defaultBind, String id, Component description, KeyMapping override) {
|
||||
this.controller = controller;
|
||||
this.bind = defaultBind;
|
||||
this.bind = this.defaultBind = defaultBind;
|
||||
this.id = id;
|
||||
this.name = Component.translatable("controlify.binding." + id);
|
||||
this.description = description;
|
||||
this.override = override;
|
||||
}
|
||||
|
||||
public ControllerBinding(Controller controller, Bind defaultBind, String id) {
|
||||
this(controller, defaultBind, id, Component.empty());
|
||||
public ControllerBinding(Controller controller, Bind defaultBind, String id, KeyMapping override) {
|
||||
this(controller, defaultBind, id, Component.empty(), override);
|
||||
}
|
||||
|
||||
public boolean held() {
|
||||
return bind.state(controller.state());
|
||||
return bind.state(controller.state(), controller);
|
||||
}
|
||||
|
||||
public boolean justPressed() {
|
||||
return held() && !bind.state(controller.prevState());
|
||||
return held() && !bind.state(controller.prevState(), controller);
|
||||
}
|
||||
|
||||
public boolean justReleased() {
|
||||
return !held() && bind.state(controller.prevState());
|
||||
return !held() && bind.state(controller.prevState(), controller);
|
||||
}
|
||||
|
||||
public Bind currentBind() {
|
||||
return bind;
|
||||
}
|
||||
|
||||
public void setCurrentBind(Bind bind) {
|
||||
this.bind = bind;
|
||||
}
|
||||
|
||||
public Bind defaultBind() {
|
||||
return defaultBind;
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Component name() {
|
||||
@ -38,4 +60,8 @@ public class ControllerBinding {
|
||||
public Component description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public KeyMapping override() {
|
||||
return override;
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,75 @@
|
||||
package dev.isxander.controlify.bindings;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.event.ControlifyEvents;
|
||||
import dev.isxander.controlify.mixins.KeyMappingAccessor;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ControllerBindings {
|
||||
public final ControllerBinding JUMP, SNEAK, ATTACK, USE, SPRINT, NEXT_SLOT, PREV_SLOT;
|
||||
public final ControllerBinding[] ALL;
|
||||
public final ControllerBinding JUMP, SNEAK, ATTACK, USE, SPRINT, NEXT_SLOT, PREV_SLOT, PAUSE, INVENTORY, CHANGE_PERSPECTIVE, OPEN_CHAT;
|
||||
|
||||
private final List<ControllerBinding> registry = new ArrayList<>();
|
||||
|
||||
public ControllerBindings(Controller controller) {
|
||||
JUMP = new ControllerBinding(controller, Bind.A_BUTTON, "jump");
|
||||
SNEAK = new ControllerBinding(controller, Bind.RIGHT_STICK, "sneak");
|
||||
ATTACK = new ControllerBinding(controller, Bind.RIGHT_TRIGGER, "attack");
|
||||
USE = new ControllerBinding(controller, Bind.LEFT_TRIGGER, "use");
|
||||
SPRINT = new ControllerBinding(controller, Bind.LEFT_STICK, "sprint");
|
||||
NEXT_SLOT = new ControllerBinding(controller, Bind.RIGHT_BUMPER, "next_slot");
|
||||
PREV_SLOT = new ControllerBinding(controller, Bind.LEFT_BUMPER, "prev_slot");
|
||||
var options = Minecraft.getInstance().options;
|
||||
|
||||
ALL = new ControllerBinding[] {
|
||||
JUMP, SNEAK, ATTACK, USE, SPRINT, NEXT_SLOT, PREV_SLOT
|
||||
};
|
||||
JUMP = register(new ControllerBinding(controller, Bind.A_BUTTON, "jump", options.keyJump));
|
||||
SNEAK = register(new ControllerBinding(controller, Bind.RIGHT_STICK, "sneak", options.keyShift));
|
||||
ATTACK = register(new ControllerBinding(controller, Bind.RIGHT_TRIGGER, "attack", options.keyAttack));
|
||||
USE = register(new ControllerBinding(controller, Bind.LEFT_TRIGGER, "use", options.keyUse));
|
||||
SPRINT = register(new ControllerBinding(controller, Bind.LEFT_STICK, "sprint", options.keySprint));
|
||||
NEXT_SLOT = register(new ControllerBinding(controller, Bind.RIGHT_BUMPER, "next_slot", null));
|
||||
PREV_SLOT = register(new ControllerBinding(controller, Bind.LEFT_BUMPER, "prev_slot", null));
|
||||
PAUSE = register(new ControllerBinding(controller, Bind.START, "pause", null));
|
||||
INVENTORY = register(new ControllerBinding(controller, Bind.Y_BUTTON, "inventory", options.keyInventory));
|
||||
CHANGE_PERSPECTIVE = register(new ControllerBinding(controller, Bind.BACK, "change_perspective", options.keyTogglePerspective));
|
||||
OPEN_CHAT = register(new ControllerBinding(controller, Bind.DPAD_UP, "open_chat", options.keyChat));
|
||||
|
||||
ControlifyEvents.CONTROLLER_BIND_REGISTRY.invoker().onRegisterControllerBinds(this);
|
||||
|
||||
ControlifyEvents.CONTROLLER_STATE_UPDATED.register(this::imitateVanillaClick);
|
||||
}
|
||||
|
||||
public ControllerBinding register(ControllerBinding binding) {
|
||||
registry.add(binding);
|
||||
return binding;
|
||||
}
|
||||
|
||||
public List<ControllerBinding> registry() {
|
||||
return Collections.unmodifiableList(registry);
|
||||
}
|
||||
|
||||
public JsonObject toJson() {
|
||||
JsonObject json = new JsonObject();
|
||||
for (var binding : registry()) {
|
||||
json.addProperty(binding.id(), binding.currentBind().identifier());
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public void fromJson(JsonObject json) {
|
||||
for (var binding : registry()) {
|
||||
var bind = json.get(binding.id());
|
||||
if (bind == null) continue;
|
||||
binding.setCurrentBind(Bind.fromIdentifier(bind.getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
private void imitateVanillaClick(Controller controller) {
|
||||
for (var binding : registry()) {
|
||||
KeyMapping vanillaKey = binding.override();
|
||||
if (vanillaKey == null) continue;
|
||||
|
||||
var vanillaKeyCode = ((KeyMappingAccessor) vanillaKey).getKey();
|
||||
|
||||
KeyMapping.set(vanillaKeyCode, binding.held());
|
||||
if (binding.justPressed()) KeyMapping.click(vanillaKeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user