From 82f67e7af9ef4ad83d67fc7af2aa342d6efb6ed7 Mon Sep 17 00:00:00 2001 From: LambdAurora Date: Thu, 5 Dec 2019 21:42:28 +0100 Subject: [PATCH] :sparkles: Add HUD and other improvements. --- .../lambdacontrols/ButtonBinding.java | 37 +++++++- .../lambdacontrols/Controller.java | 9 -- .../lambdacontrols/ControllerInput.java | 39 ++------ .../lambdacontrols/ControllerType.java | 87 ++++++++++++++++++ .../lambdacontrols/LambdaControls.java | 63 ++++++++++++- .../lambdacontrols/LambdaControlsConfig.java | 52 ++++++++++- .../lambdacontrols/gui/LambdaControlsHud.java | 52 +++++++---- .../gui/LambdaControlsSettingsScreen.java | 76 ++++++++------- .../gui/TouchscreenOverlay.java | 28 +++--- .../mixin/AbstractContainerScreenMixin.java | 21 +++++ .../lambdacontrols/mixin/InGameHudMixin.java | 14 +-- .../lambdacontrols/mixin/KeyBindingMixin.java | 4 +- .../lambdacontrols/mixin/MouseMixin.java | 5 +- .../mixin/SettingsScreenMixin.java | 3 + .../util/AbstractContainerScreenAccessor.java | 3 - .../lambdacontrols/util/CustomInGameHud.java | 21 ----- ...eyBinding.java => KeyBindingAccessor.java} | 2 +- .../assets/lambdacontrols/lang/en_us.json | 26 +++++- .../textures/gui/controller_buttons.png | Bin 3870 -> 8810 bytes src/main/resources/config.toml | 4 + src/main/resources/fabric.mod.json | 2 +- 21 files changed, 391 insertions(+), 157 deletions(-) create mode 100644 src/main/java/me/lambdaurora/lambdacontrols/ControllerType.java delete mode 100644 src/main/java/me/lambdaurora/lambdacontrols/util/CustomInGameHud.java rename src/main/java/me/lambdaurora/lambdacontrols/util/{LambdaKeyBinding.java => KeyBindingAccessor.java} (95%) diff --git a/src/main/java/me/lambdaurora/lambdacontrols/ButtonBinding.java b/src/main/java/me/lambdaurora/lambdacontrols/ButtonBinding.java index e52bb10..2246036 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/ButtonBinding.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/ButtonBinding.java @@ -9,9 +9,10 @@ package me.lambdaurora.lambdacontrols; -import me.lambdaurora.lambdacontrols.util.LambdaKeyBinding; +import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor; import net.minecraft.client.options.GameOptions; import net.minecraft.client.options.KeyBinding; +import org.aperlambda.lambdacommon.utils.Nameable; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; @@ -25,9 +26,10 @@ import java.util.Optional; * * @author LambdAurora */ -public class ButtonBinding +public class ButtonBinding implements Nameable { private static final List BINDINGS = new ArrayList<>(); + public static final ButtonBinding ATTACK = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true), "attack"); public static final ButtonBinding BACK = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, false), "back"); public static final ButtonBinding DROP_ITEM = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_B, "drop_item"); public static final ButtonBinding FORWARD = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, true), "forward"); @@ -86,6 +88,22 @@ public class ButtonBinding return this.pressed; } + @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. * @@ -105,7 +123,18 @@ public class ButtonBinding */ public static int axis_as_button(int axis, boolean positive) { - return positive ? GLFW.GLFW_GAMEPAD_BUTTON_LAST + GLFW.GLFW_GAMEPAD_AXIS_LAST + axis : GLFW.GLFW_GAMEPAD_BUTTON_LAST + GLFW.GLFW_GAMEPAD_AXIS_LAST * 2 + axis; + 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) @@ -129,6 +158,6 @@ public class ButtonBinding { BINDINGS.parallelStream().filter(binding -> binding.button == button) .map(ButtonBinding::as_key_binding) - .forEach(binding -> binding.ifPresent(key_binding -> ((LambdaKeyBinding) key_binding).handle_press_state(state))); + .forEach(binding -> binding.ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(state))); } } diff --git a/src/main/java/me/lambdaurora/lambdacontrols/Controller.java b/src/main/java/me/lambdaurora/lambdacontrols/Controller.java index dd370bd..b7aec85 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/Controller.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/Controller.java @@ -11,7 +11,6 @@ package me.lambdaurora.lambdacontrols; import org.aperlambda.lambdacommon.utils.Nameable; import org.jetbrains.annotations.NotNull; -import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWGamepadState; @@ -131,14 +130,6 @@ public class Controller implements Nameable .max(Comparator.comparingInt(Controller::get_id)); } - private static ByteBuffer resizeBuffer(ByteBuffer buffer, int new_capacity) - { - ByteBuffer newBuffer = BufferUtils.createByteBuffer(new_capacity); - buffer.flip(); - newBuffer.put(buffer); - return newBuffer; - } - /** * Reads the specified resource and returns the raw data as a ByteBuffer. * diff --git a/src/main/java/me/lambdaurora/lambdacontrols/ControllerInput.java b/src/main/java/me/lambdaurora/lambdacontrols/ControllerInput.java index a8102f9..68af7aa 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/ControllerInput.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/ControllerInput.java @@ -11,7 +11,7 @@ package me.lambdaurora.lambdacontrols; import me.lambdaurora.lambdacontrols.util.AbstractContainerScreenAccessor; import me.lambdaurora.lambdacontrols.util.CreativeInventoryScreenAccessor; -import me.lambdaurora.lambdacontrols.util.LambdaKeyBinding; +import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor; import me.lambdaurora.lambdacontrols.util.MouseAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; @@ -23,7 +23,6 @@ import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.world.WorldListWidget; import net.minecraft.client.gui.widget.AbstractPressableButtonWidget; import net.minecraft.client.gui.widget.SliderWidget; -import net.minecraft.client.options.KeyBinding; import net.minecraft.container.Slot; import net.minecraft.container.SlotActionType; import net.minecraft.item.ItemGroup; @@ -57,7 +56,6 @@ public class ControllerInput private static final Map AXIS_COOLDOWNS = new HashMap<>(); private final LambdaControlsConfig config; private int action_gui_cooldown = 0; - private boolean continuous_sneak = false; private int ignore_next_a = 0; private int last_sneak = 0; private double prev_target_yaw = 0.0; @@ -238,25 +236,11 @@ public class ControllerInput return; } } - } - // Handles sneak button and continuous sneak. - if (SNEAK.is_button(button) && client.player != null) { - if (action == 0) { - if (this.continuous_sneak) { - this.set_sneaking(client, this.continuous_sneak = false); - } else if (this.last_sneak > 3) { - this.set_sneaking(client, this.continuous_sneak = true); - } else { - this.set_sneaking(client, true); - this.last_sneak = 15; - } - } else if (action == 1) { - if (this.continuous_sneak) - return; - this.set_sneaking(client, false); + // Handles sneak button. + if (SNEAK.is_button(button) && client.player != null) { + this.toggle_sneaking(client); } - return; } if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !this.is_screen_interactive(client.currentScreen) && this.action_gui_cooldown == 0 && this.ignore_next_a == 0) { @@ -273,8 +257,6 @@ public class ControllerInput if (client.currentScreen == null && action != 2) { ButtonBinding.handle_button(button, state); - //Optional key_binding = this.config.get_keybind("button_" + button); - //key_binding.ifPresent(keyBinding -> ((LambdaKeyBinding) keyBinding).handle_press_state(action != 1)); } } @@ -291,7 +273,7 @@ public class ControllerInput boolean previous_minus_state = AXIS_STATES.getOrDefault(axis_minus, false); if (current_plus_state != previous_plus_state) { - this.config.get_keybind("axis_" + axis + "+").ifPresent(key_binding -> ((LambdaKeyBinding) key_binding).handle_press_state(current_plus_state)); + this.config.get_keybind("axis_" + axis + "+").ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(current_plus_state)); if (current_plus_state) AXIS_COOLDOWNS.put(axis, 5); } else if (current_plus_state) { @@ -301,7 +283,7 @@ public class ControllerInput } if (current_minus_state != previous_minus_state) { - this.config.get_keybind("axis_" + axis + "-").ifPresent(key_binding -> ((LambdaKeyBinding) key_binding).handle_press_state(current_minus_state)); + this.config.get_keybind("axis_" + axis + "-").ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(current_minus_state)); if (current_minus_state) AXIS_COOLDOWNS.put(axis_minus, 5); } else if (current_minus_state) { @@ -481,14 +463,13 @@ public class ControllerInput } /** - * Sets if the player is sneaking. + * Toggles whether the player is sneaking. * - * @param client The client's instance. - * @param sneaking True if the player is sneaking, else false. + * @param client The client's instance. */ - private void set_sneaking(@NotNull MinecraftClient client, boolean sneaking) + private void toggle_sneaking(@NotNull MinecraftClient client) { - ((LambdaKeyBinding) client.options.keySneak).handle_press_state(sneaking); + ((KeyBindingAccessor) client.options.keySneak).handle_press_state(!client.options.keySneak.isPressed()); } private boolean change_focus(@NotNull Screen screen, boolean down) diff --git a/src/main/java/me/lambdaurora/lambdacontrols/ControllerType.java b/src/main/java/me/lambdaurora/lambdacontrols/ControllerType.java new file mode 100644 index 0000000..83899fc --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdacontrols/ControllerType.java @@ -0,0 +1,87 @@ +/* + * Copyright © 2019 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols; + +import net.minecraft.client.resource.language.I18n; +import org.aperlambda.lambdacommon.utils.Nameable; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.Optional; + +/** + * Represents a controller type. + */ +public enum ControllerType implements Nameable +{ + DEFAULT(0), + PLAYSTATION(1), + SWITCH(2), + XBOX(3), + STEAM(4), + OUYA(5); + + private final int id; + + ControllerType(int id) + { + this.id = id; + } + + /** + * Returns the controller type's identifier. + * + * @return The controller type's identifier. + */ + public int get_id() + { + return this.id; + } + + /** + * Returns the next controller type available. + * + * @return The next available controller type. + */ + public ControllerType next() + { + ControllerType[] v = values(); + if (v.length == this.ordinal() + 1) + return v[0]; + return v[this.ordinal() + 1]; + } + + /** + * Gets the translated name of this controller type. + * + * @return The translated name of this controller type. + */ + public String get_translated_name() + { + return I18n.translate("lambdacontrols.controller_type." + this.get_name()); + } + + @Override + public @NotNull String get_name() + { + return this.name().toLowerCase(); + } + + /** + * Gets the controller type from its identifier. + * + * @param id The identifier of the controller type. + * @return The controller type if found, else empty. + */ + public static Optional by_id(@NotNull String id) + { + return Arrays.stream(values()).filter(mode -> mode.get_name().equalsIgnoreCase(id)).findFirst(); + } +} diff --git a/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java b/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java index 5061173..fbd9040 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java @@ -9,26 +9,31 @@ package me.lambdaurora.lambdacontrols; +import com.mojang.blaze3d.platform.GlStateManager; import net.fabricmc.api.ClientModInitializer; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.resource.language.I18n; import net.minecraft.client.toast.SystemToast; import net.minecraft.text.LiteralText; import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; - /** * Represents the LambdaControls mod. */ public class LambdaControls implements ClientModInitializer { - private static LambdaControls INSTANCE; - public final Logger logger = LogManager.getLogger("LambdaControls"); - public final LambdaControlsConfig config = new LambdaControlsConfig(this); - public final ControllerInput controller_input = new ControllerInput(this); + private static LambdaControls INSTANCE; + public static final Identifier CONTROLLER_BUTTONS = new Identifier("lambdacontrols", "textures/gui/controller_buttons.png"); + public final Logger logger = LogManager.getLogger("LambdaControls"); + public final LambdaControlsConfig config = new LambdaControlsConfig(this); + public final ControllerInput controller_input = new ControllerInput(this); @Override public void onInitializeClient() @@ -93,4 +98,52 @@ public class LambdaControls implements ClientModInitializer { return INSTANCE; } + + public static int draw_button_tip(int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client) + { + 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) + { + int controller_type = get().config.get_controller_type().get_id(); + String translated_action = I18n.translate(action); + + if (display) { + int button_offset = button * 15; + switch (button) { + case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB: + button_offset = 15 * 15; + break; + case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: + button_offset = 16 * 15; + break; + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100: + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200: + button_offset = 9 * 15; + break; + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100: + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200: + button_offset = 10 * 15; + break; + } + + client.getTextureManager().bindTexture(LambdaControls.CONTROLLER_BUTTONS); + GlStateManager.disableDepthTest(); + + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + DrawableHelper.blit(x, y, (float) button_offset, (float) (controller_type * 15), 15, 15, 256, 256); + GlStateManager.enableDepthTest(); + + int text_y = (15 - client.textRenderer.fontHeight) / 2; + client.textRenderer.drawWithShadow(translated_action, (float) (x + 15 + 5), (float) (y + text_y), 14737632); + } + + return display ? get_button_tip_width(translated_action, client.textRenderer) : -10; + } + + private static int get_button_tip_width(@NotNull String action, @NotNull TextRenderer text_renderer) + { + return 15 + 5 + text_renderer.getStringWidth(action); + } } diff --git a/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java b/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java index f1fb390..0221568 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/LambdaControlsConfig.java @@ -30,6 +30,9 @@ public class LambdaControlsConfig private final Map keybinding_mappings = new HashMap<>(); private final LambdaControls mod; private ControlsMode controls_mode; + private ControllerType controller_type; + // HUD settings. + private boolean hud_enable; private HudSide hud_side; // Controller settings private double dead_zone; @@ -52,12 +55,15 @@ public class LambdaControlsConfig this.config.load(); this.mod.log("Configuration loaded."); this.controls_mode = ControlsMode.by_id(this.config.getOrElse("controls", "default")).orElse(ControlsMode.DEFAULT); + // 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); - // Controller settings + // 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); - // Controller controls + // Controller controls. this.back_button = this.config.getOrElse("controller.controls.back", "none").toLowerCase(); this.forward_button = this.config.getOrElse("controller.controls.forward", "none").toLowerCase(); this.left_button = this.config.getOrElse("controller.controls.left", "none").toLowerCase(); @@ -113,6 +119,27 @@ public class LambdaControlsConfig this.config.set("controls", controls_mode.get_name()); } + /** + * Returns whether the HUD is enabled. + * + * @return True if the HUD is enabled, else false. + */ + public boolean is_hud_enabled() + { + return this.hud_enable; + } + + /** + * Sets whether the HUD is enabled. + * + * @param enable True if the HUD is enabled, else false. + */ + public void set_hud_enabled(boolean enable) + { + this.hud_enable = enable; + this.config.set("hud.enable", this.hud_enable); + } + /** * Gets the HUD side from the configuration. * @@ -160,6 +187,27 @@ public class LambdaControlsConfig this.config.set("controller.id", controller.get_id()); } + /** + * Gets the controller's type. + * + * @return The controller's type. + */ + public @NotNull ControllerType get_controller_type() + { + return this.controller_type; + } + + /** + * Sets the controller's type. + * + * @param controller_type The controller's type. + */ + public void set_controller_type(@NotNull ControllerType controller_type) + { + this.controller_type = controller_type; + this.config.set("controller.type", controller_type.get_name()); + } + /** * Gets the controller's dead zone from the configuration. * diff --git a/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsHud.java b/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsHud.java index 3aabfa5..a24918c 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsHud.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsHud.java @@ -9,45 +9,57 @@ package me.lambdaurora.lambdacontrols.gui; +import me.lambdaurora.lambdacontrols.ButtonBinding; import me.lambdaurora.lambdacontrols.ControlsMode; import me.lambdaurora.lambdacontrols.LambdaControls; -import me.lambdaurora.lambdacontrols.util.LambdaKeyBinding; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.util.hit.HitResult; import org.jetbrains.annotations.NotNull; -import org.lwjgl.glfw.GLFW; /** * Represents the LambdaControls HUD. */ -public class LambdaControlsHud +public class LambdaControlsHud extends DrawableHelper { private final MinecraftClient client; private final LambdaControls mod; - private ButtonWidget jump_button; public LambdaControlsHud(@NotNull MinecraftClient client, @NotNull LambdaControls mod) { this.client = client; this.mod = mod; - this.jump_button = new ButtonWidget(50, 50, 20, 20, "J", button-> {}); } - public void render(float delta) + /** + * Renders the LambdaControls' HUD. + */ + public void render() { - if (this.mod.config.get_controls_mode() == ControlsMode.TOUCHSCREEN) - this.render_touchscreen(delta); - } - - public void render_touchscreen(float delta) - { - //this.jump_button.render((int) this.client.mouse.getX(), (int) this.client.mouse.getY(), delta); - } - - public void on_input(double x, double y, int button, int action) - { - if (this.jump_button.mouseClicked(x, y, button)) { - ((LambdaKeyBinding) this.client.options.keyJump).handle_press_state(action != GLFW.GLFW_RELEASE); + if (this.mod.config.get_controls_mode() == ControlsMode.CONTROLLER && this.mod.config.is_hud_enabled() && this.client.currentScreen == null) { + 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, !client.player.getMainHandStack().isEmpty()) + 10; + this.draw_button_tip(x, y, ButtonBinding.ATTACK.get_button(), + client.hitResult.getType() == HitResult.Type.BLOCK ? "lambdacontrols.action.hit" : ButtonBinding.ATTACK.get_translation_key(), + client.hitResult.getType() != HitResult.Type.MISS); } } + + private int bottom(int y) + { + return this.client.window.getScaledHeight() - y - 15; + } + + private int draw_button_tip(int x, int y, @NotNull ButtonBinding button, boolean display) + { + 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) + { + return LambdaControls.draw_button_tip(x, y, button, action, display, this.client); + } } diff --git a/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsSettingsScreen.java b/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsSettingsScreen.java index 3d27411..d54bb8a 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsSettingsScreen.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/gui/LambdaControlsSettingsScreen.java @@ -11,10 +11,10 @@ package me.lambdaurora.lambdacontrols.gui; import me.lambdaurora.lambdacontrols.Controller; import me.lambdaurora.lambdacontrols.ControlsMode; -import me.lambdaurora.lambdacontrols.HudSide; import me.lambdaurora.lambdacontrols.LambdaControls; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.controls.ControlsOptionsScreen; +import net.minecraft.client.gui.widget.ButtonListWidget; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.options.*; import net.minecraft.client.resource.language.I18n; @@ -27,16 +27,19 @@ import org.lwjgl.glfw.GLFW; */ public class LambdaControlsSettingsScreen extends Screen { - private final LambdaControls mod; - private final Screen parent; - private final GameOptions options; - private final Option controller_option; - private final Option dead_zone_option; - private final Option rotation_speed_option; - private final Option mouse_speed_option; - private final Option inverts_right_x_axis; - private final Option inverts_right_y_axis; - private int buttons_y = 18; + private final LambdaControls mod; + private final Screen parent; + private final GameOptions options; + private final Option controller_option; + private final Option controller_type_option; + private final Option hud_enable_option; + private final Option hud_side_option; + private final Option dead_zone_option; + private final Option rotation_speed_option; + private final Option mouse_speed_option; + private final Option inverts_right_x_axis; + private final Option inverts_right_y_axis; + private ButtonListWidget list; public LambdaControlsSettingsScreen(Screen parent, @NotNull GameOptions options) { @@ -51,6 +54,14 @@ public class LambdaControlsSettingsScreen extends Screen current_id = GLFW.GLFW_JOYSTICK_1; this.mod.config.set_controller(Controller.by_id(current_id)); }, (game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_controller().get_name()); + this.controller_type_option = new CyclingOption("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, 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, new_value) -> { synchronized (this.mod.config) { @@ -100,46 +111,47 @@ public class LambdaControlsSettingsScreen extends Screen super.onClose(); } + private int get_text_height() + { + return (5 + this.font.fontHeight) * 3 + 5; + } + @Override protected void init() { super.init(); - int button_height = 20, spacing = 5; - this.addButton(new ButtonWidget(this.width / 2 - 155, this.buttons_y, 150, button_height, I18n.translate("lambdacontrols.menu.controls_mode") + ": " + this.mod.config.get_controls_mode().get_translated_name(), + 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(), 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, this.buttons_y, 150, button_height, I18n.translate("options.controls"), + this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, button_height, I18n.translate("options.controls"), btn -> this.minecraft.openScreen(new ControlsOptionsScreen(this, this.options)))); - this.addButton(new ButtonWidget(this.width / 2 - 155, (this.buttons_y += spacing + button_height), 150, button_height, I18n.translate("lambdacontrols.menu.hud_side") + ": " + this.mod.config.get_hud_side().get_translated_name(), - btn -> { - HudSide next = this.mod.config.get_hud_side().next(); - btn.setMessage(I18n.translate("lambdacontrols.menu.hud_side") + ": " + next.get_translated_name()); - this.mod.config.set_hud_side(next); - this.mod.config.save(); - })); - this.addButton(this.controller_option.createButton(this.options, this.width / 2 - 155, (this.buttons_y += spacing + button_height), 150)); - this.addButton(this.dead_zone_option.createButton(this.options, this.width / 2 - 155 + 160, this.buttons_y, 150)); - this.addButton(this.rotation_speed_option.createButton(this.options, this.width / 2 - 155, (this.buttons_y += spacing + button_height), 150)); - this.addButton(this.mouse_speed_option.createButton(this.options, this.width / 2 - 155 + 160, this.buttons_y, 150)); - this.addButton(this.inverts_right_x_axis.createButton(this.options, this.width / 2 - 155, (this.buttons_y += spacing + button_height), 150)); - this.addButton(this.inverts_right_y_axis.createButton(this.options, this.width / 2 - 155 + 160, this.buttons_y, 150)); + + 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.addOptionEntry(this.rotation_speed_option, this.mouse_speed_option); + this.list.addOptionEntry(this.inverts_right_x_axis, this.inverts_right_y_axis); + this.children.add(this.list); + this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 300, button_height, I18n.translate("gui.done"), (buttonWidget) -> this.minecraft.openScreen(this.parent))); - - this.buttons_y += spacing + button_height; } @Override public void render(int mouseX, int mouseY, float delta) { this.renderBackground(); + this.list.render(mouseX, mouseY, delta); super.render(mouseX, mouseY, delta); - this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.1"), this.width / 2, this.buttons_y + (20 - 8) / 2, 10526880); - this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.2"), this.width / 2, this.buttons_y + (20 - 8) / 2 + font.fontHeight + 5, 10526880); - this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.3"), this.width / 2, this.buttons_y + (20 - 8) / 2 + font.fontHeight * 2 + 10, 10526880); + this.drawCenteredString(this.font, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215); + this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.1"), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 3, 10526880); + this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.2"), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, 10526880); + this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.3"), this.width / 2, this.height - 29 - (5 + this.font.fontHeight), 10526880); } } diff --git a/src/main/java/me/lambdaurora/lambdacontrols/gui/TouchscreenOverlay.java b/src/main/java/me/lambdaurora/lambdacontrols/gui/TouchscreenOverlay.java index 0a33e63..c88f704 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/gui/TouchscreenOverlay.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/gui/TouchscreenOverlay.java @@ -11,7 +11,7 @@ package me.lambdaurora.lambdacontrols.gui; import me.lambdaurora.lambdacontrols.HudSide; import me.lambdaurora.lambdacontrols.LambdaControls; -import me.lambdaurora.lambdacontrols.util.LambdaKeyBinding; +import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor; import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.client.gui.screen.GameMenuScreen; import net.minecraft.client.gui.screen.Screen; @@ -122,7 +122,7 @@ public class TouchscreenOverlay extends Screen */ private void handle_jump(boolean state) { - ((LambdaKeyBinding) this.minecraft.options.keyJump).handle_press_state(state); + ((KeyBindingAccessor) this.minecraft.options.keyJump).handle_press_state(state); } @Override @@ -187,7 +187,7 @@ 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 -> ((LambdaKeyBinding) this.minecraft.options.keyDrop).handle_press_state(state))); + 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::handle_jump)); @@ -198,13 +198,13 @@ public class TouchscreenOverlay extends Screen this.addButton(this.fly_up_button = new TouchscreenButtonWidget(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 -> ((LambdaKeyBinding) this.minecraft.options.keySneak).handle_press_state(state))); + 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 -> { if (state) { - ((LambdaKeyBinding) this.minecraft.options.keySneak).handle_press_state(true); + ((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(true); this.start_sneak_button.visible = false; this.end_sneak_button.visible = true; } @@ -212,7 +212,7 @@ public class TouchscreenOverlay extends Screen this.addButton((this.end_sneak_button = new TouchscreenButtonWidget(sneak_button_x, sneak_button_y, 20, 20, 20, 120, 20, WIDGETS_LOCATION, state -> { if (state) { - ((LambdaKeyBinding) this.minecraft.options.keySneak).handle_press_state(false); + ((KeyBindingAccessor) this.minecraft.options.keySneak).handle_press_state(false); this.end_sneak_button.visible = false; this.start_sneak_button.visible = true; } @@ -220,31 +220,31 @@ 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 -> { - ((LambdaKeyBinding) this.minecraft.options.keyForward).handle_press_state(state); - ((LambdaKeyBinding) this.minecraft.options.keyLeft).handle_press_state(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 -> { - ((LambdaKeyBinding) this.minecraft.options.keyForward).handle_press_state(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 -> { - ((LambdaKeyBinding) this.minecraft.options.keyForward).handle_press_state(state); - ((LambdaKeyBinding) this.minecraft.options.keyRight).handle_press_state(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 -> ((LambdaKeyBinding) this.minecraft.options.keyRight).handle_press_state(state))); + 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 -> ((LambdaKeyBinding) this.minecraft.options.keyBack).handle_press_state(state))); + 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 -> ((LambdaKeyBinding) this.minecraft.options.keyLeft).handle_press_state(state))); + state -> ((KeyBindingAccessor) this.minecraft.options.keyLeft).handle_press_state(state))); } @Override diff --git a/src/main/java/me/lambdaurora/lambdacontrols/mixin/AbstractContainerScreenMixin.java b/src/main/java/me/lambdaurora/lambdacontrols/mixin/AbstractContainerScreenMixin.java index 7ec8d1a..cf2ffca 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/mixin/AbstractContainerScreenMixin.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/mixin/AbstractContainerScreenMixin.java @@ -9,11 +9,18 @@ package me.lambdaurora.lambdacontrols.mixin; +import me.lambdaurora.lambdacontrols.ControlsMode; +import me.lambdaurora.lambdacontrols.LambdaControls; import me.lambdaurora.lambdacontrols.util.AbstractContainerScreenAccessor; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen; import net.minecraft.container.Slot; +import org.lwjgl.glfw.GLFW; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** * Represents the mixin for the class AbstractContainerScreen. @@ -47,4 +54,18 @@ public abstract class AbstractContainerScreenMixin implements AbstractContainerS { return this.getSlotAt(pos_x, pos_y); } + + @Inject(method = "render", at = @At("RETURN")) + public void render(int mouseX, int mouseY, float delta, CallbackInfo ci) + { + if (LambdaControls.get().config.get_controls_mode() == ControlsMode.CONTROLLER) { + MinecraftClient client = MinecraftClient.getInstance(); + int x = 10, y = client.window.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); + } + } } diff --git a/src/main/java/me/lambdaurora/lambdacontrols/mixin/InGameHudMixin.java b/src/main/java/me/lambdaurora/lambdacontrols/mixin/InGameHudMixin.java index adfcdee..2a4ca44 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/mixin/InGameHudMixin.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/mixin/InGameHudMixin.java @@ -11,17 +11,15 @@ package me.lambdaurora.lambdacontrols.mixin; import me.lambdaurora.lambdacontrols.LambdaControls; import me.lambdaurora.lambdacontrols.gui.LambdaControlsHud; -import me.lambdaurora.lambdacontrols.util.CustomInGameHud; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.hud.InGameHud; -import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(InGameHud.class) -public class InGameHudMixin implements CustomInGameHud +public class InGameHudMixin { private LambdaControlsHud lambdacontrols_hud; @@ -32,14 +30,8 @@ public class InGameHudMixin implements CustomInGameHud } @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderMountHealth()V")) - public void on_render(float tick_delta, CallbackInfo ci) + public void on_render(CallbackInfo ci) { - lambdacontrols_hud.render(tick_delta); - } - - @Override - public @NotNull LambdaControlsHud get_lambdacontrols_hud() - { - return this.lambdacontrols_hud; + lambdacontrols_hud.render(); } } diff --git a/src/main/java/me/lambdaurora/lambdacontrols/mixin/KeyBindingMixin.java b/src/main/java/me/lambdaurora/lambdacontrols/mixin/KeyBindingMixin.java index 9ba99f9..8831b54 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/mixin/KeyBindingMixin.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/mixin/KeyBindingMixin.java @@ -9,7 +9,7 @@ package me.lambdaurora.lambdacontrols.mixin; -import me.lambdaurora.lambdacontrols.util.LambdaKeyBinding; +import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor; import net.minecraft.client.options.KeyBinding; import net.minecraft.client.util.InputUtil; import org.jetbrains.annotations.NotNull; @@ -17,7 +17,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(KeyBinding.class) -public class KeyBindingMixin implements LambdaKeyBinding +public class KeyBindingMixin implements KeyBindingAccessor { @Shadow private InputUtil.KeyCode keyCode; diff --git a/src/main/java/me/lambdaurora/lambdacontrols/mixin/MouseMixin.java b/src/main/java/me/lambdaurora/lambdacontrols/mixin/MouseMixin.java index 9ee1229..a770bd8 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/mixin/MouseMixin.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/mixin/MouseMixin.java @@ -12,15 +12,16 @@ package me.lambdaurora.lambdacontrols.mixin; import me.lambdaurora.lambdacontrols.ControlsMode; import me.lambdaurora.lambdacontrols.LambdaControls; import me.lambdaurora.lambdacontrols.util.MouseAccessor; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.Mouse; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +/** + * Adds extra access to the mouse. + */ @Mixin(Mouse.class) public abstract class MouseMixin implements MouseAccessor { diff --git a/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java b/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java index 8cbf84f..c614eb5 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java @@ -23,6 +23,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +/** + * Injects the new controls settings button. + */ @Mixin(SettingsScreen.class) public class SettingsScreenMixin extends Screen { diff --git a/src/main/java/me/lambdaurora/lambdacontrols/util/AbstractContainerScreenAccessor.java b/src/main/java/me/lambdaurora/lambdacontrols/util/AbstractContainerScreenAccessor.java index 6b8b9d8..0caa082 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/util/AbstractContainerScreenAccessor.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/util/AbstractContainerScreenAccessor.java @@ -10,9 +10,6 @@ package me.lambdaurora.lambdacontrols.util; import net.minecraft.container.Slot; -import net.minecraft.item.ItemGroup; -import org.jetbrains.annotations.NotNull; -import org.spongepowered.asm.mixin.gen.Accessor; /** * Represents an accessor to AbstractContainerScreen. diff --git a/src/main/java/me/lambdaurora/lambdacontrols/util/CustomInGameHud.java b/src/main/java/me/lambdaurora/lambdacontrols/util/CustomInGameHud.java deleted file mode 100644 index 942e4f6..0000000 --- a/src/main/java/me/lambdaurora/lambdacontrols/util/CustomInGameHud.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2019 LambdAurora - * - * This file is part of LambdaControls. - * - * Licensed under the MIT license. For more information, - * see the LICENSE file. - */ - -package me.lambdaurora.lambdacontrols.util; - -import me.lambdaurora.lambdacontrols.gui.LambdaControlsHud; -import org.jetbrains.annotations.NotNull; - -/** - * Represents a custom ingame hud with an accessor to an added hud. - */ -public interface CustomInGameHud -{ - @NotNull LambdaControlsHud get_lambdacontrols_hud(); -} diff --git a/src/main/java/me/lambdaurora/lambdacontrols/util/LambdaKeyBinding.java b/src/main/java/me/lambdaurora/lambdacontrols/util/KeyBindingAccessor.java similarity index 95% rename from src/main/java/me/lambdaurora/lambdacontrols/util/LambdaKeyBinding.java rename to src/main/java/me/lambdaurora/lambdacontrols/util/KeyBindingAccessor.java index 7fecb1d..a2cf665 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/util/LambdaKeyBinding.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/util/KeyBindingAccessor.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull; /** * Represents a Minecraft keybinding with extra access. */ -public interface LambdaKeyBinding +public interface KeyBindingAccessor { @NotNull InputUtil.KeyCode get_key_code(); diff --git a/src/main/resources/assets/lambdacontrols/lang/en_us.json b/src/main/resources/assets/lambdacontrols/lang/en_us.json index 469a9c8..25bb470 100644 --- a/src/main/resources/assets/lambdacontrols/lang/en_us.json +++ b/src/main/resources/assets/lambdacontrols/lang/en_us.json @@ -1,20 +1,44 @@ { + "lambdacontrols.action.attack": "Attack", + "lambdacontrols.action.back": "Back", + "lambdacontrols.action.drop_item": "Drop item", + "lambdacontrols.action.exit": "Exit", + "lambdacontrols.action.forward": "Forward", + "lambdacontrols.action.hit": "Hit", + "lambdacontrols.action.inventory": "Inventory", + "lambdacontrols.action.jump": "Jump", + "lambdacontrols.action.pickup": "Pickup", + "lambdacontrols.action.pickup_all": "Pickup all", + "lambdacontrols.action.quick_move": "Quick move", + "lambdacontrols.action.sneak": "Sneak", + "lambdacontrols.action.sprint": "Sprint", + "lambdacontrols.action.swap_hands": "Swap hands", + "lambdacontrols.action.use": "Use", "lambdacontrols.controller.connected": "Controller %d connected.", "lambdacontrols.controller.disconnected": "Controller %d disconnected.", "lambdacontrols.controller.mappings.1": "To configure the controller mappings, please use SDL2 Gamepad Tool", "lambdacontrols.controller.mappings.2": "(http://generalarcade.com/gamepadtool/),", "lambdacontrols.controller.mappings.3": "and put the mapping in `config/gamecontrollerdb.txt`.", + "lambdacontrols.controller_type.default": "default", + "lambdacontrols.controller_type.playstation": "PlayStation", + "lambdacontrols.controller_type.switch": "Switch", + "lambdacontrols.controller_type.xbox": "Xbox", + "lambdacontrols.controller_type.steam": "Steam", + "lambdacontrols.controller_type.ouya": "OUYA", "lambdacontrols.controls_mode.default": "Keyboard/Mouse", "lambdacontrols.controls_mode.controller": "Controller", "lambdacontrols.controls_mode.touchscreen": "Touchscreen", "lambdacontrols.hud_side.left": "left", "lambdacontrols.hud_side.right": "right", "lambdacontrols.menu.controller": "Controller", + "lambdacontrols.menu.controller_type": "Controller type", "lambdacontrols.menu.controls_mode": "Controls mode", "lambdacontrols.menu.dead_zone": "Dead zone", + "lambdacontrols.menu.hud_enable": "Enable HUD", "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.mouse_speed": "Mouse speed", - "lambdacontrols.menu.rotation_speed": "Rotation speed" + "lambdacontrols.menu.rotation_speed": "Rotation speed", + "lambdacontrols.menu.title": "LambdaControls - Settings" } \ No newline at end of file diff --git a/src/main/resources/assets/lambdacontrols/textures/gui/controller_buttons.png b/src/main/resources/assets/lambdacontrols/textures/gui/controller_buttons.png index 3242ac6f56f58da939e96f2b3386319e38e3782c..770023e2707f1ce97e3984803a2338945a39fa17 100644 GIT binary patch literal 8810 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 diff --git a/src/main/resources/config.toml b/src/main/resources/config.toml index ffa60b1..43483c2 100644 --- a/src/main/resources/config.toml +++ b/src/main/resources/config.toml @@ -4,6 +4,8 @@ controls = "default" [hud] + # Enables the HUD. + enable = true # Dertermines where the movements buttons are. side = "left" @@ -11,6 +13,8 @@ controls = "default" [controller] # Controller to use. id = 0 + # Controller's type. + type = "default" # Controller's dead zone. dead_zone = 0.20 # Rotation speed for look directions. diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 5b1dd37..2f91a53 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -13,7 +13,7 @@ "issues": "https://github.com/LambdAurora/LambdaControls/issues" }, "license": "MIT", - "icon": "assets/aurora_keystrokes/icon.png", + "icon": "assets/lambdacontrols/icon.png", "environment": "client", "entrypoints": { "client": [