Compare commits

...

8 Commits

Author SHA1 Message Date
Motschen
df7c7bbdad MidnightControls 1.3.0 - Fixes and Improvements
- Merge #48 (Split rotation speed in X and Y, thanks to @ronniedude)
- Merge #47 (Korean translations by @gyular)
- Fix #50 (Stack pick-up problems in survival mode)
- Add some compatibility measures for EMI (Will likely be improved further in the future)
- Remove all REI-related code (not working anyway, EMI is better)
- Possibly fix #41 (Random crashes when changing keybinds)
2022-06-30 21:29:59 +02:00
Martin Prokoph
3ddae57eab Merge pull request #47 from gyular/ko_kr
Added Korean Translation
2022-06-30 19:20:55 +00:00
Martin Prokoph
a0701f55f6 Merge pull request #48 from ronniedude/1.19
Split rotationspeed option to allow for separate horizontal and vertical speeds (controller)
2022-06-30 15:03:02 +00:00
ronniedude
b15766dfdb Split rotationspeed option to allow for separate horizontal and vertical speed configurations (controller) 2022-06-29 16:55:15 -04:00
gyular
19ed068da9 Added Korean Translation 2022-06-28 01:53:56 +09:00
Motschen
d2e21f8723 MidnightControls 1.2.2 - Important Bugfix
Fix #45
Fix #44
2022-06-27 14:10:03 +02:00
Motschen
b3f7350de9 MidnightControls 1.2.1 - Fix log spam 2022-06-25 22:21:51 +02:00
Motschen
34408d7a2a MidnightControls 1.2.0 - Touchscreen, Modded Keybinds, Bugfixes
- Added #40 (Modded keybind support)
- Added #20 (Touchscreen support)
- Improved #13 (Sodium screen controller support)
- Attempt to fix #31 & #38 (Jittery input on low FPS)
- Fixed #35 (Front placing being broken)
- Fixed #32 (Option to disable double tap to sprint)
- Fixed #27 (Auto-adapt controller icons)
- Fixed #19 (HUD-scaling on big scales)
- Fixed #36 (Crash on game load)
- Fixed reset option
- Fixed scrolling in trading screens
- Disable features that might be considered as cheats (install MidnightControlsExtra to enable)
2022-06-25 21:23:25 +02:00
50 changed files with 917 additions and 1007 deletions

View File

@@ -32,16 +32,16 @@ This mod also adds controller support.
- Front block placing (be careful with this one)
- New controls settings!
- Many options in config to change to your liking.
- Many controllers supported and in a simply way your own controller mappings.
- Many controllers supported and in a simple way your own controller mappings.
- An easy API for developers to add their own button bindings.
## 🎮 Supported Controllers:
- Dualshock controllers
- Dualsense controllers
- DualShock controllers
- DualSense controllers
- Xbox controllers
- Switch Pro controllers
- Joycons
- Joy-Cons
- Steam controller and Steam Deck (WIP)
- And many more!

View File

@@ -110,7 +110,7 @@ dependencies {
// modImplementation "io.github.ennuil:LibZoomer:${project.libzoomer_version}"
modImplementation "org.quiltmc:quilt-json5:1.0.0"
//modImplementation "maven.modrinth:sodium:${project.sodium_version}"
modApi "maven.modrinth:sodium:${project.sodium_version}"
//modImplementation("maven.modrinth:emi:${project.emi_version}")
modImplementation "maven.modrinth:emotecraft:${project.emotecraft_version}"
modImplementation "io.github.kosmx:bendy-lib:${project.bendylib_version}"

View File

@@ -8,7 +8,7 @@ yarn_mappings=1.19+build.1
loader_version=0.14.7
# Mod Properties
mod_version = 1.1.0
mod_version = 1.3.0
maven_group = eu.midnightdust
archives_base_name = midnightcontrols
modrinth_id=bXX9h73M
@@ -16,7 +16,7 @@ modrinth_id=bXX9h73M
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.55.2+1.19
sodium_version=mc1.19-0.4.1
sodium_version=mc1.19-0.4.2
spruceui_version=4.0.0+1.19
midnightlib_version=0.5.2
modmenu_version=4.0.0

View File

@@ -24,7 +24,8 @@ import java.util.Optional;
*/
public enum ControlsMode implements Nameable {
DEFAULT,
CONTROLLER;
CONTROLLER,
TOUCHSCREEN;
/**
* Returns the next controls mode available.

View File

@@ -37,14 +37,14 @@ public class MidnightControls implements ModInitializer {
public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString());
public static final Identifier FEATURE_CHANNEL = new Identifier(MidnightControlsConstants.FEATURE_CHANNEL.toString());
public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString());
public static final Text NOT_BOUND_TEXT = Text.translatable("midnightcontrols.not_bound");
public static boolean isExtrasLoaded;
public final Logger logger = LogManager.getLogger("MidnightControls");
@Override
public void onInitialize() {
INSTANCE = this;
isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra");
this.log("Initializing MidnightControls...");
ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> {

View File

@@ -61,7 +61,7 @@ public class MidnightControlsFeature implements Nameable {
* @return {@code true} if this feature is allowed, else {@code false}
*/
public boolean isAllowed() {
return this.allowed;
return MidnightControls.isExtrasLoaded && this.allowed;
}
/**

View File

@@ -16,10 +16,13 @@ import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.MidnightControlsFeature;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory;
import eu.midnightdust.midnightcontrols.client.controller.Controller;
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsHud;
import eu.midnightdust.midnightcontrols.client.gui.RingScreen;
import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay;
import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingRegistryImplAccessor;
import eu.midnightdust.midnightcontrols.client.ring.KeyBindingRingAction;
import eu.midnightdust.midnightcontrols.client.ring.MidnightRing;
import dev.lambdaurora.spruceui.hud.HudManager;
@@ -51,6 +54,7 @@ import java.io.File;
* @since 1.1.0
*/
public class MidnightControlsClient extends MidnightControls implements ClientModInitializer {
public static boolean lateInitDone = false;
private static MidnightControlsClient INSTANCE;
public static final KeyBinding BINDING_LOOK_UP = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_up"),
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_8, "key.categories.movement");
@@ -60,8 +64,8 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement");
public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "look_left"),
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement");
/*public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(midnightcontrolsConstants.NAMESPACE, "ring"),
InputUtil.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_5, "key.categories.misc");*/
public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(MidnightControlsConstants.NAMESPACE, "ring"),
InputUtil.Type.KEYSYM, InputUtil.UNKNOWN_KEY.getCode(), "key.categories.misc");
public static final Identifier CONTROLLER_BUTTONS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_buttons.png");
public static final Identifier CONTROLLER_EXPANDED = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_expanded.png");
public static final Identifier CONTROLLER_AXIS = new Identifier(MidnightControlsConstants.NAMESPACE, "textures/gui/controller_axis.png");
@@ -83,10 +87,10 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
//KeyBindingHelper.registerKeyBinding(BINDING_RING);
this.ring.registerAction("keybinding", KeyBindingRingAction.FACTORY);
this.ring.load();
ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) -> {
responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode));
});
ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) ->
responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)));
ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> {
int features = buf.readVarInt();
for (int i = 0; i < features; i++) {
@@ -102,23 +106,22 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave);
ClientTickEvents.START_CLIENT_TICK.register(this.reacharound::tick);
ClientTickEvents.END_CLIENT_TICK.register(this::onTick);
ClientTickEvents.START_CLIENT_TICK.register(this::onTick);
OpenScreenCallback.EVENT.register((client, screen) -> {
// if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) {
// screen = new TouchscreenOverlay(this);
// screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
// client.skipGameRender = false;
// client.currentScreen = screen;
// } else if (screen != null) {
if (screen == null && MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) {
screen = new TouchscreenOverlay(this);
screen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
client.skipGameRender = false;
client.currentScreen = screen;
} else if (screen != null) {
this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight());
//}
}
});
HudManager.register(this.hud = new MidnightControlsHud(this));
FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> {
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL);
});
FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer ->
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL));
}
/**
@@ -144,6 +147,35 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
MidnightControlsCompat.init(this);
}
ButtonCategory category;
/**
* This method is called to initialize keybindings
*/
public void initKeybindings() {
if (lateInitDone) return;
if (KeyBindingRegistryImplAccessor.getModdedKeyBindings() == null || KeyBindingRegistryImplAccessor.getModdedKeyBindings().isEmpty()) return;
for (int i = 0; i < KeyBindingRegistryImplAccessor.getModdedKeyBindings().size(); ++i) {
KeyBinding keyBinding = KeyBindingRegistryImplAccessor.getModdedKeyBindings().get(i);
if (!keyBinding.getTranslationKey().contains("midnightcontrols") && !keyBinding.getTranslationKey().contains("ok_zoomer") && !keyBinding.getTranslationKey().contains("okzoomer")) {
category = null;
InputManager.streamCategories().forEach(buttonCategory -> {
if (buttonCategory.getIdentifier().equals(new org.aperlambda.lambdacommon.Identifier("minecraft", keyBinding.getCategory())))
category = buttonCategory;
});
if (category == null) {
category = new ButtonCategory(new org.aperlambda.lambdacommon.Identifier("minecraft", keyBinding.getCategory()));
InputManager.registerCategory(category);
}
ButtonBinding buttonBinding = new ButtonBinding.Builder(keyBinding.getTranslationKey()).category(category).linkKeybind(keyBinding).register();
if (MidnightControlsConfig.debug) {
logger.info(keyBinding.getTranslationKey());
logger.info(buttonBinding);
}
}
}
InputManager.loadButtonBindings();
lateInitDone = true;
}
/**
* This method is called every Minecraft tick.
@@ -151,15 +183,15 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
* @param client the client instance
*/
public void onTick(@NotNull MinecraftClient client) {
this.initKeybindings();
this.input.tick(client);
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput))
this.input.tickController(client);
/*if (BINDING_RING.wasPressed()) {
client.openScreen(new RingScreen());
}*/
// if (BINDING_RING.wasPressed()) {
// client.setScreen(new RingScreen());
// }
}
public void onRender(MinecraftClient client) {
this.input.onRender(client.getTickDelta(), client);
}

View File

