Add working in-game chording, WIP controls screen.

This commit is contained in:
LambdAurora
2020-01-01 14:54:51 +01:00
parent e6da7adf89
commit 1b5a0e470e
16 changed files with 336 additions and 132 deletions

View File

@@ -24,6 +24,26 @@ repositories {
repositories {
maven { url = "https://jitpack.io" }
}
// SpruceUI
ivy {
url 'https://github.com/LambdAurora/SpruceUI/releases/download/'
patternLayout {
artifact '[revision]/[module]-[version].[ext]'
}
metadataSources() {
artifact()
}
}
// OkZoomer
ivy {
url 'https://github.com/joaoh1/OkZoomer/releases/download/'
patternLayout {
artifact '[revision]/[module]-[version].[ext]'
}
metadataSources() {
artifact()
}
}
}
dependencies {
@@ -40,6 +60,9 @@ dependencies {
include "me.lambdaurora:spruceui:${project.spruceui_version}"
//modCompile "io.github.cottonmc:cotton-client-commands:0.4.2+1.14.3-SNAPSHOT"
// Compatibility mods
modCompile "io.github.joaoh1:okzoomer:1.0.3"
implementation "org.jetbrains:annotations:17.0.0"
implementation "org.aperlambda:lambdajcommon:1.7.2"
implementation "com.electronwill.night-config:core:3.5.3"
@@ -48,9 +71,6 @@ dependencies {
include "org.aperlambda:lambdajcommon:1.7.2"
include "com.electronwill.night-config:core:3.5.3"
include "com.electronwill.night-config:toml:3.5.3"
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
// You may need to force-disable transitiveness on them.
}
processResources {

View File

@@ -97,7 +97,7 @@ public class LambdaControls implements ClientModInitializer
this.hud = new LambdaControlsHud(client, this);
LambdaControlsCompat.init();
LambdaControlsCompat.init(this);
}
/**

View File

@@ -59,7 +59,6 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
*/
public class LambdaInput
{
private static final Map<Integer, Boolean> BUTTON_STATES = new HashMap<>();
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
private final LambdaControlsConfig config;
// Cooldowns
@@ -136,11 +135,22 @@ public class LambdaInput
this.fetch_axe_input(client, state, true);
});
InputManager.update_bindings();
InputManager.stream_active_bindings().forEach(binding -> binding.handle(client, InputManager.get_binding_state(binding)));
InputManager.update_bindings(client);
if (this.ignore_next_a > 0)
this.ignore_next_a--;
if (client.currentScreen instanceof LambdaControlsControlsScreen && InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::is_unpressed))
{
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
if (controls_screen.focused_binding != null) {
int[] buttons = new int[controls_screen.current_buttons.size()];
for (int i = 0; i < controls_screen.current_buttons.size(); i++)
buttons[i] = controls_screen.current_buttons.get(i);
controls_screen.focused_binding.set_button(buttons);
controls_screen.focused_binding = null;
}
}
}
/**
@@ -236,31 +246,17 @@ public class LambdaInput
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
value *= -1.0F;
//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, 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, new int[]{button});
controls_screen.focused_binding = null;
controls_screen.current_buttons.add(button);
return;
}
}
@@ -344,8 +340,7 @@ public class LambdaInput
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, new int[]{axis_as_button(axis, as_button_state == 1)});
controls_screen.focused_binding = null;
controls_screen.current_buttons.add(axis_as_button(axis, as_button_state == 1));
return;
}
}

View File

@@ -0,0 +1,30 @@
/*
* 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.LambdaControls;
import org.jetbrains.annotations.NotNull;
/**
* Represents a compatibility handler for a mod.
*
* @author LambdAurora
* @version 1.1.0
* @since 1.1.0
*/
public interface CompatHandler
{
/**
* Handles compatibility of a mod.
*
* @param mod This mod instance.
*/
void handle(@NotNull LambdaControls mod);
}

View File

