mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-13 23:25:10 +01:00
Improve code further
This commit is contained in:
@@ -87,9 +87,9 @@ public class MidnightControlsClient extends MidnightControls {
|
||||
Timer timer = new Timer();
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
public void run() {
|
||||
if (client.isRunning()) {
|
||||
input.tickJoysticks(client);
|
||||
input.updateCamera(client);
|
||||
if (lateInitDone && client.isRunning()) {
|
||||
input.tickJoysticks();
|
||||
input.updateCamera();
|
||||
}
|
||||
}
|
||||
}, delay, period);
|
||||
@@ -171,10 +171,10 @@ public class MidnightControlsClient extends MidnightControls {
|
||||
*/
|
||||
public static void onTick(@NotNull MinecraftClient client) {
|
||||
initKeybindings();
|
||||
input.tick(client);
|
||||
reacharound.tick(client);
|
||||
input.tick();
|
||||
reacharound.tick();
|
||||
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput))
|
||||
input.tickController(client);
|
||||
input.tickController();
|
||||
|
||||
if (BINDING_RING.wasPressed()) {
|
||||
ring.loadFromUnbound();
|
||||
@@ -200,7 +200,7 @@ public class MidnightControlsClient extends MidnightControls {
|
||||
client.skipGameRender = false;
|
||||
client.currentScreen = screen;
|
||||
} else if (screen != null) {
|
||||
MidnightControlsClient.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight());
|
||||
MidnightControlsClient.input.onScreenOpen(client.getWindow().getWidth(), client.getWindow().getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,24 @@ package eu.midnightdust.midnightcontrols.client;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import eu.midnightdust.lib.util.PlatformFunctions;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.EmotecraftCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.LibGuiCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.YACLCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.mixin.MouseAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.util.InventoryUtil;
|
||||
import eu.midnightdust.midnightcontrols.client.util.storage.AxisStorage;
|
||||
import eu.midnightdust.midnightcontrols.client.util.storage.ButtonStorage;
|
||||
import net.minecraft.client.gui.screen.option.KeybindsScreen;
|
||||
import net.minecraft.client.gui.widget.EntryListWidget;
|
||||
import net.minecraft.client.gui.widget.PressableWidget;
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.entity.vehicle.BoatEntity;
|
||||
import net.minecraft.util.Pair;
|
||||
import org.thinkingstudio.obsidianui.widget.AbstractSpruceWidget;
|
||||
import org.thinkingstudio.obsidianui.widget.container.SpruceEntryListWidget;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControls;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.*;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.Controller;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
|
||||
@@ -26,7 +36,6 @@ import eu.midnightdust.midnightcontrols.client.enums.CameraMode;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
|
||||
import eu.midnightdust.midnightcontrols.client.touch.gui.TouchscreenOverlay;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget;
|
||||
import eu.midnightdust.midnightcontrols.client.mixin.*;
|
||||
import eu.midnightdust.midnightcontrols.client.ring.RingPage;
|
||||
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
|
||||
@@ -50,16 +59,16 @@ import net.minecraft.client.gui.screen.ingame.StonecutterScreen;
|
||||
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.*;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.text.TranslatableTextContent;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWGamepadState;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
@@ -67,12 +76,12 @@ import static org.lwjgl.glfw.GLFW.*;
|
||||
/**
|
||||
* Represents the midnightcontrols' input handler.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.7.0
|
||||
* @author Motschen, LambdAurora
|
||||
* @version 1.10.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class MidnightInput {
|
||||
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
|
||||
public static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
|
||||
// Cooldowns
|
||||
public int actionGuiCooldown = 0;
|
||||
public int joystickCooldown = 0;
|
||||
@@ -82,10 +91,8 @@ public class MidnightInput {
|
||||
private double targetPitch = 0.0;
|
||||
private float prevXAxis = 0.f;
|
||||
private float prevYAxis = 0.f;
|
||||
private int targetMouseX = 0;
|
||||
private int targetMouseY = 0;
|
||||
private float mouseSpeedX = 0.f;
|
||||
private float mouseSpeedY = 0.f;
|
||||
public float mouseSpeedX = 0.f;
|
||||
public float mouseSpeedY = 0.f;
|
||||
public int inventoryInteractionCooldown = 0;
|
||||
public int screenCloseCooldown = 0;
|
||||
|
||||
@@ -95,10 +102,8 @@ public class MidnightInput {
|
||||
|
||||
/**
|
||||
* This method is called every Minecraft tick.
|
||||
*
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void tick(@NotNull MinecraftClient client) {
|
||||
public void tick() {
|
||||
this.targetYaw = 0.F;
|
||||
this.targetPitch = 0.F;
|
||||
|
||||
@@ -114,15 +119,13 @@ public class MidnightInput {
|
||||
this.handleFlatLook(new AxisStorage(GLFW_GAMEPAD_AXIS_RIGHT_X, 0.8F, 1));
|
||||
}
|
||||
|
||||
InputManager.INPUT_MANAGER.tick(client);
|
||||
InputManager.INPUT_MANAGER.tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called every Minecraft tick for controller input update.
|
||||
*
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void tickController(@NotNull MinecraftClient client) {
|
||||
public void tickController() {
|
||||
BUTTON_COOLDOWNS.entrySet().stream().filter(entry -> entry.getValue() > 0)
|
||||
.forEach(entry -> BUTTON_COOLDOWNS.put(entry.getKey(), entry.getValue() - 1));
|
||||
// Decreases the cooldown for GUI actions.
|
||||
@@ -139,20 +142,20 @@ public class MidnightInput {
|
||||
|
||||
if (controller.isConnected()) {
|
||||
var state = controller.getState();
|
||||
this.fetchButtonInput(client, state, false);
|
||||
this.fetchTriggerInput(client, state, false);
|
||||
this.fetchButtonInput(state, false);
|
||||
this.fetchTriggerInput(state, false);
|
||||
}
|
||||
MidnightControlsConfig.getSecondController().filter(Controller::isConnected)
|
||||
.ifPresent(joycon -> {
|
||||
var state = joycon.getState();
|
||||
this.fetchButtonInput(client, state, true);
|
||||
this.fetchTriggerInput(client, state, true);
|
||||
this.fetchButtonInput(state, true);
|
||||
this.fetchTriggerInput(state, true);
|
||||
});
|
||||
|
||||
boolean allowInput = this.controlsInput == null || this.controlsInput.focusedBinding == null;
|
||||
|
||||
if (allowInput)
|
||||
InputManager.updateBindings(client);
|
||||
InputManager.updateBindings();
|
||||
|
||||
if (this.controlsInput != null) {
|
||||
InputManager.STATES.forEach((num, button) -> {
|
||||
@@ -160,7 +163,7 @@ public class MidnightInput {
|
||||
});
|
||||
}
|
||||
if (this.controlsInput != null && InputManager.STATES.int2ObjectEntrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::isUnpressed)) {
|
||||
if (MidnightControlsConfig.debug) MidnightControls.log("Finished MidnightInput Button Edit");
|
||||
if (MidnightControlsConfig.debug) MidnightControls.log("Starting MidnightInput Button Edit");
|
||||
if (this.controlsInput.focusedBinding != null && !this.controlsInput.waiting) {
|
||||
int[] buttons = new int[this.controlsInput.currentButtons.size()];
|
||||
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
|
||||
@@ -175,28 +178,25 @@ public class MidnightInput {
|
||||
}
|
||||
/**
|
||||
* This method is called 1000 times a second for smooth joystick input
|
||||
*
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void tickJoysticks(@NotNull MinecraftClient client) {
|
||||
public void tickJoysticks() {
|
||||
var controller = MidnightControlsConfig.getController();
|
||||
|
||||
if (controller.isConnected()) {
|
||||
this.fetchJoystickInput(client, controller.getState(), false);
|
||||
this.fetchJoystickInput(controller.getState(), false);
|
||||
}
|
||||
MidnightControlsConfig.getSecondController().filter(Controller::isConnected)
|
||||
.ifPresent(joycon -> {
|
||||
this.fetchJoystickInput(client, joycon.getState(), true);
|
||||
this.fetchJoystickInput(joycon.getState(), true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called before the screen is rendered.
|
||||
*
|
||||
* @param client the client instance
|
||||
* @param screen the screen to render
|
||||
*/
|
||||
public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen) {
|
||||
public void onPreRenderScreen(@NotNull Screen screen) {
|
||||
if (!isScreenInteractive(screen)) {
|
||||
InputManager.INPUT_MANAGER.updateMousePosition(client);
|
||||
}
|
||||
@@ -204,10 +204,8 @@ public class MidnightInput {
|
||||
|
||||
/**
|
||||
* This method is called to update the camera
|
||||
*
|
||||
* @param client the client instance
|
||||
*/
|
||||
public void updateCamera(@NotNull MinecraftClient client) {
|
||||
public void updateCamera() {
|
||||
if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay))
|
||||
return;
|
||||
|
||||
@@ -232,11 +230,10 @@ public class MidnightInput {
|
||||
/**
|
||||
* This method is called when a Screen is opened.
|
||||
*
|
||||
* @param client the client instance
|
||||
* @param windowWidth the window width
|
||||
* @param windowHeight the window height
|
||||
*/
|
||||
public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight) {
|
||||
public void onScreenOpen(int windowWidth, int windowHeight) {
|
||||
if (client.currentScreen == null) {
|
||||
this.mouseSpeedX = this.mouseSpeedY = 0.0F;
|
||||
InputManager.INPUT_MANAGER.resetMousePosition(windowWidth, windowHeight);
|
||||
@@ -255,7 +252,7 @@ public class MidnightInput {
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchButtonInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
private void fetchButtonInput(@NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
var buffer = gamepadState.buttons();
|
||||
for (int i = 0; i < buffer.limit(); i++) {
|
||||
int btn = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
||||
@@ -265,14 +262,14 @@ public class MidnightInput {
|
||||
|
||||
if (btnState != previousState.isPressed()) {
|
||||
state = btnState ? ButtonState.PRESS : ButtonState.RELEASE;
|
||||
this.handleButton(client, btn, btnState ? 0 : 1, btnState);
|
||||
this.handleButton(new ButtonStorage(btn, btnState ? 0 : 1, btnState));
|
||||
if (btnState)
|
||||
BUTTON_COOLDOWNS.put(btn, 5);
|
||||
} else if (btnState) {
|
||||
state = ButtonState.REPEAT;
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(btn, 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(btn, 5);
|
||||
this.handleButton(client, btn, 2, true);
|
||||
this.handleButton(new ButtonStorage(btn, 2, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +278,7 @@ public class MidnightInput {
|
||||
}
|
||||
final MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil();
|
||||
|
||||
private void fetchJoystickInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
private void fetchJoystickInput(@NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
var buffer = gamepadState.axes();
|
||||
|
||||
polarUtil.calculate(buffer.get(GLFW_GAMEPAD_AXIS_LEFT_X), buffer.get(GLFW_GAMEPAD_AXIS_LEFT_Y), 1, MidnightControlsConfig.leftDeadZone);
|
||||
@@ -293,53 +290,37 @@ public class MidnightInput {
|
||||
|
||||
boolean isRadialMenu = client.currentScreen instanceof RingScreen || (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen));
|
||||
|
||||
for (int i = 0; i < GLFW_GAMEPAD_AXIS_LEFT_TRIGGER; i++) {
|
||||
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
||||
float value = buffer.get(i);
|
||||
if (!isRadialMenu) {
|
||||
for (int i = 0; i < GLFW_GAMEPAD_AXIS_LEFT_TRIGGER; i++) {
|
||||
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
||||
float value = buffer.get(i);
|
||||
|
||||
switch (i) {
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_X -> {if (MidnightControlsConfig.analogMovement) value = leftX;}
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_Y -> {if (MidnightControlsConfig.analogMovement) value = leftY;}
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_X -> value = rightX;
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_Y -> value = rightY;
|
||||
switch (i) {
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_X -> {
|
||||
if (MidnightControlsConfig.analogMovement) value = leftX;
|
||||
}
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_Y -> {
|
||||
if (MidnightControlsConfig.analogMovement) value = leftY;
|
||||
}
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_X -> value = rightX;
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_Y -> value = rightY;
|
||||
}
|
||||
float absValue = Math.abs(value);
|
||||
|
||||
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
|
||||
value *= -1.0F;
|
||||
|
||||
int state = value > MidnightControlsConfig.rightDeadZone ? 1 : (value < -MidnightControlsConfig.rightDeadZone ? 2 : 0);
|
||||
this.handleJoystickAxis(new AxisStorage(axis, value, absValue, state));
|
||||
}
|
||||
float absValue = Math.abs(value);
|
||||
|
||||
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
|
||||
value *= -1.0F;
|
||||
|
||||
int state = value > MidnightControlsConfig.rightDeadZone ? 1 : (value < -MidnightControlsConfig.rightDeadZone ? 2 : 0);
|
||||
if (!isRadialMenu)
|
||||
this.handleJoystickAxis(client, new AxisStorage(axis, value, absValue, state));
|
||||
}
|
||||
if (isRadialMenu) {
|
||||
float x = leftX;
|
||||
float y = leftY;
|
||||
|
||||
if (x == 0 && y == 0) {
|
||||
x = rightX;
|
||||
y = rightY;
|
||||
}
|
||||
int index = -1;
|
||||
float border = 0.3f;
|
||||
if (x < -border) {
|
||||
index = 3;
|
||||
if (y < -border) index = 0;
|
||||
else if (y > border) index = 5;
|
||||
} else if (x > border) {
|
||||
index = 4;
|
||||
if (y < -border) index = 2;
|
||||
else if (y > border) index = 7;
|
||||
} else {
|
||||
if (y < -border) index = 1;
|
||||
else if (y > border) index = 6;
|
||||
}
|
||||
if (client.currentScreen instanceof RingScreen && index > -1) RingPage.selected = index;
|
||||
if (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)) EmotecraftCompat.handleEmoteSelector(index);
|
||||
else {
|
||||
boolean leftStickActive = leftX != 0 || leftY != 0;
|
||||
handleRadialMenu(leftStickActive ? leftX : rightX, leftStickActive ? leftY : rightY);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchTriggerInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
private void fetchTriggerInput(@NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||
var buffer = gamepadState.axes();
|
||||
|
||||
for (int i = GLFW_GAMEPAD_AXIS_LEFT_TRIGGER; i <= GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER; i++) {
|
||||
@@ -348,14 +329,14 @@ public class MidnightInput {
|
||||
float absValue = Math.abs(value);
|
||||
|
||||
int state = value > MidnightControlsConfig.rightDeadZone ? 1 : (value < -MidnightControlsConfig.rightDeadZone ? 2 : 0);
|
||||
this.handleTriggerAxis(client, new AxisStorage(axis, value, absValue, state));
|
||||
this.handleTriggerAxis(new AxisStorage(axis, value, absValue, state));
|
||||
}
|
||||
}
|
||||
|
||||
public void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state) {
|
||||
public void handleButton(ButtonStorage storage) {
|
||||
if (this.controlsInput != null && this.controlsInput.focusedBinding != null) {
|
||||
if (action == 0 && !this.controlsInput.currentButtons.contains(button)) {
|
||||
this.controlsInput.currentButtons.add(button);
|
||||
if (storage.action == 0 && !this.controlsInput.currentButtons.contains(storage.button)) {
|
||||
this.controlsInput.currentButtons.add(storage.button);
|
||||
|
||||
var buttons = new int[this.controlsInput.currentButtons.size()];
|
||||
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
|
||||
@@ -367,37 +348,32 @@ public class MidnightInput {
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.currentScreen != null && (action == 0 || action == 2) && button == GLFW_GAMEPAD_BUTTON_Y &&
|
||||
if (client.currentScreen != null && (storage.action != 1) && storage.button == GLFW_GAMEPAD_BUTTON_Y &&
|
||||
MidnightControlsConfig.arrowScreens.contains(client.currentScreen.getClass().getCanonicalName())) {
|
||||
pressKeyboardKey(client, GLFW.GLFW_KEY_ENTER);
|
||||
this.screenCloseCooldown = 5;
|
||||
}
|
||||
else if (action == 0 || action == 2) {
|
||||
if (client.currentScreen != null
|
||||
&& (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.actionGuiCooldown == 0) {
|
||||
switch (button) {
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP -> this.changeFocus(client.currentScreen, NavigationDirection.UP);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> this.handleLeftRight(client.currentScreen, false);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> this.handleLeftRight(client.currentScreen, true);
|
||||
}
|
||||
if (MidnightControlsConfig.wasdScreens.contains(client.currentScreen.getClass().getCanonicalName())) {
|
||||
switch (button) {
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP -> pressKeyboardKey(client, GLFW.GLFW_KEY_W);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> pressKeyboardKey(client, GLFW.GLFW_KEY_S);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> pressKeyboardKey(client, GLFW.GLFW_KEY_A);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> pressKeyboardKey(client, GLFW.GLFW_KEY_D);
|
||||
}
|
||||
else if (storage.action != 1) {
|
||||
if (client.currentScreen != null && storage.isDpad() && this.actionGuiCooldown == 0) {
|
||||
switch (storage.button) {
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP -> this.changeFocus(client.currentScreen, NavigationDirection.UP);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> this.handleLeftRight(client.currentScreen, false);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> this.handleLeftRight(client.currentScreen, true);
|
||||
}
|
||||
if (MidnightControlsConfig.wasdScreens.contains(client.currentScreen.getClass().getCanonicalName())) {
|
||||
switch (storage.button) {
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP -> pressKeyboardKey(client, GLFW.GLFW_KEY_W);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> pressKeyboardKey(client, GLFW.GLFW_KEY_S);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> pressKeyboardKey(client, GLFW.GLFW_KEY_A);
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> pressKeyboardKey(client, GLFW.GLFW_KEY_D);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (action == 1) {
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) {
|
||||
else {
|
||||
if (storage.button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) {
|
||||
if (this.actionGuiCooldown == 0) {
|
||||
var focused = client.currentScreen.getFocused();
|
||||
if (focused != null && isScreenInteractive(client.currentScreen)) {
|
||||
@@ -411,7 +387,7 @@ public class MidnightInput {
|
||||
}
|
||||
}
|
||||
|
||||
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen)
|
||||
if (storage.button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !isScreenInteractive(client.currentScreen)
|
||||
&& this.actionGuiCooldown == 0) {
|
||||
if (client.currentScreen instanceof HandledScreen<?> handledScreen && ((HandledScreenAccessor) handledScreen).midnightcontrols$getSlotAt(
|
||||
client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(),
|
||||
@@ -419,55 +395,50 @@ public class MidnightInput {
|
||||
if (!this.ignoreNextARelease && client.currentScreen != null) {
|
||||
var accessor = (MouseAccessor) client.mouse;
|
||||
accessor.midnightcontrols$onCursorPos(client.getWindow().getHandle(), client.mouse.getX(), client.mouse.getY());
|
||||
if (action == 0) { // Button pressed
|
||||
accessor.midnightcontrols$onMouseButton(client.getWindow().getHandle(), GLFW_MOUSE_BUTTON_LEFT, 1, 0);
|
||||
} else if (action == 1) { // Button released
|
||||
accessor.midnightcontrols$onMouseButton(client.getWindow().getHandle(), GLFW_MOUSE_BUTTON_LEFT, 0, 0);
|
||||
client.currentScreen.setDragging(false);
|
||||
} else if (action == 2) { // Button held down / dragging
|
||||
client.currentScreen.setDragging(true);
|
||||
switch (storage.action) {
|
||||
// Button pressed
|
||||
case 0 -> accessor.midnightcontrols$onMouseButton(client.getWindow().getHandle(), GLFW_MOUSE_BUTTON_LEFT, 1, 0);
|
||||
case 1 -> { // Button released
|
||||
accessor.midnightcontrols$onMouseButton(client.getWindow().getHandle(), GLFW_MOUSE_BUTTON_LEFT, 0, 0);
|
||||
client.currentScreen.setDragging(false);
|
||||
}
|
||||
case 2 -> client.currentScreen.setDragging(true); // Button held down / dragging
|
||||
}
|
||||
this.screenCloseCooldown = 5;
|
||||
} else {
|
||||
this.ignoreNextARelease = false;
|
||||
}
|
||||
}
|
||||
else if (button == GLFW.GLFW_GAMEPAD_BUTTON_X && client.currentScreen != null && !isScreenInteractive(client.currentScreen)
|
||||
else if (storage.button == GLFW.GLFW_GAMEPAD_BUTTON_X && client.currentScreen != null && !isScreenInteractive(client.currentScreen)
|
||||
&& this.actionGuiCooldown == 0) {
|
||||
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
|
||||
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
|
||||
if (client.currentScreen instanceof HandledScreen<?> handledScreen && ((HandledScreenAccessor) handledScreen).midnightcontrols$getSlotAt(
|
||||
client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(),
|
||||
client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()) != null) return;
|
||||
mouseX, mouseY) != null) return;
|
||||
if (!this.ignoreNextXRelease && client.currentScreen != null) {
|
||||
double mouseX = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
|
||||
double mouseY = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
|
||||
if (action == 0) {
|
||||
Screen.wrapScreenError(() -> client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_2),
|
||||
"mouseClicked event handler", client.currentScreen.getClass().getCanonicalName());
|
||||
} else if (action == 1) {
|
||||
Screen.wrapScreenError(() -> client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_2),
|
||||
"mouseReleased event handler", client.currentScreen.getClass().getCanonicalName());
|
||||
}
|
||||
if (storage.action == 0) client.currentScreen.mouseClicked(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_2);
|
||||
else if (storage.action == 1) client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_2);
|
||||
this.screenCloseCooldown = 5;
|
||||
} else {
|
||||
this.ignoreNextXRelease = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void handleTriggerAxis(@NotNull MinecraftClient client, AxisStorage storage) {
|
||||
this.setCurrentPolarities(storage);
|
||||
private void handleTriggerAxis(AxisStorage storage) {
|
||||
storage.setupButtonStates();
|
||||
}
|
||||
|
||||
private void handleJoystickAxis(@NotNull MinecraftClient client, AxisStorage storage) {
|
||||
this.setCurrentPolarities(storage);
|
||||
private void handleJoystickAxis(AxisStorage storage) {
|
||||
storage.setupButtonStates();
|
||||
|
||||
this.handleMovement(client, storage);
|
||||
this.handleMovement(storage);
|
||||
|
||||
if (this.handleScreenScrolling(client.currentScreen, storage)) return;
|
||||
|
||||
storage.absValue = (float) MathHelper.clamp(storage.absValue / MidnightControlsConfig.getAxisMaxValue(storage.axis), 0.f, 1.f);
|
||||
if (client.currentScreen == null) {
|
||||
// Handles the look direction.
|
||||
this.handleLook(client, storage);
|
||||
this.handleLook(storage);
|
||||
} else {
|
||||
boolean allowMouseControl = true;
|
||||
|
||||
@@ -521,7 +492,7 @@ public class MidnightInput {
|
||||
);
|
||||
}
|
||||
|
||||
this.moveMouseToClosestSlot(client, client.currentScreen);
|
||||
InventoryUtil.moveMouseToClosestSlot(client.currentScreen);
|
||||
}
|
||||
|
||||
this.prevXAxis = movementX;
|
||||
@@ -529,44 +500,7 @@ public class MidnightInput {
|
||||
}
|
||||
}
|
||||
|
||||
private void setCurrentPolarities(AxisStorage storage) {
|
||||
boolean currentPlusState = storage.value > storage.deadZone;
|
||||
boolean currentMinusState = storage.value < -storage.deadZone;
|
||||
if (storage.axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || storage.axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER) currentMinusState = false;
|
||||
if (!MidnightControlsConfig.analogMovement && (storage.axis == GLFW_GAMEPAD_AXIS_LEFT_X || storage.axis == GLFW_GAMEPAD_AXIS_LEFT_Y)) {
|
||||
currentPlusState = storage.asButtonState == 1;
|
||||
currentMinusState = storage.asButtonState == 2;
|
||||
}
|
||||
var posButton = ButtonBinding.axisAsButton(storage.axis, true);
|
||||
var negButton = ButtonBinding.axisAsButton(storage.axis, false);
|
||||
var previousPlusState = InputManager.STATES.getOrDefault(posButton, ButtonState.NONE);
|
||||
var previousMinusState = InputManager.STATES.getOrDefault(negButton, ButtonState.NONE);
|
||||
|
||||
if (currentPlusState != previousPlusState.isPressed()) {
|
||||
InputManager.STATES.put(posButton, currentPlusState ? ButtonState.PRESS : ButtonState.RELEASE);
|
||||
if (currentPlusState)
|
||||
BUTTON_COOLDOWNS.put(posButton, 5);
|
||||
} else if (currentPlusState) {
|
||||
InputManager.STATES.put(posButton, ButtonState.REPEAT);
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(posButton, 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(posButton, 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMinusState != previousMinusState.isPressed()) {
|
||||
InputManager.STATES.put(negButton, currentMinusState ? ButtonState.PRESS : ButtonState.RELEASE);
|
||||
if (currentMinusState)
|
||||
BUTTON_COOLDOWNS.put(negButton, 5);
|
||||
} else if (currentMinusState) {
|
||||
InputManager.STATES.put(negButton, ButtonState.REPEAT);
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(negButton, 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(negButton, 5);
|
||||
}
|
||||
}
|
||||
storage.polarity = currentPlusState ? AxisStorage.Polarity.PLUS : currentMinusState ? AxisStorage.Polarity.MINUS : AxisStorage.Polarity.ZERO;
|
||||
}
|
||||
|
||||
private void handleMovement(@NotNull MinecraftClient client, AxisStorage storage) {
|
||||
private void handleMovement(AxisStorage storage) {
|
||||
float axisValue = storage.absValue;
|
||||
if (!MidnightControlsConfig.analogMovement || (client.player != null && client.player.getVehicle() instanceof BoatEntity)) {
|
||||
axisValue = (float) (storage.absValue - storage.deadZone);
|
||||
@@ -641,6 +575,24 @@ public class MidnightInput {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void handleRadialMenu(float x, float y) {
|
||||
int index = -1;
|
||||
float border = 0.3f;
|
||||
if (x < -border) {
|
||||
index = 3;
|
||||
if (y < -border) index = 0;
|
||||
else if (y > border) index = 5;
|
||||
} else if (x > border) {
|
||||
index = 4;
|
||||
if (y < -border) index = 2;
|
||||
else if (y > border) index = 7;
|
||||
} else {
|
||||
if (y < -border) index = 1;
|
||||
else if (y > border) index = 6;
|
||||
}
|
||||
if (client.currentScreen instanceof RingScreen && index > -1) RingPage.selected = index;
|
||||
if (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)) EmotecraftCompat.handleEmoteSelector(index);
|
||||
}
|
||||
|
||||
public boolean handleListWidgetScrolling(List<? extends Element> children, float value) {
|
||||
return children.stream().filter(element -> element instanceof SpruceEntryListWidget)
|
||||
@@ -755,10 +707,9 @@ public class MidnightInput {
|
||||
/**
|
||||
* Handles the look direction input.
|
||||
*
|
||||
* @param client the client instance
|
||||
* @param storage the state of the provided axis
|
||||
*/
|
||||
public void handleLook(@NotNull MinecraftClient client, AxisStorage storage) {
|
||||
public void handleLook(AxisStorage storage) {
|
||||
if (client.player == null || !(storage.axis == GLFW_GAMEPAD_AXIS_RIGHT_Y || storage.axis == GLFW_GAMEPAD_AXIS_RIGHT_X)) return;
|
||||
// Handles the look direction.
|
||||
if (MidnightControlsConfig.cameraMode == CameraMode.FLAT) handleFlatLook(storage);
|
||||
@@ -872,59 +823,4 @@ public class MidnightInput {
|
||||
public void pressKeyboardKey(Screen screen, int key) {
|
||||
screen.keyPressed(key, 0, 1);
|
||||
}
|
||||
|
||||
// Inspired from https://github.com/MrCrayfish/Controllable/blob/1.14.X/src/main/java/com/mrcrayfish/controllable/client/ControllerInput.java#L686.
|
||||
private void moveMouseToClosestSlot(@NotNull MinecraftClient client, @Nullable Screen screen) {
|
||||
// Makes the mouse attracted to slots. This helps with selecting items when using a controller.
|
||||
if (screen instanceof HandledScreen<?> inventoryScreen) {
|
||||
var accessor = (HandledScreenAccessor) inventoryScreen;
|
||||
int guiLeft = accessor.getX();
|
||||
int guiTop = accessor.getY();
|
||||
int mouseX = (int) (targetMouseX * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth());
|
||||
int mouseY = (int) (targetMouseY * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight());
|
||||
|
||||
// Finds the closest slot in the GUI within 14 pixels.
|
||||
Optional<Pair<Slot, Double>> closestSlot = inventoryScreen.getScreenHandler().slots.parallelStream()
|
||||
.map(slot -> {
|
||||
int x = guiLeft + slot.x + 8;
|
||||
int y = guiTop + slot.y + 8;
|
||||
|
||||
// Distance between the slot and the cursor.
|
||||
double distance = Math.sqrt(Math.pow(x - mouseX, 2) + Math.pow(y - mouseY, 2));
|
||||
return new Pair<Slot, Double>(slot, distance);
|
||||
}).filter(entry -> entry.getRight() <= 14.0)
|
||||
.min(Comparator.comparingDouble(Pair::getRight));
|
||||
|
||||
if (closestSlot.isPresent() && client.player != null) {
|
||||
var slot = closestSlot.get().getLeft();
|
||||
if (slot.hasStack() || !client.player.getInventory().getMainHandStack().isEmpty()) {
|
||||
int slotCenterXScaled = guiLeft + slot.x + 8;
|
||||
int slotCenterYScaled = guiTop + slot.y + 8;
|
||||
int slotCenterX = (int) (slotCenterXScaled / ((double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()));
|
||||
int slotCenterY = (int) (slotCenterYScaled / ((double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()));
|
||||
double deltaX = slotCenterX - targetMouseX;
|
||||
double deltaY = slotCenterY - targetMouseY;
|
||||
|
||||
if (mouseX != slotCenterXScaled || mouseY != slotCenterYScaled) {
|
||||
this.targetMouseX += (int) (deltaX * 0.75);
|
||||
this.targetMouseY += (int) (deltaY * 0.75);
|
||||
} else {
|
||||
this.mouseSpeedX *= 0.3F;
|
||||
this.mouseSpeedY *= 0.3F;
|
||||
}
|
||||
this.mouseSpeedX *= .75F;
|
||||
this.mouseSpeedY *= .75F;
|
||||
} else {
|
||||
this.mouseSpeedX *= .1F;
|
||||
this.mouseSpeedY *= .1F;
|
||||
}
|
||||
} else {
|
||||
this.mouseSpeedX *= .3F;
|
||||
this.mouseSpeedY *= .3F;
|
||||
}
|
||||
} else {
|
||||
this.mouseSpeedX = 0.F;
|
||||
this.mouseSpeedY = 0.F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import net.minecraft.world.RaycastContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
|
||||
|
||||
/**
|
||||
* Represents the reach-around API of midnightcontrols.
|
||||
*
|
||||
@@ -39,10 +41,10 @@ public class MidnightReacharound {
|
||||
private boolean lastReacharoundVertical = false;
|
||||
private boolean onSlab = false;
|
||||
|
||||
public void tick(@NotNull MinecraftClient client) {
|
||||
this.lastReacharoundResult = this.tryVerticalReachAround(client);
|
||||
public void tick() {
|
||||
this.lastReacharoundResult = this.tryVerticalReachAround();
|
||||
if (this.lastReacharoundResult == null) {
|
||||
this.lastReacharoundResult = this.tryHorizontalReachAround(client);
|
||||
this.lastReacharoundResult = this.tryHorizontalReachAround();
|
||||
this.lastReacharoundVertical = false;
|
||||
} else this.lastReacharoundVertical = true;
|
||||
}
|
||||
@@ -81,10 +83,9 @@ public class MidnightReacharound {
|
||||
/**
|
||||
* Returns a nullable block hit result if vertical reach-around is possible.
|
||||
*
|
||||
* @param client the client instance
|
||||
* @return a block hit result if vertical reach-around is possible, else {@code null}
|
||||
*/
|
||||
public @Nullable BlockHitResult tryVerticalReachAround(@NotNull MinecraftClient client) {
|
||||
public @Nullable BlockHitResult tryVerticalReachAround() {
|
||||
if (!MidnightControlsFeature.VERTICAL_REACHAROUND.isAvailable())
|
||||
return null;
|
||||
if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.MISS
|
||||
@@ -113,10 +114,9 @@ public class MidnightReacharound {
|
||||
/**
|
||||
* Returns a nullable block hit result if horizontal reach-around is possible.
|
||||
*
|
||||
* @param client the client instance
|
||||
* @return a block hit result if horizontal reach-around is possible
|
||||
*/
|
||||
public @Nullable BlockHitResult tryHorizontalReachAround(@NotNull MinecraftClient client) {
|
||||
public @Nullable BlockHitResult tryHorizontalReachAround() {
|
||||
if (!MidnightControlsFeature.HORIZONTAL_REACHAROUND.isAvailable())
|
||||
return null;
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
|
||||
|
||||
/**
|
||||
* Represents an input manager for controllers.
|
||||
*
|
||||
@@ -51,17 +53,17 @@ public class InputManager {
|
||||
protected InputManager() {
|
||||
}
|
||||
|
||||
public void tick(@NotNull MinecraftClient client) {
|
||||
public void tick() {
|
||||
if (MidnightControlsConfig.autoSwitchMode && !MidnightControlsConfig.isEditing && MidnightControlsConfig.controlsMode != ControlsMode.TOUCHSCREEN)
|
||||
if (MidnightControlsConfig.getController().isConnected() && MidnightControlsConfig.getController().isGamepad())
|
||||
MidnightControlsConfig.controlsMode = ControlsMode.CONTROLLER;
|
||||
else MidnightControlsConfig.controlsMode = ControlsMode.DEFAULT;
|
||||
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) {
|
||||
this.controllerTick(client);
|
||||
this.controllerTick();
|
||||
}
|
||||
}
|
||||
|
||||
public void controllerTick(@NotNull MinecraftClient client) {
|
||||
public void controllerTick() {
|
||||
this.prevTargetMouseX = this.targetMouseX;
|
||||
this.prevTargetMouseY = this.targetMouseY;
|
||||
}
|
||||
@@ -340,7 +342,7 @@ public class InputManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateBindings(@NotNull MinecraftClient client) {
|
||||
public static void updateBindings() {
|
||||
var skipButtons = new IntArrayList();
|
||||
record ButtonStateValue(ButtonState state, float value) {
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ public class MappingsStringInputWidget extends SpruceContainerWidget {
|
||||
|
||||
protected MappingsStringInputWidget(Position position, int width, int height) {
|
||||
super(position, width, height);
|
||||
//super(new TranslatableText("midnightcontrols.menu.title.mappings.string"));
|
||||
|
||||
this.reloadMappingsOption = ReloadControllerMappingsOption.newOption(btn -> {
|
||||
this.writeMappings();
|
||||
@@ -108,6 +107,7 @@ public class MappingsStringInputWidget extends SpruceContainerWidget {
|
||||
@Override
|
||||
public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
super.renderWidget(context, mouseX, mouseY, delta);
|
||||
context.drawCenteredTextWithShadow(this.client.textRenderer, Text.translatable("midnightcontrols.menu.multiple_mapping_tip"), this.textArea.getX() + this.textArea.getWidth() / 2, this.textArea.getY() + this.textArea.getHeight() - 12, 0x888888);
|
||||
context.drawCenteredTextWithShadow(this.client.textRenderer, Text.translatable("midnightcontrols.menu.current_controller_guid", MidnightControlsConfig.getController().getGuid()), this.textArea.getX() + this.textArea.getWidth() / 2, this.height - 21, 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@ public abstract class GameRendererMixin {
|
||||
@Shadow @Final MinecraftClient client;
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Mouse;getX()D", shift = At.Shift.BEFORE))
|
||||
private void midnigtcontrols$onRender(RenderTickCounter tickCounter, boolean tick, CallbackInfo ci) {
|
||||
private void midnightcontrols$onRender(RenderTickCounter tickCounter, boolean tick, CallbackInfo ci) {
|
||||
if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER)
|
||||
MidnightControlsClient.input.onPreRenderScreen(this.client, this.client.currentScreen);
|
||||
MidnightControlsClient.input.onPreRenderScreen(this.client.currentScreen);
|
||||
}
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE))
|
||||
private void midnigtcontrols$renderVirtualCursor(RenderTickCounter tickCounter, boolean tick, CallbackInfo ci, @Local DrawContext drawContext) {
|
||||
private void midnightcontrols$renderVirtualCursor(RenderTickCounter tickCounter, boolean tick, CallbackInfo ci, @Local DrawContext drawContext) {
|
||||
MidnightControlsRenderer.renderVirtualCursor(drawContext, client);
|
||||
if (MidnightControlsClient.isWayland) MidnightControlsRenderer.renderWaylandCursor(drawContext, client);
|
||||
drawContext.draw();
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package eu.midnightdust.midnightcontrols.client.util;
|
||||
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import org.aperlambda.lambdacommon.utils.Pair;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
|
||||
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.input;
|
||||
|
||||
public class InventoryUtil {
|
||||
// Finds the closest slot in the GUI within 14 pixels.
|
||||
@@ -60,4 +63,62 @@ public class InventoryUtil {
|
||||
.min(Comparator.comparingDouble(p -> p.value))
|
||||
.map(p -> p.key);
|
||||
}
|
||||
|
||||
private static int targetMouseX = 0;
|
||||
private static int targetMouseY = 0;
|
||||
|
||||
// Inspired from https://github.com/MrCrayfish/Controllable/blob/1.14.X/src/main/java/com/mrcrayfish/controllable/client/ControllerInput.java#L686.
|
||||
public static void moveMouseToClosestSlot(@Nullable Screen screen) {
|
||||
// Makes the mouse attracted to slots. This helps with selecting items when using a controller.
|
||||
if (screen instanceof HandledScreen<?> inventoryScreen) {
|
||||
var accessor = (HandledScreenAccessor) inventoryScreen;
|
||||
int guiLeft = accessor.getX();
|
||||
int guiTop = accessor.getY();
|
||||
int mouseX = (int) (targetMouseX * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth());
|
||||
int mouseY = (int) (targetMouseY * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight());
|
||||
|
||||
// Finds the closest slot in the GUI within 14 pixels.
|
||||
Optional<net.minecraft.util.Pair<Slot, Double>> closestSlot = inventoryScreen.getScreenHandler().slots.parallelStream()
|
||||
.map(slot -> {
|
||||
int x = guiLeft + slot.x + 8;
|
||||
int y = guiTop + slot.y + 8;
|
||||
|
||||
// Distance between the slot and the cursor.
|
||||
double distance = Math.sqrt(Math.pow(x - mouseX, 2) + Math.pow(y - mouseY, 2));
|
||||
return new net.minecraft.util.Pair<>(slot, distance);
|
||||
}).filter(entry -> entry.getRight() <= 14.0)
|
||||
.min(Comparator.comparingDouble(net.minecraft.util.Pair::getRight));
|
||||
|
||||
if (closestSlot.isPresent() && client.player != null) {
|
||||
var slot = closestSlot.get().getLeft();
|
||||
if (slot.hasStack() || !client.player.getInventory().getMainHandStack().isEmpty()) {
|
||||
int slotCenterXScaled = guiLeft + slot.x + 8;
|
||||
int slotCenterYScaled = guiTop + slot.y + 8;
|
||||
int slotCenterX = (int) (slotCenterXScaled / ((double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth()));
|
||||
int slotCenterY = (int) (slotCenterYScaled / ((double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight()));
|
||||
double deltaX = slotCenterX - targetMouseX;
|
||||
double deltaY = slotCenterY - targetMouseY;
|
||||
|
||||
if (mouseX != slotCenterXScaled || mouseY != slotCenterYScaled) {
|
||||
targetMouseX += (int) (deltaX * 0.75);
|
||||
targetMouseY += (int) (deltaY * 0.75);
|
||||
} else {
|
||||
input.mouseSpeedX *= 0.3F;
|
||||
input.mouseSpeedY *= 0.3F;
|
||||
}
|
||||
input.mouseSpeedX *= .75F;
|
||||
input.mouseSpeedY *= .75F;
|
||||
} else {
|
||||
input.mouseSpeedX *= .1F;
|
||||
input.mouseSpeedY *= .1F;
|
||||
}
|
||||
} else {
|
||||
input.mouseSpeedX *= .3F;
|
||||
input.mouseSpeedY *= .3F;
|
||||
}
|
||||
} else {
|
||||
input.mouseSpeedX = 0.F;
|
||||
input.mouseSpeedY = 0.F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ package eu.midnightdust.midnightcontrols.client.util.storage;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.enums.ButtonState;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import static eu.midnightdust.midnightcontrols.client.MidnightInput.BUTTON_COOLDOWNS;
|
||||
import static eu.midnightdust.midnightcontrols.client.controller.InputManager.STATES;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_X;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y;
|
||||
@@ -14,12 +17,17 @@ public class AxisStorage {
|
||||
public float value, absValue;
|
||||
public double deadZone;
|
||||
public Polarity polarity;
|
||||
public boolean isTrigger;
|
||||
|
||||
// Only used for camera handling
|
||||
public AxisStorage(int axis, float value, int state) {
|
||||
this.axis = axis;
|
||||
this.value = value;
|
||||
this.state = state;
|
||||
this.deadZone = isLeftAxis() ? MidnightControlsConfig.leftDeadZone : MidnightControlsConfig.rightDeadZone;
|
||||
boolean currentPlusState = value > deadZone;
|
||||
boolean currentMinusState = value < -deadZone;
|
||||
this.polarity = currentPlusState ? AxisStorage.Polarity.PLUS : currentMinusState ? AxisStorage.Polarity.MINUS : AxisStorage.Polarity.ZERO;
|
||||
}
|
||||
|
||||
public AxisStorage(int axis, float value, float absValue, int state) {
|
||||
@@ -27,14 +35,14 @@ public class AxisStorage {
|
||||
this.value = value;
|
||||
this.absValue = absValue;
|
||||
this.state = state;
|
||||
deadZone = getDeadZoneValue(axis);
|
||||
asButtonState = value > .5f ? 1 : (value < -.5f ? 2 : 0);
|
||||
this.deadZone = isLeftAxis() ? MidnightControlsConfig.leftDeadZone : MidnightControlsConfig.rightDeadZone;
|
||||
this.asButtonState = value > .5f ? 1 : (value < -.5f ? 2 : 0);
|
||||
|
||||
if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
|
||||
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER)
|
||||
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
||||
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) || axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
||||
this.isTrigger = true;
|
||||
if (asButtonState == 2) {
|
||||
asButtonState = 0;
|
||||
this.asButtonState = 0;
|
||||
}
|
||||
else {
|
||||
// Fixes Triggers not working correctly on some controllers
|
||||
@@ -44,14 +52,60 @@ public class AxisStorage {
|
||||
this.state = 1;
|
||||
this.asButtonState = 1;
|
||||
}
|
||||
//if (MidnightControlsConfig.debug) System.out.println(axis + " "+ value + " " + absValue + " " + state);
|
||||
}
|
||||
}
|
||||
boolean currentPlusState = value > deadZone;
|
||||
boolean currentMinusState = value < -deadZone;
|
||||
if (isTrigger) currentMinusState = false;
|
||||
else if (!MidnightControlsConfig.analogMovement && isLeftAxis()) {
|
||||
currentPlusState = asButtonState == 1;
|
||||
currentMinusState = asButtonState == 2;
|
||||
}
|
||||
this.polarity = currentPlusState ? AxisStorage.Polarity.PLUS : currentMinusState ? AxisStorage.Polarity.MINUS : AxisStorage.Polarity.ZERO;
|
||||
}
|
||||
|
||||
public void setupButtonStates() {
|
||||
var posButton = ButtonBinding.axisAsButton(axis, true);
|
||||
var negButton = ButtonBinding.axisAsButton(axis, false);
|
||||
var previousPlusState = STATES.getOrDefault(posButton, ButtonState.NONE);
|
||||
var previousMinusState = STATES.getOrDefault(negButton, ButtonState.NONE);
|
||||
|
||||
if (polarity.isPositive() != previousPlusState.isPressed()) {
|
||||
STATES.put(posButton, polarity.isPositive() ? ButtonState.PRESS : ButtonState.RELEASE);
|
||||
if (polarity.isPositive())
|
||||
BUTTON_COOLDOWNS.put(posButton, 5);
|
||||
} else if (polarity.isPositive()) {
|
||||
STATES.put(posButton, ButtonState.REPEAT);
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(posButton, 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(posButton, 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (polarity.isNegative() != previousMinusState.isPressed()) {
|
||||
STATES.put(negButton, polarity.isNegative() ? ButtonState.PRESS : ButtonState.RELEASE);
|
||||
if (polarity.isNegative())
|
||||
BUTTON_COOLDOWNS.put(negButton, 5);
|
||||
} else if (polarity.isNegative()) {
|
||||
STATES.put(negButton, ButtonState.REPEAT);
|
||||
if (BUTTON_COOLDOWNS.getOrDefault(negButton, 0) == 0) {
|
||||
BUTTON_COOLDOWNS.put(negButton, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static double getDeadZoneValue(int axis) {
|
||||
return (axis == GLFW_GAMEPAD_AXIS_LEFT_X || axis == GLFW_GAMEPAD_AXIS_LEFT_Y) ? MidnightControlsConfig.leftDeadZone : MidnightControlsConfig.rightDeadZone;
|
||||
public boolean isLeftAxis() {
|
||||
return axis == GLFW_GAMEPAD_AXIS_LEFT_X || axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER;
|
||||
}
|
||||
public boolean isRightAxis() {
|
||||
return !isLeftAxis();
|
||||
}
|
||||
|
||||
public enum Polarity {
|
||||
MINUS, ZERO, PLUS;
|
||||
public boolean isPositive() {
|
||||
return this == PLUS;
|
||||
}
|
||||
public boolean isNegative() {
|
||||
return this == MINUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package eu.midnightdust.midnightcontrols.client.util.storage;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP;
|
||||
|
||||
public class ButtonStorage {
|
||||
public final int button, action;
|
||||
public final boolean state;
|
||||
|
||||
public ButtonStorage(int button, int action, boolean state) {
|
||||
this.button = button;
|
||||
this.action = action;
|
||||
this.state = state;
|
||||
}
|
||||
public boolean isDpad() {
|
||||
return button >= GLFW_GAMEPAD_BUTTON_DPAD_UP && button <= GLFW_GAMEPAD_BUTTON_DPAD_LEFT;
|
||||
}
|
||||
}
|
||||
@@ -184,6 +184,7 @@
|
||||
"midnightcontrols.menu.mouse_speed.tooltip": "The controller's emulated mouse speed.",
|
||||
"midnightcontrols.menu.move_chat": "Move chat input box to top",
|
||||
"midnightcontrols.menu.move_chat.tooltip": "Moves the chat input field to the top, for better input on devices with on-screen keyboards.",
|
||||
"midnightcontrols.menu.multiple_mapping_tip": "(Tip: You can also insert multiple mappings at the same time)",
|
||||
"midnightcontrols.menu.reacharound.horizontal": "Front Block Placing",
|
||||
"midnightcontrols.menu.reacharound.horizontal.tooltip": "Enables front block placing, §cmight be considered cheating on some servers§r.",
|
||||
"midnightcontrols.menu.reacharound.vertical": "Vertical Reacharound",
|
||||
|
||||
Reference in New Issue
Block a user