mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-13 07:15:10 +01:00
✨ Add better button management, the controls screen and more.
This commit is contained in:
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. Linux]
|
||||
- Minecraft [e.g. 1.14.4]
|
||||
- Fabric [e.g. fabric 0.7.2+build.174]
|
||||
- Mods [e.g. aurora_keystrokes v1.0.0, modmenu v1.7.15]
|
||||
- Version [e.g. 1.0.0]
|
||||
- Branch [e.g. dev]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at aurora42lambda@gmail.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
103
CONTRIBUTING.md
Normal file
103
CONTRIBUTING.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Contributing to LambdaControls
|
||||
|
||||
:tada: First of all, thanks for taking time to contribute! :tada:
|
||||
|
||||
The following is a set of guidelines for contributing to LambdaControls.
|
||||
Feel free to propose changes to this document in a pull request.
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[Code of Conduct](#code-of-conduct)
|
||||
|
||||
[What should I know before I get started?](#what-should-i-know-before-i-get-started)
|
||||
|
||||
[How can I contribute?](#how-can-i-contribute)
|
||||
|
||||
[Styleguides](#styleguides)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project and everyone participating in it is governed by the [Code of Conduct](https://github.com/LambdAurora/LambdaControls/blob/master/CODE_OF_CONDUCT.md).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior at [aurora42lambda@gmail.com](mailto:aurora42lambda@gmail.com).
|
||||
|
||||
## What should I know before I get started?
|
||||
|
||||
### Fabric
|
||||
|
||||
[Fabric](https://fabricmc.net/) is the mod loader and the software which allows Gradle to setup the workspace.
|
||||
|
||||
### Java 8
|
||||
|
||||
Java is the main language used to make LambdaControls alive.
|
||||
Knowing how to code in Java is necessary if you contribute to the code.
|
||||
|
||||
### Minecraft
|
||||
|
||||
As it is a Minecraft mod you should know a bit how Minecraft works and how modding works.
|
||||
|
||||
### Mixins
|
||||
|
||||
[Mixins](https://github.com/SpongePowered/Mixin/wiki) are a main part in this mod, they allow the necessary modifications to the Minecraft Client.
|
||||
|
||||
### Gradle
|
||||
|
||||
[Gradle](https://gradle.org/) is the build tool used for this project.
|
||||
|
||||
### Git
|
||||
|
||||
Git is the control version software we use for LambdaControls, please know how to use it if you consider contributing to the code.
|
||||
|
||||
Git commits should be and must be signed.
|
||||
|
||||
## How can I contribute?
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
#### Before submitting a bug report
|
||||
|
||||
- Check if you can reproduce it on other platforms, on multiple web browsers.
|
||||
- Perform a search to see if the problem has already been reported. If it has **and the issue is still open**, add a comment to the existing issue instead of opening a new one.
|
||||
|
||||
#### How do I submit a bug report?
|
||||
|
||||
Go in the issues tab in GitHub and read the [bug report guide](https://github.com/LambdAurora/LambdaControls/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)
|
||||
|
||||
### Suggesting enhancements
|
||||
|
||||
Enhancement suggestions are tracked as [GitHub issues](https://github.com/LambdAurora/LambdaControls/issues).
|
||||
Check out the [feature request](https://github.com/LambdAurora/LambdaControls/blob/master/.github/ISSUE_TEMPLATE/feature_request.md) guide.
|
||||
|
||||
### Do pull requests
|
||||
|
||||
You can help LambdaControls by writing code and submit it with pull requests.
|
||||
|
||||
Pull requests will be accepted if they follow the [styleguide](#styleguides), if they are useful, etc...
|
||||
We can refuse a pull request if the commits are not signed, so don't forget to [sign them](https://help.github.com/en/articles/signing-commits)!
|
||||
|
||||
Feel free to pull request!
|
||||
|
||||
## Styleguides
|
||||
|
||||
### Git commit messages
|
||||
|
||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
* Consider starting the commit message with an emote, emotes for your commit can be found at the [gitmoji guide](https://gitmoji.carloscuesta.me/).
|
||||
* (Not for the message) Don't forget to sign the commit.
|
||||
|
||||
### Naming convention
|
||||
|
||||
Names in the code should be explicit and always in `snake_case`, `camelCase` will not be allowed.
|
||||
`PascalCase` can be used for class name.
|
||||
|
||||
We chose `snake_case` because it is more accessible for everyone: for people who don't speak English as their native language it is more easy to see the words when they are separated,
|
||||
it also allows the correct use of screen reader on the code with `snake_case` due to the absence of upper case characters.
|
||||
|
||||
### Brace placement
|
||||
|
||||
Every braces should be at the end of the line of function declaration, etc...
|
||||
The only exception is class declarations: braces must be on the next line.
|
||||
|
||||
### Quick note for users of the Intellij IDEA IDE
|
||||
|
||||
As a user of the Intellij IDEA IDE you have the format code shortcut which use a codestyle described by a file.
|
||||
You can import the codestyle file here: [LambdAurora's dotfiles](https://github.com/LambdAurora/dotfiles/blob/master/jetbrains/lambdacodestyle2.xml).
|
||||
@@ -1,4 +1,7 @@
|
||||
# LambdaControls
|
||||
|
||||

|
||||
[](https://raw.githubusercontent.com/LambdAurora/LambdaControls/master/LICENSE)
|
||||
|
||||
A Fabric Minecraft mod which add better controls.
|
||||
It allows the use of a controller or the touchscreen.
|
||||
|
||||
@@ -10,16 +10,18 @@
|
||||
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.utils.Nameable;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Represents a button binding.
|
||||
@@ -28,28 +30,59 @@ import java.util.Optional;
|
||||
*/
|
||||
public class ButtonBinding implements Nameable
|
||||
{
|
||||
private static final List<ButtonBinding> 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");
|
||||
public static final ButtonBinding INVENTORY = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_Y, "inventory");
|
||||
public static final ButtonBinding JUMP = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_A, "jump");
|
||||
public static final ButtonBinding PAUSE_GAME = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_START, "pause_game");
|
||||
public static final ButtonBinding SNEAK = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "sneak");
|
||||
public static final ButtonBinding SPRINT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "sprint");
|
||||
public static final ButtonBinding SWAP_HANDS = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_X, "swap_hands");
|
||||
private static final List<ButtonBinding> BINDINGS = new ArrayList<>();
|
||||
private static final Map<Pair<String, Integer>, List<ButtonBinding>> CATEGORIES = new HashMap<>();
|
||||
public static final String MOVEMENT_CATEGORY = "key.categories.movement";
|
||||
public static final String GAMEPLAY_CATEGORY = "key.categories.gameplay";
|
||||
public static final String INVENTORY_CATEGORY = "key.categories.inventory";
|
||||
public static final String MULTIPLAYER_CATEGORY = "key.categories.multiplayer";
|
||||
public static final String MISC_CATEGORY = "key.categories.misc";
|
||||
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 CHAT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, "chat");
|
||||
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");
|
||||
public static final ButtonBinding INVENTORY = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_Y, "inventory");
|
||||
public static final ButtonBinding JUMP = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_A, "jump");
|
||||
public static final ButtonBinding LEFT = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, false), "left");
|
||||
public static final ButtonBinding PAUSE_GAME = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_START, "pause_game");
|
||||
public static final ButtonBinding PICK_BLOCK = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT, "pick_block");
|
||||
public static final ButtonBinding PLAYER_LIST = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_BACK, "player_list");
|
||||
public static final ButtonBinding RIGHT = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, true), "right");
|
||||
public static final ButtonBinding SCREENSHOT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN, "screenshot",
|
||||
Collections.singletonList((client, action) -> {
|
||||
ScreenshotUtils.method_1659(client.runDirectory, client.window.getFramebufferWidth(), client.window.getFramebufferHeight(), client.getFramebuffer(),
|
||||
text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)));
|
||||
return true;
|
||||
}));
|
||||
public static final ButtonBinding SMOOTH_CAMERA = new ButtonBinding(-1, "toggle_smooth_camera");
|
||||
public static final ButtonBinding SNEAK = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "sneak");
|
||||
public static final ButtonBinding SPRINT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "sprint");
|
||||
public static final ButtonBinding SWAP_HANDS = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_X, "swap_hands");
|
||||
public static final ButtonBinding TOGGLE_PERSPECTIVE = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, "toggle_perspective");
|
||||
public static final ButtonBinding USE = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true), "use");
|
||||
|
||||
private int button;
|
||||
private String key;
|
||||
private KeyBinding minecraft_key_binding = null;
|
||||
private boolean pressed = 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((client, action) -> {
|
||||
this.as_key_binding().ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(this.is_button_down()));
|
||||
return true;
|
||||
}));
|
||||
private boolean pressed = false;
|
||||
|
||||
public ButtonBinding(int button, @NotNull String key, @NotNull List<PressAction> actions)
|
||||
{
|
||||
this.default_button = this.button = button;
|
||||
this.key = key;
|
||||
this.actions.addAll(actions);
|
||||
BINDINGS.add(this);
|
||||
}
|
||||
|
||||
public ButtonBinding(int button, @NotNull String key)
|
||||
{
|
||||
this.button = button;
|
||||
this.key = key;
|
||||
BINDINGS.add(this);
|
||||
this(button, key, Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,6 +95,11 @@ public class ButtonBinding implements Nameable
|
||||
return this.button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bound button.
|
||||
*
|
||||
* @param button The bound button.
|
||||
*/
|
||||
public void set_button(int button)
|
||||
{
|
||||
this.button = button;
|
||||
@@ -88,6 +126,36 @@ public class ButtonBinding implements Nameable
|
||||
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()
|
||||
{
|
||||
@@ -139,13 +207,29 @@ public class ButtonBinding implements Nameable
|
||||
|
||||
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)
|
||||
@@ -154,10 +238,144 @@ public class ButtonBinding implements Nameable
|
||||
.forEach(binding -> binding.pressed = state);
|
||||
}
|
||||
|
||||
public static void handle_button(int button, boolean state)
|
||||
public static void handle_button(@NotNull MinecraftClient client, int button, int action)
|
||||
{
|
||||
BINDINGS.parallelStream().filter(binding -> binding.button == button)
|
||||
.map(ButtonBinding::as_key_binding)
|
||||
.forEach(binding -> binding.ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(state)));
|
||||
.forEach(binding -> {
|
||||
for (int i = binding.actions.size() - 1; i >= 0; i--) {
|
||||
if (binding.actions.get(i).press(client, 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<Map.Entry<Pair<String, Integer>, List<ButtonBinding>>> stream_categories()
|
||||
{
|
||||
return CATEGORIES.entrySet().stream();
|
||||
}
|
||||
|
||||
static {
|
||||
CATEGORIES.put(Pair.of(MOVEMENT_CATEGORY, 0), Arrays.asList(
|
||||
FORWARD,
|
||||
BACK,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
JUMP,
|
||||
SNEAK,
|
||||
SPRINT
|
||||
));
|
||||
CATEGORIES.put(Pair.of(GAMEPLAY_CATEGORY, 1), Arrays.asList(
|
||||
ATTACK,
|
||||
PICK_BLOCK,
|
||||
USE
|
||||
));
|
||||
CATEGORIES.put(Pair.of(INVENTORY_CATEGORY, 2), Arrays.asList(
|
||||
DROP_ITEM,
|
||||
INVENTORY,
|
||||
SWAP_HANDS
|
||||
));
|
||||
CATEGORIES.put(Pair.of(MULTIPLAYER_CATEGORY, 2), Arrays.asList(
|
||||
CHAT,
|
||||
PLAYER_LIST
|
||||
));
|
||||
CATEGORIES.put(Pair.of(MISC_CATEGORY, 3), Arrays.asList(
|
||||
SCREENSHOT,
|
||||
//SMOOTH_CAMERA,
|
||||
TOGGLE_PERSPECTIVE
|
||||
));
|
||||
}
|
||||
|
||||
@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, int action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ public class Controller implements Nameable
|
||||
try (SeekableByteChannel fc = Files.newByteChannel(path)) {
|
||||
buffer = createByteBuffer((int) fc.size() + 2);
|
||||
while (fc.read(buffer) != -1) {
|
||||
;
|
||||
}
|
||||
buffer.put((byte) 0);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
package me.lambdaurora.lambdacontrols;
|
||||
|
||||
import me.lambdaurora.lambdacontrols.gui.LambdaControlsControlsScreen;
|
||||
import me.lambdaurora.lambdacontrols.mixin.EntryListWidgetAccessor;
|
||||
import me.lambdaurora.lambdacontrols.util.AbstractContainerScreenAccessor;
|
||||
import me.lambdaurora.lambdacontrols.util.CreativeInventoryScreenAccessor;
|
||||
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
|
||||
@@ -20,8 +22,11 @@ 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;
|
||||
import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
|
||||
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.container.Slot;
|
||||
import net.minecraft.container.SlotActionType;
|
||||
@@ -40,8 +45,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static me.lambdaurora.lambdacontrols.ButtonBinding.PAUSE_GAME;
|
||||
import static me.lambdaurora.lambdacontrols.ButtonBinding.SNEAK;
|
||||
import static me.lambdaurora.lambdacontrols.ButtonBinding.*;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
|
||||
|
||||
@@ -109,7 +113,7 @@ public class ControllerInput
|
||||
|
||||
public void on_pre_render_screen(@NotNull MinecraftClient client, @NotNull Screen screen)
|
||||
{
|
||||
if (!this.is_screen_interactive(screen)) {
|
||||
if (!is_screen_interactive(screen)) {
|
||||
if (this.prev_target_mouse_x != this.target_mouse_x || this.prev_target_mouse_y != this.target_mouse_y) {
|
||||
double mouse_x = this.prev_target_mouse_x + (this.target_mouse_x - this.prev_target_mouse_x) * client.getTickDelta() + 0.5;
|
||||
double mouse_y = this.prev_target_mouse_y + (this.target_mouse_y - this.prev_target_mouse_y) * client.getTickDelta() + 0.5;
|
||||
@@ -172,6 +176,12 @@ public class ControllerInput
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -179,12 +189,38 @@ public class ControllerInput
|
||||
|
||||
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);
|
||||
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)) {
|
||||
if (this.action_gui_cooldown == 0) {
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP) {
|
||||
this.change_focus(client.currentScreen, false);
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) {
|
||||
this.change_focus(client.currentScreen, true);
|
||||
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT) {
|
||||
this.handle_left_right(client.currentScreen, false);
|
||||
} else {
|
||||
this.handle_left_right(client.currentScreen, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (action == 0) {
|
||||
@@ -203,8 +239,8 @@ public class ControllerInput
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) {
|
||||
if (this.action_gui_cooldown == 0) {
|
||||
Element focused = client.currentScreen.getFocused();
|
||||
if (focused != null && this.is_screen_interactive(client.currentScreen)) {
|
||||
if (this.handle_a_button(focused)) {
|
||||
if (focused != null && is_screen_interactive(client.currentScreen)) {
|
||||
if (this.handle_a_button(client.currentScreen, focused)) {
|
||||
this.action_gui_cooldown = 5; // Prevent to press too quickly the focused element, so we have to skip 5 ticks.
|
||||
return;
|
||||
}
|
||||
@@ -243,7 +279,7 @@ public class ControllerInput
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !is_screen_interactive(client.currentScreen) && this.action_gui_cooldown == 0 && this.ignore_next_a == 0) {
|
||||
double mouse_x = client.mouse.getX() * (double) client.window.getScaledWidth() / (double) client.window.getWidth();
|
||||
double mouse_y = client.mouse.getY() * (double) client.window.getScaledHeight() / (double) client.window.getHeight();
|
||||
if (action == 0) {
|
||||
@@ -256,24 +292,35 @@ public class ControllerInput
|
||||
}
|
||||
|
||||
if (client.currentScreen == null && action != 2) {
|
||||
ButtonBinding.handle_button(button, state);
|
||||
ButtonBinding.handle_button(client, button, action);
|
||||
}
|
||||
}
|
||||
|
||||
private void handle_axe(@NotNull MinecraftClient client, int axis, float value, float abs_value, int state)
|
||||
{
|
||||
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))) {
|
||||
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));
|
||||
controls_screen.focused_binding = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double dead_zone = this.config.get_dead_zone();
|
||||
if (client.currentScreen == null) {
|
||||
{
|
||||
int axis_minus = axis + 10;
|
||||
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);
|
||||
|
||||
if (current_plus_state != previous_plus_state) {
|
||||
this.config.get_keybind("axis_" + axis + "+").ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(current_plus_state));
|
||||
ButtonBinding.handle_button(client, ButtonBinding.axis_as_button(axis, true), 0);
|
||||
if (current_plus_state)
|
||||
AXIS_COOLDOWNS.put(axis, 5);
|
||||
} else if (current_plus_state) {
|
||||
@@ -283,7 +330,7 @@ public class ControllerInput
|
||||
}
|
||||
|
||||
if (current_minus_state != previous_minus_state) {
|
||||
this.config.get_keybind("axis_" + axis + "-").ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(current_minus_state));
|
||||
ButtonBinding.handle_button(client, ButtonBinding.axis_as_button(axis, false), 0);
|
||||
if (current_minus_state)
|
||||
AXIS_COOLDOWNS.put(axis_minus, 5);
|
||||
} else if (current_minus_state) {
|
||||
@@ -298,27 +345,28 @@ public class ControllerInput
|
||||
|
||||
// Handles the look direction.
|
||||
if (client.player != null) {
|
||||
double pow_value = Math.pow(abs_value, 2.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() * (abs_value + dead_zone) / (1.0 - dead_zone)) * 0.33D;
|
||||
this.target_pitch = client.player.pitch - this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
|
||||
this.target_pitch = MathHelper.clamp(this.target_pitch, -90.0D, 90.0D);
|
||||
} else if (state == 1) {
|
||||
this.target_pitch = client.player.pitch + this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * (abs_value - dead_zone) / (1.0 - dead_zone)) * 0.33D;
|
||||
this.target_pitch = client.player.pitch + this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
|
||||
this.target_pitch = MathHelper.clamp(this.target_pitch, -90.0D, 90.0D);
|
||||
}
|
||||
}
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
|
||||
if (state == 2) {
|
||||
this.target_yaw = client.player.yaw - this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * (abs_value + dead_zone) / (1.0 - dead_zone)) * 0.33D;
|
||||
this.target_yaw = client.player.yaw - this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
|
||||
} else if (state == 1) {
|
||||
this.target_yaw = client.player.yaw + this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * (abs_value + dead_zone) / (1.0 - dead_zone)) * 0.33D;
|
||||
this.target_yaw = client.player.yaw + this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean allow_mouse_control = true;
|
||||
|
||||
if (this.action_gui_cooldown == 0 && this.config.is_movement_axis(axis) && this.is_screen_interactive(client.currentScreen)) {
|
||||
if (this.action_gui_cooldown == 0 && this.config.is_movement_axis(axis) && is_screen_interactive(client.currentScreen)) {
|
||||
if (this.config.is_forward_button(axis, false, as_button_state)) {
|
||||
allow_mouse_control = this.change_focus(client.currentScreen, false);
|
||||
} else if (this.config.is_back_button(axis, false, as_button_state)) {
|
||||
@@ -412,7 +460,7 @@ public class ControllerInput
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handle_a_button(@NotNull Element focused)
|
||||
private boolean handle_a_button(@NotNull Screen screen, @NotNull Element focused)
|
||||
{
|
||||
if (focused instanceof AbstractPressableButtonWidget) {
|
||||
AbstractPressableButtonWidget button_widget = (AbstractPressableButtonWidget) focused;
|
||||
@@ -423,10 +471,17 @@ public class ControllerInput
|
||||
WorldListWidget list = (WorldListWidget) focused;
|
||||
list.method_20159().ifPresent(WorldListWidget.LevelItem::play);
|
||||
return true;
|
||||
} else if (focused instanceof MultiplayerServerListWidget) {
|
||||
MultiplayerServerListWidget list = (MultiplayerServerListWidget) focused;
|
||||
MultiplayerServerListWidget.Entry entry = list.getSelected();
|
||||
if (entry instanceof MultiplayerServerListWidget.LanServerListEntry || entry instanceof MultiplayerServerListWidget.ServerItem) {
|
||||
((MultiplayerScreen) screen).selectEntry(entry);
|
||||
((MultiplayerScreen) screen).connect();
|
||||
}
|
||||
} else if (focused instanceof ParentElement) {
|
||||
Element child_focused = ((ParentElement) focused).getFocused();
|
||||
if (child_focused != null)
|
||||
return this.handle_a_button(child_focused);
|
||||
return this.handle_a_button(screen, child_focused);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -452,6 +507,9 @@ public class ControllerInput
|
||||
slider.keyPressed(right ? 262 : 263, 0, 0);
|
||||
this.action_gui_cooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks.
|
||||
return false;
|
||||
} else if (element instanceof AlwaysSelectedEntryListWidget) {
|
||||
((EntryListWidgetAccessor) element).move_selection(right ? 1 : -1);
|
||||
return false;
|
||||
} else if (element instanceof ParentElement) {
|
||||
ParentElement entry_list = (ParentElement) element;
|
||||
Element focused = entry_list.getFocused();
|
||||
@@ -486,7 +544,7 @@ public class ControllerInput
|
||||
}
|
||||
}
|
||||
|
||||
private boolean is_screen_interactive(@NotNull Screen screen)
|
||||
static boolean is_screen_interactive(@NotNull Screen screen)
|
||||
{
|
||||
return !(screen instanceof AdvancementsScreen || screen instanceof AbstractContainerScreen);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.Optional;
|
||||
public enum ControllerType implements Nameable
|
||||
{
|
||||
DEFAULT(0),
|
||||
PLAYSTATION(1),
|
||||
DUALSHOCK(1),
|
||||
SWITCH(2),
|
||||
XBOX(3),
|
||||
STEAM(4),
|
||||
|
||||
@@ -50,7 +50,6 @@ public class LambdaControls implements ClientModInitializer
|
||||
{
|
||||
Controller.update_mappings();
|
||||
ButtonBinding.init(client.options);
|
||||
this.config.init_keybindings(client.options);
|
||||
GLFW.glfwSetJoystickCallback((jid, event) -> {
|
||||
if (event == GLFW.GLFW_CONNECTED) {
|
||||
Controller controller = Controller.by_id(jid);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
package me.lambdaurora.lambdacontrols;
|
||||
|
||||
import com.electronwill.nightconfig.core.file.FileConfig;
|
||||
import net.minecraft.client.options.GameOptions;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
@@ -19,8 +18,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
/**
|
||||
* Represents LambdaControls configuration.
|
||||
*/
|
||||
@@ -38,11 +35,6 @@ public class LambdaControlsConfig
|
||||
private double dead_zone;
|
||||
private double rotation_speed;
|
||||
private double mouse_speed;
|
||||
// Controller controls
|
||||
private String back_button;
|
||||
private String forward_button;
|
||||
private String left_button;
|
||||
private String right_button;
|
||||
|
||||
public LambdaControlsConfig(@NotNull LambdaControls mod)
|
||||
{
|
||||
@@ -64,29 +56,7 @@ public class LambdaControlsConfig
|
||||
this.rotation_speed = this.config.getOrElse("controller.rotation_speed", 40.0);
|
||||
this.mouse_speed = this.config.getOrElse("controller.mouse_speed", 25.0);
|
||||
// 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();
|
||||
this.right_button = this.config.getOrElse("controller.controls.right", "none").toLowerCase();
|
||||
}
|
||||
|
||||
public void init_keybindings(GameOptions options)
|
||||
{
|
||||
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + "+", options.keyAttack);
|
||||
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + "+", options.keyUse);
|
||||
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_X + "+", options.keyRight);
|
||||
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_X + "-", options.keyLeft);
|
||||
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_Y + "+", options.keyBack);
|
||||
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_Y + "-", options.keyForward);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_A, options.keyJump);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_B, options.keyDrop);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_X, options.keySwapHands);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_Y, options.keyInventory);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_BACK, options.keyPlayerList);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_GUIDE, options.keyScreenshot);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, options.keySneak);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_LEFT_THUMB, options.keySprint);
|
||||
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_DPAD_UP, options.keyTogglePerspective);
|
||||
ButtonBinding.load_from_config(this);
|
||||
}
|
||||
|
||||
public void save()
|
||||
@@ -343,52 +313,54 @@ public class LambdaControlsConfig
|
||||
return Optional.ofNullable(this.keybinding_mappings.get(id));
|
||||
}
|
||||
|
||||
public String get_back_button()
|
||||
/**
|
||||
* Loads the button binding from configuration.
|
||||
*
|
||||
* @param button The button binding.
|
||||
*/
|
||||
public void load_button_binding(@NotNull ButtonBinding button)
|
||||
{
|
||||
return this.back_button;
|
||||
button.set_button(this.config.getOrElse("controller.controls." + button.get_name(), button.get_button()));
|
||||
}
|
||||
|
||||
public String get_forward_button()
|
||||
/**
|
||||
* Sets the button binding in configuration.
|
||||
*
|
||||
* @param binding The button binding.
|
||||
* @param button The button.
|
||||
*/
|
||||
public void set_button_binding(@NotNull ButtonBinding binding, int button)
|
||||
{
|
||||
return this.forward_button;
|
||||
}
|
||||
|
||||
public String get_left_button()
|
||||
{
|
||||
return this.left_button;
|
||||
}
|
||||
|
||||
public String get_right_button()
|
||||
{
|
||||
return this.right_button;
|
||||
binding.set_button(button);
|
||||
this.config.set("controller.controls." + binding.get_name(), button);
|
||||
}
|
||||
|
||||
public boolean is_back_button(int btn, boolean is_btn, int state)
|
||||
{
|
||||
if (!is_btn && state == 0)
|
||||
return false;
|
||||
return this.get_back_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
|
||||
return ButtonBinding.BACK.is_button(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 this.get_forward_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
|
||||
return ButtonBinding.FORWARD.is_button(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 this.get_left_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
|
||||
return ButtonBinding.LEFT.is_button(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 this.get_right_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
|
||||
return ButtonBinding.RIGHT.is_button(ButtonBinding.axis_as_button(btn, state == 1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,7 +371,9 @@ public class LambdaControlsConfig
|
||||
*/
|
||||
public boolean is_movement_axis(int i)
|
||||
{
|
||||
return this.get_forward_button().startsWith("axe_" + i) || this.get_back_button().startsWith("axe_" + i) || this.get_left_button().startsWith("axe_" + i)
|
||||
|| this.get_right_button().startsWith("axe_" + i);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 me.lambdaurora.lambdacontrols.ButtonBinding;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ElementListWidget;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.util.Formatting;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a control list widget.
|
||||
*/
|
||||
public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Entry>
|
||||
{
|
||||
private final LambdaControlsControlsScreen gui;
|
||||
private int field_2733;
|
||||
|
||||
public ControlsListWidget(@NotNull LambdaControlsControlsScreen gui, @NotNull MinecraftClient client)
|
||||
{
|
||||
super(client, gui.width + 45, gui.height, 43, gui.height - 32, 20);
|
||||
this.gui = gui;
|
||||
|
||||
ButtonBinding.stream_categories()
|
||||
.sorted(Comparator.comparingInt(e -> e.getKey().get_value()))
|
||||
.map(category -> Pair.of(category.getKey().get_key(), category.getValue()))
|
||||
.forEach(category -> {
|
||||
this.addEntry(new CategoryEntry(category.get_key()));
|
||||
|
||||
category.get_value().forEach(binding -> {
|
||||
int i = client.textRenderer.getStringWidth(I18n.translate(binding.get_translation_key()));
|
||||
if (i > this.field_2733) {
|
||||
this.field_2733 = i;
|
||||
}
|
||||
|
||||
this.addEntry(new ControlsListWidget.ButtonBindingEntry(binding));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getScrollbarPosition()
|
||||
{
|
||||
return super.getScrollbarPosition() + 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowWidth()
|
||||
{
|
||||
return super.getRowWidth() + 32;
|
||||
}
|
||||
|
||||
public class ButtonBindingEntry extends Entry
|
||||
{
|
||||
private final ButtonBinding binding;
|
||||
private final String binding_name;
|
||||
private final ButtonWidget edit_button;
|
||||
private final ButtonWidget reset_button;
|
||||
|
||||
ButtonBindingEntry(@NotNull ButtonBinding binding)
|
||||
{
|
||||
this.binding = binding;
|
||||
this.binding_name = I18n.translate(this.binding.get_translation_key());
|
||||
this.edit_button = new ButtonWidget(0, 0, 75, 20, this.binding_name, btn -> gui.focused_binding = binding)
|
||||
{
|
||||
protected String getNarrationMessage()
|
||||
{
|
||||
return binding.is_not_bound() ? I18n.translate("narrator.controls.unbound", binding_name) : I18n.translate("narrator.controls.bound", binding_name, super.getNarrationMessage());
|
||||
}
|
||||
};
|
||||
this.reset_button = new ButtonWidget(0, 0, 50, 20, I18n.translate("controls.reset"),
|
||||
btn -> gui.mod.config.set_button_binding(binding, binding.get_default_button()))
|
||||
{
|
||||
protected String getNarrationMessage()
|
||||
{
|
||||
return I18n.translate("narrator.controls.reset", binding_name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Element> children()
|
||||
{
|
||||
return Collections.unmodifiableList(Arrays.asList(this.edit_button, this.reset_button));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(int index, int y, int x, int width, int height, int mouse_x, int mouse_y, boolean hovering, float delta)
|
||||
{
|
||||
boolean focused = gui.focused_binding == this.binding;
|
||||
TextRenderer text_renderer = ControlsListWidget.this.minecraft.textRenderer;
|
||||
String binding_name = this.binding_name;
|
||||
float var10002 = (float) (x + 90 - ControlsListWidget.this.field_2733);
|
||||
int var10003 = y + height / 2;
|
||||
text_renderer.draw(binding_name, var10002, (float) (var10003 - 9 / 2), 16777215);
|
||||
this.reset_button.x = x + 190;
|
||||
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 + 105;
|
||||
this.edit_button.y = y;
|
||||
this.edit_button.setMessage(ButtonBinding.get_localized_button_name(binding.get_button()));
|
||||
|
||||
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())) {
|
||||
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.render(mouse_x, mouse_y, delta);
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button)
|
||||
{
|
||||
if (this.edit_button.mouseClicked(mouseX, mouseY, button))
|
||||
return true;
|
||||
else
|
||||
return this.reset_button.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button)
|
||||
{
|
||||
return this.edit_button.mouseReleased(mouseX, mouseY, button) || this.reset_button.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryEntry extends Entry
|
||||
{
|
||||
private final String name;
|
||||
private final int name_width;
|
||||
|
||||
public CategoryEntry(String string)
|
||||
{
|
||||
this.name = I18n.translate(string);
|
||||
this.name_width = ControlsListWidget.this.minecraft.textRenderer.getStringWidth(this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(int index, int y, int x, int width, int height, int mouse_x, int mouse_y, boolean hovering, float delta)
|
||||
{
|
||||
ControlsListWidget.this.minecraft.textRenderer.draw(this.name, (float) (ControlsListWidget.this.minecraft.currentScreen.width / 2 - this.name_width / 2),
|
||||
(float) ((y + height) - 9 - 1), 16777215);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeFocus(boolean bl)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Element> children()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract static class Entry extends ElementListWidget.Entry<Entry>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 me.lambdaurora.lambdacontrols.ButtonBinding;
|
||||
import me.lambdaurora.lambdacontrols.LambdaControls;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
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.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Represents the controls screen.
|
||||
*/
|
||||
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;
|
||||
|
||||
protected LambdaControlsControlsScreen(@NotNull LambdaControlsSettingsScreen parent)
|
||||
{
|
||||
super(new TranslatableText("lambdacontrols.menu.title.controller_controls"));
|
||||
this.parent = parent;
|
||||
this.mod = parent.mod;
|
||||
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
|
||||
public void removed()
|
||||
{
|
||||
this.mod.config.save();
|
||||
super.removed();
|
||||
}
|
||||
|
||||
@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.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()))));
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, I18n.translate("gui.done"),
|
||||
btn -> this.minecraft.openScreen(this.parent)));
|
||||
}
|
||||
|
||||
// Replacement for Predicate#not as it is Java 11.
|
||||
private <T> Predicate<T> not(Predicate<T> target)
|
||||
{
|
||||
Objects.requireNonNull(target);
|
||||
return target.negate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(int mouse_x, int mouse_y, float delta)
|
||||
{
|
||||
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));
|
||||
super.render(mouse_x, mouse_y, delta);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.options.*;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Formatting;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
@@ -27,7 +28,7 @@ import org.lwjgl.glfw.GLFW;
|
||||
*/
|
||||
public class LambdaControlsSettingsScreen extends Screen
|
||||
{
|
||||
private final LambdaControls mod;
|
||||
final LambdaControls mod;
|
||||
private final Screen parent;
|
||||
private final GameOptions options;
|
||||
private final Option controller_option;
|
||||
@@ -37,8 +38,6 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
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)
|
||||
@@ -53,7 +52,13 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
if (current_id > GLFW.GLFW_JOYSTICK_LAST)
|
||||
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());
|
||||
}, (game_options, option) -> {
|
||||
String controller_name = this.mod.config.get_controller().get_name();
|
||||
if (controller_name.equals(String.valueOf(this.mod.config.get_controller().get_id())))
|
||||
return option.getDisplayPrefix() + Formatting.RED + controller_name;
|
||||
else
|
||||
return option.getDisplayPrefix() + controller_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());
|
||||
@@ -83,18 +88,6 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
this.mod.config.set_mouse_speed(new_value);
|
||||
}
|
||||
}, (game_options, option) -> option.getDisplayPrefix() + option.get(options));
|
||||
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
|
||||
@@ -129,14 +122,18 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
this.mod.config.save();
|
||||
}));
|
||||
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))));
|
||||
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));
|
||||
}));
|
||||
|
||||
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"),
|
||||
@@ -144,14 +141,14 @@ public class LambdaControlsSettingsScreen extends Screen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(int mouseX, int mouseY, float delta)
|
||||
public void render(int mouse_x, int mouse_y, float delta)
|
||||
{
|
||||
this.renderBackground();
|
||||
this.list.render(mouseX, mouseY, delta);
|
||||
super.render(mouseX, mouseY, delta);
|
||||
this.list.render(mouse_x, mouse_y, delta);
|
||||
super.render(mouse_x, mouse_y, delta);
|
||||
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);
|
||||
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.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.2", Formatting.GOLD.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, 10526880);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ public class TouchscreenOverlay extends Screen
|
||||
this.update_jump_buttons();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.mixin;
|
||||
|
||||
import net.minecraft.client.gui.widget.EntryListWidget;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(EntryListWidget.class)
|
||||
public interface EntryListWidgetAccessor
|
||||
{
|
||||
@Invoker("moveSelection")
|
||||
void move_selection(int amount);
|
||||
}
|
||||
@@ -1,26 +1,61 @@
|
||||
{
|
||||
"lambdacontrols.action.attack": "Attack",
|
||||
"lambdacontrols.action.back": "Back",
|
||||
"lambdacontrols.action.drop_item": "Drop item",
|
||||
"lambdacontrols.action.chat": "Open Chat",
|
||||
"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.left": "Left",
|
||||
"lambdacontrols.action.pause_game": "Pause Game",
|
||||
"lambdacontrols.action.pick_block": "Pick Block",
|
||||
"lambdacontrols.action.pickup": "Pickup",
|
||||
"lambdacontrols.action.pickup_all": "Pickup all",
|
||||
"lambdacontrols.action.player_list": "Player List",
|
||||
"lambdacontrols.action.quick_move": "Quick move",
|
||||
"lambdacontrols.action.right": "Right",
|
||||
"lambdacontrols.action.screenshot": "Take Screenshot",
|
||||
"lambdacontrols.action.sneak": "Sneak",
|
||||
"lambdacontrols.action.sprint": "Sprint",
|
||||
"lambdacontrols.action.swap_hands": "Swap hands",
|
||||
"lambdacontrols.action.swap_hands": "Swap Hands",
|
||||
"lambdacontrols.action.toggle_perspective": "Toggle Perspective",
|
||||
"lambdacontrols.action.toggle_smooth_camera": "Toggle Cinematic Camera",
|
||||
"lambdacontrols.action.use": "Use",
|
||||
"lambdacontrols.button.a": "A",
|
||||
"lambdacontrols.button.b": "B",
|
||||
"lambdacontrols.button.x": "X",
|
||||
"lambdacontrols.button.y": "Y",
|
||||
"lambdacontrols.button.left_bumper": "Left bumper",
|
||||
"lambdacontrols.button.right_bumper": "Right bumper",
|
||||
"lambdacontrols.button.back": "Back",
|
||||
"lambdacontrols.button.start": "Start",
|
||||
"lambdacontrols.button.guide": "Guide",
|
||||
"lambdacontrols.button.left_thumb": "Left thumb",
|
||||
"lambdacontrols.button.right_thumb": "Right thumb",
|
||||
"lambdacontrols.button.dpad_up": "DPAD up",
|
||||
"lambdacontrols.button.dpad_right": "DPAD right",
|
||||
"lambdacontrols.button.dpad_down": "DPAD down",
|
||||
"lambdacontrols.button.dpad_left": "DPAD left",
|
||||
"lambdacontrols.axis.left_x+": "Left X+",
|
||||
"lambdacontrols.axis.left_y+": "Left Y+",
|
||||
"lambdacontrols.axis.right_x+": "Right X+",
|
||||
"lambdacontrols.axis.right_y+": "Right Y+",
|
||||
"lambdacontrols.axis.left_trigger": "Left trigger",
|
||||
"lambdacontrols.axis.right_trigger": "Right trigger",
|
||||
"lambdacontrols.axis.left_x-": "Left X-",
|
||||
"lambdacontrols.axis.left_y-": "Left Y-",
|
||||
"lambdacontrols.axis.right_x-": "Right X-",
|
||||
"lambdacontrols.axis.right_y-": "Right Y-",
|
||||
"lambdacontrols.button.unknown": "Unknown (%d)",
|
||||
"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.mappings.1": "To configure the controller mappings, please use %sSDL2 Gamepad Tool%s",
|
||||
"lambdacontrols.controller.mappings.2": "(%shttp://generalarcade.com/gamepadtool/%s),",
|
||||
"lambdacontrols.controller.mappings.3": "and put the mapping in `%sconfig/gamecontrollerdb.txt%s`.",
|
||||
"lambdacontrols.controller_type.default": "default",
|
||||
"lambdacontrols.controller_type.playstation": "PlayStation",
|
||||
"lambdacontrols.controller_type.dualshock": "DualShock",
|
||||
"lambdacontrols.controller_type.switch": "Switch",
|
||||
"lambdacontrols.controller_type.xbox": "Xbox",
|
||||
"lambdacontrols.controller_type.steam": "Steam",
|
||||
@@ -40,5 +75,6 @@
|
||||
"lambdacontrols.menu.invert_right_y_axis": "Invert right Y",
|
||||
"lambdacontrols.menu.mouse_speed": "Mouse speed",
|
||||
"lambdacontrols.menu.rotation_speed": "Rotation speed",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Settings"
|
||||
"lambdacontrols.menu.title": "LambdaControls - Settings",
|
||||
"lambdacontrols.menu.title.controller_controls": "Controller controls"
|
||||
}
|
||||
80
src/main/resources/assets/lambdacontrols/lang/fr_fr.json
Normal file
80
src/main/resources/assets/lambdacontrols/lang/fr_fr.json
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"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.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 analogique gauche",
|
||||
"lambdacontrols.button.right_thumb": "Stick analogique 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": "(%shttp://generalarcade.com/gamepadtool/%s),",
|
||||
"lambdacontrols.controller.mappings.3": "et mettez les correspondances dans le fichier `%sconfig/gamecontrollerdb.txt%s`.",
|
||||
"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.controller": "Manette",
|
||||
"lambdacontrols.menu.controller_type": "Type de manette",
|
||||
"lambdacontrols.menu.controls_mode": "Mode de contrôle",
|
||||
"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.mouse_speed": "Vitesse de la souris",
|
||||
"lambdacontrols.menu.rotation_speed": "Vitesse de rotation",
|
||||
"lambdacontrols.menu.title": "LambdaControls - Paramètres",
|
||||
"lambdacontrols.menu.title.controller_controls": "Contrôles de la manette"
|
||||
}
|
||||
@@ -25,3 +25,39 @@ controls = "default"
|
||||
invert_right_x_axis = false
|
||||
# Inverts the right Y axis.
|
||||
invert_right_y_axis = false
|
||||
# Controller controls.
|
||||
[controller.controls]
|
||||
# Attack control.
|
||||
attack = 105
|
||||
# Back control.
|
||||
back = 201
|
||||
# Open chat control.
|
||||
chat = 12
|
||||
# Drop item control.
|
||||
drop_item = 1
|
||||
# Forward control.
|
||||
forward = 101
|
||||
# Inventory control.
|
||||
inventory = 3
|
||||
# Jump control.
|
||||
jump = 0
|
||||
# Pause game control.
|
||||
pause_game = 7
|
||||
# Pick block control.
|
||||
pick_block = 14
|
||||
# Show player list control.
|
||||
player_list = 6
|
||||
# Take screenshot control.
|
||||
screenshot = 13
|
||||
# Sneak control.
|
||||
sneak = 10
|
||||
# Sprint control.
|
||||
sprint = 9
|
||||
# Swap hands control.
|
||||
swap_hands = 2
|
||||
# Toggle perspective control.
|
||||
toggle_perspective = 11
|
||||
# Toggle smooth camera control.
|
||||
toggle_smooth_camera = -1
|
||||
# Use control.
|
||||
use = 104
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"AbstractButtonWidgetAccessor",
|
||||
"AbstractContainerScreenMixin",
|
||||
"CreativeInventoryScreenMixin",
|
||||
"EntryListWidgetAccessor",
|
||||
"GameRendererMixin",
|
||||
"InGameHudMixin",
|
||||
"KeyBindingMixin",
|
||||
|
||||
Reference in New Issue
Block a user