@@ -9,33 +9,34 @@
package me.lambdaurora.lambdacontrols.compat;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.LambdaControls;
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;
import org.jetbrains.annotations.NotNull;
/**
* Represents a compatibility handler.
*
* @author LambdAurora
* @version 1.1.0
* @since 1.1.0
*/
public class LambdaControlsCompat
{
private static final String OKZOOMER_CLASS_PATH = "io.github.joaoh1.okzoomer.OkZoomer";
public static void init()
/**
* Initializes compatibility with other mods if needed.
*
* @param mod The mod instance.
*/
public static void init(@NotNull LambdaControls mod)
{
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);
}));
mod.log("Adding okzoomer compatibility...");
new OkZoomerCompat().handle(mod);
}
InputManager.load_button_bindings(mod.config);
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.LambdaControls;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.controller.InputManager;
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
/**
* Represents a compatibility handler for OkZoomer.
*
* @author LambdAurora
* @version 1.1.0
* @since 1.1.0
*/
public class OkZoomerCompat implements CompatHandler
{
@Override
public void handle(@NotNull LambdaControls mod)
{
LambdaReflection.get_first_field_of_type(io.github.joaoh1.okzoomer.OkZoomer.class, FabricKeyBinding.class)
.map(field -> (FabricKeyBinding) LambdaReflection.get_field_value(null, field))
.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);
});
}
}

View File

@@ -10,12 +10,10 @@
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;
@@ -60,21 +58,10 @@ public class ButtonBinding implements Nameable
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));
Collections.singletonList(InputHandlers::handle_screenshot), 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));
Arrays.asList(PressAction.DEFAULT_ACTION, InputHandlers::handle_toggle_sneak), 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));
@@ -91,7 +78,7 @@ public class ButtonBinding implements Nameable
public ButtonBinding(@NotNull String key, int[] default_button, @NotNull List<PressAction> actions, boolean has_cooldown)
{
this.button = this.default_button = default_button;
this.set_button(this.default_button = default_button);
this.key = key;
this.actions.addAll(actions);
this.has_cooldown = has_cooldown;
@@ -120,6 +107,9 @@ public class ButtonBinding implements Nameable
public void set_button(int[] button)
{
this.button = button;
if (InputManager.has_binding(this))
InputManager.sort_bindings();
}
/**
@@ -214,8 +204,10 @@ public class ButtonBinding implements Nameable
{
if (state == ButtonState.REPEAT && this.has_cooldown && this.cooldown != 0)
return;
if (this.has_cooldown && state.is_pressed())
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;

View File

@@ -11,9 +11,11 @@ package me.lambdaurora.lambdacontrols.controller;
import me.lambdaurora.lambdacontrols.ButtonState;
import me.lambdaurora.lambdacontrols.util.CreativeInventoryScreenAccessor;
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.util.ScreenshotUtils;
import net.minecraft.item.ItemGroup;
import org.jetbrains.annotations.NotNull;
@@ -26,9 +28,14 @@ import org.jetbrains.annotations.NotNull;
*/
public class InputHandlers
{
private InputHandlers() {}
private static int hotbar_cooldown = 0;
public static PressAction handle_hotbar(boolean right) {
private InputHandlers()
{
}
public static PressAction handle_hotbar(boolean right)
{
return (client, button, action) -> {
if (action == ButtonState.RELEASE)
return false;
@@ -55,7 +62,8 @@ public class InputHandlers
};
}
public static boolean handle_pause_game(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, @NotNull ButtonState action) {
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)
@@ -67,4 +75,29 @@ public class InputHandlers
}
return true;
}
/**
* Handles the screenshot action.
*
* @param client The client instance.
* @param binding The binding which fired the action.
* @param action The action done on the binding.
* @return True if handled, else false.
*/
public static boolean handle_screenshot(@NotNull MinecraftClient client, @NotNull ButtonBinding binding, @NotNull ButtonState 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;
}
public static boolean handle_toggle_sneak(@NotNull MinecraftClient client, @NotNull ButtonBinding button, @NotNull ButtonState 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;
}
}

View File