@@ -9,6 +9,7 @@
package eu.midnightdust.midnightcontrols.client;
import com.google.common.collect.Lists;
import eu.midnightdust.lib.config.MidnightConfig;
import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.MidnightControlsFeature;
@@ -30,40 +31,40 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y;
*/
public class MidnightControlsConfig extends MidnightConfig {
// General
@Entry public static ControlsMode controlsMode = ControlsMode.DEFAULT;
@Entry public static boolean autoSwitchMode = true;
@Entry public static boolean debug = false;
@Entry(name = "midnightcontrols.menu.controls_mode") public static ControlsMode controlsMode = ControlsMode.DEFAULT;
@Entry(name = "midnightcontrols.menu.auto_switch_mode") public static boolean autoSwitchMode = true;
@Entry(name = "Debug") public static boolean debug = false;
// HUD
@Entry public static boolean hudEnable = true;
@Entry public static HudSide hudSide = HudSide.LEFT;
@Entry(name = "midnightcontrols.menu.hud_enable") public static boolean hudEnable = true;
@Entry(name = "midnightcontrols.menu.hud_side") public static HudSide hudSide = HudSide.LEFT;
// Gameplay
@Entry public static boolean analogMovement = true;
@Entry public static boolean fastBlockPlacing = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry public static boolean flyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers. It can also conflict with some other mods.
@Entry public static boolean verticalFlyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers.
@Entry public static boolean horizontalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry public static boolean verticalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry public static boolean shouldRenderReacharoundOutline = true;
@Entry public static int[] reacharoundOutlineColor = new int[]{255, 255, 255, 102};
// Controller
@Entry public static ControllerType controllerType = ControllerType.DEFAULT;
@Entry public static double rightDeadZone = 0.25;
@Entry public static double leftDeadZone = 0.25;
@Entry public static boolean invertRightYAxis = false;
@Entry public static boolean invertRightXAxis = false;
@Entry public static double DEFAULT_MAX_VALUE = 1;
@Entry public static double rotationSpeed = 40.0;
@Entry public static double mouseSpeed = 25.0;
@Entry public static boolean unfocusedInput = false;
@Entry public static boolean virtualMouse = false;
@Entry public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT;
@Entry public static Object controllerID = 0;
@Entry public static Object secondControllerID = -1;
@Entry public static List<String> mouseScreens = List.of("me.jellysquid.mods.sodium.client.gui","net.coderbot.iris.gui","net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui");
@Entry public static Map<String, String> BINDINGS = Map.of();
@Entry(name = "midnightcontrols.menu.analog_movement") public static boolean analogMovement = true;
@Entry(name = "midnightcontrols.menu.double_tap_to_sprint") public static boolean doubleTapToSprint = true;
@Entry(name = "midnightcontrols.menu.fast_block_placing") public static boolean fastBlockPlacing = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry(name = "midnightcontrols.menu.fly_drifting") public static boolean flyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers. It can also conflict with some other mods.
@Entry(name = "midnightcontrols.menu.fly_drifting_vertical") public static boolean verticalFlyDrifting = true; // Enabled by default as disabling this behaviour can be considered cheating on multiplayer servers.
@Entry(name = "midnightcontrols.menu.reacharound.horizontal") public static boolean horizontalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry(name = "midnightcontrols.menu.reacharound.vertical") public static boolean verticalReacharound = false; // Disabled by default as this behaviour can be considered cheating on multiplayer servers.
@Entry(name = "Reacharound Outline") public static boolean shouldRenderReacharoundOutline = true;
@Entry(name = "Reacharound Outline Color") public static int[] reacharoundOutlineColor = new int[]{255, 255, 255, 102};
@Entry(name = "midnightcontrols.menu.right_dead_zone") public static double rightDeadZone = 0.25;
@Entry(name = "midnightcontrols.menu.left_dead_zone") public static double leftDeadZone = 0.25;
@Entry(name = "midnightcontrols.menu.invert_right_y_axis") public static boolean invertRightYAxis = false;
@Entry(name = "midnightcontrols.menu.invert_right_x_axis") public static boolean invertRightXAxis = false;
@Entry(name = "midnightcontrols.menu.rotation_speed") public static double rotationSpeed = 40.0; //used for x axis, name kept for compatability
@Entry(name = "midnightcontrols.menu.y_axis_rotation_speed") public static double yAxisRotationSpeed = rotationSpeed;
@Entry(name = "midnightcontrols.menu.mouse_speed") public static double mouseSpeed = 25.0;
@Entry(name = "midnightcontrols.menu.unfocused_input") public static boolean unfocusedInput = false;
@Entry(name = "midnightcontrols.menu.virtual_mouse") public static boolean virtualMouse = false;
@Entry(name = "midnightcontrols.menu.virtual_mouse.skin") public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT;
@Entry(name = "Controller ID") public static Object controllerID = 0;
@Entry(name = "2nd Controller ID") public static Object secondControllerID = -1;
@Entry(name = "midnightcontrols.menu.controller_type") public static ControllerType controllerType = ControllerType.DEFAULT;
@Entry(name = "Mouse screens") public static List<String> mouseScreens = Lists.newArrayList("me.jellysquid.mods.sodium.client.gui", "net.coderbot.iris.gui", "net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui", "dev.emi.emi.screen");
@Entry(name = "Keybindings") public static Map<String, String> BINDINGS = new HashMap<>();
private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?");
@Entry public static double[] maxAnalogValues = new double[]{DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE, DEFAULT_MAX_VALUE};
@Entry(name = "Max analog values") public static double[] maxAnalogValues = new double[]{1, 1, 1, 1};
/**
* Loads the configuration
@@ -154,7 +155,7 @@ public class MidnightControlsConfig extends MidnightConfig {
public static double getAxisMaxValue(int axis) {
if (axis >= MidnightControlsConfig.maxAnalogValues.length)
return DEFAULT_MAX_VALUE;
return 1;
return MidnightControlsConfig.maxAnalogValues[axis];
}
@@ -251,4 +252,55 @@ public class MidnightControlsConfig extends MidnightConfig {
public static boolean isMovementAxis(int axis) {
return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X;
}
public static void reset() {
controlsMode = ControlsMode.DEFAULT;
autoSwitchMode = true;
debug = false;
hudEnable = true;
hudSide = HudSide.LEFT;
analogMovement = true;
doubleTapToSprint = true;
fastBlockPlacing = false;
flyDrifting = true;
verticalFlyDrifting = true;
horizontalReacharound = false;
verticalReacharound = false;
shouldRenderReacharoundOutline = true;
reacharoundOutlineColor = new int[]{255, 255, 255, 102};
rightDeadZone = 0.25;
leftDeadZone = 0.25;
invertRightYAxis = false;
invertRightXAxis = false;
rotationSpeed = 40.0;
yAxisRotationSpeed = rotationSpeed;
mouseSpeed = 25.0;
unfocusedInput = false;
virtualMouse = false;
virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT;
controllerID = 0;
secondControllerID = -1;
controllerType = ControllerType.DEFAULT;
mouseScreens = Lists.newArrayList("me.jellysquid.mods.sodium.client.gui", "net.coderbot.iris.gui", "net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui", "dev.emi.emi.screen");
BINDINGS = new HashMap<>();
maxAnalogValues = new double[]{1, 1, 1, 1};
}
/**
* Gets the controller type from the controller's identifier.
*
* @return the controller name matches a type, else empty
*/
public static @NotNull ControllerType matchControllerToType() {
String controller = getController().getName().toLowerCase();
if (controller.contains("xbox 360")) return ControllerType.XBOX_360;
else if (controller.contains("xbox") || controller.contains("afterglow")) return ControllerType.XBOX;
else if (controller.contains("steam deck")) return ControllerType.STEAM_DECK;
else if (controller.contains("steam")) return ControllerType.STEAM_CONTROLLER;
else if (controller.contains("dualsense")) return ControllerType.DUALSENSE;
else if (controller.contains("dualshock") || controller.contains("ps4")) return ControllerType.DUALSHOCK;
else if (controller.contains("switch") || controller.contains("joy-con")) return ControllerType.SWITCH;
else if (controller.contains("ouya")) return ControllerType.OUYA;
else return ControllerType.DEFAULT;
}
}

View File

