mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-13 07:15:10 +01:00
🚧 WIP of chording and next release.
This commit is contained in:
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -36,6 +36,8 @@ dependencies {
|
||||
modApi "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
modCompile "io.github.prospector:modmenu:1.8.0+build.16"
|
||||
modCompile "me.lambdaurora:spruceui:${project.spruceui_version}"
|
||||
include "me.lambdaurora:spruceui:${project.spruceui_version}"
|
||||
//modCompile "io.github.cottonmc:cotton-client-commands:0.4.2+1.14.3-SNAPSHOT"
|
||||
|
||||
implementation "org.jetbrains:annotations:17.0.0"
|
||||
|
||||
@@ -8,11 +8,12 @@ org.gradle.jvmargs=-Xmx1G
|
||||
loader_version=0.7.2+build.174
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.2
|
||||
mod_version = 1.1.0-test1
|
||||
maven_group = me.lambdaurora
|
||||
archives_base_name = lambdacontrols
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.4.25+build.282-1.15
|
||||
fabric_version=0.4.26+build.283-1.15
|
||||
spruceui_version=1.0.1
|
||||
|
||||
|
||||
@@ -1,517 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 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;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.ScreenshotUtils;
|
||||
import org.aperlambda.lambdacommon.Identifier;
|
||||
import org.aperlambda.lambdacommon.utils.Identifiable;
|
||||
import org.aperlambda.lambdacommon.utils.Nameable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Represents a button binding.
|
||||
*
|
||||
* @author LambdAurora
|
||||
*/
|
||||
public class ButtonBinding implements Nameable
|
||||
{
|
||||
private static final List<ButtonBinding> BINDINGS = new ArrayList<>();
|
||||
private static final List<Category> CATEGORIES = new ArrayList<>();
|
||||
public static final PressAction DEFAULT_ACTION = (client, button, action) -> {
|
||||
if (action == 2)
|
||||
return false;
|
||||
button.as_key_binding().ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(button.is_button_down()));
|
||||
return true;
|
||||
};
|
||||
public static final Category MOVEMENT_CATEGORY;
|
||||
public static final Category GAMEPLAY_CATEGORY;
|
||||
public static final Category INVENTORY_CATEGORY;
|
||||
public static final Category MULTIPLAYER_CATEGORY;
|
||||
public static final Category MISC_CATEGORY;
|
||||
public static final ButtonBinding ATTACK = new ButtonBinding("attack", axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true));
|
||||
public static final ButtonBinding BACK = new ButtonBinding("back", axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, false));
|
||||
public static final ButtonBinding CHAT = new ButtonBinding("chat", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT);
|
||||
public static final ButtonBinding DROP_ITEM = new ButtonBinding("drop_item", GLFW.GLFW_GAMEPAD_BUTTON_B);
|
||||
public static final ButtonBinding FORWARD = new ButtonBinding("forward", axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, true));
|
||||
public static final ButtonBinding INVENTORY = new ButtonBinding("inventory", GLFW.GLFW_GAMEPAD_BUTTON_Y);
|
||||
public static final ButtonBinding JUMP = new ButtonBinding("jump", GLFW.GLFW_GAMEPAD_BUTTON_A);
|
||||
public static final ButtonBinding LEFT = new ButtonBinding("left", axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, false));
|
||||
public static final ButtonBinding PAUSE_GAME = new ButtonBinding("pause_game", GLFW.GLFW_GAMEPAD_BUTTON_START);
|
||||
public static final ButtonBinding PICK_BLOCK = new ButtonBinding("pick_block", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT);
|
||||
public static final ButtonBinding PLAYER_LIST = new ButtonBinding("player_list", GLFW.GLFW_GAMEPAD_BUTTON_BACK);
|
||||
public static final ButtonBinding RIGHT = new ButtonBinding("right", axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, true));
|
||||
public static final ButtonBinding SCREENSHOT = new ButtonBinding("screenshot", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN,
|
||||
Collections.singletonList((client, button, action) -> {
|
||||
if (action == 0)
|
||||
ScreenshotUtils.saveScreenshot(client.runDirectory, client.getWindow().getFramebufferWidth(), client.getWindow().getFramebufferHeight(), client.getFramebuffer(),
|
||||
text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)));
|
||||
return true;
|
||||
}));
|
||||
public static final ButtonBinding SMOOTH_CAMERA = new ButtonBinding("toggle_smooth_camera", -1);
|
||||
public static final ButtonBinding SNEAK = new ButtonBinding("sneak", GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB,
|
||||
Arrays.asList(DEFAULT_ACTION, (client, button, action) -> {
|
||||
if (client.player != null && !client.player.abilities.flying) {
|
||||
button.as_key_binding().filter(binding -> action == 0).ifPresent(binding -> ((KeyBindingAccessor) binding).handle_press_state(!binding.isPressed()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
public static final ButtonBinding SPRINT = new ButtonBinding("sprint", GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB);
|
||||
public static final ButtonBinding SWAP_HANDS = new ButtonBinding("swap_hands", GLFW.GLFW_GAMEPAD_BUTTON_X);
|
||||
public static final ButtonBinding TOGGLE_PERSPECTIVE = new ButtonBinding("toggle_perspective", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP);
|
||||
public static final ButtonBinding USE = new ButtonBinding("use", axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true));
|
||||
|
||||
private int button;
|
||||
private int default_button;
|
||||
private String key;
|
||||
private KeyBinding minecraft_key_binding = null;
|
||||
private List<PressAction> actions = new ArrayList<>(Collections.singletonList(DEFAULT_ACTION));
|
||||
private boolean pressed = false;
|
||||
|
||||
protected ButtonBinding(@NotNull String key, int default_button, @NotNull List<PressAction> actions)
|
||||
{
|
||||
this.default_button = this.button = default_button;
|
||||
this.key = key;
|
||||
this.actions.addAll(actions);
|
||||
BINDINGS.add(this);
|
||||
}
|
||||
|
||||
protected ButtonBinding(@NotNull String key, int default_button)
|
||||
{
|
||||
this(key, default_button, Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the button bound.
|
||||
*
|
||||
* @return The bound button.
|
||||
*/
|
||||
public int get_button()
|
||||
{
|
||||
return this.button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bound button.
|
||||
*
|
||||
* @param button The bound button.
|
||||
*/
|
||||
public void set_button(int button)
|
||||
{
|
||||
this.button = button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the bound button is the specified button or not.
|
||||
*
|
||||
* @param button The button to check.
|
||||
* @return True if the bound button is the specified button, else false.
|
||||
*/
|
||||
public boolean is_button(int button)
|
||||
{
|
||||
return this.button == button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this button is down or not.
|
||||
*
|
||||
* @return True if the button is down, else false.
|
||||
*/
|
||||
public boolean is_button_down()
|
||||
{
|
||||
return this.pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this button binding is bound or not.
|
||||
*
|
||||
* @return True if this button binding is bound, else false.
|
||||
*/
|
||||
public boolean is_not_bound()
|
||||
{
|
||||
return this.button == -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default button assigned to this binding.
|
||||
*
|
||||
* @return The default button.
|
||||
*/
|
||||
public int get_default_button()
|
||||
{
|
||||
return this.default_button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the assigned button is the default button.
|
||||
*
|
||||
* @return True if the assigned button is the default button, else false.
|
||||
*/
|
||||
public boolean is_default()
|
||||
{
|
||||
return this.button == this.default_button;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String get_name()
|
||||
{
|
||||
return this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation key of this button binding.
|
||||
*
|
||||
* @return The translation key.
|
||||
*/
|
||||
public @NotNull String get_translation_key()
|
||||
{
|
||||
return "lambdacontrols.action." + this.get_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key binding equivalent of this button binding.
|
||||
*
|
||||
* @return The key binding equivalent.
|
||||
*/
|
||||
public @NotNull Optional<KeyBinding> as_key_binding()
|
||||
{
|
||||
return Optional.ofNullable(this.minecraft_key_binding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified axis as a button.
|
||||
*
|
||||
* @param axis The axis.
|
||||
* @param positive True if the axis part is positive, else false.
|
||||
* @return The axis as a button.
|
||||
*/
|
||||
public static int axis_as_button(int axis, boolean positive)
|
||||
{
|
||||
return positive ? 100 + axis : 200 + axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the second Joycon's specified button code.
|
||||
*
|
||||
* @param button The raw button code.
|
||||
* @return The second Joycon's button code.
|
||||
*/
|
||||
public static int joycon2_button(int button)
|
||||
{
|
||||
return 300 + button;
|
||||
}
|
||||
|
||||
public static void init(@NotNull GameOptions options)
|
||||
{
|
||||
ATTACK.minecraft_key_binding = options.keyAttack;
|
||||
BACK.minecraft_key_binding = options.keyBack;
|
||||
CHAT.minecraft_key_binding = options.keyChat;
|
||||
DROP_ITEM.minecraft_key_binding = options.keyDrop;
|
||||
FORWARD.minecraft_key_binding = options.keyForward;
|
||||
INVENTORY.minecraft_key_binding = options.keyInventory;
|
||||
JUMP.minecraft_key_binding = options.keyJump;
|
||||
LEFT.minecraft_key_binding = options.keyLeft;
|
||||
PICK_BLOCK.minecraft_key_binding = options.keyPickItem;
|
||||
PLAYER_LIST.minecraft_key_binding = options.keyPlayerList;
|
||||
RIGHT.minecraft_key_binding = options.keyRight;
|
||||
SCREENSHOT.minecraft_key_binding = options.keyScreenshot;
|
||||
SMOOTH_CAMERA.minecraft_key_binding = options.keySmoothCamera;
|
||||
SNEAK.minecraft_key_binding = options.keySneak;
|
||||
SPRINT.minecraft_key_binding = options.keySprint;
|
||||
SWAP_HANDS.minecraft_key_binding = options.keySwapHands;
|
||||
TOGGLE_PERSPECTIVE.minecraft_key_binding = options.keyTogglePerspective;
|
||||
USE.minecraft_key_binding = options.keyUse;
|
||||
}
|
||||
|
||||
public static void load_from_config(@NotNull LambdaControlsConfig config)
|
||||
{
|
||||
BINDINGS.forEach(config::load_button_binding);
|
||||
}
|
||||
|
||||
public static void set_button_state(int button, boolean state)
|
||||
{
|
||||
BINDINGS.parallelStream().filter(binding -> Objects.equals(binding.button, button))
|
||||
.forEach(binding -> binding.pressed = state);
|
||||
}
|
||||
|
||||
public static void handle_button(@NotNull MinecraftClient client, int button, int action)
|
||||
{
|
||||
BINDINGS.parallelStream().filter(binding -> binding.button == button)
|
||||
.forEach(binding -> {
|
||||
for (int i = binding.actions.size() - 1; i >= 0; i--) {
|
||||
if (binding.actions.get(i).press(client, binding, action))
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the button has duplicated bindings.
|
||||
*
|
||||
* @param button The button to check.
|
||||
* @return True if the button has duplicated bindings, else false.
|
||||
*/
|
||||
public static boolean has_duplicates(int button)
|
||||
{
|
||||
return BINDINGS.parallelStream().filter(binding -> binding.button == button).count() > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized name of the specified button.
|
||||
*
|
||||
* @param button The button.
|
||||
* @return The localized name of the button.
|
||||
*/
|
||||
public static @NotNull String get_localized_button_name(int button)
|
||||
{
|
||||
switch (button) {
|
||||
case -1:
|
||||
return I18n.translate("key.keyboard.unknown");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_A:
|
||||
return I18n.translate("lambdacontrols.button.a");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_B:
|
||||
return I18n.translate("lambdacontrols.button.b");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_X:
|
||||
return I18n.translate("lambdacontrols.button.x");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_Y:
|
||||
return I18n.translate("lambdacontrols.button.y");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
|
||||
return I18n.translate("lambdacontrols.button.left_bumper");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
|
||||
return I18n.translate("lambdacontrols.button.right_bumper");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_BACK:
|
||||
return I18n.translate("lambdacontrols.button.back");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_START:
|
||||
return I18n.translate("lambdacontrols.button.start");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE:
|
||||
return I18n.translate("lambdacontrols.button.guide");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
|
||||
return I18n.translate("lambdacontrols.button.left_thumb");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
|
||||
return I18n.translate("lambdacontrols.button.right_thumb");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP:
|
||||
return I18n.translate("lambdacontrols.button.dpad_up");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
|
||||
return I18n.translate("lambdacontrols.button.dpad_right");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
|
||||
return I18n.translate("lambdacontrols.button.dpad_down");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
|
||||
return I18n.translate("lambdacontrols.button.dpad_left");
|
||||
case 100:
|
||||
return I18n.translate("lambdacontrols.axis.left_x+");
|
||||
case 101:
|
||||
return I18n.translate("lambdacontrols.axis.left_y+");
|
||||
case 102:
|
||||
return I18n.translate("lambdacontrols.axis.right_x+");
|
||||
case 103:
|
||||
return I18n.translate("lambdacontrols.axis.right_y+");
|
||||
case 104:
|
||||
return I18n.translate("lambdacontrols.axis.left_trigger");
|
||||
case 105:
|
||||
return I18n.translate("lambdacontrols.axis.right_trigger");
|
||||
case 200:
|
||||
return I18n.translate("lambdacontrols.axis.left_x-");
|
||||
case 201:
|
||||
return I18n.translate("lambdacontrols.axis.left_y-");
|
||||
case 202:
|
||||
return I18n.translate("lambdacontrols.axis.right_x-");
|
||||
case 203:
|
||||
return I18n.translate("lambdacontrols.axis.right_y-");
|
||||
default:
|
||||
return I18n.translate("lambdacontrols.button.unknown", button);
|
||||
}
|
||||
}
|
||||
|
||||
public static @NotNull Stream<ButtonBinding> stream()
|
||||
{
|
||||
return BINDINGS.stream();
|
||||
}
|
||||
|
||||
public static @NotNull Stream<Category> stream_categories()
|
||||
{
|
||||
return CATEGORIES.stream();
|
||||
}
|
||||
|
||||
static {
|
||||
MOVEMENT_CATEGORY = register_default_category("key.categories.movement", category -> category.register_all_bindings(
|
||||
FORWARD,
|
||||
BACK,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
JUMP,
|
||||
SNEAK,
|
||||
SPRINT));
|
||||
GAMEPLAY_CATEGORY = register_default_category("key.categories.gameplay", category -> category.register_all_bindings(
|
||||
ATTACK,
|
||||
PICK_BLOCK,
|
||||
USE
|
||||
));
|
||||
INVENTORY_CATEGORY = register_default_category("key.categories.inventory", category -> category.register_all_bindings(
|
||||
DROP_ITEM,
|
||||
INVENTORY,
|
||||
SWAP_HANDS
|
||||
));
|
||||
MULTIPLAYER_CATEGORY = register_default_category("key.categories.multiplayer",
|
||||
category -> category.register_all_bindings(CHAT, PLAYER_LIST));
|
||||
MISC_CATEGORY = register_default_category("key.categories.misc", category -> category.register_all_bindings(
|
||||
SCREENSHOT,
|
||||
//SMOOTH_CAMERA,
|
||||
TOGGLE_PERSPECTIVE
|
||||
));
|
||||
}
|
||||
|
||||
public static ButtonBinding register(@NotNull Identifier binding_id, int default_button, @NotNull List<PressAction> actions)
|
||||
{
|
||||
return new ButtonBinding(binding_id.get_namespace() + "." + binding_id.get_name(), default_button, actions);
|
||||
}
|
||||
|
||||
public static ButtonBinding register(@NotNull Identifier binding_id, int default_button)
|
||||
{
|
||||
return register(binding_id, default_button, Collections.emptyList());
|
||||
}
|
||||
|
||||
public static ButtonBinding register(@NotNull net.minecraft.util.Identifier binding_id, int default_button, @NotNull List<PressAction> actions)
|
||||
{
|
||||
return register(new Identifier(binding_id.getNamespace(), binding_id.getPath()), default_button, actions);
|
||||
}
|
||||
|
||||
public static ButtonBinding register(@NotNull net.minecraft.util.Identifier binding_id, int default_button)
|
||||
{
|
||||
return register(binding_id, default_button, Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a category of button bindings.
|
||||
*
|
||||
* @param category The category to register.
|
||||
* @return The registered category.
|
||||
*/
|
||||
public static Category register_category(@NotNull Category category)
|
||||
{
|
||||
CATEGORIES.add(category);
|
||||
return category;
|
||||
}
|
||||
|
||||
public static Category register_category(@NotNull Identifier identifier, int priority)
|
||||
{
|
||||
return register_category(new Category(identifier, priority));
|
||||
}
|
||||
|
||||
public static Category register_category(@NotNull Identifier identifier)
|
||||
{
|
||||
return register_category(new Category(identifier));
|
||||
}
|
||||
|
||||
private static Category register_default_category(@NotNull String key, @NotNull Consumer<Category> key_adder)
|
||||
{
|
||||
Category category = register_category(new Identifier("minecraft", key), CATEGORIES.size());
|
||||
key_adder.accept(category);
|
||||
return category;
|
||||
}
|
||||
|
||||
public static class Category implements Identifiable
|
||||
{
|
||||
private final List<ButtonBinding> bindings = new ArrayList<>();
|
||||
private final Identifier id;
|
||||
private int priority;
|
||||
|
||||
public Category(@NotNull Identifier id, int priority)
|
||||
{
|
||||
this.id = id;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public Category(@NotNull Identifier id)
|
||||
{
|
||||
this(id, 100);
|
||||
}
|
||||
|
||||
public void register_binding(@NotNull ButtonBinding binding)
|
||||
{
|
||||
if (this.bindings.contains(binding))
|
||||
throw new IllegalStateException("Cannot register twice a button binding in the same category.");
|
||||
this.bindings.add(binding);
|
||||
}
|
||||
|
||||
public void register_all_bindings(@NotNull ButtonBinding... bindings)
|
||||
{
|
||||
this.register_all_bindings(Arrays.asList(bindings));
|
||||
}
|
||||
|
||||
public void register_all_bindings(@NotNull List<ButtonBinding> bindings)
|
||||
{
|
||||
bindings.forEach(this::register_binding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bindings assigned to this category.
|
||||
*
|
||||
* @return The bindings assigned to this category.
|
||||
*/
|
||||
public @NotNull List<ButtonBinding> get_bindings()
|
||||
{
|
||||
return Collections.unmodifiableList(this.bindings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translated name of this category.
|
||||
* <p>
|
||||
* The translation key should be `modid.identifier_name`.
|
||||
*
|
||||
* @return The translated name.
|
||||
*/
|
||||
public @NotNull String get_translated_name()
|
||||
{
|
||||
if (this.id.get_namespace().equals("minecraft"))
|
||||
return I18n.translate(this.id.get_name());
|
||||
else
|
||||
return I18n.translate(this.id.get_namespace() + "." + this.id.get_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the priority display of this category.
|
||||
* It will defines in which order the categories will display on the controls screen.
|
||||
*
|
||||
* @return The priority of this category.
|
||||
*/
|
||||
public int get_priority()
|
||||
{
|
||||
return this.priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Identifier get_identifier()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface PressAction
|
||||
{
|
||||
/**
|
||||
* Handles when there is a press action on the button.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param action The action done.
|
||||
*/
|
||||
boolean press(@NotNull MinecraftClient client, @NotNull ButtonBinding button, int action);
|
||||
}
|
||||
}
|
||||
52
src/main/java/me/lambdaurora/lambdacontrols/ButtonState.java
Normal file
52
src/main/java/me/lambdaurora/lambdacontrols/ButtonState.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Represents a button state.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public enum ButtonState
|
||||
{
|
||||
NONE(0),
|
||||
PRESS(1),
|
||||
RELEASE(2),
|
||||
REPEAT(3);
|
||||
|
||||
public final int id;
|
||||
|
||||
ButtonState(int id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this state is a pressed state.
|
||||
*
|
||||
* @return True if this state is a pressed state, else false.
|
||||
*/
|
||||
public boolean is_pressed()
|
||||
{
|
||||
return this == PRESS || this == REPEAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this state is an unpressed state.
|
||||
*
|
||||
* @return True if this state is an unpressed state, else false.
|
||||
*/
|
||||
public boolean is_unpressed()
|
||||
{
|
||||
return this == RELEASE || this == NONE;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -18,6 +18,10 @@ import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a controller type.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public enum ControllerType implements Nameable
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -18,6 +18,10 @@ import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents the controls mode.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public enum ControlsMode implements Nameable
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -18,6 +18,10 @@ import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents the hud side which is the side where the movements buttons are.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public enum HudSide implements Nameable
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -10,9 +10,14 @@
|
||||
package me.lambdaurora.lambdacontrols;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import me.lambdaurora.lambdacontrols.compat.LambdaControlsCompat;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.Controller;
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsHud;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
|
||||
import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
@@ -24,28 +29,35 @@ import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Represents the LambdaControls mod.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaControls implements ClientModInitializer
|
||||
{
|
||||
private static LambdaControls INSTANCE;
|
||||
public static final FabricKeyBinding BINDING_LOOK_UP = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_up"),
|
||||
public static final String MODID = "lambdacontrols";
|
||||
public static final FabricKeyBinding BINDING_LOOK_UP = FabricKeyBinding.Builder.create(new Identifier(MODID, "look_up"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_8, "key.categories.movement").build();
|
||||
public static final FabricKeyBinding BINDING_LOOK_RIGHT = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_right"),
|
||||
public static final FabricKeyBinding BINDING_LOOK_RIGHT = FabricKeyBinding.Builder.create(new Identifier(MODID, "look_right"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_6, "key.categories.movement").build();
|
||||
public static final FabricKeyBinding BINDING_LOOK_DOWN = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_down"),
|
||||
public static final FabricKeyBinding BINDING_LOOK_DOWN = FabricKeyBinding.Builder.create(new Identifier(MODID, "look_down"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement").build();
|
||||
public static final FabricKeyBinding BINDING_LOOK_LEFT = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_left"),
|
||||
public static final FabricKeyBinding BINDING_LOOK_LEFT = FabricKeyBinding.Builder.create(new Identifier(MODID, "look_left"),
|
||||
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement").build();
|
||||
public static final Identifier CONTROLLER_BUTTONS = new Identifier("lambdacontrols", "textures/gui/controller_buttons.png");
|
||||
public static final Identifier CONTROLLER_AXIS = new Identifier("lambdacontrols", "textures/gui/controller_axis.png");
|
||||
public static final Identifier CONTROLLER_BUTTONS = new Identifier(MODID, "textures/gui/controller_buttons.png");
|
||||
public static final Identifier CONTROLLER_AXIS = new Identifier(MODID, "textures/gui/controller_axis.png");
|
||||
public final Logger logger = LogManager.getLogger("LambdaControls");
|
||||
public final LambdaControlsConfig config = new LambdaControlsConfig(this);
|
||||
public final LambdaInput input = new LambdaInput(this);
|
||||
private LambdaControlsHud hud;
|
||||
private ControlsMode previous_controls_mode;
|
||||
|
||||
@Override
|
||||
@@ -53,12 +65,13 @@ public class LambdaControls implements ClientModInitializer
|
||||
{
|
||||
INSTANCE = this;
|
||||
this.log("Initializing LambdaControls...");
|
||||
this.config.load();
|
||||
|
||||
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_UP);
|
||||
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_RIGHT);
|
||||
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_DOWN);
|
||||
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_LEFT);
|
||||
|
||||
HudRenderCallback.EVENT.register(delta -> this.hud.render());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,8 +79,9 @@ public class LambdaControls implements ClientModInitializer
|
||||
*/
|
||||
public void on_mc_init(@NotNull MinecraftClient client)
|
||||
{
|
||||
Controller.update_mappings();
|
||||
ButtonBinding.init(client.options);
|
||||
this.config.load();
|
||||
Controller.update_mappings();
|
||||
GLFW.glfwSetJoystickCallback((jid, event) -> {
|
||||
if (event == GLFW.GLFW_CONNECTED) {
|
||||
Controller controller = Controller.by_id(jid);
|
||||
@@ -80,6 +94,10 @@ public class LambdaControls implements ClientModInitializer
|
||||
|
||||
this.switch_controls_mode();
|
||||
});
|
||||
|
||||
this.hud = new LambdaControlsHud(client, this);
|
||||
|
||||
LambdaControlsCompat.init();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,6 +146,16 @@ public class LambdaControls implements ClientModInitializer
|
||||
this.logger.info("[LambdaControls] " + info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a warning to the terminal.
|
||||
*
|
||||
* @param warning The warning to print.
|
||||
*/
|
||||
public void warn(String warning)
|
||||
{
|
||||
this.logger.info("[LambdaControls] " + warning);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the LambdaControls instance.
|
||||
*
|
||||
@@ -138,15 +166,39 @@ public class LambdaControls implements ClientModInitializer
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static int draw_button(int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client)
|
||||
public static Pair<Integer, Integer> draw_button(int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client)
|
||||
{
|
||||
return draw_button(x, y, button.get_button(), client);
|
||||
}
|
||||
|
||||
public static int draw_button(int x, int y, int button, @NotNull MinecraftClient client)
|
||||
public static Pair<Integer, Integer> draw_button(int x, int y, int[] buttons, @NotNull MinecraftClient client)
|
||||
{
|
||||
int height = 0;
|
||||
int length = 0;
|
||||
int current_x = x;
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
int btn = buttons[i];
|
||||
Pair<Integer, Integer> size = draw_button(current_x, y, btn, client);
|
||||
if (size.get_key() > height)
|
||||
height = size.get_value();
|
||||
length += size.get_key();
|
||||
if (i + 1 < buttons.length) {
|
||||
length += 2;
|
||||
current_x = x + length;
|
||||
}
|
||||
}
|
||||
return Pair.of(length, height);
|
||||
}
|
||||
|
||||
public static Pair<Integer, Integer> draw_button(int x, int y, int button, @NotNull MinecraftClient client)
|
||||
{
|
||||
boolean second = false;
|
||||
if (button == -1)
|
||||
return 0;
|
||||
return Pair.of(0, 0);
|
||||
else if (button >= 500) {
|
||||
button -= 1000;
|
||||
second = true;
|
||||
}
|
||||
|
||||
int controller_type = get().config.get_controller_type().get_id();
|
||||
boolean axis = false;
|
||||
@@ -218,11 +270,11 @@ public class LambdaControls implements ClientModInitializer
|
||||
client.getTextureManager().bindTexture(axis ? LambdaControls.CONTROLLER_AXIS : LambdaControls.CONTROLLER_BUTTONS);
|
||||
GlStateManager.disableDepthTest();
|
||||
|
||||
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.color4f(1.0F, second ? 0.0F : 1.0F, 1.0F, 1.0F);
|
||||
DrawableHelper.blit(x, y, (float) button_offset, (float) (controller_type * (axis ? 18 : 15)), axis ? 18 : 15, axis ? 18 : 15, 256, 256);
|
||||
GlStateManager.enableDepthTest();
|
||||
|
||||
return axis ? 18 : 15;
|
||||
return axis ? Pair.of(18, 18) : Pair.of(15, 15);
|
||||
}
|
||||
|
||||
public static int draw_button_tip(int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client)
|
||||
@@ -230,10 +282,10 @@ public class LambdaControls implements ClientModInitializer
|
||||
return draw_button_tip(x, y, button.get_button(), button.get_translation_key(), display, client);
|
||||
}
|
||||
|
||||
public static int draw_button_tip(int x, int y, int button, @NotNull String action, boolean display, @NotNull MinecraftClient client)
|
||||
public static int draw_button_tip(int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client)
|
||||
{
|
||||
if (display) {
|
||||
int button_width = draw_button(x, y, button, client);
|
||||
int button_width = draw_button(x, y, button, client).get_key();
|
||||
|
||||
String translated_action = I18n.translate(action);
|
||||
int text_y = (15 - client.textRenderer.fontHeight) / 2;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -10,55 +10,78 @@
|
||||
package me.lambdaurora.lambdacontrols;
|
||||
|
||||
import com.electronwill.nightconfig.core.file.FileConfig;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.Controller;
|
||||
import me.lambdaurora.lambdacontrols.controller.InputManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_X;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y;
|
||||
|
||||
/**
|
||||
* Represents LambdaControls configuration.
|
||||
*/
|
||||
public class LambdaControlsConfig
|
||||
{
|
||||
private final FileConfig config = FileConfig.builder("config/lambdacontrols.toml").concurrent().defaultResource("/config.toml").build();
|
||||
private final Map<String, KeyBinding> keybinding_mappings = new HashMap<>();
|
||||
private final LambdaControls mod;
|
||||
private ControlsMode controls_mode;
|
||||
private ControllerType controller_type;
|
||||
private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT;
|
||||
private static final boolean DEFAULT_AUTO_SWITCH_MODE = false;
|
||||
private static final boolean DEFAULT_HUD_ENABLE = true;
|
||||
private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT;
|
||||
private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT;
|
||||
private static final double DEFAULT_DEAD_ZONE = 0.25;
|
||||
private static final double DEFAULT_ROTATION_SPEED = 40.0;
|
||||
private static final double DEFAULT_MOUSE_SPEED = 25.0;
|
||||
|
||||
private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?");
|
||||
|
||||
private final FileConfig config = FileConfig.builder("config/lambdacontrols.toml").concurrent().defaultResource("/config.toml").build();
|
||||
private final LambdaControls mod;
|
||||
private ControlsMode controls_mode;
|
||||
private ControllerType controller_type;
|
||||
// HUD settings.
|
||||
private boolean hud_enable;
|
||||
private HudSide hud_side;
|
||||
private boolean hud_enable;
|
||||
private HudSide hud_side;
|
||||
// Controller settings
|
||||
private double dead_zone;
|
||||
private double rotation_speed;
|
||||
private double mouse_speed;
|
||||
private double dead_zone;
|
||||
private double rotation_speed;
|
||||
private double mouse_speed;
|
||||
|
||||
public LambdaControlsConfig(@NotNull LambdaControls mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration
|
||||
*/
|
||||
public void load()
|
||||
{
|
||||
this.keybinding_mappings.clear();
|
||||
this.config.load();
|
||||
this.check_and_fix();
|
||||
this.mod.log("Configuration loaded.");
|
||||
this.controls_mode = ControlsMode.by_id(this.config.getOrElse("controls", "default")).orElse(ControlsMode.DEFAULT);
|
||||
this.controls_mode = ControlsMode.by_id(this.config.getOrElse("controls", DEFAULT_CONTROLS_MODE.get_name())).orElse(DEFAULT_CONTROLS_MODE);
|
||||
// HUD settings.
|
||||
this.hud_enable = this.config.getOrElse("hud.enable", true);
|
||||
this.hud_side = HudSide.by_id(this.config.getOrElse("hud.side", "left")).orElse(HudSide.LEFT);
|
||||
this.hud_enable = this.config.getOrElse("hud.enable", DEFAULT_HUD_ENABLE);
|
||||
this.hud_side = HudSide.by_id(this.config.getOrElse("hud.side", DEFAULT_HUD_SIDE.get_name())).orElse(DEFAULT_HUD_SIDE);
|
||||
// Controller settings.
|
||||
this.controller_type = ControllerType.by_id(this.config.getOrElse("controller.type", "default")).orElse(ControllerType.DEFAULT);
|
||||
this.dead_zone = this.config.getOrElse("controller.dead_zone", 0.25);
|
||||
this.rotation_speed = this.config.getOrElse("controller.rotation_speed", 40.0);
|
||||
this.mouse_speed = this.config.getOrElse("controller.mouse_speed", 25.0);
|
||||
this.controller_type = ControllerType.by_id(this.config.getOrElse("controller.type", DEFAULT_CONTROLLER_TYPE.get_name())).orElse(DEFAULT_CONTROLLER_TYPE);
|
||||
this.dead_zone = this.config.getOrElse("controller.dead_zone", DEFAULT_DEAD_ZONE);
|
||||
this.rotation_speed = this.config.getOrElse("controller.rotation_speed", DEFAULT_ROTATION_SPEED);
|
||||
this.mouse_speed = this.config.getOrElse("controller.mouse_speed", DEFAULT_MOUSE_SPEED);
|
||||
// Controller controls.
|
||||
ButtonBinding.load_from_config(this);
|
||||
InputManager.load_button_bindings(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the configuration.
|
||||
*/
|
||||
public void save()
|
||||
{
|
||||
this.config.set("controller.dead_zone", this.dead_zone);
|
||||
@@ -68,6 +91,35 @@ public class LambdaControlsConfig
|
||||
this.mod.log("Configuration saved.");
|
||||
}
|
||||
|
||||
public void check_and_fix()
|
||||
{
|
||||
InputManager.stream_bindings().forEach(binding -> {
|
||||
String path = "controller.controls." + binding.get_name();
|
||||
Object raw = this.config.getRaw(path);
|
||||
if (raw instanceof Number) {
|
||||
this.mod.warn("Invalid data at \"" + path + "\", fixing...");
|
||||
this.config.set(path, "0;" + raw);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the configuration to default values.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
this.set_controls_mode(DEFAULT_CONTROLS_MODE);
|
||||
this.set_auto_switch_mode(DEFAULT_AUTO_SWITCH_MODE);
|
||||
this.set_hud_enabled(DEFAULT_HUD_ENABLE);
|
||||
this.set_hud_side(DEFAULT_HUD_SIDE);
|
||||
this.set_controller_type(DEFAULT_CONTROLLER_TYPE);
|
||||
this.set_dead_zone(DEFAULT_DEAD_ZONE);
|
||||
this.set_rotation_speed(DEFAULT_ROTATION_SPEED);
|
||||
this.set_mouse_speed(DEFAULT_MOUSE_SPEED);
|
||||
|
||||
InputManager.stream_bindings().forEach(binding -> this.set_button_binding(binding, binding.get_default_button()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the controls mode from the configuration.
|
||||
*
|
||||
@@ -96,7 +148,7 @@ public class LambdaControlsConfig
|
||||
*/
|
||||
public boolean has_auto_switch_mode()
|
||||
{
|
||||
return this.config.getOrElse("auto_switch_mode", false);
|
||||
return this.config.getOrElse("auto_switch_mode", DEFAULT_AUTO_SWITCH_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,6 +229,34 @@ public class LambdaControlsConfig
|
||||
this.config.set("controller.id", controller.get_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the second controller (for Joy-Con supports).
|
||||
*
|
||||
* @return The second controller.
|
||||
*/
|
||||
public @NotNull Optional<Controller> get_second_controller()
|
||||
{
|
||||
Object raw = this.config.getRaw("controller.id2");
|
||||
if (raw instanceof Number) {
|
||||
if ((int) raw == -1)
|
||||
return Optional.empty();
|
||||
return Optional.of(Controller.by_id((Integer) raw));
|
||||
} else if (raw instanceof String) {
|
||||
return Optional.of(Controller.by_guid((String) raw).orElse(Controller.by_id(GLFW.GLFW_JOYSTICK_1)));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the second controller.
|
||||
*
|
||||
* @param controller The second controller.
|
||||
*/
|
||||
public void set_second_controller(@Nullable Controller controller)
|
||||
{
|
||||
this.config.set("controller.id2", controller == null ? -1 : controller.get_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the controller's type.
|
||||
*
|
||||
@@ -318,21 +398,6 @@ public class LambdaControlsConfig
|
||||
return this.does_invert_right_y_axis() ? -1.0 : 1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keybindings.
|
||||
*
|
||||
* @return The keybindings.
|
||||
*/
|
||||
public @NotNull Map<String, KeyBinding> get_keybindings()
|
||||
{
|
||||
return this.keybinding_mappings;
|
||||
}
|
||||
|
||||
public Optional<KeyBinding> get_keybind(@NotNull String id)
|
||||
{
|
||||
return Optional.ofNullable(this.keybinding_mappings.get(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the button binding from configuration.
|
||||
*
|
||||
@@ -340,7 +405,43 @@ public class LambdaControlsConfig
|
||||
*/
|
||||
public void load_button_binding(@NotNull ButtonBinding button)
|
||||
{
|
||||
button.set_button(this.config.getOrElse("controller.controls." + button.get_name(), button.get_button()));
|
||||
button.set_button(button.get_default_button());
|
||||
String button_code = this.config.getOrElse("controller.controls." + button.get_name(), button.get_button_code());
|
||||
|
||||
Matcher matcher = BUTTON_BINDING_PATTERN.matcher(button_code);
|
||||
|
||||
try {
|
||||
int[] buttons = new int[1];
|
||||
int count = 0;
|
||||
while (matcher.find()) {
|
||||
count++;
|
||||
if (count > buttons.length)
|
||||
buttons = Arrays.copyOf(buttons, count);
|
||||
String current;
|
||||
if (!this.check_validity(button, button_code, current = matcher.group(1)))
|
||||
return;
|
||||
buttons[count - 1] = Integer.parseInt(current);
|
||||
}
|
||||
if (count == 0) {
|
||||
this.mod.warn("Malformed config value \"" + button_code + "\" for binding \"" + button.get_name() + "\".");
|
||||
this.set_button_binding(button, new int[]{-1});
|
||||
}
|
||||
|
||||
button.set_button(buttons);
|
||||
} catch (Exception e) {
|
||||
this.mod.warn("Malformed config value \"" + button_code + "\" for binding \"" + button.get_name() + "\".");
|
||||
this.config.set("controller.controls." + button.get_name(), button.get_button_code());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean check_validity(@NotNull ButtonBinding binding, @NotNull String input, String group)
|
||||
{
|
||||
if (group == null) {
|
||||
this.mod.warn("Malformed config value \"" + input + "\" for binding \"" + binding.get_name() + "\".");
|
||||
this.config.set("controller.controls." + binding.get_name(), binding.get_button_code());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,51 +450,48 @@ public class LambdaControlsConfig
|
||||
* @param binding The button binding.
|
||||
* @param button The button.
|
||||
*/
|
||||
public void set_button_binding(@NotNull ButtonBinding binding, int button)
|
||||
public void set_button_binding(@NotNull ButtonBinding binding, int[] button)
|
||||
{
|
||||
binding.set_button(button);
|
||||
this.config.set("controller.controls." + binding.get_name(), button);
|
||||
this.config.set("controller.controls." + binding.get_name(), binding.get_button_code());
|
||||
}
|
||||
|
||||
public boolean is_back_button(int btn, boolean is_btn, int state)
|
||||
{
|
||||
if (!is_btn && state == 0)
|
||||
return false;
|
||||
return ButtonBinding.BACK.is_button(ButtonBinding.axis_as_button(btn, state == 1));
|
||||
return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_Y, false) == ButtonBinding.axis_as_button(btn, state == 1);
|
||||
}
|
||||
|
||||
public boolean is_forward_button(int btn, boolean is_btn, int state)
|
||||
{
|
||||
if (!is_btn && state == 0)
|
||||
return false;
|
||||
return ButtonBinding.FORWARD.is_button(ButtonBinding.axis_as_button(btn, state == 1));
|
||||
return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_Y, true) == ButtonBinding.axis_as_button(btn, state == 1);
|
||||
}
|
||||
|
||||
public boolean is_left_button(int btn, boolean is_btn, int state)
|
||||
{
|
||||
if (!is_btn && state == 0)
|
||||
return false;
|
||||
return ButtonBinding.LEFT.is_button(ButtonBinding.axis_as_button(btn, state == 1));
|
||||
return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_X, false) == ButtonBinding.axis_as_button(btn, state == 1);
|
||||
}
|
||||
|
||||
public boolean is_right_button(int btn, boolean is_btn, int state)
|
||||
{
|
||||
if (!is_btn && state == 0)
|
||||
return false;
|
||||
return ButtonBinding.RIGHT.is_button(ButtonBinding.axis_as_button(btn, state == 1));
|
||||
return ButtonBinding.axis_as_button(GLFW_GAMEPAD_AXIS_LEFT_X, true) == ButtonBinding.axis_as_button(btn, state == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the specified axis is an axis used for movements.
|
||||
*
|
||||
* @param i The axis index.
|
||||
* @param axis The axis index.
|
||||
* @return True if the axis is used for movements, else false.
|
||||
*/
|
||||
public boolean is_movement_axis(int i)
|
||||
public boolean is_movement_axis(int axis)
|
||||
{
|
||||
return ButtonBinding.FORWARD.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.FORWARD.is_button(ButtonBinding.axis_as_button(i, false))
|
||||
|| ButtonBinding.BACK.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.BACK.is_button(ButtonBinding.axis_as_button(i, false))
|
||||
|| ButtonBinding.LEFT.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.LEFT.is_button(ButtonBinding.axis_as_button(i, false))
|
||||
|| ButtonBinding.RIGHT.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.RIGHT.is_button(ButtonBinding.axis_as_button(i, false));
|
||||
return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import io.github.prospector.modmenu.api.ModMenuApi;
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsSettingsScreen;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents the API implementation of ModMenu for LambdaControls.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class LambdaControlsModMenu implements ModMenuApi
|
||||
{
|
||||
@Override
|
||||
public String getModId()
|
||||
{
|
||||
return LambdaControls.MODID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<Screen, ? extends Screen> getConfigScreenFactory()
|
||||
{
|
||||
return screen -> new LambdaControlsSettingsScreen(screen, MinecraftClient.getInstance().options, false);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,21 +9,21 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.gui.LabelWidget;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.Controller;
|
||||
import me.lambdaurora.lambdacontrols.controller.InputManager;
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsControlsScreen;
|
||||
import me.lambdaurora.lambdacontrols.gui.TouchscreenOverlay;
|
||||
import me.lambdaurora.lambdacontrols.mixin.EntryListWidgetAccessor;
|
||||
import me.lambdaurora.lambdacontrols.util.AbstractContainerScreenAccessor;
|
||||
import me.lambdaurora.lambdacontrols.util.CreativeInventoryScreenAccessor;
|
||||
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
|
||||
import me.lambdaurora.lambdacontrols.util.MouseAccessor;
|
||||
import me.lambdaurora.spruceui.SpruceLabelWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.ParentElement;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
|
||||
import net.minecraft.client.gui.screen.world.WorldListWidget;
|
||||
@@ -32,7 +32,6 @@ import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.container.Slot;
|
||||
import net.minecraft.container.SlotActionType;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,25 +46,26 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static me.lambdaurora.lambdacontrols.ButtonBinding.*;
|
||||
import static me.lambdaurora.lambdacontrols.controller.ButtonBinding.axis_as_button;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
|
||||
|
||||
/**
|
||||
* Represents the LambdaControls' input handler.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaInput
|
||||
{
|
||||
private static final Map<Integer, Boolean> BUTTON_STATES = new HashMap<>();
|
||||
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
|
||||
private static final Map<Integer, Boolean> AXIS_STATES = new HashMap<>();
|
||||
private static final Map<Integer, Integer> AXIS_COOLDOWNS = new HashMap<>();
|
||||
private final LambdaControlsConfig config;
|
||||
// Cooldowns
|
||||
private int action_gui_cooldown = 0;
|
||||
private int ignore_next_a = 0;
|
||||
// Sneak state.
|
||||
private boolean sneak = false;
|
||||
private double prev_target_yaw = 0.0;
|
||||
private double prev_target_pitch = 0.0;
|
||||
private double target_yaw = 0.0;
|
||||
@@ -115,19 +115,29 @@ public class LambdaInput
|
||||
public void on_controller_tick(@NotNull MinecraftClient client)
|
||||
{
|
||||
BUTTON_COOLDOWNS.entrySet().stream().filter(entry -> entry.getValue() > 0).forEach(entry -> BUTTON_COOLDOWNS.put(entry.getKey(), entry.getValue() - 1));
|
||||
AXIS_COOLDOWNS.entrySet().stream().filter(entry -> entry.getValue() > 0).forEach(entry -> AXIS_COOLDOWNS.put(entry.getKey(), entry.getValue() - 1));
|
||||
// Decreases the cooldown for GUI actions.
|
||||
if (this.action_gui_cooldown > 0)
|
||||
--this.action_gui_cooldown;
|
||||
this.prev_target_mouse_x = this.target_mouse_x;
|
||||
this.prev_target_mouse_y = this.target_mouse_y;
|
||||
|
||||
InputManager.update_states();
|
||||
|
||||
Controller controller = this.config.get_controller();
|
||||
if (controller.is_connected()) {
|
||||
GLFWGamepadState state = controller.get_state();
|
||||
this.fetch_button_input(client, state);
|
||||
this.fetch_axe_input(client, state);
|
||||
this.fetch_button_input(client, state, false);
|
||||
this.fetch_axe_input(client, state, false);
|
||||
}
|
||||
this.config.get_second_controller().filter(Controller::is_connected)
|
||||
.ifPresent(joycon -> {
|
||||
GLFWGamepadState state = joycon.get_state();
|
||||
this.fetch_button_input(client, state, true);
|
||||
this.fetch_axe_input(client, state, true);
|
||||
});
|
||||
|
||||
InputManager.update_bindings();
|
||||
InputManager.stream_active_bindings().forEach(binding -> binding.handle(client, InputManager.get_binding_state(binding)));
|
||||
|
||||
if (this.ignore_next_a > 0)
|
||||
this.ignore_next_a--;
|
||||
@@ -189,66 +199,73 @@ public class LambdaInput
|
||||
}
|
||||
}
|
||||
|
||||
private void fetch_button_input(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepad_state)
|
||||
private void fetch_button_input(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepad_state, boolean left_joycon)
|
||||
{
|
||||
ByteBuffer buffer = gamepad_state.buttons();
|
||||
for (int btn = 0; btn < buffer.limit(); btn++) {
|
||||
for (int i = 0; i < buffer.limit(); i++) {
|
||||
int btn = left_joycon ? ButtonBinding.controller2_button(i) : i;
|
||||
boolean btn_state = buffer.get() == (byte) 1;
|
||||
boolean previous_state = BUTTON_STATES.getOrDefault(btn, false);
|
||||
ButtonState current_state = ButtonState.NONE;
|
||||
ButtonState previous_state = InputManager.STATES.getOrDefault(btn, ButtonState.NONE);
|
||||
|
||||
ButtonBinding.set_button_state(btn, btn_state);
|
||||
|
||||
if (btn_state != previous_state) {
|
||||
if (btn_state != previous_state.is_pressed()) {
|
||||
current_state = btn_state ? ButtonState.PRESS : ButtonState.RELEASE;
|
||||
this.handle_button(client, btn, btn_state ? 0 : 1, btn_state);
|
||||
if (btn_state)
|
||||
BUTTON_COOLDOWNS.put(btn, 5);
|
||||
} else if (btn_state) {
|
||||
current_state = ButtonState.REPEAT;
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(btn, 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(btn, 5);
|
||||
this.handle_button(client, btn, 2, true);
|
||||
}
|
||||
}
|
||||
|
||||
BUTTON_STATES.put(btn, btn_state);
|
||||
InputManager.STATES.put(btn, current_state);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetch_axe_input(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepad_state)
|
||||
private void fetch_axe_input(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepad_state, boolean left_joycon)
|
||||
{
|
||||
FloatBuffer buffer = gamepad_state.axes();
|
||||
for (int i = 0; i < buffer.limit(); i++) {
|
||||
int axis = left_joycon ? ButtonBinding.controller2_button(i) : i;
|
||||
float value = buffer.get();
|
||||
float abs_value = Math.abs(value);
|
||||
|
||||
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
|
||||
value *= -1.0F;
|
||||
|
||||
ButtonBinding.set_button_state(axis_as_button(i, true), value > 0.5F);
|
||||
ButtonBinding.set_button_state(axis_as_button(i, false), value < -0.5F);
|
||||
//InputManager.(axis_as_button(axis, true), value > 0.5F);
|
||||
//ButtonBinding.set_button_state(axis_as_button(axis, false), value < -0.5F);
|
||||
|
||||
int state = value > this.config.get_dead_zone() ? 1 : (value < -this.config.get_dead_zone() ? 2 : 0);
|
||||
this.handle_axe(client, i, value, abs_value, state);
|
||||
this.handle_axe(client, axis, value, abs_value, state);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean are_buttons_pressed(int[] buttons)
|
||||
{
|
||||
int i = 0;
|
||||
for (int btn : buttons) {
|
||||
if (BUTTON_STATES.containsKey(btn) && BUTTON_STATES.get(btn))
|
||||
i++;
|
||||
}
|
||||
return i == buttons.length;
|
||||
}
|
||||
|
||||
private void handle_button(@NotNull MinecraftClient client, int button, int action, boolean state)
|
||||
{
|
||||
if (client.currentScreen instanceof LambdaControlsControlsScreen && action == 0) {
|
||||
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
|
||||
if (controls_screen.focused_binding != null) {
|
||||
this.config.set_button_binding(controls_screen.focused_binding, button);
|
||||
this.config.set_button_binding(controls_screen.focused_binding, new int[]{button});
|
||||
controls_screen.focused_binding = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (action == 0 || action == 2) {
|
||||
// Handles RB and LB buttons.
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER || button == GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) {
|
||||
this.handle_rb_lb(client, button == GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.currentScreen != null && is_screen_interactive(client.currentScreen)
|
||||
&& (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN
|
||||
|| button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)) {
|
||||
@@ -267,19 +284,7 @@ public class LambdaInput
|
||||
}
|
||||
}
|
||||
|
||||
if (action == 0) {
|
||||
// Handles when the player presses the Start button.
|
||||
if (PAUSE_GAME.is_button(button)) {
|
||||
// If in game, then pause the game.
|
||||
if (client.currentScreen == null)
|
||||
client.openPauseMenu(false);
|
||||
else if (client.currentScreen instanceof AbstractContainerScreen) // If the current screen is a container then close it.
|
||||
client.player.closeContainer();
|
||||
else// Else just close the current screen.
|
||||
client.currentScreen.onClose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (action == 1) {
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) {
|
||||
if (this.action_gui_cooldown == 0) {
|
||||
Element focused = client.currentScreen.getFocused();
|
||||
@@ -327,11 +332,6 @@ public class LambdaInput
|
||||
client.currentScreen.mouseReleased(mouse_x, mouse_y, GLFW.GLFW_MOUSE_BUTTON_1);
|
||||
}
|
||||
this.action_gui_cooldown = 5;
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.currentScreen == null) {
|
||||
ButtonBinding.handle_button(client, button, action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,10 +340,11 @@ public class LambdaInput
|
||||
int as_button_state = value > 0.5F ? 1 : (value < -0.5F ? 2 : 0);
|
||||
|
||||
if (client.currentScreen instanceof LambdaControlsControlsScreen && as_button_state != 0
|
||||
&& !(as_button_state == 2 && (axis == GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER))) {
|
||||
&& !(as_button_state == 2 && (axis == GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER ||
|
||||
axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) || axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)))) {
|
||||
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
|
||||
if (controls_screen.focused_binding != null) {
|
||||
this.config.set_button_binding(controls_screen.focused_binding, axis_as_button(axis, as_button_state == 1));
|
||||
this.config.set_button_binding(controls_screen.focused_binding, new int[]{axis_as_button(axis, as_button_state == 1)});
|
||||
controls_screen.focused_binding = null;
|
||||
return;
|
||||
}
|
||||
@@ -352,38 +353,36 @@ public class LambdaInput
|
||||
double dead_zone = this.config.get_dead_zone();
|
||||
if (client.currentScreen == null) {
|
||||
{
|
||||
int axis_minus = axis + 100;
|
||||
boolean current_plus_state = as_button_state == 1;
|
||||
boolean current_minus_state = as_button_state == 2;
|
||||
boolean previous_plus_state = AXIS_STATES.getOrDefault(axis, false);
|
||||
boolean previous_minus_state = AXIS_STATES.getOrDefault(axis_minus, false);
|
||||
ButtonState previous_plus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, true), ButtonState.NONE);
|
||||
ButtonState previous_minus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, false), ButtonState.NONE);
|
||||
|
||||
if (current_plus_state != previous_plus_state) {
|
||||
ButtonBinding.handle_button(client, ButtonBinding.axis_as_button(axis, true), 0);
|
||||
if (current_plus_state != previous_plus_state.is_pressed()) {
|
||||
InputManager.STATES.put(axis_as_button(axis, true), current_plus_state ? ButtonState.PRESS : ButtonState.RELEASE);
|
||||
if (current_plus_state)
|
||||
AXIS_COOLDOWNS.put(axis, 5);
|
||||
BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5);
|
||||
} else if (current_plus_state) {
|
||||
if (AXIS_COOLDOWNS.getOrDefault(axis, 0) == 0) {
|
||||
AXIS_COOLDOWNS.put(axis, 5);
|
||||
InputManager.STATES.put(axis_as_button(axis, true), ButtonState.REPEAT);
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, true), 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (current_minus_state != previous_minus_state) {
|
||||
ButtonBinding.handle_button(client, ButtonBinding.axis_as_button(axis, false), 0);
|
||||
if (current_minus_state != previous_minus_state.is_pressed()) {
|
||||
InputManager.STATES.put(axis_as_button(axis, false), current_minus_state ? ButtonState.PRESS : ButtonState.RELEASE);
|
||||
if (current_minus_state)
|
||||
AXIS_COOLDOWNS.put(axis_minus, 5);
|
||||
BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5);
|
||||
} else if (current_minus_state) {
|
||||
if (AXIS_COOLDOWNS.getOrDefault(axis_minus, 0) == 0) {
|
||||
AXIS_COOLDOWNS.put(axis_minus, 5);
|
||||
InputManager.STATES.put(axis_as_button(axis, false), ButtonState.REPEAT);
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, false), 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5);
|
||||
}
|
||||
}
|
||||
|
||||
AXIS_STATES.put(axis, current_plus_state);
|
||||
AXIS_STATES.put(axis_minus, current_minus_state);
|
||||
}
|
||||
|
||||
// Handles the look direction.
|
||||
this.handle_look(client, axis, abs_value, state);
|
||||
this.handle_look(client, axis, (float) (abs_value / (1.0 - this.config.get_dead_zone())), state);
|
||||
} else {
|
||||
boolean allow_mouse_control = true;
|
||||
|
||||
@@ -422,8 +421,8 @@ public class LambdaInput
|
||||
if (Math.abs(prev_x_axis) < dead_zone && Math.abs(prev_y_axis) < dead_zone) {
|
||||
double mouse_x = client.mouse.getX();
|
||||
double mouse_y = client.mouse.getY();
|
||||
prev_target_mouse_x = target_mouse_x = (int) mouse_x;
|
||||
prev_target_mouse_y = target_mouse_y = (int) mouse_y;
|
||||
this.prev_target_mouse_x = this.target_mouse_x = (int) mouse_x;
|
||||
this.prev_target_mouse_y = this.target_mouse_y = (int) mouse_y;
|
||||
}
|
||||
|
||||
if (Math.abs(movement_x) >= dead_zone)
|
||||
@@ -440,7 +439,7 @@ public class LambdaInput
|
||||
this.mouse_speed_y = 0.F;
|
||||
}
|
||||
|
||||
if (Math.abs(this.mouse_speed_x) > .05F || Math.abs(this.mouse_speed_y) > .05F) {
|
||||
if (Math.abs(this.mouse_speed_x) >= .05F || Math.abs(this.mouse_speed_y) >= .05F) {
|
||||
this.target_mouse_x += this.mouse_speed_x * this.config.get_mouse_speed();
|
||||
this.target_mouse_x = MathHelper.clamp(this.target_mouse_x, 0, client.getWindow().getWidth());
|
||||
this.target_mouse_y += this.mouse_speed_y * this.config.get_mouse_speed();
|
||||
@@ -455,32 +454,6 @@ public class LambdaInput
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the press on RB on LB.
|
||||
*
|
||||
* @param client The client's instance.
|
||||
* @param right True if RB is pressed, else false.
|
||||
*/
|
||||
private void handle_rb_lb(@NotNull MinecraftClient client, boolean right)
|
||||
{
|
||||
// When ingame
|
||||
if (client.currentScreen == null && client.player != null) {
|
||||
if (right)
|
||||
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;
|
||||
} else if (client.currentScreen instanceof CreativeInventoryScreen) {
|
||||
CreativeInventoryScreenAccessor creative_inventory = (CreativeInventoryScreenAccessor) client.currentScreen;
|
||||
int current_selected_tab = creative_inventory.get_selected_tab();
|
||||
int next_tab = current_selected_tab + (right ? 1 : -1);
|
||||
if (next_tab < 0)
|
||||
next_tab = ItemGroup.GROUPS.length - 1;
|
||||
else if (next_tab >= ItemGroup.GROUPS.length)
|
||||
next_tab = 0;
|
||||
creative_inventory.set_selected_tab(ItemGroup.GROUPS[next_tab]);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handle_a_button(@NotNull Screen screen, @NotNull Element focused)
|
||||
{
|
||||
if (focused instanceof AbstractPressableButtonWidget) {
|
||||
@@ -488,8 +461,8 @@ public class LambdaInput
|
||||
button_widget.playDownSound(MinecraftClient.getInstance().getSoundManager());
|
||||
button_widget.onPress();
|
||||
return true;
|
||||
} else if (focused instanceof LabelWidget) {
|
||||
((LabelWidget) focused).on_press();
|
||||
} else if (focused instanceof SpruceLabelWidget) {
|
||||
((SpruceLabelWidget) focused).on_press();
|
||||
return true;
|
||||
} else if (focused instanceof WorldListWidget) {
|
||||
WorldListWidget list = (WorldListWidget) focused;
|
||||
@@ -557,7 +530,7 @@ public class LambdaInput
|
||||
{
|
||||
// Handles the look direction.
|
||||
if (client.player != null) {
|
||||
double pow_value = Math.pow(value, 2.0);
|
||||
double pow_value = Math.pow(value, 4.0);
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
|
||||
if (state == 2) {
|
||||
this.target_pitch = client.player.pitch - this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
|
||||
|
||||
@@ -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.compat;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.InputManager;
|
||||
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import org.aperlambda.lambdacommon.utils.LambdaReflection;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Represents a compatibility handler.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
*/
|
||||
public class LambdaControlsCompat
|
||||
{
|
||||
private static final String OKZOOMER_CLASS_PATH = "io.github.joaoh1.okzoomer.OkZoomer";
|
||||
|
||||
public static void init()
|
||||
{
|
||||
if (FabricLoader.getInstance().isModLoaded("okzoomer") && LambdaReflection.does_class_exist(OKZOOMER_CLASS_PATH)) {
|
||||
LambdaReflection.get_class(OKZOOMER_CLASS_PATH).map(clazz -> LambdaReflection.get_first_field_of_type(clazz, FabricKeyBinding.class))
|
||||
.ifPresent(field -> field.map(f -> (FabricKeyBinding) LambdaReflection.get_field_value(null, f))
|
||||
.ifPresent(zoom_key_binding -> {
|
||||
ButtonBinding binding = InputManager.register_binding(new ButtonBinding("zoom", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_X}, true));
|
||||
binding.set_key_binding(zoom_key_binding);
|
||||
ButtonBinding.MISC_CATEGORY.register_binding(binding);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* 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.controller;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonState;
|
||||
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.ScreenshotUtils;
|
||||
import org.aperlambda.lambdacommon.utils.Nameable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lambdaurora.lambdacontrols.controller.InputManager.register_binding;
|
||||
import static me.lambdaurora.lambdacontrols.controller.InputManager.register_default_category;
|
||||
|
||||
/**
|
||||
* Represents a button binding.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class ButtonBinding implements Nameable
|
||||
{
|
||||
public static final ButtonCategory MOVEMENT_CATEGORY;
|
||||
public static final ButtonCategory GAMEPLAY_CATEGORY;
|
||||
public static final ButtonCategory INVENTORY_CATEGORY;
|
||||
public static final ButtonCategory MULTIPLAYER_CATEGORY;
|
||||
public static final ButtonCategory MISC_CATEGORY;
|
||||
|
||||
public static final ButtonBinding ATTACK = register_binding(new ButtonBinding("attack", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)}, false));
|
||||
public static final ButtonBinding BACK = register_binding(new ButtonBinding("back", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, false)}, false));
|
||||
public static final ButtonBinding CHAT = register_binding(new ButtonBinding("chat", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT}, true));
|
||||
public static final ButtonBinding DROP_ITEM = register_binding(new ButtonBinding("drop_item", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, true));
|
||||
public static final ButtonBinding FORWARD = register_binding(new ButtonBinding("forward", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, true)}, false));
|
||||
public static final ButtonBinding HOTBAR_LEFT = register_binding(new ButtonBinding("hotbar_left", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER},
|
||||
Collections.singletonList(InputHandlers.handle_hotbar(false)), true));
|
||||
public static final ButtonBinding HOTBAR_RIGHT = register_binding(new ButtonBinding("hotbar_right", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER},
|
||||
Collections.singletonList(InputHandlers.handle_hotbar(true)), true));
|
||||
public static final ButtonBinding INVENTORY = register_binding(new ButtonBinding("inventory", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, true));
|
||||
public static final ButtonBinding JUMP = register_binding(new ButtonBinding("jump", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, false));
|
||||
public static final ButtonBinding LEFT = register_binding(new ButtonBinding("left", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, false)}, false));
|
||||
public static final ButtonBinding PAUSE_GAME = register_binding(new ButtonBinding("pause_game", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_START},
|
||||
Collections.singletonList(InputHandlers::handle_pause_game), true));
|
||||
public static final ButtonBinding PICK_BLOCK = register_binding(new ButtonBinding("pick_block", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT}, true));
|
||||
public static final ButtonBinding PLAYER_LIST = register_binding(new ButtonBinding("player_list", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_BACK}, false));
|
||||
public static final ButtonBinding RIGHT = register_binding(new ButtonBinding("right", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, true)}, false));
|
||||
public static final ButtonBinding SCREENSHOT = register_binding(new ButtonBinding("screenshot", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_A},
|
||||
Collections.singletonList((client, button, action) -> {
|
||||
if (action == ButtonState.PRESS)
|
||||
ScreenshotUtils.saveScreenshot(client.runDirectory, client.getWindow().getFramebufferWidth(), client.getWindow().getFramebufferHeight(), client.getFramebuffer(),
|
||||
text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)));
|
||||
return true;
|
||||
}), true));
|
||||
public static final ButtonBinding SMOOTH_CAMERA = register_binding(new ButtonBinding("toggle_smooth_camera", new int[]{-1}, true));
|
||||
public static final ButtonBinding SNEAK = register_binding(new ButtonBinding("sneak", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB},
|
||||
Arrays.asList(PressAction.DEFAULT_ACTION, (client, button, action) -> {
|
||||
if (client.player != null && !client.player.abilities.flying) {
|
||||
button.as_key_binding().filter(binding -> action == ButtonState.PRESS).ifPresent(binding -> ((KeyBindingAccessor) binding).handle_press_state(!binding.isPressed()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}), true));
|
||||
public static final ButtonBinding SPRINT = register_binding(new ButtonBinding("sprint", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB}, false));
|
||||
public static final ButtonBinding SWAP_HANDS = register_binding(new ButtonBinding("swap_hands", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, true));
|
||||
public static final ButtonBinding TOGGLE_PERSPECTIVE = register_binding(new ButtonBinding("toggle_perspective", new int[]{GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW.GLFW_GAMEPAD_BUTTON_Y}, true));
|
||||
public static final ButtonBinding USE = register_binding(new ButtonBinding("use", new int[]{axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)}, false));
|
||||
|
||||
private int[] button;
|
||||
private int[] default_button;
|
||||
private String key;
|
||||
private KeyBinding minecraft_key_binding = null;
|
||||
private List<PressAction> actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION));
|
||||
private boolean has_cooldown;
|
||||
private int cooldown = 0;
|
||||
boolean pressed = false;
|
||||
|
||||
public ButtonBinding(@NotNull String key, int[] default_button, @NotNull List<PressAction> actions, boolean has_cooldown)
|
||||
{
|
||||
this.button = this.default_button = default_button;
|
||||
this.key = key;
|
||||
this.actions.addAll(actions);
|
||||
this.has_cooldown = has_cooldown;
|
||||
}
|
||||
|
||||
public ButtonBinding(@NotNull String key, int[] default_button, boolean has_cooldown)
|
||||
{
|
||||
this(key, default_button, Collections.emptyList(), has_cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the button bound.
|
||||
*
|
||||
* @return The bound button.
|
||||
*/
|
||||
public int[] get_button()
|
||||
{
|
||||
return this.button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bound button.
|
||||
*
|
||||
* @param button The bound button.
|
||||
*/
|
||||
public void set_button(int[] button)
|
||||
{
|
||||
this.button = button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the bound button is the specified button or not.
|
||||
*
|
||||
* @param button The button to check.
|
||||
* @return True if the bound button is the specified button, else false.
|
||||
*/
|
||||
public boolean is_button(int[] button)
|
||||
{
|
||||
return InputManager.are_buttons_equivalent(button, this.button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this button is down or not.
|
||||
*
|
||||
* @return True if the button is down, else false.
|
||||
*/
|
||||
public boolean is_button_down()
|
||||
{
|
||||
return this.pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this button binding is bound or not.
|
||||
*
|
||||
* @return True if this button binding is bound, else false.
|
||||
*/
|
||||
public boolean is_not_bound()
|
||||
{
|
||||
return this.button[0] == -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default button assigned to this binding.
|
||||
*
|
||||
* @return The default button.
|
||||
*/
|
||||
public int[] get_default_button()
|
||||
{
|
||||
return this.default_button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the assigned button is the default button.
|
||||
*
|
||||
* @return True if the assigned button is the default button, else false.
|
||||
*/
|
||||
public boolean is_default()
|
||||
{
|
||||
return this.button.length == this.default_button.length && InputManager.are_buttons_equivalent(this.button, this.default_button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the button code.
|
||||
*
|
||||
* @return The button code.
|
||||
*/
|
||||
public @NotNull String get_button_code()
|
||||
{
|
||||
return Arrays.stream(this.button)
|
||||
.mapToObj(btn -> Integer.valueOf(btn).toString())
|
||||
.collect(Collectors.joining("+"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key binding to emulate with this button binding.
|
||||
*
|
||||
* @param key_binding The optional key binding.
|
||||
*/
|
||||
public void set_key_binding(@Nullable KeyBinding key_binding)
|
||||
{
|
||||
this.minecraft_key_binding = key_binding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the button binding cooldown.
|
||||
*/
|
||||
public void update()
|
||||
{
|
||||
if (this.has_cooldown && this.cooldown > 0)
|
||||
this.cooldown--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the button binding.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param state The state.
|
||||
*/
|
||||
public void handle(@NotNull MinecraftClient client, @NotNull ButtonState state)
|
||||
{
|
||||
if (state == ButtonState.REPEAT && this.has_cooldown && this.cooldown != 0)
|
||||
return;
|
||||
if (this.has_cooldown && state.is_pressed())
|
||||
this.cooldown = 5;
|
||||
for (int i = this.actions.size() - 1; i >= 0; i--) {
|
||||
if (this.actions.get(i).press(client, this, state))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String get_name()
|
||||
{
|
||||
return this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation key of this button binding.
|
||||
*
|
||||
* @return The translation key.
|
||||
*/
|
||||
public @NotNull String get_translation_key()
|
||||
{
|
||||
return "lambdacontrols.action." + this.get_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key binding equivalent of this button binding.
|
||||
*
|
||||
* @return The key binding equivalent.
|
||||
*/
|
||||
public @NotNull Optional<KeyBinding> as_key_binding()
|
||||
{
|
||||
return Optional.ofNullable(this.minecraft_key_binding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified axis as a button.
|
||||
*
|
||||
* @param axis The axis.
|
||||
* @param positive True if the axis part is positive, else false.
|
||||
* @return The axis as a button.
|
||||
*/
|
||||
public static int axis_as_button(int axis, boolean positive)
|
||||
{
|
||||
return positive ? 100 + axis : 200 + axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the second Joycon's specified button code.
|
||||
*
|
||||
* @param button The raw button code.
|
||||
* @return The second Joycon's button code.
|
||||
*/
|
||||
public static int controller2_button(int button)
|
||||
{
|
||||
return 500 + button;
|
||||
}
|
||||
|
||||
public static void init(@NotNull GameOptions options)
|
||||
{
|
||||
ATTACK.minecraft_key_binding = options.keyAttack;
|
||||
BACK.minecraft_key_binding = options.keyBack;
|
||||
CHAT.minecraft_key_binding = options.keyChat;
|
||||
DROP_ITEM.minecraft_key_binding = options.keyDrop;
|
||||
FORWARD.minecraft_key_binding = options.keyForward;
|
||||
INVENTORY.minecraft_key_binding = options.keyInventory;
|
||||
JUMP.minecraft_key_binding = options.keyJump;
|
||||
LEFT.minecraft_key_binding = options.keyLeft;
|
||||
PICK_BLOCK.minecraft_key_binding = options.keyPickItem;
|
||||
PLAYER_LIST.minecraft_key_binding = options.keyPlayerList;
|
||||
RIGHT.minecraft_key_binding = options.keyRight;
|
||||
SCREENSHOT.minecraft_key_binding = options.keyScreenshot;
|
||||
SMOOTH_CAMERA.minecraft_key_binding = options.keySmoothCamera;
|
||||
SNEAK.minecraft_key_binding = options.keySneak;
|
||||
SPRINT.minecraft_key_binding = options.keySprint;
|
||||
SWAP_HANDS.minecraft_key_binding = options.keySwapHands;
|
||||
TOGGLE_PERSPECTIVE.minecraft_key_binding = options.keyTogglePerspective;
|
||||
USE.minecraft_key_binding = options.keyUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized name of the specified button.
|
||||
*
|
||||
* @param button The button.
|
||||
* @return The localized name of the button.
|
||||
*/
|
||||
public static @NotNull String get_localized_button_name(int button)
|
||||
{
|
||||
switch (button % 500) {
|
||||
case -1:
|
||||
return I18n.translate("key.keyboard.unknown");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_A:
|
||||
return I18n.translate("lambdacontrols.button.a");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_B:
|
||||
return I18n.translate("lambdacontrols.button.b");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_X:
|
||||
return I18n.translate("lambdacontrols.button.x");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_Y:
|
||||
return I18n.translate("lambdacontrols.button.y");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
|
||||
return I18n.translate("lambdacontrols.button.left_bumper");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
|
||||
return I18n.translate("lambdacontrols.button.right_bumper");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_BACK:
|
||||
return I18n.translate("lambdacontrols.button.back");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_START:
|
||||
return I18n.translate("lambdacontrols.button.start");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE:
|
||||
return I18n.translate("lambdacontrols.button.guide");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
|
||||
return I18n.translate("lambdacontrols.button.left_thumb");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
|
||||
return I18n.translate("lambdacontrols.button.right_thumb");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP:
|
||||
return I18n.translate("lambdacontrols.button.dpad_up");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
|
||||
return I18n.translate("lambdacontrols.button.dpad_right");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
|
||||
return I18n.translate("lambdacontrols.button.dpad_down");
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
|
||||
return I18n.translate("lambdacontrols.button.dpad_left");
|
||||
case 100:
|
||||
return I18n.translate("lambdacontrols.axis.left_x+");
|
||||
case 101:
|
||||
return I18n.translate("lambdacontrols.axis.left_y+");
|
||||
case 102:
|
||||
return I18n.translate("lambdacontrols.axis.right_x+");
|
||||
case 103:
|
||||
return I18n.translate("lambdacontrols.axis.right_y+");
|
||||
case 104:
|
||||
return I18n.translate("lambdacontrols.axis.left_trigger");
|
||||
case 105:
|
||||
return I18n.translate("lambdacontrols.axis.right_trigger");
|
||||
case 200:
|
||||
return I18n.translate("lambdacontrols.axis.left_x-");
|
||||
case 201:
|
||||
return I18n.translate("lambdacontrols.axis.left_y-");
|
||||
case 202:
|
||||
return I18n.translate("lambdacontrols.axis.right_x-");
|
||||
case 203:
|
||||
return I18n.translate("lambdacontrols.axis.right_y-");
|
||||
default:
|
||||
return I18n.translate("lambdacontrols.button.unknown", button);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
MOVEMENT_CATEGORY = register_default_category("key.categories.movement", category -> category.register_all_bindings(
|
||||
ButtonBinding.FORWARD,
|
||||
ButtonBinding.BACK,
|
||||
ButtonBinding.LEFT,
|
||||
ButtonBinding.RIGHT,
|
||||
ButtonBinding.JUMP,
|
||||
ButtonBinding.SNEAK,
|
||||
ButtonBinding.SPRINT));
|
||||
GAMEPLAY_CATEGORY = register_default_category("key.categories.gameplay", category -> category.register_all_bindings(
|
||||
ButtonBinding.ATTACK,
|
||||
ButtonBinding.PICK_BLOCK,
|
||||
ButtonBinding.USE
|
||||
));
|
||||
INVENTORY_CATEGORY = register_default_category("key.categories.inventory", category -> category.register_all_bindings(
|
||||
ButtonBinding.DROP_ITEM,
|
||||
ButtonBinding.HOTBAR_LEFT,
|
||||
ButtonBinding.HOTBAR_RIGHT,
|
||||
ButtonBinding.INVENTORY,
|
||||
ButtonBinding.SWAP_HANDS
|
||||
));
|
||||
MULTIPLAYER_CATEGORY = register_default_category("key.categories.multiplayer",
|
||||
category -> category.register_all_bindings(ButtonBinding.CHAT, ButtonBinding.PLAYER_LIST));
|
||||
MISC_CATEGORY = register_default_category("key.categories.misc", category -> category.register_all_bindings(
|
||||
ButtonBinding.SCREENSHOT,
|
||||
//SMOOTH_CAMERA,
|
||||
ButtonBinding.TOGGLE_PERSPECTIVE
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.controller;
|
||||
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import org.aperlambda.lambdacommon.Identifier;
|
||||
import org.aperlambda.lambdacommon.utils.Identifiable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a button binding category
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class ButtonCategory implements Identifiable
|
||||
{
|
||||
private final List<ButtonBinding> bindings = new ArrayList<>();
|
||||
private final Identifier id;
|
||||
private int priority;
|
||||
|
||||
public ButtonCategory(@NotNull Identifier id, int priority)
|
||||
{
|
||||
this.id = id;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public ButtonCategory(@NotNull Identifier id)
|
||||
{
|
||||
this(id, 100);
|
||||
}
|
||||
|
||||
public void register_binding(@NotNull ButtonBinding binding)
|
||||
{
|
||||
if (this.bindings.contains(binding))
|
||||
throw new IllegalStateException("Cannot register twice a button binding in the same category.");
|
||||
this.bindings.add(binding);
|
||||
}
|
||||
|
||||
public void register_all_bindings(@NotNull ButtonBinding... bindings)
|
||||
{
|
||||
this.register_all_bindings(Arrays.asList(bindings));
|
||||
}
|
||||
|
||||
public void register_all_bindings(@NotNull List<ButtonBinding> bindings)
|
||||
{
|
||||
bindings.forEach(this::register_binding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bindings assigned to this category.
|
||||
*
|
||||
* @return The bindings assigned to this category.
|
||||
*/
|
||||
public @NotNull List<ButtonBinding> get_bindings()
|
||||
{
|
||||
return Collections.unmodifiableList(this.bindings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translated name of this category.
|
||||
* <p>
|
||||
* The translation key should be `modid.identifier_name`.
|
||||
*
|
||||
* @return The translated name.
|
||||
*/
|
||||
public @NotNull String get_translated_name()
|
||||
{
|
||||
if (this.id.get_namespace().equals("minecraft"))
|
||||
return I18n.translate(this.id.get_name());
|
||||
else
|
||||
return I18n.translate(this.id.get_namespace() + "." + this.id.get_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the priority display of this category.
|
||||
* It will defines in which order the categories will display on the controls screen.
|
||||
*
|
||||
* @return The priority of this category.
|
||||
*/
|
||||
public int get_priority()
|
||||
{
|
||||
return this.priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Identifier get_identifier()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -7,8 +7,9 @@
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package me.lambdaurora.lambdacontrols;
|
||||
package me.lambdaurora.lambdacontrols.controller;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import org.aperlambda.lambdacommon.utils.Nameable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
@@ -31,6 +32,10 @@ import static org.lwjgl.BufferUtils.createByteBuffer;
|
||||
|
||||
/**
|
||||
* Represents a controller.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Controller implements Nameable
|
||||
{
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.controller;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonState;
|
||||
import me.lambdaurora.lambdacontrols.util.CreativeInventoryScreenAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents some input handlers.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class InputHandlers
|
||||
{
|
||||
private InputHandlers() {}
|
||||
|
||||
public static PressAction handle_hotbar(boolean right) {
|
||||
return (client, button, action) -> {
|
||||
if (action == ButtonState.RELEASE)
|
||||
return false;
|
||||
|
||||
// When ingame
|
||||
if (client.currentScreen == null && client.player != null) {
|
||||
if (right)
|
||||
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;
|
||||
return true;
|
||||
} else if (client.currentScreen instanceof CreativeInventoryScreen) {
|
||||
CreativeInventoryScreenAccessor creative_inventory = (CreativeInventoryScreenAccessor) client.currentScreen;
|
||||
int current_selected_tab = creative_inventory.get_selected_tab();
|
||||
int next_tab = current_selected_tab + (right ? 1 : -1);
|
||||
if (next_tab < 0)
|
||||
next_tab = ItemGroup.GROUPS.length - 1;
|
||||
else if (next_tab >= ItemGroup.GROUPS.length)
|
||||
next_tab = 0;
|
||||
creative_inventory.set_selected_tab(ItemGroup.GROUPS[next_tab]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean handle_pause_game(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, @NotNull ButtonState action) {
|
||||
if (action == ButtonState.PRESS) {
|
||||
// If in game, then pause the game.
|
||||
if (client.currentScreen == null)
|
||||
client.openPauseMenu(false);
|
||||
else if (client.currentScreen instanceof AbstractContainerScreen && client.player != null) // If the current screen is a container then close it.
|
||||
client.player.closeContainer();
|
||||
else // Else just close the current screen.
|
||||
client.currentScreen.onClose();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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.controller;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonState;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControlsConfig;
|
||||
import org.aperlambda.lambdacommon.Identifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Represents an input manager for controllers.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class InputManager
|
||||
{
|
||||
private static final List<ButtonBinding> BINDINGS = new ArrayList<>();
|
||||
private static final List<ButtonCategory> CATEGORIES = new ArrayList<>();
|
||||
public static final Map<Integer, ButtonState> STATES = new HashMap<>();
|
||||
|
||||
public static @NotNull ButtonBinding register_binding(@NotNull ButtonBinding binding)
|
||||
{
|
||||
if (BINDINGS.contains(binding))
|
||||
throw new IllegalStateException("Cannot register twice a button binding in the registry.");
|
||||
BINDINGS.add(binding);
|
||||
return binding;
|
||||
}
|
||||
|
||||
public static ButtonBinding register_binding(@NotNull Identifier binding_id, int[] default_button, @NotNull List<PressAction> actions, boolean has_cooldown)
|
||||
{
|
||||
return register_binding(new ButtonBinding(binding_id.get_namespace() + "." + binding_id.get_name(), default_button, actions, has_cooldown));
|
||||
}
|
||||
|
||||
public static ButtonBinding register_binding(@NotNull Identifier binding_id, int[] default_button, boolean has_cooldown)
|
||||
{
|
||||
return register_binding(binding_id, default_button, Collections.emptyList(), has_cooldown);
|
||||
}
|
||||
|
||||
public static ButtonBinding register_binding(@NotNull net.minecraft.util.Identifier binding_id, int[] default_button, @NotNull List<PressAction> actions, boolean has_cooldown)
|
||||
{
|
||||
return register_binding(new Identifier(binding_id.getNamespace(), binding_id.getPath()), default_button, actions, has_cooldown);
|
||||
}
|
||||
|
||||
public static ButtonBinding register_binding(@NotNull net.minecraft.util.Identifier binding_id, int[] default_button, boolean has_cooldown)
|
||||
{
|
||||
return register_binding(binding_id, default_button, Collections.emptyList(), has_cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a category of button bindings.
|
||||
*
|
||||
* @param category The category to register.
|
||||
* @return The registered category.
|
||||
*/
|
||||
public static ButtonCategory register_category(@NotNull ButtonCategory category)
|
||||
{
|
||||
CATEGORIES.add(category);
|
||||
return category;
|
||||
}
|
||||
|
||||
public static ButtonCategory register_category(@NotNull Identifier identifier, int priority)
|
||||
{
|
||||
return register_category(new ButtonCategory(identifier, priority));
|
||||
}
|
||||
|
||||
public static ButtonCategory register_category(@NotNull Identifier identifier)
|
||||
{
|
||||
return register_category(new ButtonCategory(identifier));
|
||||
}
|
||||
|
||||
protected static ButtonCategory register_default_category(@NotNull String key, @NotNull Consumer<ButtonCategory> key_adder)
|
||||
{
|
||||
ButtonCategory category = register_category(new Identifier("minecraft", key), CATEGORIES.size());
|
||||
key_adder.accept(category);
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the button bindings from configuration.
|
||||
*
|
||||
* @param config The configuration instance.
|
||||
*/
|
||||
public static void load_button_bindings(@NotNull LambdaControlsConfig config)
|
||||
{
|
||||
BINDINGS.forEach(config::load_button_binding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the binding state.
|
||||
*
|
||||
* @param binding The binding.
|
||||
* @return The current state of the binding.
|
||||
*/
|
||||
public static @NotNull ButtonState get_binding_state(@NotNull ButtonBinding binding)
|
||||
{
|
||||
ButtonState state = ButtonState.REPEAT;
|
||||
for (int btn : binding.get_button()) {
|
||||
ButtonState btn_state = InputManager.STATES.getOrDefault(btn, ButtonState.NONE);
|
||||
if (btn_state == ButtonState.PRESS)
|
||||
state = ButtonState.PRESS;
|
||||
else if (btn_state == ButtonState.RELEASE) {
|
||||
state = ButtonState.RELEASE;
|
||||
break;
|
||||
} else if (btn_state == ButtonState.NONE) {
|
||||
state = ButtonState.NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the button has duplicated bindings.
|
||||
*
|
||||
* @param button The button to check.
|
||||
* @return True if the button has duplicated bindings, else false.
|
||||
*/
|
||||
public static boolean has_duplicated_bindings(int[] button)
|
||||
{
|
||||
return BINDINGS.parallelStream().filter(binding -> are_buttons_equivalent(binding.get_button(), button)).count() > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the specified buttons are equivalent or not.
|
||||
*
|
||||
* @param buttons1 First set of buttons.
|
||||
* @param buttons2 Second set of buttons.
|
||||
* @return True if the two sets of buttons are equivalent, else false.
|
||||
*/
|
||||
public static boolean are_buttons_equivalent(int[] buttons1, int[] buttons2)
|
||||
{
|
||||
if (buttons1.length != buttons2.length)
|
||||
return false;
|
||||
int count = 0;
|
||||
for (int btn : buttons1) {
|
||||
for (int btn2 : buttons2) {
|
||||
if (btn == btn2) {
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count == buttons1.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the button states.
|
||||
*/
|
||||
public static void update_states()
|
||||
{
|
||||
STATES.forEach((btn, state) -> {
|
||||
if (state == ButtonState.PRESS)
|
||||
STATES.put(btn, ButtonState.REPEAT);
|
||||
else if (state == ButtonState.RELEASE)
|
||||
STATES.put(btn, ButtonState.NONE);
|
||||
});
|
||||
}
|
||||
|
||||
public static void update_bindings() {
|
||||
BINDINGS.forEach(binding -> binding.pressed = get_binding_state(binding).is_pressed());
|
||||
BINDINGS.forEach(ButtonBinding::update);
|
||||
}
|
||||
|
||||
public static @NotNull Stream<ButtonBinding> stream_bindings()
|
||||
{
|
||||
return BINDINGS.stream();
|
||||
}
|
||||
|
||||
public static @NotNull Stream<ButtonBinding> stream_active_bindings()
|
||||
{
|
||||
return BINDINGS.stream().filter(binding -> {
|
||||
for (int btn : binding.get_button()) {
|
||||
if (InputManager.STATES.getOrDefault(btn, ButtonState.NONE) == ButtonState.NONE)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public static @NotNull Stream<ButtonCategory> stream_categories()
|
||||
{
|
||||
return CATEGORIES.stream();
|
||||
}
|
||||
}
|
||||
@@ -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.controller;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonState;
|
||||
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a press action callback.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface PressAction
|
||||
{
|
||||
PressAction DEFAULT_ACTION = (client, button, action) -> {
|
||||
if (action == ButtonState.REPEAT || client.currentScreen != null)
|
||||
return false;
|
||||
button.as_key_binding().ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(button.is_button_down()));
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles when there is a press action.
|
||||
*
|
||||
* @param client The client instance.
|
||||
* @param action The action done.
|
||||
*/
|
||||
boolean press(@NotNull MinecraftClient client, @NotNull ButtonBinding button, @NotNull ButtonState action);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 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.gui;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a button with an icon instead of text.
|
||||
*/
|
||||
public abstract class AbstractIconButtonWidget extends ButtonWidget
|
||||
{
|
||||
private int icon_size = 0;
|
||||
|
||||
public AbstractIconButtonWidget(int x, int y, int width, int height, @NotNull String message, @NotNull PressAction on_press)
|
||||
{
|
||||
super(x, y, width, height, message, on_press);
|
||||
}
|
||||
|
||||
protected abstract int render_icon(int mouse_x, int mouse_y, float delta, int x, int y);
|
||||
|
||||
@Override
|
||||
public void renderButton(int mouse_x, int mouse_y, float delta)
|
||||
{
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
client.getTextureManager().bindTexture(WIDGETS_LOCATION);
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
int i = this.getYImage(this.isHovered());
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
|
||||
this.blit(this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
|
||||
this.blit(this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
|
||||
this.renderBg(client, mouse_x, mouse_y);
|
||||
|
||||
this.icon_size = this.render_icon(mouse_x, mouse_y, delta, this.x + 4, this.y + (this.height / 2 - this.icon_size / 2));
|
||||
|
||||
if (!this.getMessage().isEmpty()) {
|
||||
int j = this.active ? 16777215 : 10526880;
|
||||
this.drawCenteredString(client.textRenderer, this.getMessage(), this.x + 8 + this.icon_size + (this.width - 8 - this.icon_size - 6) / 2,
|
||||
this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,8 +9,9 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.gui;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import me.lambdaurora.spruceui.AbstractIconButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -23,18 +24,18 @@ public class ControllerButtonWidget extends AbstractIconButtonWidget
|
||||
|
||||
public ControllerButtonWidget(int x, int y, int width, @NotNull ButtonBinding button_binding, @NotNull PressAction on_press)
|
||||
{
|
||||
super(x, y, width, 20, ButtonBinding.get_localized_button_name(button_binding.get_button()), on_press);
|
||||
super(x, y, width, 20, ButtonBinding.get_localized_button_name(button_binding.get_button()[0]), on_press);
|
||||
this.binding = button_binding;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
this.setMessage(ButtonBinding.get_localized_button_name(binding.get_button()));
|
||||
this.setMessage(ButtonBinding.get_localized_button_name(binding.get_button()[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int render_icon(int mouse_x, int mouse_y, float delta, int x, int y)
|
||||
{
|
||||
return LambdaControls.draw_button(x, y, this.binding, MinecraftClient.getInstance());
|
||||
return LambdaControls.draw_button(x, y, this.binding, MinecraftClient.getInstance()).get_value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.gui;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonCategory;
|
||||
import me.lambdaurora.lambdacontrols.controller.InputManager;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -39,8 +41,8 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
|
||||
super(client, gui.width + 45, gui.height, 43, gui.height - 32, 24);
|
||||
this.gui = gui;
|
||||
|
||||
ButtonBinding.stream_categories()
|
||||
.sorted(Comparator.comparingInt(ButtonBinding.Category::get_priority))
|
||||
InputManager.stream_categories()
|
||||
.sorted(Comparator.comparingInt(ButtonCategory::get_priority))
|
||||
.forEach(category -> {
|
||||
this.addEntry(new CategoryEntry(category));
|
||||
|
||||
@@ -78,7 +80,7 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
|
||||
{
|
||||
this.binding = binding;
|
||||
this.binding_name = I18n.translate(this.binding.get_translation_key());
|
||||
this.edit_button = new ControllerButtonWidget(0, 0, 90, this.binding, btn -> gui.focused_binding = binding)
|
||||
this.edit_button = new ControllerButtonWidget(0, 0, 110, this.binding, btn -> gui.focused_binding = binding)
|
||||
{
|
||||
protected String getNarrationMessage()
|
||||
{
|
||||
@@ -114,16 +116,16 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
|
||||
this.reset_button.y = y;
|
||||
this.reset_button.active = !this.binding.is_default();
|
||||
this.reset_button.render(mouse_x, mouse_y, delta);
|
||||
this.edit_button.x = x + 85;
|
||||
this.edit_button.x = x + 75;
|
||||
this.edit_button.y = y;
|
||||
this.edit_button.update();
|
||||
|
||||
if (focused) {
|
||||
this.edit_button.setMessage(Formatting.WHITE + "> " + Formatting.YELLOW + this.edit_button.getMessage() + Formatting.WHITE + " <");
|
||||
} else if (!this.binding.is_not_bound() && ButtonBinding.has_duplicates(this.binding.get_button())) {
|
||||
} else if (!this.binding.is_not_bound() && InputManager.has_duplicated_bindings(this.binding.get_button())) {
|
||||
this.edit_button.setMessage(Formatting.RED + this.edit_button.getMessage());
|
||||
} else if (this.binding.is_not_bound()) {
|
||||
this.edit_button.setMessage(Formatting.GOLD + edit_button.getMessage());
|
||||
this.edit_button.setMessage(Formatting.GOLD + this.edit_button.getMessage());
|
||||
}
|
||||
|
||||
this.edit_button.render(mouse_x, mouse_y, delta);
|
||||
@@ -148,7 +150,7 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
|
||||
private final String name;
|
||||
private final int name_width;
|
||||
|
||||
public CategoryEntry(@NotNull ButtonBinding.Category category)
|
||||
public CategoryEntry(@NotNull ButtonCategory category)
|
||||
{
|
||||
this.name = category.get_translated_name();
|
||||
this.name_width = ControlsListWidget.this.minecraft.textRenderer.getStringWidth(this.name);
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 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.gui;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Drawable;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.Matrix4f;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Represents a label widget.
|
||||
*/
|
||||
// @TODO move this to a GUI library.
|
||||
public class LabelWidget extends DrawableHelper implements Element, Drawable
|
||||
{
|
||||
public static final Consumer<LabelWidget> DEFAULT_ACTION = label -> {
|
||||
};
|
||||
|
||||
private final MinecraftClient client = MinecraftClient.getInstance();
|
||||
private final Consumer<LabelWidget> press_action;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int max_width;
|
||||
//private final int max_height;
|
||||
private String text;
|
||||
private String tooltip_text;
|
||||
public boolean visible;
|
||||
private int width;
|
||||
private int height;
|
||||
private boolean centered;
|
||||
protected boolean hovered;
|
||||
protected boolean focused;
|
||||
|
||||
public LabelWidget(int x, int y, @NotNull String text, int max_width, @NotNull Consumer<LabelWidget> press_action, boolean centered)
|
||||
{
|
||||
this.visible = true;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.max_width = max_width;
|
||||
this.press_action = press_action;
|
||||
this.centered = centered;
|
||||
this.set_text(text);
|
||||
}
|
||||
|
||||
public LabelWidget(int x, int y, @NotNull String text, int max_width, @NotNull Consumer<LabelWidget> press_action)
|
||||
{
|
||||
this(x, y, text, max_width, press_action, false);
|
||||
}
|
||||
|
||||
public LabelWidget(int x, int y, @NotNull String text, int max_width, boolean centered)
|
||||
{
|
||||
this(x, y, text, max_width, DEFAULT_ACTION, centered);
|
||||
}
|
||||
|
||||
public LabelWidget(int x, int y, @NotNull String text, int max_width)
|
||||
{
|
||||
this(x, y, text, max_width, DEFAULT_ACTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text of this label.
|
||||
*
|
||||
* @param text The text to set.
|
||||
*/
|
||||
public void set_text(@NotNull String text)
|
||||
{
|
||||
int width = this.client.textRenderer.getStringWidth(text);
|
||||
while (width > this.max_width) {
|
||||
text = text.substring(0, text.length() - 1);
|
||||
width = this.client.textRenderer.getStringWidth(text);
|
||||
}
|
||||
|
||||
this.text = text;
|
||||
this.width = width;
|
||||
this.height = this.client.textRenderer.fontHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tooltip text of this label.
|
||||
*
|
||||
* @param text The tooltip text.
|
||||
*/
|
||||
public void set_tooltip_text(String text)
|
||||
{
|
||||
this.tooltip_text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of this label widget.
|
||||
*
|
||||
* @return The width of this label widget.
|
||||
*/
|
||||
public int get_width()
|
||||
{
|
||||
return this.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of this label widget.
|
||||
*
|
||||
* @return The height of this label widget.
|
||||
*/
|
||||
public int get_height()
|
||||
{
|
||||
return this.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires the press event on this label widget.
|
||||
*/
|
||||
public void on_press()
|
||||
{
|
||||
this.press_action.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(int mouse_x, int mouse_y, float delta)
|
||||
{
|
||||
if (this.visible) {
|
||||
int x = this.centered ? this.x - this.client.textRenderer.getStringWidth(this.text) / 2 : this.x;
|
||||
this.hovered = mouse_x >= x && mouse_y >= this.y && mouse_x < x + this.width && mouse_y < this.y + this.height;
|
||||
this.drawString(this.client.textRenderer, this.text, x, this.y, 10526880);
|
||||
|
||||
if (this.tooltip_text != null && !this.tooltip_text.isEmpty()) {
|
||||
List<String> wrapped_tooltip_text = this.client.textRenderer.wrapStringToWidthAsList(this.tooltip_text, Math.max(this.width / 2, 200));
|
||||
if (this.hovered)
|
||||
this.render_tooltip(wrapped_tooltip_text, mouse_x, mouse_y);
|
||||
else if (this.focused)
|
||||
this.render_tooltip(wrapped_tooltip_text, this.x - 12, this.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouse_x, double mouse_y, int button)
|
||||
{
|
||||
if (this.visible && button == GLFW.GLFW_MOUSE_BUTTON_1) {
|
||||
if (this.hovered) {
|
||||
this.on_press();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeFocus(boolean down)
|
||||
{
|
||||
if (this.visible) {
|
||||
this.focused = !this.focused;
|
||||
return this.focused;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void render_tooltip(List<String> text, int x, int y)
|
||||
{
|
||||
if (!text.isEmpty()) {
|
||||
RenderSystem.disableRescaleNormal();
|
||||
RenderSystem.disableDepthTest();
|
||||
int i = 0;
|
||||
|
||||
for (String string : text) {
|
||||
int j = this.client.textRenderer.getStringWidth(string);
|
||||
if (j > i) {
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
int k = x + 12;
|
||||
int l = y - 12;
|
||||
int n = 8;
|
||||
if (text.size() > 1) {
|
||||
n += 2 + (text.size() - 1) * 10;
|
||||
}
|
||||
|
||||
if (k + i > this.client.getWindow().getScaledWidth()) {
|
||||
k -= 28 + i;
|
||||
}
|
||||
|
||||
if (l + n + 6 > this.client.getWindow().getScaledHeight()) {
|
||||
l = this.client.getWindow().getScaledHeight() - n - 6;
|
||||
}
|
||||
|
||||
this.setBlitOffset(300);
|
||||
this.client.getItemRenderer().zOffset = 300.0F;
|
||||
this.fillGradient(k - 3, l - 4, k + i + 3, l - 3, -267386864, -267386864);
|
||||
this.fillGradient(k - 3, l + n + 3, k + i + 3, l + n + 4, -267386864, -267386864);
|
||||
this.fillGradient(k - 3, l - 3, k + i + 3, l + n + 3, -267386864, -267386864);
|
||||
this.fillGradient(k - 4, l - 3, k - 3, l + n + 3, -267386864, -267386864);
|
||||
this.fillGradient(k + i + 3, l - 3, k + i + 4, l + n + 3, -267386864, -267386864);
|
||||
this.fillGradient(k - 3, l - 3 + 1, k - 3 + 1, l + n + 3 - 1, 1347420415, 1344798847);
|
||||
this.fillGradient(k + i + 2, l - 3 + 1, k + i + 3, l + n + 3 - 1, 1347420415, 1344798847);
|
||||
this.fillGradient(k - 3, l - 3, k + i + 3, l - 3 + 1, 1347420415, 1347420415);
|
||||
this.fillGradient(k - 3, l + n + 2, k + i + 3, l + n + 3, 1344798847, 1344798847);
|
||||
MatrixStack matrix_stack = new MatrixStack();
|
||||
VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
|
||||
matrix_stack.translate(0.0D, 0.0D, this.client.getItemRenderer().zOffset);
|
||||
Matrix4f matrix4f = matrix_stack.peek().getModel();
|
||||
|
||||
for (int r = 0; r < text.size(); ++r) {
|
||||
String string2 = text.get(r);
|
||||
if (string2 != null) {
|
||||
this.client.textRenderer.draw(string2, (float) k, (float) l, -1, true, matrix4f, immediate, false, 0, 15728880);
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
l += 2;
|
||||
}
|
||||
|
||||
l += 10;
|
||||
}
|
||||
|
||||
immediate.draw();
|
||||
this.setBlitOffset(0);
|
||||
this.client.getItemRenderer().zOffset = 0.0F;
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.enableRescaleNormal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,9 +9,12 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.gui;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import me.lambdaurora.lambdacontrols.controller.InputManager;
|
||||
import me.lambdaurora.spruceui.SpruceButtonWidget;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.options.BooleanOption;
|
||||
import net.minecraft.client.options.Option;
|
||||
@@ -27,19 +30,21 @@ import java.util.function.Predicate;
|
||||
*/
|
||||
public class LambdaControlsControlsScreen extends Screen
|
||||
{
|
||||
private final LambdaControlsSettingsScreen parent;
|
||||
final LambdaControls mod;
|
||||
private final Option inverts_right_x_axis;
|
||||
private final Option inverts_right_y_axis;
|
||||
private ControlsListWidget bindings_list_widget;
|
||||
private ButtonWidget reset_button;
|
||||
public ButtonBinding focused_binding;
|
||||
private final Screen parent;
|
||||
final LambdaControls mod;
|
||||
private final Option inverts_right_x_axis;
|
||||
private final Option inverts_right_y_axis;
|
||||
private final boolean hide_settings;
|
||||
private ControlsListWidget bindings_list_widget;
|
||||
private ButtonWidget reset_button;
|
||||
public ButtonBinding focused_binding;
|
||||
|
||||
protected LambdaControlsControlsScreen(@NotNull LambdaControlsSettingsScreen parent)
|
||||
public LambdaControlsControlsScreen(@NotNull Screen parent, boolean hide_settings)
|
||||
{
|
||||
super(new TranslatableText("lambdacontrols.menu.title.controller_controls"));
|
||||
this.parent = parent;
|
||||
this.mod = parent.mod;
|
||||
this.mod = LambdaControls.get();
|
||||
this.hide_settings = hide_settings;
|
||||
this.inverts_right_x_axis = new BooleanOption("lambdacontrols.menu.invert_right_x_axis", game_options -> this.mod.config.does_invert_right_x_axis(),
|
||||
(game_options, new_value) -> {
|
||||
synchronized (this.mod.config) {
|
||||
@@ -64,12 +69,17 @@ public class LambdaControlsControlsScreen extends Screen
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
this.addButton(this.inverts_right_x_axis.createButton(this.minecraft.options, this.width / 2 - 155, 18, 150));
|
||||
this.addButton(this.inverts_right_y_axis.createButton(this.minecraft.options, this.width / 2 - 155 + 160, 18, 150));
|
||||
//this.addButton(this.inverts_right_x_axis.createButton(this.minecraft.options, this.width / 2 - 155, 18, 150));
|
||||
//this.addButton(this.inverts_right_y_axis.createButton(this.minecraft.options, this.width / 2 - 155 + 160, 18, 150));
|
||||
this.addButton(new SpruceButtonWidget(this.width / 2 - 155, 18, this.hide_settings ? 310 : 150, 20, I18n.translate("lambdacontrols.menu.keyboard_controls"),
|
||||
btn -> this.minecraft.openScreen(new ControlsOptionsScreen(this, this.minecraft.options))));
|
||||
if (!this.hide_settings)
|
||||
this.addButton(new SpruceButtonWidget(this.width / 2 - 155 + 160, 18, 150, 20, I18n.translate("menu.options"),
|
||||
btn -> this.minecraft.openScreen(new LambdaControlsSettingsScreen(this, this.minecraft.options, true))));
|
||||
this.bindings_list_widget = new ControlsListWidget(this, this.minecraft);
|
||||
this.children.add(this.bindings_list_widget);
|
||||
this.reset_button = this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 150, 20, I18n.translate("controls.resetAll"),
|
||||
btn -> ButtonBinding.stream().forEach(binding -> this.mod.config.set_button_binding(binding, binding.get_default_button()))));
|
||||
btn -> InputManager.stream_bindings().forEach(binding -> this.mod.config.set_button_binding(binding, binding.get_default_button()))));
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, I18n.translate("gui.done"),
|
||||
btn -> this.minecraft.openScreen(this.parent)));
|
||||
}
|
||||
@@ -87,7 +97,7 @@ public class LambdaControlsControlsScreen extends Screen
|
||||
this.renderBackground();
|
||||
this.bindings_list_widget.render(mouse_x, mouse_y, delta);
|
||||
this.drawCenteredString(this.font, this.title.asFormattedString(), this.width / 2, 8, 16777215);
|
||||
this.reset_button.active = ButtonBinding.stream().anyMatch(this.not(ButtonBinding::is_default));
|
||||
this.reset_button.active = InputManager.stream_bindings().anyMatch(this.not(ButtonBinding::is_default));
|
||||
super.render(mouse_x, mouse_y, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.gui;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.HudSide;
|
||||
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.ControlsMode;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -19,11 +20,17 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents the LambdaControls HUD.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class LambdaControlsHud extends DrawableHelper
|
||||
{
|
||||
private final MinecraftClient client;
|
||||
private final LambdaControls mod;
|
||||
private int width_bottom = 0;
|
||||
private int width_top = 0;
|
||||
|
||||
public LambdaControlsHud(@NotNull MinecraftClient client, @NotNull LambdaControls mod)
|
||||
{
|
||||
@@ -37,12 +44,12 @@ public class LambdaControlsHud extends DrawableHelper
|
||||
public void render()
|
||||
{
|
||||
if (this.mod.config.get_controls_mode() == ControlsMode.CONTROLLER && this.mod.config.is_hud_enabled() && this.client.currentScreen == null && !this.client.options.hudHidden) {
|
||||
int x = 10, y = bottom(10);
|
||||
x += this.draw_button_tip(x, y, ButtonBinding.INVENTORY, true) + 10;
|
||||
this.draw_button_tip(x, y, ButtonBinding.SWAP_HANDS, true);
|
||||
x = 10;
|
||||
x += this.draw_button_tip(x, (y -= 20), ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty()) + 10;
|
||||
this.draw_button_tip(x, y, ButtonBinding.ATTACK.get_button(),
|
||||
int x = this.mod.config.get_hud_side() == HudSide.LEFT ? 10 : client.getWindow().getScaledWidth() - 10 - this.width_bottom, y = bottom(10);
|
||||
x += (this.width_bottom = this.draw_button_tip(x, y, ButtonBinding.INVENTORY, true) + 10);
|
||||
this.width_bottom += this.draw_button_tip(x, y, ButtonBinding.SWAP_HANDS, true);
|
||||
x = this.mod.config.get_hud_side() == HudSide.LEFT ? 10 : client.getWindow().getScaledWidth() - 10 - this.width_top;
|
||||
x += (this.width_top = this.draw_button_tip(x, (y -= 20), ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty()) + 10);
|
||||
this.width_top += this.draw_button_tip(x, y, ButtonBinding.ATTACK.get_button(),
|
||||
this.client.crosshairTarget.getType() == HitResult.Type.BLOCK ? "lambdacontrols.action.hit" : ButtonBinding.ATTACK.get_translation_key(),
|
||||
this.client.crosshairTarget.getType() != HitResult.Type.MISS);
|
||||
}
|
||||
@@ -58,7 +65,7 @@ public class LambdaControlsHud extends DrawableHelper
|
||||
return LambdaControls.draw_button_tip(x, y, button, display, this.client);
|
||||
}
|
||||
|
||||
private int draw_button_tip(int x, int y, int button, @NotNull String action, boolean display)
|
||||
private int draw_button_tip(int x, int y, int[] button, @NotNull String action, boolean display)
|
||||
{
|
||||
return LambdaControls.draw_button_tip(x, y, button, action, display, this.client);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,14 +9,21 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.gui;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.Controller;
|
||||
import me.lambdaurora.lambdacontrols.ControlsMode;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import me.lambdaurora.lambdacontrols.controller.Controller;
|
||||
import me.lambdaurora.spruceui.SpruceButtonWidget;
|
||||
import me.lambdaurora.spruceui.SpruceLabelWidget;
|
||||
import me.lambdaurora.spruceui.Tooltip;
|
||||
import me.lambdaurora.spruceui.option.*;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonListWidget;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.options.*;
|
||||
import net.minecraft.client.options.CyclingOption;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.options.Option;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Formatting;
|
||||
@@ -29,30 +36,32 @@ import org.lwjgl.glfw.GLFW;
|
||||
*/
|
||||
public class LambdaControlsSettingsScreen extends Screen
|
||||
{
|
||||
public static final String GAMEPAD_TOOL_URL = "http://generalarcade.com/gamepadtool/";
|
||||
final LambdaControls mod;
|
||||
private final Screen parent;
|
||||
private final GameOptions options;
|
||||
private final Option auto_switch_mode_option;
|
||||
private final Option controller_option;
|
||||
private final Option controller_type_option;
|
||||
private final Option dead_zone_option;
|
||||
private final Option hud_enable_option;
|
||||
private final Option hud_side_option;
|
||||
private final Option mouse_speed_option;
|
||||
private final Option rotation_speed_option;
|
||||
private final String controller_mappings_url_text = I18n.translate("lambdacontrols.controller.mappings.2", Formatting.GOLD.toString(), GAMEPAD_TOOL_URL, Formatting.RESET.toString());
|
||||
private ButtonListWidget list;
|
||||
private LabelWidget gamepad_tool_url_label;
|
||||
public static final String GAMEPAD_TOOL_URL = "http://generalarcade.com/gamepadtool/";
|
||||
final LambdaControls mod;
|
||||
private final Screen parent;
|
||||
private final boolean hide_controls;
|
||||
private final Option auto_switch_mode_option;
|
||||
private final Option controller_option;
|
||||
private final Option second_controller_option;
|
||||
private final Option controller_type_option;
|
||||
private final Option dead_zone_option;
|
||||
private final Option hud_enable_option;
|
||||
private final Option hud_side_option;
|
||||
private final Option mouse_speed_option;
|
||||
private final Option rotation_speed_option;
|
||||
private final Option reset_option;
|
||||
private final String controller_mappings_url_text = I18n.translate("lambdacontrols.controller.mappings.2", Formatting.GOLD.toString(), GAMEPAD_TOOL_URL, Formatting.RESET.toString());
|
||||
private ButtonListWidget list;
|
||||
private SpruceLabelWidget gamepad_tool_url_label;
|
||||
|
||||
public LambdaControlsSettingsScreen(Screen parent, @NotNull GameOptions options)
|
||||
public LambdaControlsSettingsScreen(Screen parent, @NotNull GameOptions options, boolean hide_controls)
|
||||
{
|
||||
super(new TranslatableText("lambdacontrols.title.settings"));
|
||||
this.mod = LambdaControls.get();
|
||||
this.parent = parent;
|
||||
this.options = options;
|
||||
this.auto_switch_mode_option = new BooleanOption("lambdacontrols.menu.auto_switch_mode", game_options -> this.mod.config.has_auto_switch_mode(),
|
||||
(game_options, new_value) -> this.mod.config.set_auto_switch_mode(new_value));
|
||||
this.hide_controls = hide_controls;
|
||||
this.auto_switch_mode_option = new SpruceBooleanOption("lambdacontrols.menu.auto_switch_mode", game_options -> this.mod.config.has_auto_switch_mode(),
|
||||
(game_options, new_value) -> this.mod.config.set_auto_switch_mode(new_value), new TranslatableText("lambdacontrols.tooltip.auto_switch_mode"));
|
||||
this.controller_option = new CyclingOption("lambdacontrols.menu.controller", (game_options, amount) -> {
|
||||
int current_id = this.mod.config.get_controller().get_id();
|
||||
current_id += amount;
|
||||
@@ -68,15 +77,34 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
else
|
||||
return option.getDisplayPrefix() + controller_name;
|
||||
});
|
||||
this.controller_type_option = new CyclingOption("lambdacontrols.menu.controller_type",
|
||||
this.second_controller_option = new SpruceCyclingOption("lambdacontrols.menu.controller2",
|
||||
(game_options, amount) -> {
|
||||
int current_id = this.mod.config.get_second_controller().map(Controller::get_id).orElse(-1);
|
||||
current_id += amount;
|
||||
if (current_id > GLFW.GLFW_JOYSTICK_LAST)
|
||||
current_id = -1;
|
||||
this.mod.config.set_second_controller(current_id == -1 ? null : Controller.by_id(current_id));
|
||||
}, (game_options, option) -> this.mod.config.get_second_controller().map(controller -> {
|
||||
String controller_name = controller.get_name();
|
||||
if (!controller.is_connected())
|
||||
return option.getDisplayPrefix() + Formatting.RED + controller_name;
|
||||
else if (!controller.is_gamepad())
|
||||
return option.getDisplayPrefix() + Formatting.GOLD + controller_name;
|
||||
else
|
||||
return option.getDisplayPrefix() + controller_name;
|
||||
}).orElse(option.getDisplayPrefix() + Formatting.RED + I18n.translate("options.off")),
|
||||
new TranslatableText("lambdacontrols.tooltip.controller2"));
|
||||
this.controller_type_option = new SpruceCyclingOption("lambdacontrols.menu.controller_type",
|
||||
(game_options, amount) -> this.mod.config.set_controller_type(this.mod.config.get_controller_type().next()),
|
||||
(game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_controller_type().get_translated_name());
|
||||
this.hud_enable_option = new BooleanOption("lambdacontrols.menu.hud_enable", (game_options) -> this.mod.config.is_hud_enabled(),
|
||||
(game_options, new_value) -> this.mod.config.set_hud_enabled(new_value));
|
||||
this.hud_side_option = new CyclingOption("lambdacontrols.menu.hud_side",
|
||||
(game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_controller_type().get_translated_name(),
|
||||
new TranslatableText("lambdacontrols.tooltip.controller_type"));
|
||||
this.hud_enable_option = new SpruceBooleanOption("lambdacontrols.menu.hud_enable", (game_options) -> this.mod.config.is_hud_enabled(),
|
||||
(game_options, new_value) -> this.mod.config.set_hud_enabled(new_value), new TranslatableText("lambdacontrols.tooltip.hud_enable"));
|
||||
this.hud_side_option = new SpruceCyclingOption("lambdacontrols.menu.hud_side",
|
||||
(game_options, amount) -> this.mod.config.set_hud_side(this.mod.config.get_hud_side().next()),
|
||||
(game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_hud_side().get_translated_name());
|
||||
this.dead_zone_option = new DoubleOption("lambdacontrols.menu.dead_zone", 0.05, 1.0, 0.05F, game_options -> this.mod.config.get_dead_zone(),
|
||||
(game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_hud_side().get_translated_name(),
|
||||
new TranslatableText("lambdacontrols.tooltip.hud_side"));
|
||||
this.dead_zone_option = new SpruceDoubleOption("lambdacontrols.menu.dead_zone", 0.05, 1.0, 0.05F, game_options -> this.mod.config.get_dead_zone(),
|
||||
(game_options, new_value) -> {
|
||||
synchronized (this.mod.config) {
|
||||
this.mod.config.set_dead_zone(new_value);
|
||||
@@ -84,19 +112,26 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
}, (game_options, option) -> {
|
||||
String value = String.valueOf(option.get(options));
|
||||
return option.getDisplayPrefix() + value.substring(0, Math.min(value.length(), 5));
|
||||
});
|
||||
this.rotation_speed_option = new DoubleOption("lambdacontrols.menu.rotation_speed", 0.0, 50.0, 0.5F, game_options -> this.mod.config.get_rotation_speed(),
|
||||
}, new TranslatableText("lambdacontrols.tooltip.dead_zone"));
|
||||
this.rotation_speed_option = new SpruceDoubleOption("lambdacontrols.menu.rotation_speed", 0.0, 50.0, 0.5F, game_options -> this.mod.config.get_rotation_speed(),
|
||||
(game_options, new_value) -> {
|
||||
synchronized (this.mod.config) {
|
||||
this.mod.config.set_rotation_speed(new_value);
|
||||
}
|
||||
}, (game_options, option) -> option.getDisplayPrefix() + option.get(options));
|
||||
this.mouse_speed_option = new DoubleOption("lambdacontrols.menu.mouse_speed", 0.0, 50.0, 0.5F, game_options -> this.mod.config.get_mouse_speed(),
|
||||
}, (game_options, option) -> option.getDisplayPrefix() + option.get(options),
|
||||
new TranslatableText("lambdacontrols.tooltip.rotation_speed"));
|
||||
this.mouse_speed_option = new SpruceDoubleOption("lambdacontrols.menu.mouse_speed", 0.0, 50.0, 0.5F, game_options -> this.mod.config.get_mouse_speed(),
|
||||
(game_options, new_value) -> {
|
||||
synchronized (this.mod.config) {
|
||||
this.mod.config.set_mouse_speed(new_value);
|
||||
}
|
||||
}, (game_options, option) -> option.getDisplayPrefix() + option.get(options));
|
||||
}, (game_options, option) -> option.getDisplayPrefix() + option.get(options),
|
||||
new TranslatableText("lambdacontrols.tooltip.mouse_speed"));
|
||||
this.reset_option = new SpruceResetOption(btn -> {
|
||||
this.mod.config.reset();
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,36 +158,45 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
{
|
||||
super.init();
|
||||
int button_height = 20;
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155, 18, 150, button_height, I18n.translate("lambdacontrols.menu.controls_mode") + ": " + this.mod.config.get_controls_mode().get_translated_name(),
|
||||
SpruceButtonWidget controls_mode_btn = new SpruceButtonWidget(this.width / 2 - 155, 18, this.hide_controls ? 310 : 150, button_height,
|
||||
I18n.translate("lambdacontrols.menu.controls_mode") + ": " + this.mod.config.get_controls_mode().get_translated_name(),
|
||||
btn -> {
|
||||
ControlsMode next = this.mod.config.get_controls_mode().next();
|
||||
btn.setMessage(I18n.translate("lambdacontrols.menu.controls_mode") + ": " + next.get_translated_name());
|
||||
this.mod.config.set_controls_mode(next);
|
||||
this.mod.config.save();
|
||||
}));
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, button_height, I18n.translate("options.controls"),
|
||||
btn -> {
|
||||
if (this.mod.config.get_controls_mode() == ControlsMode.CONTROLLER)
|
||||
this.minecraft.openScreen(new LambdaControlsControlsScreen(this));
|
||||
else
|
||||
this.minecraft.openScreen(new ControlsOptionsScreen(this, this.options));
|
||||
}));
|
||||
});
|
||||
controls_mode_btn.set_tooltip(new TranslatableText("lambdacontrols.tooltip.controls_mode"));
|
||||
this.addButton(controls_mode_btn);
|
||||
if (!this.hide_controls)
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, button_height, I18n.translate("options.controls"),
|
||||
btn -> {
|
||||
if (this.mod.config.get_controls_mode() == ControlsMode.CONTROLLER)
|
||||
this.minecraft.openScreen(new LambdaControlsControlsScreen(this, true));
|
||||
else
|
||||
this.minecraft.openScreen(new ControlsOptionsScreen(this, this.minecraft.options));
|
||||
}));
|
||||
|
||||
this.list = new ButtonListWidget(this.minecraft, this.width, this.height, 43, this.height - 29 - this.get_text_height(), 25);
|
||||
this.list.addSingleOptionEntry(this.controller_option);
|
||||
this.list.addOptionEntry(this.controller_type_option, this.dead_zone_option);
|
||||
this.list.addOptionEntry(this.hud_enable_option, this.hud_side_option);
|
||||
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.general", true, null));
|
||||
this.list.addOptionEntry(this.rotation_speed_option, this.mouse_speed_option);
|
||||
this.list.addSingleOptionEntry(this.auto_switch_mode_option);
|
||||
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.controller", true, null));
|
||||
this.list.addSingleOptionEntry(this.controller_option);
|
||||
this.list.addSingleOptionEntry(this.second_controller_option);
|
||||
this.list.addOptionEntry(this.controller_type_option, this.dead_zone_option);
|
||||
this.list.addSingleOptionEntry(new ReloadControllerMappingsOption());
|
||||
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null));
|
||||
this.list.addOptionEntry(this.hud_enable_option, this.hud_side_option);
|
||||
this.children.add(this.list);
|
||||
|
||||
this.gamepad_tool_url_label = new LabelWidget(this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, this.controller_mappings_url_text, this.width,
|
||||
this.gamepad_tool_url_label = new SpruceLabelWidget(this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, this.controller_mappings_url_text, this.width,
|
||||
label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true);
|
||||
this.gamepad_tool_url_label.set_tooltip_text(I18n.translate("chat.link.open"));
|
||||
this.gamepad_tool_url_label.set_tooltip(new TranslatableText("chat.link.open"));
|
||||
this.children.add(this.gamepad_tool_url_label);
|
||||
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 300, button_height, I18n.translate("gui.done"),
|
||||
this.addButton(this.reset_option.createButton(this.minecraft.options, this.width / 2 - 155, this.height - 29, 150));
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, button_height, I18n.translate("gui.done"),
|
||||
(buttonWidget) -> this.minecraft.openScreen(this.parent)));
|
||||
}
|
||||
|
||||
@@ -166,5 +210,7 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.1", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 3, 10526880);
|
||||
this.gamepad_tool_url_label.render(mouse_x, mouse_y, delta);
|
||||
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight), 10526880);
|
||||
|
||||
Tooltip.render_all();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.gui;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.Controller;
|
||||
import me.lambdaurora.lambdacontrols.controller.Controller;
|
||||
import me.lambdaurora.spruceui.SpruceButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.options.Option;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
@@ -36,13 +36,15 @@ public class ReloadControllerMappingsOption extends Option implements Nameable
|
||||
@Override
|
||||
public AbstractButtonWidget createButton(GameOptions options, int x, int y, int width)
|
||||
{
|
||||
return new ButtonWidget(x, y, width, 20, this.get_name(), btn -> {
|
||||
SpruceButtonWidget button = new SpruceButtonWidget(x, y, width, 20, this.get_name(), btn -> {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
Controller.update_mappings();
|
||||
if (client.currentScreen != null)
|
||||
client.currentScreen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.mappings.updated"), null));
|
||||
});
|
||||
button.set_tooltip(new TranslatableText("lambdacontrols.tooltip.reload_controller_mappings"));
|
||||
return button;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 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.gui;
|
||||
|
||||
import net.minecraft.client.gui.widget.TexturedButtonWidget;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Represents a touchscreen button widget.
|
||||
*/
|
||||
public class TouchscreenButtonWidget extends TexturedButtonWidget
|
||||
{
|
||||
private final Consumer<Boolean> on_change_state;
|
||||
|
||||
public TouchscreenButtonWidget(int x, int y, int width, int height, int u, int v, int hovered_v_offset, Identifier texture, @NotNull Consumer<Boolean> on_changed_state)
|
||||
{
|
||||
super(x, y, width, height, u, v, hovered_v_offset, texture, 256, 256, btn -> on_changed_state.accept(true));
|
||||
this.on_change_state = on_changed_state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(double mouseX, double mouseY)
|
||||
{
|
||||
super.onRelease(mouseX, mouseY);
|
||||
this.on_change_state.accept(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button)
|
||||
{
|
||||
if (this.active && this.visible) {
|
||||
if (this.isValidClickButton(button)) {
|
||||
boolean clicked = this.clicked(mouseX, mouseY);
|
||||
if (clicked) {
|
||||
this.onClick(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY)
|
||||
{
|
||||
super.onDrag(mouseX, mouseY, deltaX, deltaY);
|
||||
if (this.active && !this.isHovered)
|
||||
this.on_change_state.accept(false);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -12,6 +12,7 @@ package me.lambdaurora.lambdacontrols.gui;
|
||||
import me.lambdaurora.lambdacontrols.HudSide;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
|
||||
import me.lambdaurora.spruceui.SpruceTexturedButtonWidget;
|
||||
import net.minecraft.client.gui.screen.ChatScreen;
|
||||
import net.minecraft.client.gui.screen.GameMenuScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
@@ -35,18 +36,18 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
|
||||
*/
|
||||
public class TouchscreenOverlay extends Screen
|
||||
{
|
||||
public static final Identifier WIDGETS_LOCATION = new Identifier("lambdacontrols", "textures/gui/widgets.png");
|
||||
private LambdaControls mod;
|
||||
private TouchscreenButtonWidget jump_button;
|
||||
private TouchscreenButtonWidget fly_button;
|
||||
private TouchscreenButtonWidget fly_up_button;
|
||||
private TouchscreenButtonWidget fly_down_button;
|
||||
private int fly_button_enable_ticks = 0;
|
||||
private int forward_button_tick = 0;
|
||||
private TouchscreenButtonWidget forward_left_button;
|
||||
private TouchscreenButtonWidget forward_right_button;
|
||||
private TouchscreenButtonWidget start_sneak_button;
|
||||
private TouchscreenButtonWidget end_sneak_button;
|
||||
public static final Identifier WIDGETS_LOCATION = new Identifier("lambdacontrols", "textures/gui/widgets.png");
|
||||
private LambdaControls mod;
|
||||
private SpruceTexturedButtonWidget jump_button;
|
||||
private SpruceTexturedButtonWidget fly_button;
|
||||
private SpruceTexturedButtonWidget fly_up_button;
|
||||
private SpruceTexturedButtonWidget fly_down_button;
|
||||
private int fly_button_enable_ticks = 0;
|
||||
private int forward_button_tick = 0;
|
||||
private SpruceTexturedButtonWidget forward_left_button;
|
||||
private SpruceTexturedButtonWidget forward_right_button;
|
||||
private SpruceTexturedButtonWidget start_sneak_button;
|
||||
private SpruceTexturedButtonWidget end_sneak_button;
|
||||
|
||||
public TouchscreenOverlay(@NotNull LambdaControls mod)
|
||||
{
|
||||
@@ -108,7 +109,7 @@ public class TouchscreenOverlay extends Screen
|
||||
this.fly_down_button.visible = true;
|
||||
if (old_state_fly != this.fly_button.visible) {
|
||||
this.fly_button_enable_ticks = 5;
|
||||
this.handle_jump(false);
|
||||
this.handle_jump(null, false);
|
||||
} else if (this.fly_button_enable_ticks > 0)
|
||||
this.fly_button_enable_ticks--;
|
||||
} else {
|
||||
@@ -122,9 +123,10 @@ public class TouchscreenOverlay extends Screen
|
||||
/**
|
||||
* Handles the jump button.
|
||||
*
|
||||
* @param btn The pressed button.
|
||||
* @param state The state of the jump button.
|
||||
*/
|
||||
private void handle_jump(boolean state)
|
||||
private void handle_jump(ButtonWidget btn, boolean state)
|
||||
{
|
||||
((KeyBindingAccessor) this.minecraft.options.keyJump).handle_press_state(state);
|
||||
}
|
||||
@@ -182,8 +184,8 @@ public class TouchscreenOverlay extends Screen
|
||||
sneak_button_x = scaled_width - 10 - 40 - 5;
|
||||
}
|
||||
// Swap items hand.
|
||||
this.addButton(new TouchscreenButtonWidget(swap_hands_x, sneak_button_y, 20, 20, 0, 160, 20, WIDGETS_LOCATION,
|
||||
state -> {
|
||||
this.addButton(new SpruceTexturedButtonWidget(swap_hands_x, sneak_button_y, 20, 20, 0, 160, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> {
|
||||
if (state) {
|
||||
if (!this.minecraft.player.isSpectator()) {
|
||||
this.minecraft.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_HELD_ITEMS, BlockPos.ORIGIN, Direction.DOWN));
|
||||
@@ -191,31 +193,31 @@ public class TouchscreenOverlay extends Screen
|
||||
}
|
||||
}));
|
||||
// Drop
|
||||
this.addButton(new TouchscreenButtonWidget(swap_hands_x, sneak_button_y + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION,
|
||||
state -> ((KeyBindingAccessor) this.minecraft.options.keyDrop).handle_press_state(state)));
|
||||
this.addButton(new SpruceTexturedButtonWidget(swap_hands_x, sneak_button_y + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyDrop).handle_press_state(state)));
|
||||
// Jump keys
|
||||
this.addButton(this.jump_button = new TouchscreenButtonWidget(jump_button_x, sneak_button_y, 20, 20, 0, 40, 20, WIDGETS_LOCATION,
|
||||
this.addButton(this.jump_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y, 20, 20, 0, 40, 20, WIDGETS_LOCATION,
|
||||
this::handle_jump));
|
||||
this.addButton(this.fly_button = new TouchscreenButtonWidget(jump_button_x, sneak_button_y, 20, 20, 20, 40, 20, WIDGETS_LOCATION,
|
||||
state -> {
|
||||
this.addButton(this.fly_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y, 20, 20, 20, 40, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> {
|
||||
if (this.fly_button_enable_ticks == 0) this.minecraft.player.abilities.flying = false;
|
||||
}));
|
||||
this.addButton(this.fly_up_button = new TouchscreenButtonWidget(jump_button_x, sneak_button_y - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION,
|
||||
this.addButton(this.fly_up_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION,
|
||||
this::handle_jump));
|
||||
this.addButton(this.fly_down_button = new TouchscreenButtonWidget(jump_button_x, sneak_button_y + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION,
|
||||
state -> ((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(state)));
|
||||
this.addButton(this.fly_down_button = new SpruceTexturedButtonWidget(jump_button_x, sneak_button_y + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(state)));
|
||||
this.update_jump_buttons();
|
||||
// Movements keys
|
||||
this.addButton((this.start_sneak_button = new TouchscreenButtonWidget(sneak_button_x, sneak_button_y, 20, 20, 0, 120, 20, WIDGETS_LOCATION,
|
||||
state -> {
|
||||
this.addButton((this.start_sneak_button = new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y, 20, 20, 0, 120, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> {
|
||||
if (state) {
|
||||
((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(true);
|
||||
this.start_sneak_button.visible = false;
|
||||
this.end_sneak_button.visible = true;
|
||||
}
|
||||
})));
|
||||
this.addButton((this.end_sneak_button = new TouchscreenButtonWidget(sneak_button_x, sneak_button_y, 20, 20, 20, 120, 20, WIDGETS_LOCATION,
|
||||
state -> {
|
||||
this.addButton((this.end_sneak_button = new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y, 20, 20, 20, 120, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> {
|
||||
if (state) {
|
||||
((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(false);
|
||||
this.end_sneak_button.visible = false;
|
||||
@@ -223,33 +225,33 @@ public class TouchscreenOverlay extends Screen
|
||||
}
|
||||
})));
|
||||
this.end_sneak_button.visible = false;
|
||||
this.addButton(this.forward_left_button = new TouchscreenButtonWidget(sneak_button_x - 20 - 5, sneak_button_y - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION,
|
||||
state -> {
|
||||
this.addButton(this.forward_left_button = new SpruceTexturedButtonWidget(sneak_button_x - 20 - 5, sneak_button_y - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> {
|
||||
((KeyBindingAccessor) this.minecraft.options.keyForward).handle_press_state(state);
|
||||
((KeyBindingAccessor) this.minecraft.options.keyLeft).handle_press_state(state);
|
||||
this.update_forward_buttons_state(state);
|
||||
}));
|
||||
this.forward_left_button.visible = false;
|
||||
this.addButton(new TouchscreenButtonWidget(sneak_button_x, sneak_button_y - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION,
|
||||
state -> {
|
||||
this.addButton(new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> {
|
||||
((KeyBindingAccessor) this.minecraft.options.keyForward).handle_press_state(state);
|
||||
this.update_forward_buttons_state(state);
|
||||
this.forward_left_button.visible = true;
|
||||
this.forward_right_button.visible = true;
|
||||
}));
|
||||
this.addButton(this.forward_right_button = new TouchscreenButtonWidget(sneak_button_x + 20 + 5, sneak_button_y - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION,
|
||||
state -> {
|
||||
this.addButton(this.forward_right_button = new SpruceTexturedButtonWidget(sneak_button_x + 20 + 5, sneak_button_y - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> {
|
||||
((KeyBindingAccessor) this.minecraft.options.keyForward).handle_press_state(state);
|
||||
((KeyBindingAccessor) this.minecraft.options.keyRight).handle_press_state(state);
|
||||
this.update_forward_buttons_state(state);
|
||||
}));
|
||||
this.forward_right_button.visible = true;
|
||||
this.addButton(new TouchscreenButtonWidget(sneak_button_x + 20 + 5, sneak_button_y, 20, 20, 20, 80, 20, WIDGETS_LOCATION,
|
||||
state -> ((KeyBindingAccessor) this.minecraft.options.keyRight).handle_press_state(state)));
|
||||
this.addButton(new TouchscreenButtonWidget(sneak_button_x, sneak_button_y + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION,
|
||||
state -> ((KeyBindingAccessor) this.minecraft.options.keyBack).handle_press_state(state)));
|
||||
this.addButton(new TouchscreenButtonWidget(sneak_button_x - 20 - 5, sneak_button_y, 20, 20, 60, 80, 20, WIDGETS_LOCATION,
|
||||
state -> ((KeyBindingAccessor) this.minecraft.options.keyLeft).handle_press_state(state)));
|
||||
this.addButton(new SpruceTexturedButtonWidget(sneak_button_x + 20 + 5, sneak_button_y, 20, 20, 20, 80, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyRight).handle_press_state(state)));
|
||||
this.addButton(new SpruceTexturedButtonWidget(sneak_button_x, sneak_button_y + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyBack).handle_press_state(state)));
|
||||
this.addButton(new SpruceTexturedButtonWidget(sneak_button_x - 20 - 5, sneak_button_y, 20, 20, 60, 80, 20, WIDGETS_LOCATION,
|
||||
(btn, state) -> ((KeyBindingAccessor) this.minecraft.options.keyLeft).handle_press_state(state)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -60,10 +60,10 @@ public abstract class AbstractContainerScreenMixin implements AbstractContainerS
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
int x = 10, y = client.getWindow().getScaledHeight() - 10 - 15;
|
||||
|
||||
x += LambdaControls.draw_button_tip(x, y, GLFW.GLFW_GAMEPAD_BUTTON_A, "lambdacontrols.action.pickup_all", true, client) + 10;
|
||||
x += LambdaControls.draw_button_tip(x, y, GLFW.GLFW_GAMEPAD_BUTTON_B, "lambdacontrols.action.exit", true, client) + 10;
|
||||
x += LambdaControls.draw_button_tip(x, y, GLFW.GLFW_GAMEPAD_BUTTON_X, "lambdacontrols.action.pickup", true, client) + 10;
|
||||
LambdaControls.draw_button_tip(x, y, GLFW.GLFW_GAMEPAD_BUTTON_Y, "lambdacontrols.action.quick_move", true, client);
|
||||
x += LambdaControls.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "lambdacontrols.action.pickup_all", true, client) + 10;
|
||||
x += LambdaControls.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "lambdacontrols.action.exit", true, client) + 10;
|
||||
x += LambdaControls.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "lambdacontrols.action.pickup", true, client) + 10;
|
||||
LambdaControls.draw_button_tip(x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, "lambdacontrols.action.quick_move", true, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.mixin;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsControlsScreen;
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsSettingsScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
|
||||
import net.minecraft.client.gui.screen.options.GameOptionsScreen;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.text.Text;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
/**
|
||||
* Injects the new controls settings button.
|
||||
*/
|
||||
@Mixin(ControlsOptionsScreen.class)
|
||||
public class ControlsOptionsScreenMixin extends GameOptionsScreen
|
||||
{
|
||||
public ControlsOptionsScreenMixin(Screen parent, GameOptions game_options, Text text)
|
||||
{
|
||||
super(parent, game_options, text);
|
||||
}
|
||||
|
||||
@Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/options/ControlsOptionsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 1))
|
||||
private AbstractButtonWidget on_init(ControlsOptionsScreen screen, AbstractButtonWidget btn)
|
||||
{
|
||||
if (this.parent instanceof LambdaControlsControlsScreen)
|
||||
return this.addButton(btn);
|
||||
else
|
||||
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).get_height(), I18n.translate("menu.options"),
|
||||
b -> this.minecraft.openScreen(new LambdaControlsSettingsScreen(this, this.gameOptions, true))));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
@@ -9,12 +9,17 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols.mixin;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.ControlsMode;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsControlsScreen;
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsSettingsScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.SettingsScreen;
|
||||
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.text.Text;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -28,10 +33,6 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@Mixin(SettingsScreen.class)
|
||||
public class SettingsScreenMixin extends Screen
|
||||
{
|
||||
@Final
|
||||
@Shadow
|
||||
private GameOptions settings;
|
||||
|
||||
protected SettingsScreenMixin(Text title)
|
||||
{
|
||||
super(title);
|
||||
@@ -40,7 +41,11 @@ public class SettingsScreenMixin extends Screen
|
||||
@Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SettingsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 7))
|
||||
private AbstractButtonWidget on_init(SettingsScreen screen, AbstractButtonWidget btn)
|
||||
{
|
||||
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).get_height(), btn.getMessage(),
|
||||
b -> this.minecraft.openScreen(new LambdaControlsSettingsScreen(this, this.settings))));
|
||||
if (LambdaControls.get().config.get_controls_mode() == ControlsMode.CONTROLLER) {
|
||||
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).get_height(), btn.getMessage(),
|
||||
b -> this.minecraft.openScreen(new LambdaControlsControlsScreen(this, false))));
|
||||
} else {
|
||||
return this.addButton(btn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
|
||||
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of LambdaControls.
|
||||
*
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
"lambdacontrols.action.exit": "Exit",
|
||||
"lambdacontrols.action.forward": "Forward",
|
||||
"lambdacontrols.action.hit": "Hit",
|
||||
"lambdacontrols.action.hotbar_left": "Hotbar left",
|
||||
"lambdacontrols.action.hotbar_right": "Hotbar right",
|
||||
"lambdacontrols.action.inventory": "Inventory",
|
||||
"lambdacontrols.action.jump": "Jump",
|
||||
"lambdacontrols.action.left": "Left",
|
||||
@@ -72,6 +74,7 @@
|
||||
"lambdacontrols.hud_side.right": "right",
|
||||
"lambdacontrols.menu.auto_switch_mode": "Auto switch mode",
|
||||
"lambdacontrols.menu.controller": "Controller",
|
||||
"lambdacontrols.menu.controller2": "Second controller",
|
||||
"lambdacontrols.menu.controller_type": "Controller type",
|
||||
"lambdacontrols.menu.controls_mode": "Mode",
|
||||
"lambdacontrols.menu.dead_zone": "Dead zone",
|
||||
@@ -79,9 +82,23 @@
|
||||
"lambdacontrols.menu.hud_side": "HUD side",
|
||||
"lambdacontrols.menu.invert_right_x_axis": "Invert right X",
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Invert right Y",
|
||||
"lambdacontrols.menu.keyboard_controls": "Keyboard controls...",
|
||||
"lambdacontrols.menu.mouse_speed": "Mouse speed",
|
||||
"lambdacontrols.menu.reload_controller_mappings": "Reload controller mappings",
|
||||
"lambdacontrols.menu.rotation_speed": "Rotation speed",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Settings",
|
||||
"lambdacontrols.menu.title.controller_controls": "Controller controls"
|
||||
"lambdacontrols.menu.title.controller": "Controller options",
|
||||
"lambdacontrols.menu.title.controller_controls": "Controller controls",
|
||||
"lambdacontrols.menu.title.general": "General options",
|
||||
"lambdacontrols.menu.title.hud": "HUD options",
|
||||
"lambdacontrols.tooltip.auto_switch_mode": "Sets whether the controls mode should be switched automatically to Controller if a controller is connected.",
|
||||
"lambdacontrols.tooltip.controller2": "Defines a second controller to use, which allow Joy-Cons support for example.",
|
||||
"lambdacontrols.tooltip.controller_type": "Changes the controller type to displays the correct buttons.",
|
||||
"lambdacontrols.tooltip.controls_mode": "Changes the controls mode.",
|
||||
"lambdacontrols.tooltip.dead_zone": "Sets the dead zone of the controller's axises.",
|
||||
"lambdacontrols.tooltip.hud_enable": "Toggles the on-screen controller button indicator.",
|
||||
"lambdacontrols.tooltip.hud_side": "Changes the position of the HUD.",
|
||||
"lambdacontrols.tooltip.mouse_speed": "Changes the emulated mouse speed with a controller.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "Changes the camera rotation speed in controller mode.",
|
||||
"lambdacontrols.tooltip.reload_controller_mappings": "Reloads the controller mappings file."
|
||||
}
|
||||
104
src/main/resources/assets/lambdacontrols/lang/fr_ca.json
Normal file
104
src/main/resources/assets/lambdacontrols/lang/fr_ca.json
Normal file
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"key.lambdacontrols.look_down": "Regarder en bas",
|
||||
"key.lambdacontrols.look_left": "Regarder à gauche",
|
||||
"key.lambdacontrols.look_right": "Regarder à droite",
|
||||
"key.lambdacontrols.look_up": "Regarder en haut",
|
||||
"lambdacontrols.action.attack": "Attaquer",
|
||||
"lambdacontrols.action.back": "Reculer",
|
||||
"lambdacontrols.action.chat": "Ouvrir le tchat",
|
||||
"lambdacontrols.action.drop_item": "Jeter l'objet",
|
||||
"lambdacontrols.action.exit": "Sortir",
|
||||
"lambdacontrols.action.forward": "Avancer",
|
||||
"lambdacontrols.action.hit": "Taper",
|
||||
"lambdacontrols.action.hotbar_left": "Case à gauche de la barre d'action",
|
||||
"lambdacontrols.action.hotbar_right": "Case à droite de la barre d'action",
|
||||
"lambdacontrols.action.inventory": "Inventaire",
|
||||
"lambdacontrols.action.jump": "Sauter",
|
||||
"lambdacontrols.action.left": "Aller à gauche",
|
||||
"lambdacontrols.action.pause_game": "Mettre en pause le jeu",
|
||||
"lambdacontrols.action.pick_block": "Choisir le bloc",
|
||||
"lambdacontrols.action.pickup": "Prendre",
|
||||
"lambdacontrols.action.pickup_all": "Prendre tout",
|
||||
"lambdacontrols.action.player_list": "Afficher la liste des joueurs",
|
||||
"lambdacontrols.action.quick_move": "Mouvement rapide",
|
||||
"lambdacontrols.action.right": "Aller à droite",
|
||||
"lambdacontrols.action.screenshot": "Prendre une capture d'écran",
|
||||
"lambdacontrols.action.sneak": "S'accroupir",
|
||||
"lambdacontrols.action.sprint": "Courir",
|
||||
"lambdacontrols.action.swap_hands": "Échanger de mains",
|
||||
"lambdacontrols.action.toggle_perspective": "Changer de point de vue",
|
||||
"lambdacontrols.action.toggle_smooth_camera": "Basculer en mode cinématique",
|
||||
"lambdacontrols.action.use": "Utiliser",
|
||||
"lambdacontrols.button.a": "A",
|
||||
"lambdacontrols.button.b": "B",
|
||||
"lambdacontrols.button.x": "X",
|
||||
"lambdacontrols.button.y": "Y",
|
||||
"lambdacontrols.button.left_bumper": "Gâchette haute gauche",
|
||||
"lambdacontrols.button.right_bumper": "Gâchette haute droite",
|
||||
"lambdacontrols.button.back": "Retour",
|
||||
"lambdacontrols.button.start": "Touche Menu",
|
||||
"lambdacontrols.button.guide": "Guide",
|
||||
"lambdacontrols.button.left_thumb": "Stick gauche",
|
||||
"lambdacontrols.button.right_thumb": "Stick droit",
|
||||
"lambdacontrols.button.dpad_up": "D-Pad haut",
|
||||
"lambdacontrols.button.dpad_right": "D-Pad droit",
|
||||
"lambdacontrols.button.dpad_down": "D-Pad bas",
|
||||
"lambdacontrols.button.dpad_left": "D-Pad gauche",
|
||||
"lambdacontrols.axis.left_x+": "X+ Gauche",
|
||||
"lambdacontrols.axis.left_y+": "Y+ Gauche",
|
||||
"lambdacontrols.axis.right_x+": "X+ Droit",
|
||||
"lambdacontrols.axis.right_y+": "Y+ Droit",
|
||||
"lambdacontrols.axis.left_trigger": "Gâchette gauche",
|
||||
"lambdacontrols.axis.right_trigger": "Gâchette droite",
|
||||
"lambdacontrols.axis.left_x-": "X- Gauche",
|
||||
"lambdacontrols.axis.left_y-": "Y- Gauche",
|
||||
"lambdacontrols.axis.right_x-": "X- Droit",
|
||||
"lambdacontrols.axis.right_y-": "Y- Droit",
|
||||
"lambdacontrols.button.unknown": "Inconnu (%d)",
|
||||
"lambdacontrols.controller.connected": "Manette %d connecté.",
|
||||
"lambdacontrols.controller.disconnected": "Manette %d déconnecté.",
|
||||
"lambdacontrols.controller.mappings.1": "Pour configurer les correspondances de la manette, veuillez utiliser %sSDL2 Gamepad Tool%s",
|
||||
"lambdacontrols.controller.mappings.2": "(%s%s%s),",
|
||||
"lambdacontrols.controller.mappings.3": "et mettez les correspondances dans le fichier `%s.minecraft/config/gamecontrollerdb.txt%s`.",
|
||||
"lambdacontrols.controller.mappings.updated": "Configuration des manettes mise à jour!",
|
||||
"lambdacontrols.controller_type.default": "default",
|
||||
"lambdacontrols.controller_type.dualshock": "DualShock",
|
||||
"lambdacontrols.controller_type.switch": "Switch",
|
||||
"lambdacontrols.controller_type.xbox": "Xbox",
|
||||
"lambdacontrols.controller_type.steam": "Steam",
|
||||
"lambdacontrols.controller_type.ouya": "OUYA",
|
||||
"lambdacontrols.controls_mode.default": "Clavier/Souris",
|
||||
"lambdacontrols.controls_mode.controller": "Manette",
|
||||
"lambdacontrols.controls_mode.touchscreen": "Tactile",
|
||||
"lambdacontrols.hud_side.left": "gauche",
|
||||
"lambdacontrols.hud_side.right": "droit",
|
||||
"lambdacontrols.menu.auto_switch_mode": "Changement auto de mode",
|
||||
"lambdacontrols.menu.controller": "Manette",
|
||||
"lambdacontrols.menu.controller2": "Deuxième manette",
|
||||
"lambdacontrols.menu.controller_type": "Type de manette",
|
||||
"lambdacontrols.menu.controls_mode": "Mode",
|
||||
"lambdacontrols.menu.dead_zone": "Zone morte",
|
||||
"lambdacontrols.menu.hud_enable": "Activer le HUD",
|
||||
"lambdacontrols.menu.hud_side": "Côté du HUD",
|
||||
"lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)",
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)",
|
||||
"lambdacontrols.menu.keyboard_controls": "Contrôles clavier...",
|
||||
"lambdacontrols.menu.mouse_speed": "Vitesse de la souris",
|
||||
"lambdacontrols.menu.reload_controller_mappings": "Recharge la configuration des manettes",
|
||||
"lambdacontrols.menu.rotation_speed": "Vitesse de rotation",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Paramètres",
|
||||
"lambdacontrols.menu.title.controller": "Options de manettes",
|
||||
"lambdacontrols.menu.title.controller_controls": "Contrôles de la manette",
|
||||
"lambdacontrols.menu.title.general": "Options générales",
|
||||
"lambdacontrols.menu.title.hud": "Options du HUD",
|
||||
"lambdacontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.",
|
||||
"lambdacontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.",
|
||||
"lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.",
|
||||
"lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.",
|
||||
"lambdacontrols.tooltip.dead_zone": "Détermine la zone morte des axes de la manette.",
|
||||
"lambdacontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.",
|
||||
"lambdacontrols.tooltip.hud_side": "Change la position du HUD.",
|
||||
"lambdacontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
|
||||
"lambdacontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes."
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
"lambdacontrols.action.exit": "Sortir",
|
||||
"lambdacontrols.action.forward": "Avancer",
|
||||
"lambdacontrols.action.hit": "Taper",
|
||||
"lambdacontrols.action.hotbar_left": "Case à gauche de la barre d'action",
|
||||
"lambdacontrols.action.hotbar_right": "Case à droite de la barre d'action",
|
||||
"lambdacontrols.action.inventory": "Inventaire",
|
||||
"lambdacontrols.action.jump": "Sauter",
|
||||
"lambdacontrols.action.left": "Aller à gauche",
|
||||
@@ -36,8 +38,8 @@
|
||||
"lambdacontrols.button.back": "Retour",
|
||||
"lambdacontrols.button.start": "Touche Menu",
|
||||
"lambdacontrols.button.guide": "Guide",
|
||||
"lambdacontrols.button.left_thumb": "Stick analogique gauche",
|
||||
"lambdacontrols.button.right_thumb": "Stick analogique droit",
|
||||
"lambdacontrols.button.left_thumb": "Stick gauche",
|
||||
"lambdacontrols.button.right_thumb": "Stick droit",
|
||||
"lambdacontrols.button.dpad_up": "D-Pad haut",
|
||||
"lambdacontrols.button.dpad_right": "D-Pad droit",
|
||||
"lambdacontrols.button.dpad_down": "D-Pad bas",
|
||||
@@ -72,16 +74,31 @@
|
||||
"lambdacontrols.hud_side.right": "droit",
|
||||
"lambdacontrols.menu.auto_switch_mode": "Changement auto de mode",
|
||||
"lambdacontrols.menu.controller": "Manette",
|
||||
"lambdacontrols.menu.controller2": "Deuxième manette",
|
||||
"lambdacontrols.menu.controller_type": "Type de manette",
|
||||
"lambdacontrols.menu.controls_mode": "Mode",
|
||||
"lambdacontrols.menu.dead_zone": "Zone morte",
|
||||
"lambdacontrols.menu.hud_enable": "Activer le HUD",
|
||||
"lambdacontrols.menu.hud_side": "Côté du HUD",
|
||||
"lambdacontrols.menu.invert_right_x_axis": "Inverser le joystick droit (X)",
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Inverser le joystick droit (Y)",
|
||||
"lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)",
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)",
|
||||
"lambdacontrols.menu.keyboard_controls": "Contrôles clavier...",
|
||||
"lambdacontrols.menu.mouse_speed": "Vitesse de la souris",
|
||||
"lambdacontrols.menu.reload_controller_mappings": "Recharge la configuration des manettes",
|
||||
"lambdacontrols.menu.rotation_speed": "Vitesse de rotation",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Paramètres",
|
||||
"lambdacontrols.menu.title.controller_controls": "Contrôles de la manette"
|
||||
"lambdacontrols.menu.title.controller": "Options de manettes",
|
||||
"lambdacontrols.menu.title.controller_controls": "Contrôles de la manette",
|
||||
"lambdacontrols.menu.title.general": "Options générales",
|
||||
"lambdacontrols.menu.title.hud": "Options du HUD",
|
||||
"lambdacontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.",
|
||||
"lambdacontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.",
|
||||
"lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.",
|
||||
"lambdacontrols.tooltip.controls_mode": "Change le mode de contrôle.",
|
||||
"lambdacontrols.tooltip.dead_zone": "Détermine la zone morte des axes de la manette.",
|
||||
"lambdacontrols.tooltip.hud_enable": "Détermine si l'indicateur des buttons de la manette doit être affiché ou non.",
|
||||
"lambdacontrols.tooltip.hud_side": "Change la position du HUD.",
|
||||
"lambdacontrols.tooltip.mouse_speed": "Change la vitesse de la souris émulée par la manette.",
|
||||
"lambdacontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
|
||||
"lambdacontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes."
|
||||
}
|
||||
@@ -15,6 +15,8 @@ auto_switch_mode = false
|
||||
[controller]
|
||||
# Controller to use.
|
||||
id = 0
|
||||
# Second controller to use.
|
||||
id2 = -1
|
||||
# Controller's type.
|
||||
type = "default"
|
||||
# Controller's dead zone.
|
||||
@@ -30,36 +32,42 @@ auto_switch_mode = false
|
||||
# Controller controls.
|
||||
[controller.controls]
|
||||
# Attack control.
|
||||
attack = 105
|
||||
attack = "105"
|
||||
# Back control.
|
||||
back = 201
|
||||
back = "201"
|
||||
# Open chat control.
|
||||
chat = 12
|
||||
chat = "12"
|
||||
# Drop item control.
|
||||
drop_item = 1
|
||||
drop_item = "1"
|
||||
# Forward control.
|
||||
forward = 101
|
||||
forward = "101"
|
||||
# Hot-bar left control.
|
||||
hotbar_left = "4"
|
||||
# Hot-bar right control.
|
||||
hotbar_right = "5"
|
||||
# Inventory control.
|
||||
inventory = 3
|
||||
inventory = "3"
|
||||
# Jump control.
|
||||
jump = 0
|
||||
jump = "0"
|
||||
# Pause game control.
|
||||
pause_game = 7
|
||||
pause_game = "7"
|
||||
# Pick block control.
|
||||
pick_block = 14
|
||||
pick_block = "14"
|
||||
# Show player list control.
|
||||
player_list = 6
|
||||
player_list = "6"
|
||||
# Take screenshot control.
|
||||
screenshot = 13
|
||||
screenshot = "11+0"
|
||||
# Sneak control.
|
||||
sneak = 10
|
||||
sneak = "10"
|
||||
# Sprint control.
|
||||
sprint = 9
|
||||
sprint = "9"
|
||||
# Swap hands control.
|
||||
swap_hands = 2
|
||||
swap_hands = "2"
|
||||
# Toggle perspective control.
|
||||
toggle_perspective = 11
|
||||
toggle_perspective = "11+3"
|
||||
# Toggle smooth camera control.
|
||||
toggle_smooth_camera = -1
|
||||
toggle_smooth_camera = "-1"
|
||||
# Use control.
|
||||
use = 104
|
||||
use = "104"
|
||||
# Zoom control.
|
||||
zoom = "11+2"
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
"entrypoints": {
|
||||
"client": [
|
||||
"me.lambdaurora.lambdacontrols.LambdaControls"
|
||||
],
|
||||
"modmenu": [
|
||||
"me.lambdaurora.lambdacontrols.LambdaControlsModMenu"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
@@ -26,7 +29,11 @@
|
||||
"depends": {
|
||||
"fabricloader": ">=0.4.0",
|
||||
"fabric": "*",
|
||||
"minecraft": "1.15.x"
|
||||
"minecraft": "1.15.x",
|
||||
"spruceui": ">=1.0.1"
|
||||
},
|
||||
"recommends": {
|
||||
"modmenu": ">=1.8.0+build.16"
|
||||
},
|
||||
"suggests": {
|
||||
"flamingo": "*"
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
"client": [
|
||||
"AbstractButtonWidgetAccessor",
|
||||
"AbstractContainerScreenMixin",
|
||||
"ControlsOptionsScreenMixin",
|
||||
"CreativeInventoryScreenMixin",
|
||||
"EntryListWidgetAccessor",
|
||||
"GameRendererMixin",
|
||||
"InGameHudMixin",
|
||||
"KeyBindingMixin",
|
||||
"MinecraftClientMixin",
|
||||
"MouseMixin",
|
||||
@@ -17,4 +17,4 @@
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user