@@ -11,11 +11,13 @@ package me.lambdaurora.lambdacontrols.controller;
import me.lambdaurora.lambdacontrols.ButtonState;
import me.lambdaurora.lambdacontrols.LambdaControlsConfig;
import net.minecraft.client.MinecraftClient;
import org.aperlambda.lambdacommon.Identifier;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -31,34 +33,86 @@ public class InputManager
private static final List<ButtonCategory> CATEGORIES = new ArrayList<>();
public static final Map<Integer, ButtonState> STATES = new HashMap<>();
/**
* Returns whether the specified binding is registered or not.
*
* @param binding The binding to check.
* @return True if the binding is registered, else false.
*/
public static boolean has_binding(@NotNull ButtonBinding binding)
{
return BINDINGS.contains(binding);
}
/**
* Returns whether the specified binding is registered or not.
*
* @param name The name of the binding to check.
* @return True if the binding is registered, else false.
*/
public static boolean has_binding(@NotNull String name)
{
return BINDINGS.parallelStream().map(ButtonBinding::get_name).anyMatch(binding -> binding.equalsIgnoreCase(name));
}
/**
* Returns whether the specified binding is registered or not.
*
* @param identifier The identifier of the binding to check.
* @return True if the binding is registered, else false.
*/
public static boolean has_binding(@NotNull Identifier identifier)
{
return has_binding(identifier.get_namespace() + "." + identifier.get_name());
}
/**
* Registers a button binding.
*
* @param binding The binding to register.
* @return The registered binding.
*/
public static @NotNull ButtonBinding register_binding(@NotNull ButtonBinding binding)
{
if (BINDINGS.contains(binding))
if (has_binding(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)
public static @NotNull 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)
public static @NotNull 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)
public static @NotNull 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)
public static @NotNull 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);
}
/**
* Sorts bindings to get bindings with the higher button counts first.
*/
public static void sort_bindings()
{
synchronized (BINDINGS) {
List<ButtonBinding> sorted_bindings = BINDINGS.stream().sorted(Collections.reverseOrder(Comparator.comparingInt(binding -> binding.get_button().length)))
.collect(Collectors.toList());
BINDINGS.clear();
BINDINGS.addAll(sorted_bindings);
}
}
/**
* Registers a category of button bindings.
*
@@ -95,7 +149,8 @@ public class InputManager
*/
public static void load_button_bindings(@NotNull LambdaControlsConfig config)
{
BINDINGS.forEach(config::load_button_binding);
List<ButtonBinding> load_queue = new ArrayList<>(BINDINGS);
load_queue.forEach(config::load_button_binding);
}
/**
@@ -156,6 +211,18 @@ public class InputManager
return count == buttons1.length;
}
/**
* Returns whether the button set contains the specified button or not.
*
* @param buttons The button set.
* @param button The button to check.
* @return True if the button set contains the specified button, else false.
*/
public static boolean contains_button(int[] buttons, int button)
{
return Arrays.stream(buttons).anyMatch(btn -> btn == button);
}
/**
* Updates the button states.
*/
@@ -169,9 +236,29 @@ public class InputManager
});
}
public static void update_bindings() {
BINDINGS.forEach(binding -> binding.pressed = get_binding_state(binding).is_pressed());
BINDINGS.forEach(ButtonBinding::update);
public static void update_bindings(@NotNull MinecraftClient client)
{
List<Integer> skip_buttons = new ArrayList<>();
Map<ButtonBinding, ButtonState> states = new HashMap<>();
for (ButtonBinding binding : BINDINGS) {
ButtonState binding_state = get_binding_state(binding);
if (skip_buttons.stream().anyMatch(btn -> contains_button(binding.get_button(), btn))) {
if (binding.pressed)
binding_state = ButtonState.RELEASE;
else
binding_state = ButtonState.NONE;
}
binding.pressed = binding_state.is_pressed();
binding.update();
if (binding.pressed)
Arrays.stream(binding.get_button()).forEach(skip_buttons::add);
states.put(binding, binding_state);
}
states.forEach((binding, state) -> {
if (state != ButtonState.NONE)
binding.handle(client, state);
});
}
public static @NotNull Stream<ButtonBinding> stream_bindings()
@@ -179,17 +266,6 @@ public class InputManager
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();

View File

@@ -80,7 +80,10 @@ 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, 110, this.binding, btn -> gui.focused_binding = binding)
this.edit_button = new ControllerButtonWidget(0, 0, 110, this.binding, btn -> {
gui.focused_binding = binding;
gui.current_buttons.clear();
})
{
protected String getNarrationMessage()
{

View File

@@ -9,19 +9,19 @@
package me.lambdaurora.lambdacontrols.gui;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
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;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.TranslatableText;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
@@ -32,12 +32,11 @@ public class LambdaControlsControlsScreen extends Screen
{
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;
public List<Integer> current_buttons = new ArrayList<>();
public LambdaControlsControlsScreen(@NotNull Screen parent, boolean hide_settings)
{
@@ -45,18 +44,6 @@ public class LambdaControlsControlsScreen extends Screen
this.parent = parent;
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) {
this.mod.config.set_invert_right_x_axis(new_value);
}
});
this.inverts_right_y_axis = new BooleanOption("lambdacontrols.menu.invert_right_y_axis", game_options -> this.mod.config.does_invert_right_y_axis(),
(game_options, new_value) -> {
synchronized (this.mod.config) {
this.mod.config.set_invert_right_y_axis(new_value);
}
});
}
@Override
@@ -69,8 +56,6 @@ 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(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)

View File