@@ -10,7 +10,11 @@
package eu.midnightdust.midnightcontrols.client;
import com.google.common.collect.ImmutableSet;
import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.compat.SodiumCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.Controller;
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
@@ -28,6 +32,7 @@ import dev.lambdaurora.spruceui.widget.SpruceElement;
import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import net.fabricmc.fabric.impl.item.group.CreativeGuiExtensions;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement;
@@ -37,6 +42,7 @@ import net.minecraft.client.gui.screen.advancement.AdvancementTab;
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.MerchantScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.gui.screen.world.WorldListWidget;
@@ -261,7 +267,7 @@ public class MidnightInput {
}
}
private void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state) {
public void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state) {
if (this.controlsInput != null && this.controlsInput.focusedBinding != null) {
if (action == 0 && !this.controlsInput.currentButtons.contains(button)) {
this.controlsInput.currentButtons.add(button);
@@ -277,7 +283,7 @@ public class MidnightInput {
}
if (action == 0 || action == 2) {
if (client.currentScreen != null && isScreenInteractive(client.currentScreen)
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) {
@@ -304,11 +310,6 @@ public class MidnightInput {
}
}
if (this.handleInventory(client, button)) {
this.ignoreNextARelease = true;
return;
}
if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
if (client.currentScreen != null && client.currentScreen.getClass() != TitleScreen.class) {
if (!MidnightControlsCompat.handleMenuBack(client, client.currentScreen))
@@ -341,65 +342,6 @@ public class MidnightInput {
}
}
/**
* Handles inventory interaction.
*
* @param client the client instance
* @param button the button pressed
* @return {@code true} if an inventory interaction was done
*/
private boolean handleInventory(@NotNull MinecraftClient client, int button) {
// if (!(client.currentScreen instanceof HandledScreen screen))
// return false;
//
// if (client.interactionManager == null || client.player == null)
// return false;
//
// if (this.inventoryInteractionCooldown > 0)
// return true;
//
// if (button == GLFW.GLFW_GAMEPAD_BUTTON_B) {
// client.player.closeHandledScreen();
// return true;
// }
//
// double x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
// double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
//
// var accessor = (HandledScreenAccessor) screen;
// Slot slot = ((HandledScreenAccessor) client.currentScreen).midnightcontrols$getSlotAt(x, y);
//
// int slotId;
// if (slot == null) {
// if (client.player.currentScreenHandler.getCursorStack().isEmpty())
// return false;
// slotId = accessor.midnightcontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1;
// } else {
// slotId = slot.id;
// }
//
// var actionType = SlotActionType.PICKUP;
// int clickData = GLFW.GLFW_MOUSE_BUTTON_1;
// switch (button) {
// case GLFW_GAMEPAD_BUTTON_A:
// if (screen instanceof CreativeInventoryScreen)
// if (((CreativeInventoryScreenAccessor) screen).midnightcontrols$isCreativeInventorySlot(slot))
// actionType = SlotActionType.CLONE;
// if (slot != null && MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot)))
// actionType = SlotActionType.CLONE;
// break;
// case GLFW.GLFW_GAMEPAD_BUTTON_X:
// clickData = GLFW_MOUSE_BUTTON_2;
// break;
// case GLFW.GLFW_GAMEPAD_BUTTON_Y:
// actionType = SlotActionType.QUICK_MOVE;
// break;
// default:
// return false;
// }
//
// accessor.midnightcontrols$onMouseClick(slot, slotId, clickData, actionType);
return false;
}
/**
* Tries to go back.
@@ -502,6 +444,14 @@ public class MidnightInput {
}
return;
}
} else if (client.currentScreen instanceof MerchantScreen merchantScreen) {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
// @TODO allow rebinding to left stick
if (absValue >= deadZone) {
merchantScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f));
}
return;
}
} else if (client.currentScreen instanceof AdvancementsScreen advancementsScreen) {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X || axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
var accessor = (AdvancementsScreenAccessor) advancementsScreen;
@@ -520,6 +470,14 @@ public class MidnightInput {
element.mouseScrolled(0.0, 0.0, -value);
return true;
});
client.currentScreen.children().stream().filter(element -> element instanceof SpruceEntryListWidget)
.map(element -> (SpruceEntryListWidget<?>) element)
.filter(element -> element.getType().isFocused())
.anyMatch(element -> {
MidnightControls.get().log(String.valueOf(value));
element.mouseScrolled(0.0, 0.0, -value);
return true;
});
return;
}
}
@@ -591,7 +549,7 @@ public class MidnightInput {
}
}
private boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) {
public boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) {
if (focused instanceof PressableWidget widget) {
widget.playDownSound(MinecraftClient.getInstance().getSoundManager());
widget.onPress();
@@ -679,9 +637,9 @@ public class MidnightInput {
double powValue = Math.pow(value, 2.0);
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
if (state == 2) {
this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powValue) * 0.11D;
} else if (state == 1) {
this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powValue) * 0.11D;
}
}
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
@@ -701,6 +659,7 @@ public class MidnightInput {
}
return false;
}
if (FabricLoader.getInstance().isModLoaded("sodium")) SodiumCompat.handleInput(screen, direction.isLookingForward());
if (!screen.changeFocus(direction.isLookingForward())) {
if (screen.changeFocus(direction.isLookingForward())) {
this.actionGuiCooldown = 5;

View File

@@ -144,7 +144,7 @@ public class MidnightReacharound {
return null;
}
return new BlockHitResult(client.crosshairTarget.getPos(), direction, blockPos, false);
return new BlockHitResult(new Vec3d(blockPos.getX(),blockPos.getY(),blockPos.getZ()), direction, blockPos, false);
}
return null;
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import io.github.kosmx.emotes.arch.gui.screen.ingame.FastChosseScreen;
import io.github.kosmx.emotes.main.network.ClientEmotePlay;
import org.jetbrains.annotations.NotNull;
/**
* Represents a compatibility handler for Emotecraft.
*
* @author Motschen
* @version 1.4.3
* @since 1.0.0
*/
public class EmotecraftCompat implements CompatHandler {
@Override
public void handle(@NotNull MidnightControlsClient mod) {
new ButtonBinding.Builder("key.emotecraft.fastchoose")
.buttons(16)
.onlyInGame()
.cooldown(true)
.category(ButtonBinding.MISC_CATEGORY)
.action((client, button, value, action) -> {
client.setScreen(new FastChosseScreen(null));
return true;
})
.register();
new ButtonBinding.Builder("key.emotecraft.stop")
.buttons(17)
.onlyInGame()
.cooldown(true)
.category(ButtonBinding.MISC_CATEGORY)
.action((client, button, value, action) -> {
ClientEmotePlay.clientStopLocalEmote();
return true;
})
.register();
}
}

View File

@@ -53,10 +53,6 @@ public class MidnightControlsCompat {
mod.log("Adding HQM compatibility...");
HANDLERS.add(new HQMCompat());
}
if (FabricLoader.getInstance().isModLoaded("emotecraft")) {
mod.log("Adding Emotecraft compatibility...");
HANDLERS.add(new EmotecraftCompat());
}
HANDLERS.forEach(handler -> handler.handle(mod));
InputManager.loadButtonBindings();
}
@@ -163,4 +159,12 @@ public class MidnightControlsCompat {
public static boolean isReiPresent() {
return FabricLoader.getInstance().isModLoaded("roughlyenoughitems");
}
/**
* Returns whether EMI is present.
*
* @return true if EMI is present, else false
*/
public static boolean isEMIPresent() {
return FabricLoader.getInstance().isModLoaded("emi");
}
}

View File

@@ -9,6 +9,7 @@
package eu.midnightdust.midnightcontrols.client.compat;
import net.fabricmc.loader.api.FabricLoader;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
@@ -29,10 +30,7 @@ public class MidnightControlsMixinPlugin implements IMixinConfigPlugin {
private final HashMap<String, Boolean> conditionalMixins = new HashMap<>();
public MidnightControlsMixinPlugin() {
this.putConditionalMixin("EntryListWidgetAccessor", MidnightControlsCompat.isReiPresent());
this.putConditionalMixin("EntryWidgetAccessor", MidnightControlsCompat.isReiPresent());
this.putConditionalMixin("RecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent());
this.putConditionalMixin("VillagerRecipeViewingScreenAccessor", MidnightControlsCompat.isReiPresent());
this.putConditionalMixin("SodiumOptionsGUIAccessor", FabricLoader.getInstance().isModLoaded("sodium"));
}
private void putConditionalMixin(@NotNull String path, boolean condition) {

View File

@@ -1,355 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.compat.mixin.EntryListWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.compat.mixin.EntryWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.controller.InputHandlers;
import eu.midnightdust.midnightcontrols.client.controller.PressAction;
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.EntryListWidget;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Optional;
import static eu.midnightdust.midnightcontrols.client.compat.CompatHandler.SlotPos.INVALID_SLOT;
import static org.lwjgl.glfw.GLFW.*;
/**
* Represents a compatibility handler for REI.
*
* @author LambdAurora
* @version 1.7.0
* @since 1.2.0
*/
public class ReiCompat implements CompatHandler {
private static EntryListWidget ENTRY_LIST_WIDGET;
@Override
public void handle(@NotNull MidnightControlsClient mod) {
/*ButtonBinding.builder(new Identifier("rei", "category_back"))
.buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleTab(false))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "category_next"))
.buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleTab(true))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "page_back"))
.buttons(ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_X, false))
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handlePage(false))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "page_next"))
.buttons(ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_X, true))
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handlePage(true))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "recipe_back"))
.buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleRecipe(false))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "recipe_next"))
.buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleRecipe(true))
.cooldown(true)
.register();
// For some reasons this is broken.
ButtonBinding.builder(new Identifier("rei", "show_usage"))
.buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handleShowRecipeUsage(true))
.cooldown(true)
.register();
ButtonBinding.builder(new Identifier("rei", "show_recipe"))
.buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB)
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action(handleShowRecipeUsage(false))
.cooldown(true)
.register();
*/
}
/*
@Override
public boolean requireMouseOnScreen(Screen screen) {
return isViewingScreen(screen);
}
@Override
public @Nullable CompatHandler.SlotPos getSlotAt(@NotNull Screen screen, int mouseX, int mouseY) {
ScreenOverlayImpl overlay = ScreenOverlayImpl.getInstance();
if (overlay.isInside(mouseX, mouseY)) {
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return null;
return this.getSlotAt(widget, mouseX, mouseY, false);
} else if (isViewingScreen(screen)) {
for (Element element : screen.children()) {
var slot = this.getSlotAt(element, mouseX, mouseY, true);
if (slot != null)
return slot;
}
}
return null;
}
private @Nullable CompatHandler.SlotPos getSlotAt(@NotNull Element element, int mouseX, int mouseY, boolean allowEmpty) {
if (element instanceof EntryWidget) {
EntryWidget entry = (EntryWidget) element;
if (entry.containsMouse(mouseX, mouseY)) {
if (!allowEmpty && entry.getEntries().isEmpty())
return INVALID_SLOT;
return new SlotPos(entry.getBounds().getX() + 1, entry.getBounds().getY() + 1);
}
} else if (element instanceof EntryListWidget) {
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries();
for (EntryListEntryWidget entry : entries) {
var slot = this.getSlotAt(entry, mouseX, mouseY, allowEmpty);
if (slot != null && slot != INVALID_SLOT)
return slot;
}
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds widgetWithBounds) {
for (var child : widgetWithBounds.children()) {
var slot = this.getSlotAt(child, mouseX, mouseY, allowEmpty);
if (slot != null && slot != INVALID_SLOT)
return slot;
}
}
return null;
}
private static boolean isViewingScreen(Screen screen) {
return screen instanceof DefaultDisplayViewingScreen || screen instanceof CompositeDisplayViewingScreen;
}
@Override
public boolean handleMenuBack(@NotNull MinecraftClient client, @NotNull Screen screen) {
if (!isViewingScreen(screen))
return false;
MinecraftClient.getInstance().setScreen(REIRuntimeImpl.getInstance().getPreviousContainerScreen());
REIRuntimeImpl.getInstance().getLastOverlay().init();
return true;
}
private static EntryListWidget getEntryListWidget() {
if (ENTRY_LIST_WIDGET == null) {
ENTRY_LIST_WIDGET = LambdaReflection.getFirstFieldOfType(ContainerScreenOverlay.class, EntryListWidget.class)
.map(field -> (EntryListWidget) LambdaReflection.getFieldValue(null, field))
.orElse(null);
}
return ENTRY_LIST_WIDGET;
}
private static @Nullable AbstractEntryStack getCurrentStack(@NotNull MinecraftClient client) {
double x = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
double y = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
if (isViewingScreen(client.currentScreen)) {
for (Element element : client.currentScreen.children()) {
EntryStack stack = getCurrentStack(element, x, y);
if (stack != null)
return stack;
}
}
Optional<ContainerScreenOverlay> overlay = REIRuntimeImpl.getInstance().getOverlay(false,false);
if (!overlay.isPresent())
return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return ScreenOverlayImpl.getInstance().getInstance().getOverlayMenu()..getScreenFocusedStack(client.currentScreen);
return getCurrentStack(widget, x, y);
}
private static @Nullable EntryStack getCurrentStack(@NotNull Element element, double mouseX, double mouseY) {
if (element instanceof EntryWidget) {
EntryWidget entry = (EntryWidget) element;
if (entry.containsMouse(mouseX, mouseY))
return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry();
} else if (element instanceof EntryListWidget) {
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries();
for (EntryListEntryWidget entry : entries) {
if (entry.containsMouse(mouseX, mouseY)) {
return ((EntryWidgetAccessor) entry).lambdacontrols_getCurrentEntry();
}
}
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds) {
for (Element child : ((WidgetWithBounds) element).children()) {
EntryStack stack = getCurrentStack(child, mouseX, mouseY);
if (stack != null)
return stack;
}
}
return null;
}
private static PressAction handleShowRecipeUsage(boolean usage) {
return (client, button, value, action) -> {
if (action.isUnpressed())
return false;
EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
if (stack == null) {
stack = getCurrentStack(client);
}
if (stack != null && !stack.isEmpty()) {
stack = stack.copy();
if (usage) {
return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addUsagesFor(stack).setInputNotice(stack).fillPreferredOpenedCategory());
} else {
return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory());
}
}
return false;
};
}
private static PressAction handlePage(boolean next) {
return (client, button, value, action) -> {
if (action == ButtonState.RELEASE)
return false;
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent())
return false;
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return false;
if (next)
widget.nextPage();
else
widget.previousPage();
widget.updateEntriesPosition();
return true;
};
}
/**
* Returns the handler for category tabs buttons.
*
* @param next True if the action is to switch to the next tab.
* @return The handler.
*/
/*
private static PressAction handleTab(boolean next) {
return (client, button, value, action) -> {
if (action != ButtonState.RELEASE)
return false;
if (client.currentScreen instanceof RecipeViewingScreen) {
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
if (next)
screen.getCategoryNext().onClick();
else
screen.getCategoryBack().onClick();
return true;
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) {
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex();
screen.setSelectedCategoryIndex(getNextIndex(currentTab, categories.size(), next));
screen.setSelectedRecipeIndex(0);
screen.lambdacontrols_init();
return true;
}
return false;
};
}
private static PressAction handleRecipe(boolean next) {
return (client, button, value, action) -> {
if (action.isUnpressed())
return false;
if (client.currentScreen instanceof RecipeViewingScreen) {
RecipeViewingScreenAccessor screen = (RecipeViewingScreenAccessor) client.currentScreen;
if (next)
screen.getRecipeNext().onClick();
else
screen.getRecipeBack().onClick();
return true;
} else if (client.currentScreen instanceof VillagerRecipeViewingScreen) {
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex();
List<RecipeDisplay> recipes = screen.getCategoryMap().get(categories.get(currentTab));
if (recipes.size() == 0)
return true;
int currentRecipe = screen.getSelectedRecipeIndex();
int nextRecipe = getNextIndex(currentRecipe, recipes.size(), next);
if (nextRecipe == 0) {
screen.getScrolling().scrollTo(0.0, true);
} else if (nextRecipe == recipes.size() - 1) {
screen.getScrolling().scrollTo(screen.getScrolling().getMaxScroll(), true);
} else {
double scrollAmount = screen.getScrolling().getMaxScroll() / (float) recipes.size();
screen.getScrolling().offset(next ? scrollAmount : -scrollAmount, true);
}
screen.setSelectedRecipeIndex(nextRecipe);
screen.lambdacontrols_init();
return true;
}
return false;
};
}
private static int getNextIndex(int currentIndex, int size, boolean next) {
int nextIndex = currentIndex + (next ? 1 : -1);
if (nextIndex < 0)
nextIndex = size - 1;
else if (nextIndex >= size)
nextIndex = 0;
return nextIndex;
}
*/
}

View File

@@ -0,0 +1,41 @@
package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.compat.mixin.SodiumOptionsGUIAccessor;
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
public class SodiumCompat {
private static final MinecraftClient client = MinecraftClient.getInstance();
public static void handleInput(Screen screen, boolean direction) {
if (screen instanceof SodiumOptionsGUI optionsGUI) {
SodiumOptionsGUIAccessor accessor = (SodiumOptionsGUIAccessor) optionsGUI;
final int max = accessor.getControls().size()-1;
var option = accessor.getControls().stream().filter(ControlElement::isHovered).findFirst().orElse(accessor.getControls().get(0));
int i = accessor.getControls().indexOf(option);
i = (direction ? ((max > i) ? ++i : 0) : (i > 0 ? --i : max));
var dimensions = accessor.getControls().get(i).getDimensions();
InputManager.INPUT_MANAGER.targetMouseX = (int) (client.getWindow().getScaleFactor() * dimensions.getCenterX());
InputManager.INPUT_MANAGER.targetMouseY = (int) (client.getWindow().getScaleFactor() * dimensions.getCenterY());
MidnightControlsClient.get().input.actionGuiCooldown = 5;
if (MidnightControlsConfig.debug) MidnightControls.get().log(i+" "+accessor.getControls().size()+" | " + dimensions.getCenterX() + " " + dimensions.getCenterY());
}
}
public static void handleTabs(Screen screen, boolean direction) {
if (screen instanceof SodiumOptionsGUI optionsGUI) {
SodiumOptionsGUIAccessor accessor = (SodiumOptionsGUIAccessor) optionsGUI;
final int max = accessor.getPages().size()-1;
int i = accessor.getPages().indexOf(accessor.getCurrentPage());
i = (direction ? ((max > i) ? ++i : 0) : (i > 0 ? --i : max));
if (MidnightControlsConfig.debug) MidnightControls.get().log(""+i);
optionsGUI.setPage(accessor.getPages().get(i));
}
}
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.widget.EntryListWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
/**
* Represents an accessor to REI's EntryListWidget.
*
* @author LambdAurora
* @version 1.5.0
* @since 1.5.0
*/
@Mixin(value = EntryListWidget.class, remap = false)
public interface EntryListWidgetAccessor {
@Accessor(value = "children")
List<Element> getEntries();
}

View File

@@ -1,23 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
/**
* Represents an accessor to REI's EntryWidget.
*
* @author LambdAurora
* @version 1.5.0
* @since 1.5.0
*/
//@Mixin(value = EntryWidget.class, remap = false)
public interface EntryWidgetAccessor {
/*@Invoker("getCurrentEntry")
EntryStack midnightcontrols_getCurrentEntry();*/
}

View File

@@ -1,32 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
/**
* Represents an accessor to REI's RecipeViewingScreen.
*
* @author LambdAurora
* @version 1.7.0
* @since 1.2.0
*/
//@Mixin(value = DefaultDisplayViewingScreen.class, remap = false)
public interface RecipeViewingScreenAccessor {
/*@Accessor("categoryBack")
Button getCategoryBack();
@Accessor("categoryNext")
Button getCategoryNext();
@Accessor("recipeBack")
Button getRecipeBack();
@Accessor("recipeNext")
Button getRecipeNext();*/
}

View File

@@ -0,0 +1,19 @@
package eu.midnightdust.midnightcontrols.client.compat.mixin;
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
import me.jellysquid.mods.sodium.client.gui.options.OptionPage;
import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(value = SodiumOptionsGUI.class, remap = false)
public interface SodiumOptionsGUIAccessor {
@Accessor
List<ControlElement<?>> getControls();
@Accessor
List<OptionPage> getPages();
@Accessor
OptionPage getCurrentPage();
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.compat.mixin;
/**
* Represents an accessor to REI's VillagerRecipeViewingScreen.
*
* @author LambdAurora
* @version 1.7.0
* @since 1.2.0
*/
//@Mixin(CompositeDisplayViewingScreen.class)
public interface VillagerRecipeViewingScreenAccessor {
/*@Accessor(value = "categoryMap", remap = false)
Map<DisplayCategory<?>, List<Display>> getCategoryMap();
@Accessor(value = "categories", remap = false)
List<DisplayCategory<?>> getCategories();
@Accessor(value = "selectedCategoryIndex", remap = false)
int getSelectedCategoryIndex();
@Accessor(value = "selectedCategoryIndex", remap = false)
void setSelectedCategoryIndex(int selectedCategoryIndex);
@Accessor(value = "selectedRecipeIndex", remap = false)
int getSelectedRecipeIndex();
@Accessor(value = "selectedRecipeIndex", remap = false)
void setSelectedRecipeIndex(int selectedRecipeIndex);
@Accessor(value = "scrolling", remap = false)
ScrollingContainer getScrolling();
@Invoker("init")
void midnightcontrols_init();*/
}

View File

@@ -13,6 +13,7 @@ import eu.midnightdust.midnightcontrols.client.ButtonState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.aperlambda.lambdacommon.utils.function.PairPredicate;
@@ -75,9 +76,9 @@ public class ButtonBinding {
public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).onlyInGame().register();
public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register();
public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register();
.action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null && client.currentScreen.getClass().toString().contains("sodium"))).cooldown().register();
public static final ButtonBinding TAB_RIGHT = new Builder("tab_next").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register();
.action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements).or((client, binding) -> client.currentScreen != null && client.currentScreen.getClass().toString().contains("sodium"))).cooldown().register();
public static final ButtonBinding PAGE_LEFT = new Builder("page_back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true))
.action(InputHandlers.handlePage(false)).filter(InputHandlers::inInventory).cooldown().register();
public static final ButtonBinding PAGE_RIGHT = new Builder("page_next").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true))
@@ -248,7 +249,7 @@ public class ButtonBinding {
* @return the translation key
*/
public @NotNull String getTranslationKey() {
return "midnightcontrols.action." + this.getName();
return I18n.hasTranslation("midnightcontrols.action." + this.getName()) ? "midnightcontrols.action." + this.getName() : this.getName();
}
public @NotNull Text getText() {
@@ -440,7 +441,7 @@ public class ButtonBinding {
}
public Builder(@NotNull Identifier identifier) {
this(identifier.getNamespace() + "." + identifier.getNamespace());
this(identifier.getNamespace() + "." + identifier.getPath());
}
/**

View File

@@ -13,6 +13,7 @@ import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.Text;
import org.aperlambda.lambdacommon.utils.Nameable;
@@ -136,7 +137,7 @@ public record Controller(int id) implements Nameable {
}
}
buffer.flip(); // Force Java 8 >.<
if (buffer != null) buffer.flip(); // Force Java 8 >.<
return buffer;
}
@@ -149,7 +150,6 @@ public record Controller(int id) implements Nameable {
File databaseFile = new File("config/gamecontrollerdatabase.txt");
try {
BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile));
byte[] dataBuffer = new byte[1024];
int bytesRead;
@@ -159,11 +159,11 @@ public record Controller(int id) implements Nameable {
out.close();
} catch (Exception ignored) {/* Just continue when internet connection is not available */}
var database = ioResourceToBuffer(databaseFile.getPath(), 1024);
GLFW.glfwUpdateGamepadMappings(database);
if (database != null) GLFW.glfwUpdateGamepadMappings(database);
if (!MidnightControlsClient.MAPPINGS_FILE.exists())
return;
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
GLFW.glfwUpdateGamepadMappings(buffer);
if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
} catch (IOException e) {
e.printStackTrace();
}
@@ -178,6 +178,7 @@ public record Controller(int id) implements Nameable {
if (client != null) {
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT,
Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string)));
MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string);
}
}
} catch (Throwable e) {

View File

@@ -13,11 +13,13 @@ import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightInput;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.compat.SodiumCompat;
import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor;
import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor;
import eu.midnightdust.midnightcontrols.client.mixin.RecipeBookWidgetAccessor;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import net.fabricmc.fabric.impl.item.group.CreativeGuiExtensions;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.Framebuffer;
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
@@ -26,6 +28,7 @@ import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.util.ScreenshotRecorder;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.Items;
import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType;
import org.aperlambda.lambdacommon.utils.Pair;
@@ -64,7 +67,7 @@ public class InputHandlers {
client.player.getInventory().selectedSlot = client.player.getInventory().selectedSlot == 0 ? 8 : client.player.getInventory().selectedSlot - 1;
return true;
} else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) {
int currentTab = inventory.getSelectedTab();
int currentTab = CreativeInventoryScreenAccessor.getSelectedTab();
int nextTab = currentTab + (next ? 1 : -1);
if (nextTab < 0)
nextTab = ItemGroup.GROUPS.length - 1;
@@ -105,7 +108,7 @@ public class InputHandlers {
}
}
return true;
}
} else if (FabricLoader.getInstance().isModLoaded("sodium")) SodiumCompat.handleTabs(client.currentScreen, next);
return false;
};
}
@@ -140,22 +143,29 @@ public class InputHandlers {
int slotId;
if (slot == null) {
if (client.player.currentScreenHandler.getCursorStack().isEmpty())
if (button.getName().equals("take_all")) {
return false;
}
slotId = accessor.midnightcontrols$isClickOutsideBounds(x, y, accessor.getX(), accessor.getY(), GLFW_MOUSE_BUTTON_1) ? -999 : -1;
} else {
slotId = slot.id;
}
var actionType = SlotActionType.PICKUP;
int clickData = GLFW.GLFW_MOUSE_BUTTON_1;
MidnightControlsClient.get().input.inventoryInteractionCooldown = 5;
switch (button.getName()) {
case "take_all":
if (accessor instanceof CreativeInventoryScreen)
if (accessor instanceof CreativeInventoryScreen) {
if (((CreativeInventoryScreenAccessor) accessor).midnightcontrols$isCreativeInventorySlot(slot))
actionType = SlotActionType.CLONE;
if (slot != null && MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot)))
actionType = SlotActionType.CLONE;
if (slot != null && MidnightControlsCompat.streamCompatHandlers().anyMatch(handler -> handler.isCreativeSlot(screen, slot)))
actionType = SlotActionType.CLONE;
} else {
if (slot != null && screen.getScreenHandler().getCursorStack() != null) {
return screen.mouseReleased(x, y, GLFW.GLFW_MOUSE_BUTTON_1);
} else actionType = SlotActionType.PICKUP_ALL;
}
break;
case "take":
clickData = GLFW_MOUSE_BUTTON_2;