@@ -21,6 +21,7 @@ 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.BooleanOption;
import net.minecraft.client.options.CyclingOption;
import net.minecraft.client.options.GameOptions;
import net.minecraft.client.options.Option;
@@ -36,23 +37,28 @@ 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 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 static final String GAMEPAD_TOOL_URL = "http://generalarcade.com/gamepadtool/";
final LambdaControls mod;
private final Screen parent;
private final boolean hide_controls;
// General options
private final Option auto_switch_mode_option;
private final Option rotation_speed_option;
private final Option mouse_speed_option;
private final Option reset_option;
// Controller options
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 inverts_right_x_axis;
private final Option inverts_right_y_axis;
// Hud options
private final Option hud_enable_option;
private final Option hud_side_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, boolean hide_controls)
{
@@ -60,8 +66,29 @@ public class LambdaControlsSettingsScreen extends Screen
this.mod = LambdaControls.get();
this.parent = parent;
this.hide_controls = hide_controls;
// General options
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.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),
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),
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());
});
// Controller options
this.controller_option = new CyclingOption("lambdacontrols.menu.controller", (game_options, amount) -> {
int current_id = this.mod.config.get_controller().get_id();
current_id += amount;
@@ -98,12 +125,6 @@ public class LambdaControlsSettingsScreen extends Screen
(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(),
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(),
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) {
@@ -113,25 +134,25 @@ public class LambdaControlsSettingsScreen extends Screen
String value = String.valueOf(option.get(options));
return option.getDisplayPrefix() + value.substring(0, Math.min(value.length(), 5));
}, 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(),
this.inverts_right_x_axis = new SpruceBooleanOption("lambdacontrols.menu.invert_right_x_axis", game_options -> this.mod.config.does_invert_right_x_axis(),
(game_options, new_value) -> {
synchronized (this.mod.config) {
this.mod.config.set_rotation_speed(new_value);
this.mod.config.set_invert_right_x_axis(new_value);
}
}, (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(),
}, null);
this.inverts_right_y_axis = new SpruceBooleanOption("lambdacontrols.menu.invert_right_y_axis", game_options -> this.mod.config.does_invert_right_y_axis(),
(game_options, new_value) -> {
synchronized (this.mod.config) {
this.mod.config.set_mouse_speed(new_value);
this.mod.config.set_invert_right_y_axis(new_value);
}
}, (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());
});
}, null);
// HUD options
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(),
new TranslatableText("lambdacontrols.tooltip.hud_side"));
}
@Override
@@ -178,14 +199,18 @@ public class LambdaControlsSettingsScreen extends Screen
}));
this.list = new ButtonListWidget(this.minecraft, this.width, this.height, 43, this.height - 29 - this.get_text_height(), 25);
// General options
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);
// Controller options
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.addOptionEntry(this.inverts_right_x_axis, this.inverts_right_y_axis);
this.list.addSingleOptionEntry(new ReloadControllerMappingsOption());
// HUD options
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);

View File

@@ -29,6 +29,7 @@
"lambdacontrols.action.toggle_perspective": "Toggle Perspective",
"lambdacontrols.action.toggle_smooth_camera": "Toggle Cinematic Camera",
"lambdacontrols.action.use": "Use",
"lambdacontrols.action.zoom": "Zoom",
"lambdacontrols.button.a": "A",
"lambdacontrols.button.b": "B",
"lambdacontrols.button.x": "X",

View File

@@ -29,6 +29,7 @@
"lambdacontrols.action.toggle_perspective": "Changer de point de vue",
"lambdacontrols.action.toggle_smooth_camera": "Basculer en mode cinématique",
"lambdacontrols.action.use": "Utiliser",
"lambdacontrols.action.zoom": "Zoom",
"lambdacontrols.button.a": "A",
"lambdacontrols.button.b": "B",
"lambdacontrols.button.x": "X",

View File

@@ -29,6 +29,7 @@
"lambdacontrols.action.toggle_perspective": "Changer de point de vue",
"lambdacontrols.action.toggle_smooth_camera": "Basculer en mode cinématique",
"lambdacontrols.action.use": "Utiliser",
"lambdacontrols.action.zoom": "Zoom",
"lambdacontrols.button.a": "A",
"lambdacontrols.button.b": "B",
"lambdacontrols.button.x": "X",

View File

@@ -33,7 +33,8 @@
"spruceui": ">=1.0.1"
},
"recommends": {
"modmenu": ">=1.8.0+build.16"
"modmenu": ">=1.8.0+build.16",
"okzoomer": ">=1.0.3"
},
"suggests": {
"flamingo": "*"