View File

@@ -42,10 +42,10 @@ public class InputManager {
private static final List<ButtonCategory> CATEGORIES = new ArrayList<>();
public static final Int2ObjectMap<ButtonState> STATES = new Int2ObjectOpenHashMap<>();
public static final Int2FloatMap BUTTON_VALUES = new Int2FloatOpenHashMap();
private int prevTargetMouseX = 0;
private int prevTargetMouseY = 0;
private int targetMouseX = 0;
private int targetMouseY = 0;
public int prevTargetMouseX = 0;
public int prevTargetMouseY = 0;
public int targetMouseX = 0;
public int targetMouseY = 0;
protected InputManager() {
}

View File

@@ -53,6 +53,7 @@ public class MidnightControlsHud extends Hud {
private String attackAction = "";
private String placeAction = "";
private int ticksDisplayedCrosshair = 0;
private static float scale = 1f;
public MidnightControlsHud(@NotNull MidnightControlsClient mod) {
super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator"));
@@ -71,19 +72,26 @@ public class MidnightControlsHud extends Hud {
this.dropItemButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.DROP_ITEM);
this.attackButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.ATTACK);
this.useButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.USE);
if (client.getWindow().getScaleFactor() >= 4) {
scale = (float) (0.75f * (client.getWindow().getScaleFactor()-3));
} else scale = 1f;
}
/**
* Renders the midnightcontrols' HUD.
*/
@Override
public void render(MatrixStack matrices, float tickDelta) {
if (this.client == null) return;
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && this.client.currentScreen == null) {
int y = bottom(2);
this.renderFirstIcons(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y);
this.renderSecondIcons(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y);
this.renderFirstSection(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y);
this.renderSecondSection(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y);
if (scale != 1f) matrices.scale(scale,scale,scale);
this.renderFirstIcons(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y);
this.renderSecondIcons(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y);
this.renderFirstSection(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y);
this.renderSecondSection(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : (int) ((client.getWindow().getScaledWidth() - 2) * (1 / scale)), y);
if (scale != 1f) matrices.scale(1,1,1);
}
if (this.mod.reacharound.isLastReacharoundVertical()) {
@@ -246,7 +254,7 @@ public class MidnightControlsHud extends Hud {
}
private int bottom(int y) {
return this.client.getWindow().getScaledHeight() - y - MidnightControlsRenderer.ICON_SIZE;
return (int) ((this.client.getWindow().getScaledHeight() * (1/scale)) - y - MidnightControlsRenderer.ICON_SIZE);
}
private int width(@NotNull ButtonBinding binding) {

View File

@@ -10,6 +10,8 @@
package eu.midnightdust.midnightcontrols.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.ControllerType;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.MidnightInput;
@@ -106,7 +108,7 @@ public class MidnightControlsRenderer {
second = true;
}
int controllerType = MidnightControlsConfig.controllerType.getId();
int controllerType = MidnightControlsConfig.controllerType == ControllerType.DEFAULT ? MidnightControlsConfig.matchControllerToType().getId() : MidnightControlsConfig.controllerType.getId();
boolean axis = false;
int buttonOffset = button * 15;
switch (button) {

View File

@@ -55,11 +55,13 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
private final SpruceOption inputModeOption;
private final SpruceOption autoSwitchModeOption;
private final SpruceOption rotationSpeedOption;
private final SpruceOption yAxisRotationSpeedOption;
private final SpruceOption mouseSpeedOption;
private final SpruceOption virtualMouseOption;
private final SpruceOption resetOption;
// Gameplay options
private final SpruceOption analogMovementOption;
private final SpruceOption doubleTapToSprintOption;
private final SpruceOption autoJumpOption;
private final SpruceOption fastBlockPlacingOption;
private final SpruceOption frontBlockPlacingOption;
@@ -171,13 +173,17 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
() -> MidnightControlsConfig.rotationSpeed,
value -> MidnightControlsConfig.rotationSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.tooltip.rotation_speed"));
this.yAxisRotationSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.y_axis_rotation_speed", 0.0, 100.0, .5f,
() -> MidnightControlsConfig.yAxisRotationSpeed,
value -> MidnightControlsConfig.yAxisRotationSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.tooltip.y_axis_rotation_speed"));
this.mouseSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.mouse_speed", 0.0, 150.0, .5f,
() -> MidnightControlsConfig.mouseSpeed,
value -> MidnightControlsConfig.mouseSpeed = value, option -> option.getDisplayText(Text.literal(String.valueOf(option.get()))),
Text.translatable("midnightcontrols.tooltip.mouse_speed"));
this.resetOption = SpruceSimpleActionOption.reset(btn -> {
// TODO
MidnightControlsConfig.init("midnightcontrols", MidnightControlsConfig.class);
MidnightControlsConfig.reset();
var client = MinecraftClient.getInstance();
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
});
@@ -185,6 +191,9 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
this.analogMovementOption = new SpruceToggleBooleanOption("midnightcontrols.menu.analog_movement",
() -> MidnightControlsConfig.analogMovement, value -> MidnightControlsConfig.analogMovement = value,
Text.translatable("midnightcontrols.tooltip.analog_movement"));
this.doubleTapToSprintOption = new SpruceToggleBooleanOption("midnightcontrols.menu.double_tap_to_sprint",
() -> MidnightControlsConfig.doubleTapToSprint, value -> MidnightControlsConfig.doubleTapToSprint = value,
Text.translatable("midnightcontrols.tooltip.double_tap_to_sprint"));
this.autoJumpOption = new SpruceToggleBooleanOption("options.autoJump",
() -> this.client.options.getAutoJump().getValue(),
newValue -> this.client.options.getAutoJump().setValue(newValue),
@@ -292,9 +301,11 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
public SpruceOptionListWidget buildGeneralTab(int width, int height) {
var list = new SpruceOptionListWidget(Position.origin(), width, height);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.inputModeOption);
list.addSingleOptionEntry(this.autoSwitchModeOption);
list.addSingleOptionEntry(this.rotationSpeedOption);
list.addSingleOptionEntry(this.yAxisRotationSpeedOption);
list.addSingleOptionEntry(this.mouseSpeedOption);
list.addSingleOptionEntry(this.virtualMouseOption);
return list;
@@ -302,18 +313,21 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
public SpruceOptionListWidget buildGameplayTab(int width, int height) {
var list = new SpruceOptionListWidget(Position.origin(), width, height);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.analogMovementOption);
list.addSingleOptionEntry(this.fastBlockPlacingOption);
list.addSingleOptionEntry(this.frontBlockPlacingOption);
list.addSingleOptionEntry(this.verticalReacharoundOption);
list.addSingleOptionEntry(this.flyDriftingOption);
list.addSingleOptionEntry(this.flyVerticalDriftingOption);
list.addSingleOptionEntry(this.doubleTapToSprintOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.fastBlockPlacingOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.frontBlockPlacingOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.verticalReacharoundOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.flyDriftingOption);
if (MidnightControls.isExtrasLoaded) list.addSingleOptionEntry(this.flyVerticalDriftingOption);
list.addSingleOptionEntry(this.autoJumpOption);
return list;
}
public SpruceOptionListWidget buildVisualTab(int width, int height) {
var list = new SpruceOptionListWidget(Position.origin(), width, height);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.controllerTypeOption);
list.addSingleOptionEntry(this.virtualMouseSkinOption);
list.addSingleOptionEntry(new SpruceSeparatorOption("midnightcontrols.menu.title.hud", true, null));
@@ -352,6 +366,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
labels.addChild(aboutMappings3);
var list = new SpruceOptionListWidget(Position.origin(), width, listHeight);
list.setBackground(new MidnightControlsBackground(130));
list.addSingleOptionEntry(this.controllerOption);
list.addSingleOptionEntry(this.secondControllerOption);
list.addSingleOptionEntry(this.unfocusedInputOption);
@@ -377,6 +392,11 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
}
public static class MidnightControlsBackground implements Background {
private int transparency = 160;
public MidnightControlsBackground() {}
public MidnightControlsBackground(int transparency) {
this.transparency = transparency;
}
@Override
public void render(MatrixStack matrixStack, SpruceWidget widget, int vOffset, int mouseX, int mouseY, float delta) {
fill(matrixStack, widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight(), MidnightColorUtil.hex2Rgb("#000000"));
@@ -388,7 +408,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
float r = (float)(color.getRed()) / 255.0F;
float g = (float)(color.getGreen()) / 255.0F;
float b = (float)(color.getBlue()) / 255.0F;
float t = (float)(160) / 255.0F;
float t = (float)(transparency) / 255.0F;
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
RenderSystem.enableBlend();
RenderSystem.disableTexture();

View File

@@ -46,10 +46,10 @@ public class RingScreen extends Screen {
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
/*if (midnightcontrolsClient.BINDING_RING.matchesMouse(button)) {
this.onClose();
if (mod.ring.getCurrentPage().onClick(client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight(), (int) mouseX, (int) mouseY)) {
this.close();
return true;
}*/
}
return false;
}
}

View File

@@ -9,18 +9,18 @@
package eu.midnightdust.midnightcontrols.client.gui;
import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget;
import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import eu.midnightdust.midnightcontrols.client.HudSide;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.gui.widget.SilentTexturedButtonWidget;
import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.GameMenuScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.text.Text;
import net.minecraft.util.Arm;
@@ -37,265 +37,259 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
* Represents the touchscreen overlay
*/
public class TouchscreenOverlay extends Screen {
public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png");
private MidnightControlsClient mod;
private SpruceTexturedButtonWidget jumpButton;
private SpruceTexturedButtonWidget flyButton;
private SpruceTexturedButtonWidget flyUpButton;
private SpruceTexturedButtonWidget flyDownButton;
private int flyButtonEnableTicks = 0;
private int forwardButtonTick = 0;
private SpruceTexturedButtonWidget forwardLeftButton;
private SpruceTexturedButtonWidget forwardRightButton;
private SpruceTexturedButtonWidget startSneakButton;
private SpruceTexturedButtonWidget endSneakButton;
public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png");
private MidnightControlsClient mod;
private SilentTexturedButtonWidget jumpButton;
private SilentTexturedButtonWidget flyButton;
private SilentTexturedButtonWidget flyUpButton;
private SilentTexturedButtonWidget flyDownButton;
private int flyButtonEnableTicks = 0;
private int forwardButtonTick = 0;
private SilentTexturedButtonWidget forwardLeftButton;
private SilentTexturedButtonWidget forwardRightButton;
private SilentTexturedButtonWidget startSneakButton;
private SilentTexturedButtonWidget endSneakButton;
public TouchscreenOverlay(@NotNull MidnightControlsClient mod)
{
public TouchscreenOverlay(@NotNull MidnightControlsClient mod) {
super(Text.literal("Touchscreen overlay"));
this.mod = mod;
this.passEvents = true;
}
// @Override
// public boolean shouldPause()
// {
// return false;
// }
//
// @Override
// public boolean keyPressed(int keyCode, int scanCode, int modifiers)
// {
// super.keyPressed(keyCode,scanCode,modifiers);
// //return false;
// return true;
// }
//
// private void pauseGame(boolean bl)
// {
// if (this.client == null)
// return;
// boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote();
// if (bl2) {
// this.client.setScreen(new GameMenuScreen(!bl));
// this.client.getSoundManager().pauseAll();
// } else {
// this.client.setScreen(new GameMenuScreen(true));
// }
// }
//
// /**
// * Updates the forward button ticks cooldown.
// *
// * @param state The button state.
// *
// */
// private void updateForwardButtonsState(boolean state)
// {
// if (state)
// this.forwardButtonTick = -1;
// else
// this.forwardButtonTick = 20;
// }
//
// /**
// * Updates the jump buttons.
// */
// private void updateJumpButtons()
// {
// if (this.client == null)
// return;
// if (!this.client.interactionManager.isFlyingLocked()) {
// boolean oldStateFly = this.flyButton.visible;
// this.jumpButton.visible = false;
// this.flyButton.visible = true;
// this.flyUpButton.visible = true;
// this.flyDownButton.visible = true;
// if (oldStateFly != this.flyButton.visible) {
// this.flyButtonEnableTicks = 5;
// this.handleJump(null, false);
// } else if (this.flyButtonEnableTicks > 0)
// this.flyButtonEnableTicks--;
// } else {
// this.jumpButton.visible = true;
// this.flyButton.visible = false;
// this.flyUpButton.visible = false;
// this.flyDownButton.visible = false;
// }
// }
//
// /**
// * Handles the jump button.
// *
// * @param btn The pressed button.
// * @param state The state of the jump button.
// */
// private void handleJump(ButtonWidget btn, boolean state)
// {
// ((KeyBindingAccessor) this.client.options.keyJump).midnightcontrols$handlePressState(state);
// }
//
// @Override
// public void tick()
// {
// if (this.forwardButtonTick > 0) {
// this.forwardButtonTick--;
// } else if (this.forwardButtonTick == 0) {
// if (this.forwardLeftButton.visible)
// this.forwardLeftButton.visible = false;
// if (this.forwardRightButton.visible)
// this.forwardRightButton.visible = false;
// }
// this.updateJumpButtons();
// }
//
// @Override
// protected void init()
// {
// super.init();
// int scaledWidth = this.client.getWindow().getScaledWidth();
// int scaledHeight = this.client.getWindow().getScaledHeight();
// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256,
// btn -> this.client.setScreen(new ChatScreen("")), LiteralText.EMPTY));
// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256,
// btn -> this.pauseGame(false)));
// // Inventory buttons.
// int inventoryButtonX = scaledWidth / 2;
// int inventoryButtonY = scaledHeight - 16 - 5;
// if (this.client.options.mainArm == Arm.LEFT) {
// inventoryButtonX = inventoryButtonX - 91 - 24;
// } else {
// inventoryButtonX = inventoryButtonX + 91 + 4;
// }
// this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256,
// btn -> {
// if (this.client.interactionManager.hasRidingInventory()) {
// this.client.player.openRidingInventory();
// } else {
// this.client.getTutorialManager().onInventoryOpened();
// this.client.openScreen(new InventoryScreen(this.client.player));
// }
// }));
// int jumpButtonX, swapHandsX, sneakButtonX;
// int sneakButtonY = scaledHeight - 10 - 40 - 5;
// if (MidnightControlsConfig.hudSide == HudSide.LEFT) {
// jumpButtonX = scaledWidth - 20 - 20;
// swapHandsX = jumpButtonX - 5 - 40;
// sneakButtonX = 10 + 20 + 5;
// } else {
// jumpButtonX = 20;
// swapHandsX = jumpButtonX + 5 + 40;
// sneakButtonX = scaledWidth - 10 - 40 - 5;
// }
// // Swap items hand.
// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY, 20, 20, 0, 160, 20, WIDGETS_LOCATION,
// (btn, state) -> {
// if (state) {
// if (!this.client.player.isSpectator()) {
// this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN));
// }
// }
// }));
// // Drop
// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION,
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyDrop).midnightcontrols$handlePressState(state)));
// // Jump keys
// this.addDrawableChild(this.jumpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 0, 40, 20, WIDGETS_LOCATION,
// this::handleJump));
// this.addDrawableChild(this.flyButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 20, 40, 20, WIDGETS_LOCATION,
// (btn, state) -> {
// if (this.flyButtonEnableTicks == 0) this.client..abilities.flying = false;
// }));
// this.addDrawableChild(this.flyUpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION,
// this::handleJump));
// this.addDrawableChild(this.flyDownButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION,
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(state)));
// this.updateJumpButtons();
// // Movements keys
// this.addDrawableChild((this.startSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 0, 120, 20, WIDGETS_LOCATION,
// (btn, state) -> {
// if (state) {
// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(true);
// this.startSneakButton.setVisible(false);
// this.endSneakButton.setVisible(true);
// }
// })));
// this.addDrawableChild((this.endSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 20, 120, 20, WIDGETS_LOCATION,
// (btn, state) -> {
// if (state) {
// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(false);
// this.endSneakButton.setVisible(false);
// this.startSneakButton.setVisible(true);
// }
// })));
// this.endSneakButton.setVisible(false);
// this.addDrawableChild(this.forwardLeftButton = new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION,
// (btn, state) -> {
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state);
// ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state);
// this.updateForwardButtonsState(state);
// }));
// this.forwardLeftButton.setVisible(false);
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION,
// (btn, state) -> {
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state);
// this.updateForwardButtonsState(state);
// this.forwardLeftButton.setVisible(true);
// this.forwardRightButton.setVisible(true);
// }));
// this.addDrawableChild(this.forwardRightButton = new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION,
// (btn, state) -> {
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state);
// ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state);
// this.updateForwardButtonsState(state);
// }));
// this.forwardRightButton.setVisible(true);
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY, 20, 20, 20, 80, 20, WIDGETS_LOCATION,
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state)));
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION,
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyBack).midnightcontrols$handlePressState(state)));
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY, 20, 20, 60, 80, 20, WIDGETS_LOCATION,
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state)));
//
// this.children().forEach(button -> {
// if (button instanceof SpruceTexturedButtonWidget) {
// ((SpruceTexturedButtonWidget) button).setSilent(true);
// }
// });
// }
//
// @Override
// public boolean mouseClicked(double mouseX, double mouseY, int button)
// {
// if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) {
// int centerX = this.width / 2;
// if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) {
// for (int slot = 0; slot < 9; ++slot) {
// int slotX = centerX - 90 + slot * 20 + 2;
// if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) {
// this.client.player.getInventory().selectedSlot = slot;
// return true;
// }
// }
// }
// }
// return super.mouseClicked(mouseX, mouseY, button);
// }
//
// @Override
// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY)
// {
// if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) {
// if (deltaY > 0.01)
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2);
// else if (deltaY < 0.01)
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1);
//
// if (deltaX > 0.01)
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2);
// else if (deltaX < 0.01)
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1);
// }
// return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
// }
@Override
public boolean shouldPause()
{
return false;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
super.keyPressed(keyCode,scanCode,modifiers);
//return false;
return true;
}
private void pauseGame(boolean bl) {
if (this.client == null)
return;
boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote();
if (bl2) {
this.client.setScreen(new GameMenuScreen(!bl));
this.client.getSoundManager().pauseAll();
} else {
this.client.setScreen(new GameMenuScreen(true));
}
}
/**
* Updates the forward button ticks cooldown.
*
* @param state The button state.
*
*/
private void updateForwardButtonsState(boolean state) {
if (state)
this.forwardButtonTick = -1;
else
this.forwardButtonTick = 20;
}
/**
* Updates the jump buttons.
*/
private void updateJumpButtons() {
if (this.client == null)
return;
if (!this.client.interactionManager.isFlyingLocked()) {
boolean oldStateFly = this.flyButton.isVisible();
this.jumpButton.setVisible(false);
this.flyButton.setVisible(true);
this.flyUpButton.setVisible(true);
this.flyDownButton.setVisible(true);
if (oldStateFly != this.flyButton.isVisible()) {
this.flyButtonEnableTicks = 5;
this.setJump(false);
} else if (this.flyButtonEnableTicks > 0)
this.flyButtonEnableTicks--;
} else {
this.jumpButton.setVisible(true);
this.flyButton.setVisible(false);
this.flyUpButton.setVisible(false);
this.flyDownButton.setVisible(false);
}
}
/**
* Handles the jump button.
*
* @param btn The pressed button.
*/
private void handleJump(SpruceButtonWidget btn) {
((KeyBindingAccessor) this.client.options.jumpKey).midnightcontrols$handlePressState(btn.isActive());
}
/**
* Handles the jump button.
*
* @param state The state.
*/
private void setJump(boolean state) {
((KeyBindingAccessor) this.client.options.jumpKey).midnightcontrols$handlePressState(state);
}
@Override
public void tick() {
if (this.forwardButtonTick > 0) {
this.forwardButtonTick--;
} else if (this.forwardButtonTick == 0) {
if (this.forwardLeftButton.isVisible())
this.forwardLeftButton.setVisible(false);
if (this.forwardRightButton.isVisible())
this.forwardRightButton.setVisible(false);
}
this.updateJumpButtons();
}
@Override
protected void init() {
super.init();
int scaledWidth = this.client.getWindow().getScaledWidth();
int scaledHeight = this.client.getWindow().getScaledHeight();
this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, new Identifier("textures/gui/widgets.png"), 256, 256,
btn -> this.client.setScreen(new ChatScreen("")), Text.empty()));
this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256,
btn -> this.pauseGame(false)));
// Inventory buttons.
int inventoryButtonX = scaledWidth / 2;
int inventoryButtonY = scaledHeight - 16 - 5;
if (this.client.options.getMainArm().getValue() == Arm.LEFT) {
inventoryButtonX = inventoryButtonX - 91 - 24;
} else {
inventoryButtonX = inventoryButtonX + 91 + 4;
}
this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256,
btn -> {
if (this.client.interactionManager.hasRidingInventory()) {
this.client.player.openRidingInventory();
} else {
this.client.getTutorialManager().onInventoryOpened();
this.client.setScreen(new InventoryScreen(this.client.player));
}
}));
int jumpButtonX, swapHandsX, sneakButtonX;
int sneakButtonY = scaledHeight - 10 - 40 - 5;
if (MidnightControlsConfig.hudSide == HudSide.LEFT) {
jumpButtonX = scaledWidth - 20 - 20;
swapHandsX = jumpButtonX - 5 - 40;
sneakButtonX = 10 + 20 + 5;
} else {
jumpButtonX = 20;
swapHandsX = jumpButtonX + 5 + 40;
sneakButtonX = scaledWidth - 10 - 40 - 5;
}
// Swap items hand.
this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(swapHandsX, sneakButtonY), 20, 20, Text.empty(),
button -> {
if (button.isActive()) {
if (!this.client.player.isSpectator()) {
this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN));
}
}
},0, 160, 20, WIDGETS_LOCATION));
// Drop
this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(swapHandsX, sneakButtonY + 5 + 20), 20, 20, Text.empty(), btn ->
((KeyBindingAccessor) this.client.options.dropKey).midnightcontrols$handlePressState(btn.isActive()), 0, 160, 20, WIDGETS_LOCATION));
// Jump keys
this.addDrawableChild(this.jumpButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(), this::handleJump, 0, 40, 20, WIDGETS_LOCATION));
this.addDrawableChild(this.flyButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(),btn -> {
if (this.flyButtonEnableTicks == 0) this.client.player.getAbilities().flying = false;
}, 20, 40, 20, WIDGETS_LOCATION)
);
this.addDrawableChild(this.flyUpButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY - 5 - 20), 20, 20,Text.empty(),
this::handleJump, 40, 40, 20, WIDGETS_LOCATION
));
this.addDrawableChild(this.flyDownButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY + 20 + 5), 20, 20, Text.empty(),
btn -> ((KeyBindingAccessor) this.client.options.sneakKey).midnightcontrols$handlePressState(btn.isActive()), 60, 40, 20, WIDGETS_LOCATION
));
this.updateJumpButtons();
// Movements keys
this.addDrawableChild((this.startSneakButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY), 20, 20, Text.empty(), btn -> {
if (btn.isActive()) {
((KeyBindingAccessor) this.client.options.sneakKey).midnightcontrols$handlePressState(true);
this.startSneakButton.setVisible(false);
this.endSneakButton.setVisible(true);
}
}, 0, 120, 20, WIDGETS_LOCATION))
);
this.addDrawableChild((this.endSneakButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY), 20, 20, Text.empty(), btn -> {
if (btn.isActive()) {
((KeyBindingAccessor) this.client.options.sneakKey).midnightcontrols$handlePressState(false);
this.endSneakButton.setVisible(false);
this.startSneakButton.setVisible(true);
}
}, 20, 120, 20, WIDGETS_LOCATION)));
this.endSneakButton.setVisible(false);
this.addDrawableChild(this.forwardLeftButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> {
((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive());
((KeyBindingAccessor) this.client.options.leftKey).midnightcontrols$handlePressState(btn.isActive());
this.updateForwardButtonsState(btn.isActive());
}, 80, 80, 20, WIDGETS_LOCATION
));
this.forwardLeftButton.setVisible(false);
this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> {
((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive());
this.updateForwardButtonsState(btn.isActive());
this.forwardLeftButton.setVisible(true);
this.forwardRightButton.setVisible(true);
}, 0, 80, 20, WIDGETS_LOCATION
));
this.addDrawableChild(this.forwardRightButton = new SilentTexturedButtonWidget(Position.of(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20), 20, 20, Text.empty(), btn -> {
((KeyBindingAccessor) this.client.options.forwardKey).midnightcontrols$handlePressState(btn.isActive());
((KeyBindingAccessor) this.client.options.rightKey).midnightcontrols$handlePressState(btn.isActive());
this.updateForwardButtonsState(btn.isActive());
}, 100, 80, 20, WIDGETS_LOCATION
));
this.forwardRightButton.setVisible(true);
this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX + 20 + 5, sneakButtonY), 20, 20, Text.empty(),
btn -> ((KeyBindingAccessor) this.client.options.rightKey).midnightcontrols$handlePressState(btn.isActive()), 20, 80, 20, WIDGETS_LOCATION
));
this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX, sneakButtonY + 20 + 5), 20, 20, Text.empty(),
btn -> ((KeyBindingAccessor) this.client.options.backKey).midnightcontrols$handlePressState(btn.isActive()), 40, 80, 20, WIDGETS_LOCATION
));
this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX - 20 - 5, sneakButtonY), 20, 20, Text.empty(),
btn -> ((KeyBindingAccessor) this.client.options.leftKey).midnightcontrols$handlePressState(btn.isActive()), 60, 80, 20, WIDGETS_LOCATION
));
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) {
int centerX = this.width / 2;
if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) {
for (int slot = 0; slot < 9; ++slot) {
int slotX = centerX - 90 + slot * 20 + 2;
if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) {
this.client.player.getInventory().selectedSlot = slot;
return true;
}
}
}
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) {
if (deltaY > 0.01)
this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2);
else if (deltaY < 0.01)
this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1);
if (deltaX > 0.01)
this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2);
else if (deltaX < 0.01)
this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1);
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
}

View File

@@ -17,6 +17,7 @@ import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.SpruceTexts;
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen;
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
@@ -49,6 +50,7 @@ public class ControllerControlsWidget extends SpruceContainerWidget {
Text.translatable("midnightcontrols.menu.keyboard_controls"),
btn -> this.client.setScreen(new ControlsOptionsScreen(null, this.client.options))));
this.bindingsListWidget = new ControlsListWidget(Position.of(this, 0, 43), this.width, this.height - 43 - 35, this);
this.bindingsListWidget.setBackground(new MidnightControlsSettingsScreen.MidnightControlsBackground(130));
this.addChild(this.bindingsListWidget);
this.addChild(this.resetButton = new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150, 20,
SpruceTexts.CONTROLS_RESET_ALL,

View File

@@ -0,0 +1,26 @@
package eu.midnightdust.midnightcontrols.client.gui.widget;
import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
public class SilentTexturedButtonWidget extends SpruceTexturedButtonWidget {
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, PressAction action, int u, int v, int hoveredVOffset, Identifier texture) {
super(position, width, height, message, action, u, v, hoveredVOffset, texture);
}
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, boolean showMessage, PressAction action, int u, int v, int hoveredVOffset, Identifier texture) {
super(position, width, height, message, showMessage, action, u, v, hoveredVOffset, texture);
}
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, PressAction action, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight) {
super(position, width, height, message, action, u, v, hoveredVOffset, texture, textureWidth, textureHeight);
}
public SilentTexturedButtonWidget(Position position, int width, int height, Text message, boolean showMessage, PressAction action, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight) {
super(position, width, height, message, showMessage, action, u, v, hoveredVOffset, texture, textureWidth, textureHeight);
}
@Override
public void playDownSound() {}
}

View File

@@ -10,6 +10,7 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import com.mojang.authlib.GameProfile;
import eu.midnightdust.midnightcontrols.MidnightControls;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.controller.MovementHandler;
@@ -27,6 +28,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
@@ -53,10 +55,13 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
@Shadow
protected abstract boolean isCamera();
@Shadow protected int ticksLeftToDoubleTapSprint;
@Inject(method = "move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V"))
public void onMove(MovementType type, Vec3d movement, CallbackInfo ci) {
var mod = MidnightControlsClient.get();
if (!MidnightControlsConfig.doubleTapToSprint) ticksLeftToDoubleTapSprint = 0;
if (!MidnightControls.isExtrasLoaded) return;
if (type == MovementType.SELF) {
if (this.getAbilities().flying && (!MidnightControlsConfig.flyDrifting || !MidnightControlsConfig.verticalFlyDrifting)) {
if (!this.hasMovementInput()) {
@@ -79,7 +84,7 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
@Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z"))
public void onTickMovement(CallbackInfo ci) {
if (this.getAbilities().flying && this.isCamera()) {
if (MidnightControlsConfig.verticalFlyDrifting)
if (MidnightControlsConfig.verticalFlyDrifting || !MidnightControls.isExtrasLoaded)
return;
int moving = 0;
if (this.input.sneaking) {

View File

@@ -29,7 +29,9 @@ public interface CreativeInventoryScreenAccessor {
* @return the selected tab index
*/
@Accessor("selectedTab")
int getSelectedTab();
static int getSelectedTab() {
return 0;
}
/**
* Sets the selected tab.

View File

@@ -13,6 +13,7 @@ import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.MidnightInput;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import net.minecraft.client.MinecraftClient;
@@ -20,9 +21,11 @@ import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
import org.spongepowered.asm.mixin.injection.At;
@@ -34,6 +37,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
*/
@Mixin(HandledScreen.class)
public abstract class HandledScreenMixin implements HandledScreenAccessor {
@Unique private static float scale = 1f;
@Accessor("x")
public abstract int getX();
@@ -55,16 +59,26 @@ public abstract class HandledScreenMixin implements HandledScreenAccessor {
public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) {
var client = MinecraftClient.getInstance();
int x = 2, y = client.getWindow().getScaledHeight() - 2 - MidnightControlsRenderer.ICON_SIZE;
if (client.getWindow().getScaleFactor() >= 4) {
scale = (float) (0.75f * (client.getWindow().getScaleFactor()-3));
} else scale = 1f;
if (scale != 1f) matrices.scale(scale,scale,scale);
int x = 2, y = (int) (client.getWindow().getScaledHeight() * (1 / scale) - 2 - MidnightControlsRenderer.ICON_SIZE);
if (MidnightControlsCompat.isEMIPresent()) {
x += 40 * (1 / scale);
}
x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_A}, "midnightcontrols.action.pickup_all", true, client) + 2;
x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_B}, "midnightcontrols.action.exit", true, client) + 2;
if (MidnightControlsCompat.isReiPresent()) {
x = 2;
y -= 24;
}
x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "midnightcontrols.action.pickup", true, client) + 2;
if (MidnightControlsCompat.isEMIPresent()) {
x = (int) (client.getWindow().getScaledWidth() * (1 / scale) - 55 - client.textRenderer.getWidth(Text.translatable("midnightcontrols.action.pickup")) * (1 / scale) - client.textRenderer.getWidth(Text.translatable("midnightcontrols.action.quick_move")) - MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.TAKE) - MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.QUICK_MOVE));
}
x = MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_X}, "midnightcontrols.action.pickup", true, client);
MidnightControlsRenderer.drawButtonTip(matrices, x, y, new int[]{GLFW.GLFW_GAMEPAD_BUTTON_Y}, "midnightcontrols.action.quick_move", true, client);
if (scale != 1f) matrices.scale(1,1,1);
}
}
}

View File

@@ -28,7 +28,7 @@ public class KeyBindingMixin implements KeyBindingAccessor {
if (!this.pressed)
this.pressed = true;
++this.timesPressed;
return oldPressed != this.pressed;
return !oldPressed;
}
@Override

View File

@@ -0,0 +1,17 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
import net.minecraft.client.option.KeyBinding;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(value = KeyBindingRegistryImpl.class, remap = false)
public interface KeyBindingRegistryImplAccessor {
@Accessor @Final
static List<KeyBinding> getModdedKeyBindings() {
return null;
}
}

View File

@@ -54,10 +54,6 @@ public abstract class MinecraftClientMixin {
@Nullable
public ClientPlayerInteractionManager interactionManager;
@Shadow
@Nullable
public ClientWorld world;
@Shadow
@Final
public GameRenderer gameRenderer;
@@ -104,18 +100,26 @@ public abstract class MinecraftClientMixin {
this.midnightcontrols$lastTargetSide = side;
}
// Removed front placing sprinting as way too cheaty.
/*else if (this.player.isSprinting()) {
hitResult = midnightcontrolsClient.get().reacharound.getLastReacharoundResult();
else if (this.player.isSprinting()) {
hitResult = MidnightControlsClient.get().reacharound.getLastReacharoundResult();
if (hitResult != null) {
if (cooldown > 0)
this.itemUseCooldown = 0;
}
}*/
}
this.midnightcontrols$lastPos = this.player.getPos();
}
// Applied three times for smooth camera turning even on low FPS
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Recorder;startTick()V", shift = At.Shift.AFTER))
private void onPreRender(CallbackInfo ci) {
MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this));
}
@Inject(method = "render", at = @At("HEAD"))
private void onRender(boolean fullRender, CallbackInfo ci) {
private void onRender(CallbackInfo ci) {
MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this));
}
@Inject(method = "render", at = @At("TAIL"))
private void onPostRender(CallbackInfo ci) {
MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this));
}

View File

@@ -51,16 +51,16 @@ public final class MidnightRing {
* Loads the ring from configuration.
*/
public void load() {
// List<Config> configPages = MidnightControlsConfig.ringPages;
// if (configPages != null) {
// this.pages.clear();
// for (var configPage : configPages) {
// RingPage.parseRingPage(configPage).ifPresent(this.pages::add);
// }
// }
// if (this.pages.isEmpty()) {
// this.pages.add(RingPage.DEFAULT);
// }
List<Config> configPages = null;
if (configPages != null) {
this.pages.clear();
for (var configPage : configPages) {
RingPage.parseRingPage(configPage).ifPresent(this.pages::add);
}
}
if (this.pages.isEmpty()) {
this.pages.add(RingPage.DEFAULT);
}
}
public @NotNull RingPage getCurrentPage() {

View File

@@ -10,11 +10,15 @@
package eu.midnightdust.midnightcontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.util.math.MatrixStack;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@@ -36,6 +40,11 @@ public class RingPage extends DrawableHelper {
for (int i = 0; i < 8; i++) {
this.actions[i] = null;
}
this.actions[0] = new DummyRingAction(null);
this.actions[1] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_UP);
this.actions[2] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_LEFT);
this.actions[3] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_RIGHT);
this.actions[4] = new KeyBindingRingAction(null, MidnightControlsClient.BINDING_LOOK_DOWN);
}
/**
@@ -83,6 +92,52 @@ public class RingPage extends DrawableHelper {
private static boolean isHovered(int x, int y, int mouseX, int mouseY) {
return mouseX >= x && mouseY >= y && mouseX <= x + MidnightRing.ELEMENT_SIZE && mouseY <= y + MidnightRing.ELEMENT_SIZE;
}
/**
* Renders the ring page.
*
* @param width the screen width
* @param height the screen height
* @param mouseX the mouse X-coordinate
* @param mouseY the mouse Y-coordinate
*/
public boolean onClick(int width, int height, int mouseX, int mouseY) {
int centerX = width / 2;
int centerY = height / 2;
int offset = MidnightRing.ELEMENT_SIZE + (MidnightRing.ELEMENT_SIZE / 2) + 5;
int y = centerY - offset;
int x = centerX - offset;
for (int i = 0; i < 3; i++) {
var ringAction = this.actions[i];
if (ringAction != null && isHovered(x,y,mouseX,mouseY)) {
ringAction.activate(RingButtonMode.PRESS);
return true;
}
x += 55;
}
y += 55;
x = centerX - offset;
for (int i = 3; i < 5; i++) {
var ringAction = this.actions[i];
if (ringAction != null && isHovered(x,y,mouseX,mouseY)) {
ringAction.activate(RingButtonMode.PRESS);
return true;
}
x += 55 * 2;
}
y += 55;
x = centerX - offset;
for (int i = 5; i < 8; i++) {
var ringAction = this.actions[i];
if (ringAction != null && isHovered(x,y,mouseX,mouseY)) {
ringAction.activate(RingButtonMode.PRESS);
return true;
}
x += 55;
}
return false;
}
/**
* Tries to parse a ring page configuration.

View File

@@ -92,6 +92,7 @@
"midnightcontrols.menu.controller2": "Zweiter Controller",
"midnightcontrols.menu.controller_type": "Controller-Typ",
"midnightcontrols.menu.controls_mode": "Modus",
"midnightcontrols.menu.double_tap_to_sprint": "Doppel-Tipp zum Sprinten",
"midnightcontrols.menu.fast_block_placing": "Schnelles Bauen",
"midnightcontrols.menu.fly_drifting": "Flug-Drifting",
"midnightcontrols.menu.fly_drifting_vertical": "Vertikales Flug-Drifting",
@@ -111,7 +112,8 @@
"midnightcontrols.menu.reacharound.vertical": "Vertikales Umgreifen",
"midnightcontrols.menu.reload_controller_mappings": "Controller-Mappings neuladen",
"midnightcontrols.menu.right_dead_zone": "Rechte tote Zone",
"midnightcontrols.menu.rotation_speed": "Rotationsgeschwindigkeit",
"midnightcontrols.menu.rotation_speed": "Rotationsgeschwindigkeit (X-Achse)",
"midnightcontrols.menu.y_axis_rotation_speed": "Rotationsgeschwindigkeit (Y-Achse)",
"midnightcontrols.menu.separator.controller": "Controller",
"midnightcontrols.menu.separator.general": "Generell",
"midnightcontrols.menu.title": "MidnightControls - Einstellungen",
@@ -147,7 +149,8 @@
"midnightcontrols.tooltip.reacharound.vertical": "Aktiviert vertikales Platzieren von Blöcken, §cwird von manchen Servern als cheaten eingestuft§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "Lädt die Controller-Mappings neu.",
"midnightcontrols.tooltip.right_dead_zone": "Die tote Zone für den rechten Analogstick.",
"midnightcontrols.tooltip.rotation_speed": "Die Kamerarotationsgeschwindigkeit im Controllermodus.",
"midnightcontrols.tooltip.rotation_speed": "Die Kamerarotationsgeschwindigkeit im Controllermodus. (X-Achse)",
"midnightcontrols.tooltip.y_axis_rotation_speed": "Die Kamerarotationsgeschwindigkeit im Controllermodus. (Y-Achse)",
"midnightcontrols.tooltip.unfocused_input": "Erlaube Controllereingabe auch wenn das Fenster nicht fokussiert ist.",
"midnightcontrols.tooltip.virtual_mouse": "Aktiviere die virtuelle Maus.",
"midnightcontrols.virtual_mouse.skin.default_light": "Standard Hell",

View File

@@ -96,6 +96,7 @@
"midnightcontrols.menu.controller2": "Second Controller",
"midnightcontrols.menu.controller_type": "Controller Type",
"midnightcontrols.menu.controls_mode": "Mode",
"midnightcontrols.menu.double_tap_to_sprint": "Double-Tap to Sprint",
"midnightcontrols.menu.fast_block_placing": "Fast Block Placing",
"midnightcontrols.menu.fly_drifting": "Fly Drifting",
"midnightcontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting",
@@ -115,7 +116,8 @@
"midnightcontrols.menu.reacharound.vertical": "Vertical Reacharound",
"midnightcontrols.menu.reload_controller_mappings": "Reload Controller Mappings",
"midnightcontrols.menu.right_dead_zone": "Right Dead Zone",
"midnightcontrols.menu.rotation_speed": "Rotation Speed",
"midnightcontrols.menu.rotation_speed": "X Axis Rotation Speed",
"midnightcontrols.menu.y_axis_rotation_speed": "Y Axis Rotation Speed",
"midnightcontrols.menu.separator.controller": "Controller",
"midnightcontrols.menu.separator.general": "General",
"midnightcontrols.menu.title": "MidnightControls - Settings",
@@ -151,7 +153,8 @@
"midnightcontrols.tooltip.reacharound.vertical": "Enables vertical reacharound, §cmight be considered cheating on some servers§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "Reloads the controller mappings file.",
"midnightcontrols.tooltip.right_dead_zone": "The dead zone for the controller's right analogue stick.",
"midnightcontrols.tooltip.rotation_speed": "The camera rotation speed in controller mode.",
"midnightcontrols.tooltip.rotation_speed": "The camera X Axis rotation speed in controller mode.",
"midnightcontrols.tooltip.y_axis_rotation_speed": "The camera Y Axis rotation speed in controller mode.",
"midnightcontrols.tooltip.unfocused_input": "Allow controller input when the window is not focused.",
"midnightcontrols.tooltip.virtual_mouse": "Enable the virtual mouse which is handful in the case of a splitscreen.",
"midnightcontrols.virtual_mouse.skin.default_light": "Default Light",

View File

@@ -104,7 +104,8 @@
"midnightcontrols.menu.reacharound.vertical": "Alcance vertical",
"midnightcontrols.menu.reload_controller_mappings": "Recargar asignaciones de controlador",
"midnightcontrols.menu.right_dead_zone": "Zona muerta derecha",
"midnightcontrols.menu.rotation_speed": "Velocidad de rotación",
"midnightcontrols.menu.rotation_speed": "Velocidad de rotación (eje X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Velocidad de rotación (eje Y)",
"midnightcontrols.menu.separator.controller": "Controlador",
"midnightcontrols.menu.separator.general": "General",
"midnightcontrols.menu.title": "midnightcontrols - Configuraciones",
@@ -140,7 +141,8 @@
"midnightcontrols.tooltip.reacharound.vertical": "Habilita el alcance vertical, §cpodría considerarse trampa en algunos servidores§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "Vuelve a cargar el archivo de asignaciones del controlador.",
"midnightcontrols.tooltip.right_dead_zone": "La zona muerta de la palanca analógica derecha del controlador.",
"midnightcontrols.tooltip.rotation_speed": "La velocidad de rotación de la cámara en modo controlador.",
"midnightcontrols.tooltip.rotation_speed": "La velocidad de rotación de la cámara en modo controlador. (eje X)",
"midnightcontrols.tooltip.y_axis_rotation_speed": "La velocidad de rotación de la cámara en modo controlador. (eje Y)",
"midnightcontrols.tooltip.unfocused_input": "Habilita entrada del controlador cuando la ventana no está enfocada.",
"midnightcontrols.tooltip.virtual_mouse": "Habilite el ratón virtual que es útil en el caso de una pantalla dividida.",
"midnightcontrols.virtual_mouse.skin.default_light": "Ligera por defecto",

View File

@@ -104,7 +104,8 @@
"midnightcontrols.menu.reacharound.vertical": "Placement vertical",
"midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes",
"midnightcontrols.menu.right_dead_zone": "Zone morte axe droit",
"midnightcontrols.menu.rotation_speed": "Vitesse de rotation",
"midnightcontrols.menu.rotation_speed": "Vitesse de rotation (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Vitesse de rotation (Y)",
"midnightcontrols.menu.separator.general": "Général",
"midnightcontrols.menu.separator.controller": "Manette",
"midnightcontrols.menu.title": "midnightcontrols - Paramètres",
@@ -140,7 +141,8 @@
"midnightcontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.",
"midnightcontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.",
"midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
"midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra. (X)",
"midnightcontrols.tooltip.y_axis_rotation_speed": "Change la vitesse de rotation de la caméra. (Y)",
"midnightcontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.",
"midnightcontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.",
"midnightcontrols.virtual_mouse.skin.default_light": "défaut clair",

View File

@@ -104,7 +104,8 @@
"midnightcontrols.menu.reacharound.vertical": "Placement vertical",
"midnightcontrols.menu.reload_controller_mappings": "Recharger les manettes",
"midnightcontrols.menu.right_dead_zone": "Zone morte axe droit",
"midnightcontrols.menu.rotation_speed": "Vitesse de rotation",
"midnightcontrols.menu.rotation_speed": "Vitesse de rotation (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Vitesse de rotation (Y)",
"midnightcontrols.menu.separator.general": "Général",
"midnightcontrols.menu.separator.controller": "Manette",
"midnightcontrols.menu.title": "midnightcontrols - Paramètres",
@@ -140,7 +141,8 @@
"midnightcontrols.tooltip.reacharound.vertical": "Active le placement vertical de blocs, c'est-à-dire de blocs en dessous du bloc sur lequel vous êtes placé, §cpeut être considérer comme de la triche sur certains serveurs§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "Recharge le fichier de configuration des manettes.",
"midnightcontrols.tooltip.right_dead_zone": "Zone morte de l'axe droit de la manette.",
"midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra.",
"midnightcontrols.tooltip.rotation_speed": "Change la vitesse de rotation de la caméra. (X)",
"midnightcontrols.tooltip.y_axis_rotation_speed": "Change la vitesse de rotation de la caméra. (Y)",
"midnightcontrols.tooltip.unfocused_input": "Autorise les entrées manette quand la fenêtre n'est pas sélectionnée.",
"midnightcontrols.tooltip.virtual_mouse": "Active la souris virtuelle qui est pratique dans le cas d'un écran partagé.",
"midnightcontrols.virtual_mouse.skin.default_light": "défaut clair",

View File

@@ -0,0 +1,158 @@
{
"midnightcontrols.midnightconfig.title": "MidnightControls 고급 설정",
"key.midnightcontrols.look_down": "아래쪽 보기",
"key.midnightcontrols.look_left": "왼쪽 보기",
"key.midnightcontrols.look_right": "오른쪽 보기",
"key.midnightcontrols.look_up": "위쪽 보기",
"key.midnightcontrols.ring": "컨트롤 링 표시",
"midnightcontrols.action.attack": "공격",
"midnightcontrols.action.back": "뒤로",
"midnightcontrols.action.chat": "채팅 열기",
"midnightcontrols.action.drop_item": "아이템 버리기",
"midnightcontrols.action.exit": "종료",
"midnightcontrols.action.forward": "앞으로",
"midnightcontrols.action.hit": "때리기",
"midnightcontrols.action.hotbar_left": "단축 바 왼쪽",
"midnightcontrols.action.hotbar_right": "단축 바 오른쪽",
"midnightcontrols.action.inventory": "보관함",
"midnightcontrols.action.jump": "점프",
"midnightcontrols.action.left": "왼쪽",
"midnightcontrols.action.pause_game": "게임 일시 중지",
"midnightcontrols.action.pick_block": "블록 집기",
"midnightcontrols.action.pickup": "집기",
"midnightcontrols.action.pickup_all": "모두 집기",
"midnightcontrols.action.place": "놓기",
"midnightcontrols.action.player_list": "플레이어 목록",
"midnightcontrols.action.quick_move": "빠른 이동",
"midnightcontrols.action.right": "오른쪽",
"midnightcontrols.action.screenshot": "스크린샷 찍기",
"midnightcontrols.action.sneak": "은신",
"midnightcontrols.action.sprint": "달리기",
"midnightcontrols.action.swap_hands": "손 전환",
"midnightcontrols.action.toggle_perspective": "시점 토글",
"midnightcontrols.action.toggle_smooth_camera": "시네마틱 카메라 토글",
"midnightcontrols.action.use": "사용",
"midnightcontrols.action.zoom": "확대/축소",
"midnightcontrols.action.zoom_in": "확대",
"midnightcontrols.action.zoom_out": "축소",
"midnightcontrols.action.zoom_reset": "확대/축소 초기화",
"midnightcontrols.action.key.emotecraft.fastchoose": "이모트 빠른 선택",
"midnightcontrols.action.key.emotecraft.stop": "이모트 중지",
"midnightcontrols.button.a": "A",
"midnightcontrols.button.b": "B",
"midnightcontrols.button.x": "X",
"midnightcontrols.button.y": "Y",
"midnightcontrols.button.left_bumper": "왼쪽 범퍼",
"midnightcontrols.button.right_bumper": "오른쪽 범퍼",
"midnightcontrols.button.back": "뒤로",
"midnightcontrols.button.start": "시작",
"midnightcontrols.button.guide": "가이드",
"midnightcontrols.button.left_thumb": "왼쪽 엄지",
"midnightcontrols.button.right_thumb": "오른쪽 엄지",
"midnightcontrols.button.dpad_up": "DPAD 위",
"midnightcontrols.button.dpad_right": "DPAD 오른쪽",
"midnightcontrols.button.dpad_down": "DPAD 아래",
"midnightcontrols.button.dpad_left": "DPAD 왼쪽",
"midnightcontrols.button.l4": "L4",
"midnightcontrols.button.l5": "L5",
"midnightcontrols.button.r4": "R4",
"midnightcontrols.button.r5": "L5",
"midnightcontrols.axis.left_x+": "왼쪽 X+",
"midnightcontrols.axis.left_y+": "왼쪽 Y+",
"midnightcontrols.axis.right_x+": "오른쪽 X+",
"midnightcontrols.axis.right_y+": "오른쪽 Y+",
"midnightcontrols.axis.left_trigger": "왼쪽 트리거",
"midnightcontrols.axis.right_trigger": "오른쪽 트리거",
"midnightcontrols.axis.left_x-": "왼쪽 X-",
"midnightcontrols.axis.left_y-": "왼쪽 Y-",
"midnightcontrols.axis.right_x-": "오른쪽 X-",
"midnightcontrols.axis.right_y-": "오른쪽 Y-",
"midnightcontrols.button.unknown": "알 수 없음 (%d)",
"midnightcontrols.controller.connected": "컨트롤러 %d 연결됨.",
"midnightcontrols.controller.disconnected": "컨트롤러 %d 연결 끊김.",
"midnightcontrols.controller.mappings.1": "컨트롤러 매핑을 설정하려면, %s을 사용하세요",
"midnightcontrols.controller.mappings.3": "그리고 매핑 파일 편집기에 매핑을 붙여 넣으세요.",
"midnightcontrols.controller.mappings.error": "매핑을 불러오던 중 오류.",
"midnightcontrols.controller.mappings.error.write": "파일에 매핑 작성 중 오류.",
"midnightcontrols.controller.mappings.updated": "매핑 업데이트됨!",
"midnightcontrols.controller_type.default": "기본",
"midnightcontrols.controller_type.dualshock": "듀얼쇼크",
"midnightcontrols.controller_type.switch": "스위치",
"midnightcontrols.controller_type.xbox": "엑스박스",
"midnightcontrols.controller_type.steam": "스팀",
"midnightcontrols.controller_type.ouya": "우야",
"midnightcontrols.controls_mode.default": "키보드/마우스",
"midnightcontrols.controls_mode.controller": "컨트롤러",
"midnightcontrols.controls_mode.touchscreen": "터치스크린",
"midnightcontrols.hud_side.left": "왼쪽",
"midnightcontrols.hud_side.right": "오른쪽",
"midnightcontrols.menu.analog_movement": "아날로그 움직임",
"midnightcontrols.menu.auto_switch_mode": "자동 전환 모드",
"midnightcontrols.menu.controller": "컨트롤러",
"midnightcontrols.menu.controller2": "보조 컨트롤러",
"midnightcontrols.menu.controller_type": "컨트롤러 종류",
"midnightcontrols.menu.controls_mode": "모드",
"midnightcontrols.menu.fast_block_placing": "빠른 블록 배치",
"midnightcontrols.menu.fly_drifting": "비행 관성",
"midnightcontrols.menu.fly_drifting_vertical": "비행 수직 관성",
"midnightcontrols.menu.hud_enable": "HUD 사용",
"midnightcontrols.menu.hud_side": "HUD 측면",
"midnightcontrols.menu.invert_right_x_axis": "오른쪽 X 반전",
"midnightcontrols.menu.invert_right_y_axis": "오른쪽 Y 반전",
"midnightcontrols.menu.keyboard_controls": "키보드 컨트롤...",
"midnightcontrols.menu.left_dead_zone": "왼쪽 데드 존",
"midnightcontrols.menu.mappings.open_input_str": "매핑 파일 편집기 열기",
"midnightcontrols.menu.max_left_x_value": "왼쪽 X 축 최댓값",
"midnightcontrols.menu.max_left_y_value": "왼쪽 Y 축 최댓값",
"midnightcontrols.menu.max_right_x_value": "오른쪽 X 축 최댓값",
"midnightcontrols.menu.max_right_y_value": "오른쪽 Y 축 최댓값",
"midnightcontrols.menu.mouse_speed": "마우스 속도",
"midnightcontrols.menu.reacharound.horizontal": "블록 전면 배치",
"midnightcontrols.menu.reacharound.vertical": "블록 수직 배치",
"midnightcontrols.menu.reload_controller_mappings": "컨트롤러 매핑 다시 불러오기",
"midnightcontrols.menu.right_dead_zone": "오른쪽 데드 존",
"midnightcontrols.menu.rotation_speed": "회전 속도",
"midnightcontrols.menu.separator.controller": "컨트롤러",
"midnightcontrols.menu.separator.general": "일반",
"midnightcontrols.menu.title": "MidnightControls - 설정",
"midnightcontrols.menu.title.controller": "컨트롤러 옵션",
"midnightcontrols.menu.title.controller_controls": "컨트롤러 제어",
"midnightcontrols.menu.title.gameplay": "게임플레이 옵션",
"midnightcontrols.menu.title.general": "일반 옵션",
"midnightcontrols.menu.title.hud": "HUD 옵션",
"midnightcontrols.menu.title.mappings.string": "매핑 파일 편집기",
"midnightcontrols.menu.title.visual": "외형 옵션",
"midnightcontrols.menu.unfocused_input": "언포커스 인풋",
"midnightcontrols.menu.virtual_mouse": "가상 마우스",
"midnightcontrols.menu.virtual_mouse.skin": "가상 마우스 스킨",
"midnightcontrols.narrator.unbound": "%s 해제됨",
"midnightcontrols.not_bound": "바인딩되지 않음",
"midnightcontrols.tooltip.analog_movement": "가능한 경우 아날로그 움직임을 사용합니다.",
"midnightcontrols.tooltip.auto_switch_mode": "컨트롤러가 연결되면 자동으로 컨트롤 모드가 컨트롤러로 전환됩니다.",
"midnightcontrols.tooltip.controller2": "보조 컨트롤러를 사용하려면 Joy-Cons 지원을 허용하세요.",
"midnightcontrols.tooltip.controller_type": "올바른 버튼을 표시할 컨트롤러 종류입니다.",
"midnightcontrols.tooltip.controls_mode": "컨트롤 모드.",
"midnightcontrols.tooltip.fast_block_placing": "크리에이티브 모드에서 비행하는 동안 사용자 속도에 따른 빠른 블록 배치를 사용합니다. §c일부 서버에선 치팅 행위로 취급될 수 있습니다.",
"midnightcontrols.tooltip.fly_drifting": "비행하는 동안 바닐라처럼 관성을 적용합니다.",
"midnightcontrols.tooltip.fly_drifting_vertical": "비행하는 동안 바닐라처럼 수직 관성을 적용합니다.",
"midnightcontrols.tooltip.hud_enable": "화면 컨트롤러 버튼 표시기 토글",
"midnightcontrols.tooltip.hud_side": "HUD 위치.",
"midnightcontrols.tooltip.left_dead_zone": "컨트롤러 왼쪽 아날로그 스틱 데드 존.",
"midnightcontrols.tooltip.max_left_x_value": "모드가 인식하는 왼쪽 X 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.tooltip.max_left_y_value": "모드가 인식하는 왼쪽 Y 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.tooltip.max_right_x_value": "모드가 인식하는 오른쪽 X 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.tooltip.max_right_y_value": "모드가 인식하는 오른쪽 Y 축 최댓값을 변경합니다. 사용자의 축이 전체 범위를 사용하지 않고 느리게 보일 경우 유용합니다.",
"midnightcontrols.tooltip.mouse_speed": "컨트롤러의 에뮬레이트된 마우스 속도.",
"midnightcontrols.tooltip.reacharound.horizontal": "블록 전면 배치를 사용합니다. §c일부 서버에선 치팅 행위로 취급될 수 있습니다§r.",
"midnightcontrols.tooltip.reacharound.vertical": "블록 수직 배치를 사용합니다. 블록 아래에 다른 블록을 배치할 수 있습니다. §c일부 서버에선 치팅 행위로 취급될 수 있습니다§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "컨트롤러 매핑 파일을 다시 불러옵니다.",
"midnightcontrols.tooltip.right_dead_zone": "컨트롤러 오른쪽 아날로그 스틱 데드 존",
"midnightcontrols.tooltip.rotation_speed": "컨트롤러 모드에서 적용되는 카메라 회전 속도.",
"midnightcontrols.tooltip.unfocused_input": "창이 활성화된 상태가 아니여도 컨트롤러 입력 허용.",
"midnightcontrols.tooltip.virtual_mouse": "분할 화면에선 도움 되는 가상 마우스를 사용합니다.",
"midnightcontrols.virtual_mouse.skin.default_light": "기본 라이트",
"midnightcontrols.virtual_mouse.skin.default_dark": "기본 다크",
"midnightcontrols.virtual_mouse.skin.second_light": "두 번째 라이트",
"midnightcontrols.virtual_mouse.skin.second_dark": "두 번째 다크",
"modmenu.descriptionTranslation.midnightcontrols": "컨트롤러 제어 및 전반적인 향상된 제어 기능을 추가합니다.\n안타깝게도 업데이트가 끊긴 LambdaControls의 Fork 버전입니다."
}

View File

@@ -98,7 +98,8 @@
"midnightcontrols.menu.reacharound.horizontal": "Alt Öne Blok Koyma",
"midnightcontrols.menu.reacharound.vertical": "En Alta Blok Koyma",
"midnightcontrols.menu.reload_controller_mappings": "Oyun Kolu Eşleştirmelerini Yenile",
"midnightcontrols.menu.rotation_speed": "Dönme Hızı",
"midnightcontrols.menu.rotation_speed": "Dönme Hızı (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "Dönme Hızı (Y)",
"midnightcontrols.menu.title": "midnightcontrols - Ayarlar",
"midnightcontrols.menu.title.controller": "Oyun Kolu Seçenekleri",
"midnightcontrols.menu.title.controller_controls": "Oyun Kolu Kontrolleri",
@@ -124,7 +125,8 @@
"midnightcontrols.tooltip.reacharound.horizontal": "Hızlı blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.§r.",
"midnightcontrols.tooltip.reacharound.vertical": "En alta blok koymayı etkinleştirir. §cBazı sunucular bunun hile olduğunu düşünebilir.§r.",
"midnightcontrols.tooltip.reload_controller_mappings": "Oyun kolu için eşleştirme dosyasını yeniler.",
"midnightcontrols.tooltip.rotation_speed": "Oyun kolu modunda olan kamera dönme hızı",
"midnightcontrols.tooltip.rotation_speed": "Oyun kolu modunda olan kamera dönme hızı (X)",
"midnightcontrols.tooltip.y_axis_rotation_speed": "Oyun kolu modunda olan kamera dönme hızı (Y)",
"midnightcontrols.tooltip.unfocused_input": "Oyun penceresinde değilken oyun kolu girişine izine verir.",
"midnightcontrols.tooltip.virtual_mouse": "Sanal fareyi etkinleştirir. Çift ekran oynanılacağı zaman işe yarar.",
"midnightcontrols.virtual_mouse.skin.default_light": "Varsayılan Aydınlık Tema",

View File

@@ -104,7 +104,8 @@
"midnightcontrols.menu.reacharound.vertical": "垂直方向方块放置辅助",
"midnightcontrols.menu.reload_controller_mappings": "重新加载手柄按键映射",
"midnightcontrols.menu.right_dead_zone": "右摇杆死区",
"midnightcontrols.menu.rotation_speed": "镜头旋转速度",
"midnightcontrols.menu.rotation_speed": "镜头旋转速度 (X)",
"midnightcontrols.menu.y_axis_rotation_speed": "镜头旋转速度 (Y)",
"midnightcontrols.menu.separator.controller": "手柄",
"midnightcontrols.menu.separator.general": "通用",
"midnightcontrols.menu.title": "midnightcontrols — 设置",
@@ -140,7 +141,8 @@
"midnightcontrols.tooltip.reacharound.vertical": "启用垂直方向方块放置辅助,可在脚下方块的下方放置方块。\n§c在部分服务器可能会被认定为作弊。",
"midnightcontrols.tooltip.reload_controller_mappings": "重新加载手柄的按键映射文件。",
"midnightcontrols.tooltip.right_dead_zone": "右摇杆配置的死区。\n死区决定摇杆要偏离中心位置多远才能让摇杆的输入有效。",
"midnightcontrols.tooltip.rotation_speed": "手柄操作模式下的镜头旋转速度。",
"midnightcontrols.tooltip.rotation_speed": "手柄操作模式下的镜头旋转速度。(X)",
"midnightcontrols.tooltip.y_axis_rotation_speed": "手柄操作模式下的镜头旋转速度。(Y)",
"midnightcontrols.tooltip.unfocused_input": "即使游戏窗口处于非活动状态,也允许手柄进行按键输入。",
"midnightcontrols.tooltip.virtual_mouse": "启用虚拟鼠标,在分屏的情况下很有用。",
"midnightcontrols.virtual_mouse.skin.default_light": "默认样式(白色)",

View File

@@ -16,7 +16,8 @@
"MinecraftClientMixin",
"MouseMixin",
"RecipeBookWidgetAccessor",
"WorldRendererMixin"
"WorldRendererMixin",
"KeyBindingRegistryImplAccessor"
],
"injectors": {
"defaultRequire": 1

View File

@@ -4,6 +4,7 @@
"plugin": "eu.midnightdust.midnightcontrols.client.compat.MidnightControlsMixinPlugin",
"compatibilityLevel": "JAVA_16",
"client": [
"SodiumOptionsGUIAccessor"
],
"injectors": {
"defaultRequire": 1

View File

@@ -1,6 +1,6 @@
{
"pack": {
"pack_format": 8,
"pack_format": 9,
"description": "Makes the controller buttons look like from Bedrock Edition"
}
}