Compare commits

..

15 Commits
1.4.1 ... 1.5.0

Author SHA1 Message Date
LambdAurora
deccb758ea Fix compilation crash. 2020-09-01 14:30:40 +02:00
LambdAurora
b7c60f8651 🔖 LambdaControls v1.5.0: Update to Minecraft 1.16.2. 2020-09-01 14:29:06 +02:00
LambdAurora
1ee75bc4e5 Fix issues, improve REI compat and horizontal reach-around, WIP on ring. 2020-08-25 16:06:38 +02:00
LambdAurora
1f0ddab36b Fix lot of bugs and update to 1.16.2. 2020-08-19 17:58:50 +02:00
LambdAurora
8a919934e2 Merge pull request #24 from joaoh1/1.16
👽 Fix compatibility with Ok Zoomer 4.0.0 betas
2020-08-14 17:47:08 +02:00
joaoh1
0178f5e684 👽 Fix compatibility with Ok Zoomer 4.0.0 betas 2020-08-14 12:40:45 -03:00
LambdAurora
c495e2ae0c Merge pull request #22 from FlashyReese/1.16
Add es_mx localization
2020-08-03 11:23:02 +02:00
Yao Chung Hu
3ecce09775 fix: use of words 2020-08-02 18:59:59 -05:00
Yao Chung Hu
e94d2eb240 new: added es_mx localization 2020-08-02 18:54:35 -05:00
LambdAurora
7571a2aa1b Merge pull request #21 from joaoh1/1.16
🚸 Hide Ok Zoomer's extra keybinds when disabled
2020-07-31 21:40:44 +02:00
joaoh1
d09a225518 🚸 Hide Ok Zoomer's extra keybinds when disabled 2020-07-31 15:55:43 -03:00
LambdAurora
4290d79bd0 Merge pull request #18 from Hambaka/1.16
🌐 Add Simplified Chinese localization.
2020-07-20 21:09:30 +02:00
Hambaka
f9f0a7a18d 🌐 Add Simplified Chinese localization. 2020-07-21 02:49:01 +08:00
LambdAurora
f889fc6367 Fix chording problem. 2020-07-20 19:22:18 +02:00
LambdAurora
7dcbda7e57 Update CHANGELOG. 2020-07-19 00:11:43 +02:00
54 changed files with 1448 additions and 261 deletions

View File

@@ -89,3 +89,24 @@ This update also has a backport 1.14.4 version ([#9](https://github.com/LambdAur
- Started to work on action ring.
- Will allow for better compability with other mods.
- Might be interesting for keyboard users too.
### v1.4.1
- Fixed crash with [REI](https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items).
## v1.5.0
- Added mappings string editor screen.
- Added Simplified Chinese translations ([#18](https://github.com/LambdAurora/LambdaControls/pull/18)).
- Added Mexican Spanish translations ([#22](https://github.com/LambdAurora/LambdaControls/pull/22)).
- Added Xbox 360 button skin and overhauled Xbox button skin.
- Added debug option.
- Respect toggle setting in Accessibility screen.
- Tweaked rotation speeds.
- Updated to Minecraft 1.16.2.
- Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to 1.6.4.
- Overhauled REI compatibility.
- Improved horizontal reach-around.
- Fixed crashes with Ok Zoomer.
- Fixed crashes with key unbinding.
- More WIP on keybind ring.

View File

@@ -7,7 +7,7 @@ archivesBaseName = project.archives_base_name + "-core"
dependencies {
api "org.jetbrains:annotations:17.0.0"
api "org.aperlambda:lambdajcommon:1.8.0"
api "org.aperlambda:lambdajcommon:1.8.1"
}
java {

View File

@@ -21,14 +21,14 @@ import java.util.Optional;
* Represents a feature.
*
* @author LambdAurora
* @version 1.3.2
* @version 1.5.0
* @since 1.1.0
*/
public class LambdaControlsFeature implements Nameable
{
private static final List<LambdaControlsFeature> FEATURES = new ArrayList<>();
public static final LambdaControlsFeature FAST_BLOCK_PLACING = new LambdaControlsFeature("fast_block_placing", true, true);
public static final LambdaControlsFeature FRONT_BLOCK_PLACING = new LambdaControlsFeature("front_block_placing", true, false);
public static final LambdaControlsFeature HORIZONTAL_REACHAROUND = new LambdaControlsFeature("horizontal_reacharound", true, false);
public static final LambdaControlsFeature VERTICAL_REACHAROUND = new LambdaControlsFeature("vertical_reacharound", true, false);
private final String key;
@@ -157,7 +157,7 @@ public class LambdaControlsFeature implements Nameable
static {
FEATURES.add(FAST_BLOCK_PLACING);
FEATURES.add(FRONT_BLOCK_PLACING);
FEATURES.add(HORIZONTAL_REACHAROUND);
FEATURES.add(VERTICAL_REACHAROUND);
}
}

View File

@@ -20,16 +20,6 @@ repositories {
repositories {
maven { url = "https://jitpack.io" }
}
// OkZoomer
ivy {
url 'https://github.com/joaoh1/OkZoomer/releases/download/'
patternLayout {
artifact '[revision]/[module]-[revision].[ext]'
}
metadataSources() {
artifact()
}
}
}
configurations {
@@ -41,7 +31,7 @@ configurations {
dependencies {
//to change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
@@ -52,12 +42,12 @@ dependencies {
include "com.github.lambdaurora:spruceui:${project.spruceui_version}"
// Compatibility mods
modImplementation "io.github.joaoh1:okzoomer:4.0.0-alpha.4.1.16.1"
modImplementation "me.shedaniel:RoughlyEnoughItems:4.5.5"
modImplementation "com.github.joaoh1:okzoomer:e13183c59b"
modImplementation "me.shedaniel:RoughlyEnoughItems:5.2.3"
api project(":core")
shadowInternal project(":core")
shadow("org.aperlambda:lambdajcommon:1.8.0") {
shadow("org.aperlambda:lambdajcommon:1.8.1") {
// Minecraft already has all that google crap.
exclude group: 'com.google.code.gson'
exclude group: 'com.google.guava'

View File

@@ -29,7 +29,7 @@ import java.util.Optional;
* Represents the LambdaControls mod.
*
* @author LambdAurora
* @version 1.3.0
* @version 1.5.0
* @since 1.0.0
*/
public class LambdaControls implements ModInitializer
@@ -56,7 +56,7 @@ public class LambdaControls implements ModInitializer
.ifPresent(controlsMode -> context.getTaskQueue()
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode)));
context.getTaskQueue().execute(() ->
ServerSidePacketRegistry.INSTANCE.sendToPlayer(context.getPlayer(), FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.FRONT_BLOCK_PLACING)));
ServerSidePacketRegistry.INSTANCE.sendToPlayer(context.getPlayer(), FEATURE_CHANNEL, this.makeFeatureBuffer(LambdaControlsFeature.HORIZONTAL_REACHAROUND)));
});
ServerSidePacketRegistry.INSTANCE.register(CONTROLS_MODE_CHANNEL,
(context, attachedData) -> ControlsMode.byId(attachedData.readString(32))

View File

@@ -9,6 +9,7 @@
package me.lambdaurora.lambdacontrols.client;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.Nameable;
@@ -21,7 +22,7 @@ import java.util.Optional;
* Represents a controller type.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.4.3
* @since 1.0.0
*/
public enum ControllerType implements Nameable
@@ -29,9 +30,10 @@ public enum ControllerType implements Nameable
DEFAULT(0),
DUALSHOCK(1),
SWITCH(2),
XBOX(3),
STEAM(4),
OUYA(5);
XBOX_360(3, new LiteralText("Xbox 360")),
XBOX(4),
STEAM(5),
OUYA(6);
private final int id;
private final Text text;
@@ -39,7 +41,13 @@ public enum ControllerType implements Nameable
ControllerType(int id)
{
this.id = id;
this.text = new TranslatableText(this.getTranslationKey());
this.text = new TranslatableText("lambdacontrols.controller_type." + this.getName());
}
ControllerType(int id, @NotNull Text text)
{
this.id = id;
this.text = text;
}
/**
@@ -65,16 +73,6 @@ public enum ControllerType implements Nameable
return v[this.ordinal() + 1];
}
/**
* Returns the translation key of this controller type.
*
* @return The translation key.
*/
public @NotNull String getTranslationKey()
{
return "lambdacontrols.controller_type." + this.getName();
}
/**
* Gets the translated text of this controller type.
*

View File

@@ -18,7 +18,10 @@ import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsHud;
import me.lambdaurora.lambdacontrols.client.gui.RingScreen;
import me.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay;
import me.lambdaurora.lambdacontrols.client.ring.KeyBindingRingAction;
import me.lambdaurora.lambdacontrols.client.ring.LambdaRing;
import me.lambdaurora.spruceui.event.OpenScreenCallback;
import me.lambdaurora.spruceui.hud.HudManager;
import net.fabricmc.api.ClientModInitializer;
@@ -35,11 +38,13 @@ import net.minecraft.util.Identifier;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
import java.io.File;
/**
* Represents the LambdaControls client mod.
*
* @author LambdAurora
* @version 1.3.2
* @version 1.5.0
* @since 1.1.0
*/
public class LambdaControlsClient extends LambdaControls implements ClientModInitializer
@@ -53,11 +58,15 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement");
public static final KeyBinding BINDING_LOOK_LEFT = InputManager.makeKeyBinding(new Identifier(LambdaControlsConstants.NAMESPACE, "look_left"),
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement");
/*public static final KeyBinding BINDING_RING = InputManager.makeKeyBinding(new Identifier(LambdaControlsConstants.NAMESPACE, "ring"),
InputUtil.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_5, "key.categories.misc");*/
public static final Identifier CONTROLLER_BUTTONS = new Identifier(LambdaControlsConstants.NAMESPACE, "textures/gui/controller_buttons.png");
public static final Identifier CONTROLLER_AXIS = new Identifier(LambdaControlsConstants.NAMESPACE, "textures/gui/controller_axis.png");
public static final Identifier CURSOR_TEXTURE = new Identifier(LambdaControlsConstants.NAMESPACE, "textures/gui/cursor.png");
public final static File MAPPINGS_FILE = new File("config/gamecontrollerdb.txt");
public final LambdaControlsConfig config = new LambdaControlsConfig(this);
public final LambdaInput input = new LambdaInput(this);
public final LambdaRing ring = new LambdaRing(this);
public final LambdaReacharound reacharound = new LambdaReacharound();
private LambdaControlsHud hud;
private ControlsMode previousControlsMode;
@@ -70,6 +79,9 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
KeyBindingHelper.registerKeyBinding(BINDING_LOOK_RIGHT);
KeyBindingHelper.registerKeyBinding(BINDING_LOOK_DOWN);
KeyBindingHelper.registerKeyBinding(BINDING_LOOK_LEFT);
//KeyBindingHelper.registerKeyBinding(BINDING_RING);
this.ring.registerAction("keybinding", KeyBindingRingAction.FACTORY);
ClientSidePacketRegistry.INSTANCE.register(CONTROLS_MODE_CHANNEL, (context, attachedData) -> context.getTaskQueue()
.execute(() -> ClientSidePacketRegistry.INSTANCE.sendToServer(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(this.config.getControlsMode()))));
@@ -131,6 +143,10 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
this.input.onTick(client);
if (this.config.getControlsMode() == ControlsMode.CONTROLLER && (client.isWindowFocused() || this.config.hasUnfocusedInput()))
this.input.onControllerTick(client);
/*if (BINDING_RING.wasPressed()) {
client.openScreen(new RingScreen());
}*/
}
public void onRender(MinecraftClient client)

View File

@@ -36,6 +36,7 @@ public class LambdaControlsConfig
// General
private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT;
private static final boolean DEFAULT_AUTO_SWITCH_MODE = false;
private static final boolean DEFAULT_DEBUG = false;
// HUD
private static final boolean DEFAULT_HUD_ENABLE = true;
private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT;
@@ -43,7 +44,7 @@ public class LambdaControlsConfig
private static final boolean DEFAULT_FAST_BLOCK_INTERACTION = true;
private static final boolean DEFAULT_FLY_DRIFTING = false;
private static final boolean DEFAULT_FLY_VERTICAL_DRIFTING = true;
private static final boolean DEFAULT_FRONT_BLOCK_PLACING = false;
private static final boolean DEFAULT_HORIZONTAL_REACHAROUND = false;
private static final boolean DEFAULT_VERTICAL_REACHAROUND = false;
private static final boolean DEFAULT_REACHAROUND_OUTLINE = true;
private static final int[] DEFAULT_REACHAROUND_OUTLINE_COLOR = new int[]{255, 255, 255, 102};
@@ -95,7 +96,7 @@ public class LambdaControlsConfig
this.hudSide = HudSide.byId(this.config.getOrElse("hud.side", DEFAULT_HUD_SIDE.getName())).orElse(DEFAULT_HUD_SIDE);
// Gameplay
LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(this.config.getOrElse("gameplay.fast_block_placing", DEFAULT_FAST_BLOCK_INTERACTION));
LambdaControlsFeature.FRONT_BLOCK_PLACING.setEnabled(this.config.getOrElse("gameplay.reacharound.horizontal", DEFAULT_FRONT_BLOCK_PLACING));
LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(this.config.getOrElse("gameplay.reacharound.horizontal", DEFAULT_HORIZONTAL_REACHAROUND));
LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(this.config.getOrElse("gameplay.reacharound.vertical", DEFAULT_VERTICAL_REACHAROUND));
this.shouldRenderReacharoundOutline = this.config.getOrElse("gameplay.reacharound.outline", DEFAULT_REACHAROUND_OUTLINE);
this.reacharoundOutlineColor = this.config.getOptional("gameplay.reacharound.outline_color").map(hex -> parseColor((String) hex)).orElse(DEFAULT_REACHAROUND_OUTLINE_COLOR);
@@ -109,6 +110,8 @@ public class LambdaControlsConfig
this.virtualMouseSkin = VirtualMouseSkin.byId(this.config.getOrElse("controller.virtual_mouse_skin", DEFAULT_VIRTUAL_MOUSE_SKIN.getName())).orElse(DEFAULT_VIRTUAL_MOUSE_SKIN);
// Controller controls.
InputManager.loadButtonBindings(this);
this.mod.ring.load(this.config);
}
/**
@@ -137,7 +140,7 @@ public class LambdaControlsConfig
});
if (this.config.contains("gameplay.front_block_placing.enabled")) {
this.setFrontBlockPlacing(this.config.getOrElse("gameplay.front_block_placing.enabled", DEFAULT_FRONT_BLOCK_PLACING));
this.setFrontBlockPlacing(this.config.getOrElse("gameplay.front_block_placing.enabled", DEFAULT_HORIZONTAL_REACHAROUND));
this.config.remove("gameplay.front_block_placing.enabled");
}
@@ -172,11 +175,12 @@ public class LambdaControlsConfig
// General
this.setControlsMode(DEFAULT_CONTROLS_MODE);
this.setAutoSwitchMode(DEFAULT_AUTO_SWITCH_MODE);
this.setDebug(DEFAULT_DEBUG);
// Gameplay
this.setFastBlockPlacing(DEFAULT_FAST_BLOCK_INTERACTION);
this.setFlyDrifting(DEFAULT_FLY_DRIFTING);
this.setFlyVerticalDrifting(DEFAULT_FLY_VERTICAL_DRIFTING);
this.setFrontBlockPlacing(DEFAULT_FRONT_BLOCK_PLACING);
this.setFrontBlockPlacing(DEFAULT_HORIZONTAL_REACHAROUND);
this.setVerticalReacharound(DEFAULT_VERTICAL_REACHAROUND);
this.setRenderReacharoundOutline(DEFAULT_REACHAROUND_OUTLINE);
// Controller
@@ -236,6 +240,26 @@ public class LambdaControlsConfig
this.config.set("auto_switch_mode", autoSwitchMode);
}
/**
* Returns whether the mod has debug enabled or not.
*
* @return True if debug is enabled, else false.
*/
public boolean hasDebug()
{
return this.config.getOrElse("debug", DEFAULT_DEBUG);
}
/**
* Sets whether the mod has debug enabled or not.
*
* @param debug True if debug is enabled, else false.
*/
protected void setDebug(boolean debug)
{
this.config.set("debug", debug);
}
/*
HUD settings
*/
@@ -354,7 +378,7 @@ public class LambdaControlsConfig
*/
public boolean hasFrontBlockPlacing()
{
return LambdaControlsFeature.FRONT_BLOCK_PLACING.isEnabled();
return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isEnabled();
}
/**
@@ -364,7 +388,7 @@ public class LambdaControlsConfig
*/
public void setFrontBlockPlacing(boolean enable)
{
LambdaControlsFeature.FRONT_BLOCK_PLACING.setEnabled(enable);
LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(enable);
this.config.set("gameplay.reacharound.horizontal", enable);
}

View File

@@ -32,7 +32,7 @@ import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.gui.screen.pack.ResourcePackScreen;
import net.minecraft.client.gui.screen.pack.PackScreen;
import net.minecraft.client.gui.screen.world.WorldListWidget;
import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
@@ -64,7 +64,7 @@ import static org.lwjgl.glfw.GLFW.*;
* Represents the LambdaControls' input handler.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.4.3
* @since 1.0.0
*/
public class LambdaInput
@@ -669,16 +669,16 @@ public class LambdaInput
double powValue = Math.pow(value, 2.0);
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
if (state == 2) {
this.targetPitch = -this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D;
this.targetPitch = -this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D;
} else if (state == 1) {
this.targetPitch = this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D;
this.targetPitch = this.config.getRightYAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D;
}
}
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
if (state == 2) {
this.targetYaw = -this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D;
this.targetYaw = -this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D;
} else if (state == 1) {
this.targetYaw = this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.33D;
this.targetYaw = this.config.getRightXAxisSign() * (this.config.getRotationSpeed() * powValue) * 0.11D;
}
}
}
@@ -700,7 +700,7 @@ public class LambdaInput
public static boolean isScreenInteractive(@NotNull Screen screen)
{
return !(screen instanceof AdvancementsScreen || screen instanceof HandledScreen || screen instanceof ResourcePackScreen || LambdaControlsCompat.requireMouseOnScreen(screen));
return !(screen instanceof AdvancementsScreen || screen instanceof HandledScreen || screen instanceof PackScreen || LambdaControlsCompat.requireMouseOnScreen(screen));
}
// Inspired from https://github.com/MrCrayfish/Controllable/blob/1.14.X/src/main/java/com/mrcrayfish/controllable/client/ControllerInput.java#L686.

View File

@@ -23,26 +23,27 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RayTraceContext;
import net.minecraft.world.RaycastContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Represents the reacharound API of LambdaControls.
* Represents the reach-around API of LambdaControls.
*
* @version 1.3.2
* @version 1.5.0
* @since 1.3.2
*/
public class LambdaReacharound
{
private BlockHitResult lastReacharoundResult = null;
private boolean lastReacharoundVertical = false;
private boolean onSlab = false;
public void tick(@NotNull MinecraftClient client)
{
this.lastReacharoundResult = this.tryVerticalReachAround(client);
if (this.lastReacharoundResult == null) {
this.lastReacharoundResult = this.tryFrontPlace(client);
this.lastReacharoundResult = this.tryHorizontalReachAround(client);
this.lastReacharoundVertical = false;
} else this.lastReacharoundVertical = true;
}
@@ -74,7 +75,7 @@ public class LambdaReacharound
*/
public boolean isReacharoundAvailable()
{
return LambdaControlsFeature.FRONT_BLOCK_PLACING.isAvailable() || LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable();
return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || LambdaControlsFeature.VERTICAL_REACHAROUND.isAvailable();
}
private float getPlayerRange(@NotNull MinecraftClient client)
@@ -83,10 +84,10 @@ public class LambdaReacharound
}
/**
* Returns a nullable block hit result if vertical reacharound is possible.
* Returns a nullable block hit result if vertical reach-around is possible.
*
* @param client The client instance.
* @return A block hit result if vertical reacharound is possible, else null.
* @return A block hit result if vertical reach-around is possible, else null.
*/
public @Nullable BlockHitResult tryVerticalReachAround(@NotNull MinecraftClient client)
{
@@ -101,7 +102,7 @@ public class LambdaReacharound
Vec3d rotationVec = client.player.getRotationVec(1.0F);
float range = getPlayerRange(client);
Vec3d rayVec = pos.add(rotationVec.x * range, rotationVec.y * range, rotationVec.z * range).add(0, 0.75, 0);
BlockHitResult result = client.world.rayTrace(new RayTraceContext(pos, rayVec, RayTraceContext.ShapeType.OUTLINE, RayTraceContext.FluidHandling.NONE, client.player));
BlockHitResult result = client.world.raycast(new RaycastContext(pos, rayVec, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, client.player));
if (result.getType() == HitResult.Type.BLOCK) {
BlockPos blockPos = result.getBlockPos().down();
@@ -116,19 +117,26 @@ public class LambdaReacharound
}
/**
* Returns a nullable block hit result if front placing is possible.
* Returns a nullable block hit result if horizontal reach-around is possible.
*
* @param client The client instance.
* @return A block hit result if front placing is possible.
* @return A block hit result if horizontal reach-around is possible.
*/
public @Nullable BlockHitResult tryFrontPlace(@NotNull MinecraftClient client)
public @Nullable BlockHitResult tryHorizontalReachAround(@NotNull MinecraftClient client)
{
if (!LambdaControlsFeature.FRONT_BLOCK_PLACING.isAvailable())
if (!LambdaControlsFeature.HORIZONTAL_REACHAROUND.isAvailable())
return null;
if (client.player != null && client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.MISS && client.player.isOnGround() && client.player.pitch > 35.0F) {
if (client.player.isRiding())
return null;
BlockPos playerPos = client.player.getBlockPos().down();
if (client.player.getY() - playerPos.getY() - 1.0 >= 0.25) {
playerPos = playerPos.up();
this.onSlab = true;
} else {
this.onSlab = false;
}
BlockPos targetPos = new BlockPos(client.crosshairTarget.getPos()).subtract(playerPos);
BlockPos vector = new BlockPos(MathHelper.clamp(targetPos.getX(), -1, 1), 0, MathHelper.clamp(targetPos.getZ(), -1, 1));
BlockPos blockPos = playerPos.add(vector);
@@ -148,17 +156,19 @@ public class LambdaReacharound
return null;
}
public static @NotNull BlockHitResult withSideForReacharound(@NotNull BlockHitResult result, @Nullable ItemStack stack)
public @NotNull BlockHitResult withSideForReacharound(@NotNull BlockHitResult result, @Nullable ItemStack stack)
{
if (stack == null || stack.isEmpty() || !(stack.getItem() instanceof BlockItem))
return result;
return withSideForReacharound(result, Block.getBlockFromItem(stack.getItem()));
}
public static @NotNull BlockHitResult withSideForReacharound(@NotNull BlockHitResult result, @NotNull Block block)
public @NotNull BlockHitResult withSideForReacharound(@NotNull BlockHitResult result, @NotNull Block block)
{
if (block instanceof SlabBlock)
result = result.withSide(Direction.DOWN);
if (block instanceof SlabBlock) {
if (this.onSlab) result = result.withSide(Direction.UP);
else result = result.withSide(Direction.DOWN);
}
return result;
}
}

View File

@@ -15,6 +15,7 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.screen.slot.Slot;
import net.minecraft.util.hit.BlockHitResult;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -22,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
* Represents a compatibility handler for a mod.
*
* @author LambdAurora
* @version 1.3.2
* @version 1.5.0
* @since 1.1.0
*/
public interface CompatHandler
@@ -45,6 +46,20 @@ public interface CompatHandler
return false;
}
/**
* Returns a slot at the specified location if possible.
*
* @param screen The screen.
* @param mouseX The mouse X-coordinate.
* @param mouseY The mouse Y-coordinate.
* @return A slot if present, else null.
* @since 1.5.0
*/
default @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY)
{
return null;
}
/**
* Returns whether the current slot is a creative slot or not.
*

View File

@@ -14,8 +14,10 @@ import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.screen.slot.Slot;
import net.minecraft.util.hit.BlockHitResult;
import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,7 +29,7 @@ import java.util.stream.Stream;
* Represents a compatibility handler.
*
* @author LambdAurora
* @version 1.3.2
* @version 1.5.0
* @since 1.1.0
*/
public class LambdaControlsCompat
@@ -88,6 +90,24 @@ public class LambdaControlsCompat
return HANDLERS.stream().anyMatch(handler -> handler.requireMouseOnScreen(screen));
}
/**
* Returns a slot at the specified location if possible.
*
* @param screen The screen.
* @param mouseX The mouse X-coordinate.
* @param mouseY The mouse Y-coordinate.
* @return A slot if present, else null.
*/
public static @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY)
{
for (CompatHandler handler : HANDLERS) {
Pair<Integer, Integer> slot = handler.getSlotAt(screen, mouseX, mouseY);
if (slot != null)
return slot;
}
return null;
}
/**
* Returns a custom translation key to make custom attack action strings on the HUD.
*

View File

@@ -9,6 +9,7 @@
package me.lambdaurora.lambdacontrols.client.compat;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
@@ -21,7 +22,7 @@ import java.util.Set;
* This plugin is only present for the conditional mixins.
*
* @author LambdAurora
* @version 1.2.0
* @version 1.5.0
* @since 1.2.0
*/
public class LambdaControlsMixinPlugin implements IMixinConfigPlugin
@@ -30,8 +31,15 @@ public class LambdaControlsMixinPlugin implements IMixinConfigPlugin
public LambdaControlsMixinPlugin()
{
this.conditionalMixins.put("me.lambdaurora.lambdacontrols.client.compat.mixin.RecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent());
this.conditionalMixins.put("me.lambdaurora.lambdacontrols.client.compat.mixin.VillagerRecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent());
this.putConditionalMixin("EntryListWidgetAccessor", LambdaControlsCompat.isReiPresent());
this.putConditionalMixin("EntryWidgetAccessor", LambdaControlsCompat.isReiPresent());
this.putConditionalMixin("RecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent());
this.putConditionalMixin("VillagerRecipeViewingScreenAccessor", LambdaControlsCompat.isReiPresent());
}
private void putConditionalMixin(@NotNull String path, boolean condition)
{
this.conditionalMixins.put("me.lambdaurora.lambdacontrols.client.compat.mixin." + path, condition);
}
@Override

View File

@@ -9,11 +9,9 @@
package me.lambdaurora.lambdacontrols.client.compat;
import io.github.joaoh1.okzoomer.client.OkZoomerClientMod;
import io.github.joaoh1.okzoomer.main.OkZoomerMod;
import io.github.joaoh1.okzoomer.client.keybinds.ZoomKeybinds;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import org.aperlambda.lambdacommon.Identifier;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
@@ -21,13 +19,11 @@ import org.lwjgl.glfw.GLFW;
* Represents a compatibility handler for OkZoomer.
*
* @author LambdAurora
* @version 1.3.0
* @version 1.4.3
* @since 1.1.0
*/
public class OkZoomerCompat implements CompatHandler
{
public static final String OKZOOMER_CLASS_PATH = "io.github.joaoh1.okzoomer.client.OkZoomerClientMod";
@Override
public void handle(@NotNull LambdaControlsClient mod)
{
@@ -36,28 +32,30 @@ public class OkZoomerCompat implements CompatHandler
.onlyInGame()
.cooldown(true)
.category(ButtonBinding.MISC_CATEGORY)
.linkKeybind(OkZoomerClientMod.zoomKeyBinding)
.linkKeybind(ZoomKeybinds.zoomKey)
.register();
new ButtonBinding.Builder("zoom.in")
if (ZoomKeybinds.areExtraKeybindsEnabled()) {
new ButtonBinding.Builder("zoom_in")
.buttons(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, ButtonBinding.axisAsButton(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true))
.onlyInGame()
.cooldown(true)
.category(ButtonBinding.MISC_CATEGORY)
.linkKeybind(OkZoomerClientMod.increaseZoomKeyBinding)
.linkKeybind(ZoomKeybinds.increaseZoomKey)
.register();
new ButtonBinding.Builder("zoom.out")
new ButtonBinding.Builder("zoom_out")
.buttons(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, ButtonBinding.axisAsButton(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true))
.onlyInGame()
.cooldown(true)
.category(ButtonBinding.MISC_CATEGORY)
.linkKeybind(OkZoomerClientMod.decreaseZoomKeyBinding)
.linkKeybind(ZoomKeybinds.decreaseZoomKey)
.register();
new ButtonBinding.Builder("zoom.reset")
new ButtonBinding.Builder("zoom_reset")
.onlyInGame()
.cooldown(true)
.category(ButtonBinding.MISC_CATEGORY)
.linkKeybind(OkZoomerClientMod.resetZoomKeyBinding)
.linkKeybind(ZoomKeybinds.resetZoomKey)
.register();
}
}
}

View File

@@ -11,24 +11,32 @@ package me.lambdaurora.lambdacontrols.client.compat;
import me.lambdaurora.lambdacontrols.client.ButtonState;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.compat.mixin.EntryListWidgetAccessor;
import me.lambdaurora.lambdacontrols.client.compat.mixin.EntryWidgetAccessor;
import me.lambdaurora.lambdacontrols.client.compat.mixin.RecipeViewingScreenAccessor;
import me.lambdaurora.lambdacontrols.client.compat.mixin.VillagerRecipeViewingScreenAccessor;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.InputHandlers;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.lambdacontrols.client.controller.PressAction;
import me.shedaniel.rei.api.REIHelper;
import me.shedaniel.rei.api.RecipeCategory;
import me.shedaniel.rei.api.*;
import me.shedaniel.rei.gui.ContainerScreenOverlay;
import me.shedaniel.rei.gui.PreRecipeViewingScreen;
import me.shedaniel.rei.gui.RecipeViewingScreen;
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
import me.shedaniel.rei.gui.widget.EntryListEntryWidget;
import me.shedaniel.rei.gui.widget.EntryListWidget;
import me.shedaniel.rei.gui.widget.EntryWidget;
import me.shedaniel.rei.gui.widget.WidgetWithBounds;
import me.shedaniel.rei.impl.ScreenHelper;
import me.shedaniel.rei.impl.widgets.ButtonWidget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.Identifier;
import org.aperlambda.lambdacommon.utils.LambdaReflection;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Optional;
@@ -39,67 +47,124 @@ import static org.lwjgl.glfw.GLFW.*;
* Represents a compatibility handler for REI.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.5.0
* @since 1.2.0
*/
public class ReiCompat implements CompatHandler
{
private static final Pair<Integer, Integer> INVALID_SLOT = new Pair<>(-1, -1);
private static EntryListWidget ENTRY_LIST_WIDGET;
@Override
public void handle(@NotNull LambdaControlsClient mod)
{
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "category_back"))
ButtonBinding.builder(new Identifier("rei", "category_back"))
.buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.filter((client, binding) -> isViewingScreen(client.currentScreen))
.action(handleTab(false))
.cooldown(true)
.build());
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "category_next"))
.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)
.build());
.register();
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "page_back"))
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)
.build());
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "page_next"))
.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)
.build());
.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.
InputManager.registerBinding(new ButtonBinding.Builder(new Identifier("rei", "show_usage"))
ButtonBinding.builder(new Identifier("rei", "show_usage"))
.buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.filter((client, binding) -> InputHandlers.inInventory(client, binding) || isViewingScreen(client.currentScreen))
.action((client, button, value, action) -> {
if (action != ButtonState.RELEASE)
return false;
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent())
return false;
double mouseX = client.mouse.getX();
double mouseY = client.mouse.getY();
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return false;
return widget.mouseClicked(mouseX, mouseY, GLFW_MOUSE_BUTTON_2);
})
.action(handleShowRecipeUsage(true))
.cooldown(true)
.build());
.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);
return isViewingScreen(screen) || screen instanceof PreRecipeViewingScreen;
}
@Override
public @Nullable Pair<Integer, Integer> getSlotAt(@NotNull Screen screen, int mouseX, int mouseY)
{
Optional<ContainerScreenOverlay> overlay = ScreenHelper.getOptionalOverlay();
if (overlay.isPresent() && overlay.get().isInside(mouseX, mouseY)) {
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return null;
Pair<Integer, Integer> slot = this.getSlotAt(widget, mouseX, mouseY, false);
if (slot != null && slot != INVALID_SLOT)
return slot;
} else if (isViewingScreen(screen)) {
for (Element element : screen.children()) {
Pair<Integer, Integer> slot = this.getSlotAt(element, mouseX, mouseY, true);
if (slot != null && slot != INVALID_SLOT)
return slot;
}
}
return null;
}
private @Nullable Pair<Integer, Integer> 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.entries().isEmpty())
return INVALID_SLOT;
return Pair.of(entry.getBounds().getX() + 1, entry.getBounds().getY() + 1);
}
} else if (element instanceof EntryListWidget) {
List<EntryListEntryWidget> entries = ((EntryListWidgetAccessor) element).getEntries();
for (EntryListEntryWidget entry : entries) {
Pair<Integer, Integer> slot = this.getSlotAt(entry, mouseX, mouseY, allowEmpty);
if (slot != null && slot != INVALID_SLOT)
return slot;
}
} else if (!(element instanceof ButtonWidget) && element instanceof WidgetWithBounds) {
for (Element child : ((WidgetWithBounds) element).children()) {
Pair<Integer, Integer> slot = this.getSlotAt(child, mouseX, mouseY, allowEmpty);
if (slot != null && slot != INVALID_SLOT)
return slot;
}
}
return null;
}
private static boolean isViewingScreen(Screen screen)
@@ -128,6 +193,76 @@ public class ReiCompat implements CompatHandler
return ENTRY_LIST_WIDGET;
}
private static @Nullable EntryStack 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 = ScreenHelper.getOptionalOverlay();
if (!overlay.isPresent())
return RecipeHelper.getInstance().getScreenFocusedStack(client.currentScreen);
EntryListWidget widget = getEntryListWidget();
if (widget == null)
return RecipeHelper.getInstance().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) -> {
@@ -175,16 +310,66 @@ public class ReiCompat implements CompatHandler
VillagerRecipeViewingScreenAccessor screen = (VillagerRecipeViewingScreenAccessor) client.currentScreen;
List<RecipeCategory<?>> categories = screen.getCategories();
int currentTab = screen.getSelectedCategoryIndex();
int nextTab = currentTab + (next ? 1 : -1);
if (nextTab < 0)
nextTab = categories.size() - 1;
else if (nextTab >= categories.size())
nextTab = 0;
screen.setSelectedCategoryIndex(nextTab);
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,31 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.compat.mixin;
import me.shedaniel.rei.gui.widget.EntryListEntryWidget;
import me.shedaniel.rei.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 = "entries")
List<EntryListEntryWidget> getEntries();
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.compat.mixin;
import me.shedaniel.rei.api.EntryStack;
import me.shedaniel.rei.gui.widget.EntryWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
/**
* 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 lambdacontrols_getCurrentEntry();
}

View File

@@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.gen.Accessor;
* Represents an accessor to REI's RecipeViewingScreen.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.5.0
* @since 1.2.0
*/
@Mixin(value = RecipeViewingScreen.class, remap = false)
@@ -29,4 +29,10 @@ public interface RecipeViewingScreenAccessor
@Accessor("categoryNext")
Button getCategoryNext();
@Accessor("recipeBack")
Button getRecipeBack();
@Accessor("recipeNext")
Button getRecipeNext();
}

View File

@@ -9,24 +9,30 @@
package me.lambdaurora.lambdacontrols.client.compat.mixin;
import me.shedaniel.clothconfig2.api.ScrollingContainer;
import me.shedaniel.rei.api.RecipeCategory;
import me.shedaniel.rei.api.RecipeDisplay;
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.util.List;
import java.util.Map;
/**
* Represents an accessor to REI's VillagerRecipeViewingScreen.
*
* @author LambdAurora
* @version 1.4.1
* @version 1.5.0
* @since 1.2.0
*/
@Mixin(VillagerRecipeViewingScreen.class)
public interface VillagerRecipeViewingScreenAccessor
{
@Accessor(value = "categoryMap", remap = false)
Map<RecipeCategory<?>, List<RecipeDisplay>> getCategoryMap();
@Accessor(value = "categories", remap = false)
List<RecipeCategory<?>> getCategories();
@@ -36,6 +42,15 @@ public interface VillagerRecipeViewingScreenAccessor
@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 lambdacontrols_init();
}

View File

@@ -32,7 +32,7 @@ import static org.lwjgl.glfw.GLFW.*;
* Represents a button binding.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.5.0
* @since 1.0.0
*/
public class ButtonBinding implements Nameable
@@ -46,43 +46,43 @@ public class ButtonBinding implements Nameable
public static final ButtonBinding ATTACK = new Builder("attack").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)).onlyInGame().register();
public static final ButtonBinding BACK = new Builder("back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false))
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding CHAT = new Builder("chat").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT).onlyInGame().cooldown(true).register();
public static final ButtonBinding DROP_ITEM = new Builder("drop_item").buttons(GLFW_GAMEPAD_BUTTON_B).onlyInGame().cooldown(true).register();
public static final ButtonBinding CHAT = new Builder("chat").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT).onlyInGame().cooldown().register();
public static final ButtonBinding DROP_ITEM = new Builder("drop_item").buttons(GLFW_GAMEPAD_BUTTON_B).onlyInGame().cooldown().register();
public static final ButtonBinding FORWARD = new Builder("forward").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true))
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding HOTBAR_LEFT = new Builder("hotbar_left").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.action(InputHandlers.handleHotbar(false)).onlyInGame().cooldown(true).register();
.action(InputHandlers.handleHotbar(false)).onlyInGame().cooldown().register();
public static final ButtonBinding HOTBAR_RIGHT = new Builder("hotbar_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.action(InputHandlers.handleHotbar(true)).onlyInGame().cooldown(true).register();
public static final ButtonBinding INVENTORY = new Builder("inventory").buttons(GLFW_GAMEPAD_BUTTON_Y).onlyInGame().cooldown(true).register();
.action(InputHandlers.handleHotbar(true)).onlyInGame().cooldown().register();
public static final ButtonBinding INVENTORY = new Builder("inventory").buttons(GLFW_GAMEPAD_BUTTON_Y).onlyInGame().cooldown().register();
public static final ButtonBinding JUMP = new Builder("jump").buttons(GLFW_GAMEPAD_BUTTON_A).onlyInGame().register();
public static final ButtonBinding LEFT = new Builder("left").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false))
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding PAUSE_GAME = new Builder("pause_game").buttons(GLFW_GAMEPAD_BUTTON_START).action(InputHandlers::handlePauseGame).cooldown(true).register();
public static final ButtonBinding PICK_BLOCK = new Builder("pick_block").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT).onlyInGame().cooldown(true).register();
public static final ButtonBinding PAUSE_GAME = new Builder("pause_game").buttons(GLFW_GAMEPAD_BUTTON_START).action(InputHandlers::handlePauseGame).cooldown().register();
public static final ButtonBinding PICK_BLOCK = new Builder("pick_block").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT).onlyInGame().cooldown().register();
public static final ButtonBinding PLAYER_LIST = new Builder("player_list").buttons(GLFW_GAMEPAD_BUTTON_BACK).onlyInGame().register();
public static final ButtonBinding RIGHT = new Builder("right").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true))
.action(MovementHandler.HANDLER).register();
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A)
.action(InputHandlers::handleScreenshot).cooldown(true).register();
.action(InputHandlers::handleScreenshot).cooldown().register();
public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
.action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown(true).register();
.action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)
.action(InputHandlers.handleInventorySlotPad(3)).onlyInInventory().cooldown(true).register();
.action(InputHandlers.handleInventorySlotPad(3)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_RIGHT = new Builder("slot_right").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)
.action(InputHandlers.handleInventorySlotPad(2)).onlyInInventory().cooldown(true).register();
.action(InputHandlers.handleInventorySlotPad(2)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_UP = new Builder("slot_up").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP)
.action(InputHandlers.handleInventorySlotPad(0)).onlyInInventory().cooldown(true).register();
public static final ButtonBinding SMOOTH_CAMERA = new Builder("toggle_smooth_camera").cooldown(true).register();
.action(InputHandlers.handleInventorySlotPad(0)).onlyInInventory().cooldown().register();
public static final ButtonBinding SMOOTH_CAMERA = new Builder("toggle_smooth_camera").onlyInGame().cooldown().register();
public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.actions(PressAction.DEFAULT_ACTION, InputHandlers::handleToggleSneak).onlyInGame().cooldown(true).register();
public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).register();
public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).cooldown(true).register();
.actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register();
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(true).register();
.action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).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(true).register();
public static final ButtonBinding TOGGLE_PERSPECTIVE = new Builder("toggle_perspective").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_Y).cooldown(true).register();
.action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register();
public static final ButtonBinding TOGGLE_PERSPECTIVE = new Builder("toggle_perspective").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_Y).cooldown().register();
public static final ButtonBinding USE = new Builder("use").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)).register();
private int[] button;
@@ -267,12 +267,19 @@ public class ButtonBinding implements Nameable
*
* @return The key binding equivalent.
*/
public @NotNull
Optional<KeyBinding> asKeyBinding()
public @NotNull Optional<KeyBinding> asKeyBinding()
{
return Optional.ofNullable(this.mcKeyBinding);
}
@Override
public String toString()
{
return "ButtonBinding{id=\"" + this.key + "\","
+ "hasCooldown=" + this.hasCooldown
+ "}";
}
/**
* Returns the specified axis as a button.
*
@@ -426,11 +433,36 @@ public class ButtonBinding implements Nameable
));
}
/**
* Returns a builder instance.
*
* @param identifier The identifier of the button binding.
* @return The builder instance
* @since 1.5.0
*/
public static Builder builder(@NotNull Identifier identifier)
{
return new Builder(identifier);
}
/**
* Returns a builder instance.
*
* @param identifier The identifier of the button binding.
* @return The builder instance.
* @since 1.5.0
*/
public static Builder builder(@NotNull net.minecraft.util.Identifier identifier)
{
return new Builder(identifier);
}
/**
* Represents a quick {@link ButtonBinding} builder.
*
* @author LambdAurora
* @version 1.1.0
* @version 1.5.0
* @since 1.1.0
*/
public static class Builder
@@ -558,6 +590,17 @@ public class ButtonBinding implements Nameable
return this;
}
/**
* Puts a cooldown on the {@link ButtonBinding}.
*
* @return The builder instance.
* @since 1.5.0
*/
public Builder cooldown()
{
return this.cooldown(true);
}
/**
* Sets the category of the {@link ButtonBinding}.
*

View File

@@ -9,13 +9,20 @@
package me.lambdaurora.lambdacontrols.client.controller;
import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.Nameable;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWGamepadState;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import java.io.File;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
@@ -34,7 +41,7 @@ import static org.lwjgl.BufferUtils.createByteBuffer;
* Represents a controller.
*
* @author LambdAurora
* @version 1.0.0
* @version 1.4.3
* @since 1.0.0
*/
public class Controller implements Nameable
@@ -167,14 +174,47 @@ public class Controller implements Nameable
public static void updateMappings()
{
try {
File mappingsFile = new File("config/gamecontrollerdb.txt");
if (!mappingsFile.exists())
if (!LambdaControlsClient.MAPPINGS_FILE.exists())
return;
LambdaControlsClient.get().log("Updating controller mappings...");
ByteBuffer buffer = ioResourceToBuffer(mappingsFile.getPath(), 1024);
ByteBuffer buffer = ioResourceToBuffer(LambdaControlsClient.MAPPINGS_FILE.getPath(), 1024);
GLFW.glfwUpdateGamepadMappings(buffer);
} catch (IOException e) {
e.printStackTrace();
}
MemoryStack memoryStack = MemoryStack.stackPush();
try {
PointerBuffer pointerBuffer = memoryStack.mallocPointer(1);
int i = GLFW.glfwGetError(pointerBuffer);
if (i != 0) {
long l = pointerBuffer.get();
String string = l == 0L ? "" : MemoryUtil.memUTF8(l);
MinecraftClient client = MinecraftClient.getInstance();
if (client != null) {
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT,
new TranslatableText("lambdacontrols.controller.mappings.error"), new LiteralText(string)));
}
}
} catch (Throwable e) {
/* Ignored :concern: */
} finally {
memoryStack.close();
}
if (LambdaControlsClient.get().config.hasDebug()) {
for (int i = GLFW.GLFW_JOYSTICK_1; i <= GLFW.GLFW_JOYSTICK_16; i++) {
Controller controller = byId(i);
if (!controller.isConnected())
continue;
LambdaControls.get().log(String.format("Controller #%d name: \"%s\"\n GUID: %s\n Gamepad: %s",
controller.id,
controller.getName(),
controller.getGuid(),
controller.isGamepad()));
}
}
}
}

View File

@@ -23,6 +23,7 @@ import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget;
import net.minecraft.client.options.Option;
import net.minecraft.client.util.ScreenshotUtils;
import net.minecraft.item.ItemGroup;
import net.minecraft.screen.slot.Slot;
@@ -39,7 +40,7 @@ import java.util.stream.Collectors;
* Represents some input handlers.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.4.3
* @since 1.1.0
*/
public class InputHandlers
@@ -142,12 +143,16 @@ public class InputHandlers
public static boolean handleToggleSneak(@NotNull MinecraftClient client, @NotNull ButtonBinding button, float value, @NotNull ButtonState action)
{
if (client.player != null && !client.player.abilities.flying) {
button.asKeyBinding().filter(binding -> action == ButtonState.PRESS).ifPresent(binding -> ((KeyBindingAccessor) binding).lambdacontrols_handlePressState(!binding.isPressed()));
button.asKeyBinding().ifPresent(binding -> {
boolean sneakToggled = client.options.sneakToggled;
if (client.player.abilities.flying && sneakToggled)
client.options.sneakToggled = false;
binding.setPressed(button.pressed);
if (client.player.abilities.flying && sneakToggled)
client.options.sneakToggled = true;
});
return true;
}
return false;
}
public static PressAction handleInventorySlotPad(int direction)
{

View File

@@ -345,6 +345,11 @@ public class InputManager
else
state = ButtonState.NONE;
}
if (state == ButtonState.RELEASE && !binding.pressed) {
state = ButtonState.NONE;
}
binding.pressed = state.isPressed();
binding.update();
if (binding.pressed)

View File

@@ -12,13 +12,14 @@ package me.lambdaurora.lambdacontrols.client.controller;
import me.lambdaurora.lambdacontrols.client.ButtonState;
import me.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.options.StickyKeyBinding;
import org.jetbrains.annotations.NotNull;
/**
* Represents a press action callback.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.4.3
* @since 1.0.0
*/
@FunctionalInterface
@@ -27,7 +28,12 @@ public interface PressAction
PressAction DEFAULT_ACTION = (client, button, value, action) -> {
if (action == ButtonState.REPEAT || client.currentScreen != null)
return false;
button.asKeyBinding().ifPresent(binding -> ((KeyBindingAccessor) binding).lambdacontrols_handlePressState(button.isButtonDown()));
button.asKeyBinding().ifPresent(binding -> {
if (binding instanceof StickyKeyBinding)
binding.setPressed(button.pressed);
else
((KeyBindingAccessor) binding).lambdacontrols_handlePressState(button.isButtonDown());
});
return true;
};

View File

@@ -14,6 +14,7 @@ import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.spruceui.SpruceButtonWidget;
import me.lambdaurora.spruceui.SpruceTexts;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
@@ -24,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents the controls screen.
@@ -67,8 +69,8 @@ public class ControllerControlsScreen extends Screen
this.bindingsListWidget = new ControlsListWidget(this, this.client);
this.children.add(this.bindingsListWidget);
this.resetButton = this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 150, 20,
new TranslatableText("controls.resetAll"),
btn -> InputManager.streamBindings().forEach(binding -> this.mod.config.setButtonBinding(binding, binding.getDefaultButton()))));
SpruceTexts.CONTROLS_RESET_ALL,
btn -> InputManager.streamBindings().collect(Collectors.toSet()).forEach(binding -> this.mod.config.setButtonBinding(binding, binding.getDefaultButton()))));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20,
SpruceTexts.GUI_DONE,
btn -> this.client.openScreen(this.parent)));
@@ -79,7 +81,7 @@ public class ControllerControlsScreen extends Screen
{
this.renderBackground(matrices);
this.bindingsListWidget.render(matrices, mouseX, mouseY, delta);
this.drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 8, 16777215);
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 8, 16777215);
this.resetButton.active = InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault));
super.render(matrices, mouseX, mouseY, delta);
}

View File

@@ -38,7 +38,7 @@ import java.util.List;
*/
public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Entry>
{
private static final int[] UNBOUND = new int[0];
private static final int[] UNBOUND = new int[]{-1};
private final ControllerControlsScreen gui;
private int field_2733;

View File

@@ -12,6 +12,7 @@ package me.lambdaurora.lambdacontrols.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.LambdaInput;
import me.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
import net.minecraft.client.MinecraftClient;
@@ -29,7 +30,7 @@ import org.lwjgl.glfw.GLFW;
* Represents the LambdaControls renderer.
*
* @author LambdAurora
* @version 1.3.2
* @version 1.5.0
* @since 1.2.0
*/
public class LambdaControlsRenderer
@@ -251,6 +252,16 @@ public class LambdaControlsRenderer
}
}
if (!hoverSlot) {
Pair<Integer, Integer> slot = LambdaControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY);
if (slot != null) {
mouseX = slot.getFirst();
mouseY = slot.getSecond();
hoverSlot = true;
}
}
if (!hoverSlot) {
mouseX -= 8;
mouseY -= 8;

View File

@@ -20,6 +20,7 @@ import me.lambdaurora.spruceui.Tooltip;
import me.lambdaurora.spruceui.option.*;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
import net.minecraft.client.gui.widget.ButtonListWidget;
@@ -247,6 +248,7 @@ public class LambdaControlsSettingsScreen extends Screen
this.list.addOptionEntry(this.frontBlockPlacingOption, this.verticalReacharoundOption);
this.list.addSingleOptionEntry(this.flyDriftingOption);
this.list.addSingleOptionEntry(this.flyVerticalDriftingOption);
this.list.addOptionEntry(Option.SNEAK_TOGGLED, Option.SPRINT_TOGGLED);
// Controller options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.controller", true, null));
this.list.addSingleOptionEntry(this.controllerOption);
@@ -256,6 +258,8 @@ public class LambdaControlsSettingsScreen extends Screen
this.list.addOptionEntry(this.unfocusedInputOption, this.virtualMouseOption);
this.list.addSingleOptionEntry(this.virtualMouseSkinOption);
this.list.addSingleOptionEntry(new ReloadControllerMappingsOption());
this.list.addSingleOptionEntry(new SpruceSimpleActionOption("lambdacontrols.menu.mappings.open_input_str",
btn -> this.client.openScreen(new MappingsStringInputScreen(this))));
// HUD options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null));
this.list.addOptionEntry(this.hudEnableOption, this.hudSideOption);
@@ -268,7 +272,7 @@ public class LambdaControlsSettingsScreen extends Screen
this.addButton(this.resetOption.createButton(this.client.options, this.width / 2 - 155, this.height - 29, 150));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, buttonHeight, SpruceTexts.GUI_DONE,
(buttonWidget) -> this.client.openScreen(this.parent)));
btn -> this.client.openScreen(this.parent)));
}
@Override
@@ -277,10 +281,10 @@ public class LambdaControlsSettingsScreen extends Screen
this.renderBackground(matrices);
this.list.render(matrices, mouseX, mouseY, delta);
super.render(matrices, mouseX, mouseY, delta);
this.drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215);
this.drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.controller.mappings.1", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight) * 3, 10526880);
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215);
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.controller.mappings.1", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight) * 3, 10526880);
this.gamepadToolUrlLabel.render(matrices, mouseX, mouseY, delta);
this.drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight), 10526880);
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight), 10526880);
Tooltip.renderAll(matrices);
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.SpruceTextAreaWidget;
import me.lambdaurora.spruceui.SpruceTexts;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.options.Option;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import org.jetbrains.annotations.Nullable;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
/**
* Represents the controller mappings file editor screen.
*
* @author LambdAurora
* @version 1.4.3
* @since 1.4.3
*/
public class MappingsStringInputScreen extends Screen
{
private final Screen parent;
private final Option reloadMappingsOption;
private String mappings;
private SpruceTextAreaWidget textArea;
protected MappingsStringInputScreen(@Nullable Screen parent)
{
super(new TranslatableText("lambdacontrols.menu.title.mappings.string"));
this.parent = parent;
this.reloadMappingsOption = new ReloadControllerMappingsOption(btn -> {
this.writeMappings();
});
}
@Override
public void removed()
{
this.writeMappings();
Controller.updateMappings();
super.removed();
}
@Override
public void onClose()
{
this.removed();
super.onClose();
}
public void writeMappings()
{
if (this.textArea != null) {
this.mappings = this.textArea.getText();
System.out.println(this.mappings);
try {
FileWriter fw = new FileWriter(LambdaControlsClient.MAPPINGS_FILE, false);
fw.write(this.mappings);
fw.close();
} catch (IOException e) {
if (this.client != null)
this.client.getToastManager().add(SystemToast.create(this.client, SystemToast.Type.TUTORIAL_HINT,
new TranslatableText("lambdacontrols.controller.mappings.error.write"), LiteralText.EMPTY));
e.printStackTrace();
}
}
}
@Override
protected void init()
{
super.init();
if (this.textArea != null) {
this.mappings = this.textArea.getText();
}
String mappings = "";
if (this.mappings != null)
mappings = this.mappings;
else if (LambdaControlsClient.MAPPINGS_FILE.exists()) {
try {
mappings = String.join("\n", Files.readAllLines(LambdaControlsClient.MAPPINGS_FILE.toPath()));
this.mappings = mappings;
} catch (IOException e) {
/* Ignored */
}
}
int textFieldWidth = (int) (this.width * (3.0 / 4.0));
this.textArea = new SpruceTextAreaWidget(this.textRenderer, this.width / 2 - textFieldWidth / 2, 50, textFieldWidth, this.height - 100, new LiteralText(mappings));
this.textArea.setText(mappings);
// Display as many lines as possible
this.textArea.setDisplayedLines(this.textArea.getInnerHeight() / this.textRenderer.fontHeight);
this.addButton(this.textArea);
this.addButton(this.reloadMappingsOption.createButton(this.client.options, this.width / 2 - 155, this.height - 29, 150));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
(buttonWidget) -> this.client.openScreen(this.parent)));
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta)
{
this.renderBackground(matrices);
super.render(matrices, mouseX, mouseY, delta);
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 8, 16777215);
}
}

View File

@@ -10,46 +10,39 @@
package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.SpruceButtonWidget;
import me.lambdaurora.spruceui.option.SpruceSimpleActionOption;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.options.GameOptions;
import net.minecraft.client.options.Option;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.Nameable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
/**
* Represents the option to reload the controller mappings.
*/
public class ReloadControllerMappingsOption extends Option implements Nameable
public class ReloadControllerMappingsOption extends SpruceSimpleActionOption
{
private static final String KEY = "lambdacontrols.menu.reload_controller_mappings";
public ReloadControllerMappingsOption()
{
super(KEY);
this(null);
}
@Override
public AbstractButtonWidget createButton(GameOptions options, int x, int y, int width)
public ReloadControllerMappingsOption(@Nullable Consumer<AbstractButtonWidget> before)
{
SpruceButtonWidget button = new SpruceButtonWidget(x, y, width, 20, new TranslatableText(KEY), btn -> {
super(KEY, btn -> {
MinecraftClient client = MinecraftClient.getInstance();
if (before != null)
before.accept(btn);
Controller.updateMappings();
if (client.currentScreen != null)
if (client.currentScreen instanceof LambdaControlsSettingsScreen)
client.currentScreen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.mappings.updated"), null));
});
button.setTooltip(new TranslatableText("lambdacontrols.tooltip.reload_controller_mappings"));
return button;
}
@Override
public @NotNull String getName()
{
return I18n.translate(KEY);
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT,
new TranslatableText("lambdacontrols.controller.mappings.updated"), LiteralText.EMPTY));
}, new TranslatableText("lambdacontrols.tooltip.reload_controller_mappings"));
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.ring.RingPage;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText;
/**
* Represents the controls ring screen.
*
* @author LambdAurora
* @version 1.4.3
* @since 1.4.3
*/
public class RingScreen extends Screen
{
protected final LambdaControlsClient mod;
public RingScreen()
{
super(new TranslatableText("lambdacontrols.menu.title.ring"));
this.mod = LambdaControlsClient.get();
}
@Override
public boolean isPauseScreen()
{
return false;
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta)
{
super.render(matrices, mouseX, mouseY, delta);
RingPage page = this.mod.ring.getCurrentPage();
page.render(matrices, this.textRenderer, this.width, this.height, mouseX, mouseY, delta);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button)
{
/*if (LambdaControlsClient.BINDING_RING.matchesMouse(button)) {
this.onClose();
return true;
}*/
return false;
}
}

View File

@@ -106,7 +106,7 @@ public abstract class MinecraftClientMixin
}
// Removed front placing sprinting as way too cheaty.
/* else if (this.player.isSprinting()) {
hitResult = this.lambdacontrols_frontBlockPlaceResult;
hitResult = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
if (hitResult != null) {
if (cooldown > 0)
this.itemUseCooldown = 0;
@@ -136,15 +136,16 @@ public abstract class MinecraftClientMixin
@Inject(method = "doItemUse()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"), locals = LocalCapture.CAPTURE_FAILEXCEPTION, cancellable = true)
private void onItemUse(CallbackInfo ci, Hand[] hands, int handCount, int handIndex, Hand hand, ItemStack stackInHand)
{
if (!stackInHand.isEmpty() && this.player.pitch > 35.0F && LambdaControlsClient.get().reacharound.isReacharoundAvailable()) {
LambdaControlsClient mod = LambdaControlsClient.get();
if (!stackInHand.isEmpty() && this.player.pitch > 35.0F && mod.reacharound.isReacharoundAvailable()) {
if (this.crosshairTarget != null && this.crosshairTarget.getType() == HitResult.Type.MISS && this.player.isOnGround()) {
if (!stackInHand.isEmpty() && stackInHand.getItem() instanceof BlockItem) {
BlockHitResult hitResult = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
BlockHitResult hitResult = mod.reacharound.getLastReacharoundResult();
if (hitResult == null)
return;
hitResult = LambdaReacharound.withSideForReacharound(hitResult, stackInHand);
hitResult = mod.reacharound.withSideForReacharound(hitResult, stackInHand);
int previousStackCount = stackInHand.getCount();
ActionResult result = this.interactionManager.interactBlock(this.player, this.world, hand, hitResult);

View File

@@ -40,7 +40,7 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
/**
* Represents a mixin to WorldRenderer.
* <p>
* Handles the rendering of the block outline of the front block placing.
* Handles the rendering of the block outline of the reach-around features.
*/
@Mixin(WorldRenderer.class)
public abstract class WorldRendererMixin
@@ -84,8 +84,10 @@ public abstract class WorldRendererMixin
if (stack == null || !(stack.getItem() instanceof BlockItem))
return;
LambdaControlsClient mod = LambdaControlsClient.get();
Block block = ((BlockItem) stack.getItem()).getBlock();
result = LambdaReacharound.withSideForReacharound(result, block);
result = mod.reacharound.withSideForReacharound(result, block);
ItemPlacementContext context = new ItemPlacementContext(new ItemUsageContext(this.client.player, Hand.MAIN_HAND, result));
BlockState placementState = block.getPlacementState(context);
@@ -94,7 +96,7 @@ public abstract class WorldRendererMixin
Vec3d pos = camera.getPos();
VoxelShape outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity()));
int[] color = LambdaControlsClient.get().config.getReacharoundOutlineColor();
int[] color = mod.config.getReacharoundOutlineColor();
VertexConsumer vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
drawShapeOutline(matrices, vertexConsumer, outlineShape,

View File

@@ -0,0 +1,41 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.util.math.MatrixStack;
import org.jetbrains.annotations.NotNull;
public class DummyRingAction extends RingAction
{
public DummyRingAction(@NotNull Config config)
{
super(config);
}
@Override
public @NotNull String getName()
{
return "dummy";
}
@Override
public void onAction(@NotNull RingButtonMode mode)
{
}
@Override
public void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered)
{
drawCenteredString(matrices, textRenderer, this.getName(), x + 25, y + 25 - textRenderer.fontHeight / 2, 0xffffff);
}
}

View File

@@ -9,16 +9,26 @@
package me.lambdaurora.lambdacontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import me.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier;
public class KeyBindingRingAction extends RingAction
{
public static final Factory FACTORY = new Factory();
public final KeyBinding binding;
public KeyBindingRingAction(@NotNull KeyBinding binding)
public KeyBindingRingAction(@NotNull Config config, @NotNull KeyBinding binding)
{
super(config);
this.binding = binding;
}
@@ -43,4 +53,25 @@ public class KeyBindingRingAction extends RingAction
break;
}
}
@Override
public void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered)
{
drawCenteredText(matrices, textRenderer, new TranslatableText(this.getName()), x + 25, y + 25 - textRenderer.fontHeight / 2, 0xffffff);
}
protected static class Factory implements RingAction.Factory
{
@Override
public @NotNull Supplier<RingAction> newFromGui(@NotNull Screen screen)
{
return () -> null;
}
@Override
public @Nullable RingAction parse(@NotNull Config config)
{
return null;
}
}
}

View File

@@ -9,26 +9,65 @@
package me.lambdaurora.lambdacontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.IntStream;
/**
* Represents a key binding ring.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.5.0
* @since 1.4.0
*/
public class LambdaRing
public final class LambdaRing
{
private final List<RingPage> pages = new ArrayList<>(Collections.singletonList(new RingPage()));
public static final int ELEMENT_SIZE = 50;
private final Object2ObjectMap<String, RingAction.Factory> actionFactories = new Object2ObjectOpenHashMap<>();
private final List<RingPage> pages = new ArrayList<>(Collections.singletonList(RingPage.DEFAULT));
private final LambdaControlsClient mod;
private int currentPage = 0;
public LambdaRing()
public LambdaRing(@NotNull LambdaControlsClient mod)
{
this.mod = mod;
}
public void registerAction(@NotNull String name, @NotNull RingAction.Factory factory)
{
if (this.actionFactories.containsKey(name)) {
this.mod.warn("Tried to register twice a ring action: \"" + name + "\".");
return;
}
this.actionFactories.put(name, factory);
}
/**
* Loads the ring from configuration.
*
* @param config The configuration.
*/
public void load(@NotNull Config config)
{
List<Config> configPages = config.get("ring.pages");
if (configPages != null) {
this.pages.clear();
for (Config configPage : configPages) {
RingPage.parseRingPage(configPage).ifPresent(this.pages::add);
}
}
if (this.pages.isEmpty()) {
this.pages.add(RingPage.DEFAULT);
}
}
public @NotNull RingPage getCurrentPage()

View File

@@ -9,27 +9,42 @@
package me.lambdaurora.lambdacontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.Nameable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier;
/**
* Represents a ring action.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.5.0
* @since 1.4.0
*/
public abstract class RingAction implements Nameable
public abstract class RingAction extends DrawableHelper implements Nameable
{
protected Config config;
protected boolean activated = false;
public RingAction(@NotNull Config config)
{
this.config = config;
}
/**
* Gets the translated name of the ring action.
* Gets the text name of the ring action.
*
* @return The translated name.
* @return The text name.
*/
public TranslatableText getTranslatedName()
public Text getTextName()
{
return new TranslatableText(this.getName());
}
@@ -52,4 +67,25 @@ public abstract class RingAction implements Nameable
}
public abstract void onAction(@NotNull RingButtonMode mode);
public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered)
{
fill(matrices, x, y, x + LambdaRing.ELEMENT_SIZE, y + LambdaRing.ELEMENT_SIZE, hovered ? 0xbb777777 : 0xbb000000);
drawIcon(matrices, textRenderer, x, y, hovered);
}
public abstract void drawIcon(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int x, int y, boolean hovered);
/**
* Represents a factory for {@link RingAction}.
*
* @version 1.4.3
* @since 1.4.3
*/
public interface Factory
{
@NotNull Supplier<RingAction> newFromGui(@NotNull Screen screen);
@Nullable RingAction parse(@NotNull Config config);
}
}

View File

@@ -9,16 +9,102 @@
package me.lambdaurora.lambdacontrols.client.ring;
import com.electronwill.nightconfig.core.Config;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.util.math.MatrixStack;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Optional;
/**
* Represents a ring page.
*
* @author LambdAurora
* @version 1.4.0
* @version 1.5.0
* @since 1.4.0
*/
public class RingPage
public class RingPage extends DrawableHelper
{
public static final RingPage DEFAULT = new RingPage("Default");
public final String name;
private RingAction[] actions = new RingAction[8];
public RingPage(@NotNull String name)
{
this.name = name;
for (int i = 0; i < 8; i++) {
this.actions[i] = null;
}
}
/**
* Renders the ring page.
*
* @param matrices The matrices.
* @param width The screen width.
* @param height The screen height.
* @param mouseX The mouse X-coordinate.
* @param mouseY The mouse Y-coordinate.
* @param tickDelta The tick delta.
*/
public void render(@NotNull MatrixStack matrices, @NotNull TextRenderer textRenderer, int width, int height, int mouseX, int mouseY, float tickDelta)
{
int centerX = width / 2;
int centerY = height / 2;
int offset = LambdaRing.ELEMENT_SIZE + (LambdaRing.ELEMENT_SIZE / 2) + 5;
int y = centerY - offset;
int x = centerX - offset;
for (int i = 0; i < 3; i++) {
RingAction ringAction = this.actions[i];
if (ringAction != null)
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
x += 55;
}
y += 55;
x = centerX - offset;
for (int i = 3; i < 5; i++) {
RingAction ringAction = this.actions[i];
if (ringAction != null)
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
x += 55 * 2;
}
y += 55;
x = centerX - offset;
for (int i = 5; i < 8; i++) {
RingAction ringAction = this.actions[i];
if (ringAction != null)
ringAction.render(matrices, textRenderer, x, y, isHovered(x, y, mouseX, mouseY));
x += 55;
}
}
private static boolean isHovered(int x, int y, int mouseX, int mouseY)
{
return mouseX >= x && mouseY >= y && mouseX <= x + LambdaRing.ELEMENT_SIZE && mouseY <= y + LambdaRing.ELEMENT_SIZE;
}
/**
* Tries to parse a ring page configuration.
*
* @param config The configuration.
* @return An optional ring page.
*/
public static @NotNull Optional<RingPage> parseRingPage(@NotNull Config config)
{
String name = config.get("name");
if (name == null)
return Optional.empty();
RingPage page = new RingPage(name);
List<Config> actionConfigs = config.get("actions");
return Optional.of(page);
}
}

View File

@@ -3,6 +3,7 @@
"key.lambdacontrols.look_left": "Look left",
"key.lambdacontrols.look_right": "Look right",
"key.lambdacontrols.look_up": "Look up",
"key.lambdacontrols.ring": "Show controls ring",
"lambdacontrols.action.attack": "Attack",
"lambdacontrols.action.back": "Back",
"lambdacontrols.action.chat": "Open Chat",
@@ -64,6 +65,8 @@
"lambdacontrols.controller.disconnected": "Controller %d disconnected.",
"lambdacontrols.controller.mappings.1": "To configure the controller mappings, please use %sSDL2 Gamepad Tool%s",
"lambdacontrols.controller.mappings.3": "and put the mapping in `%s.minecraft/config/gamecontrollerdb.txt%s`.",
"lambdacontrols.controller.mappings.error": "Error while loading mappings.",
"lambdacontrols.controller.mappings.error.write": "Error while writing mappings to file.",
"lambdacontrols.controller.mappings.updated": "Updated mappings!",
"lambdacontrols.controller_type.default": "default",
"lambdacontrols.controller_type.dualshock": "DualShock",
@@ -90,6 +93,7 @@
"lambdacontrols.menu.invert_right_x_axis": "Invert Right X",
"lambdacontrols.menu.invert_right_y_axis": "Invert Right Y",
"lambdacontrols.menu.keyboard_controls": "Keyboard Controls...",
"lambdacontrols.menu.mappings.open_input_str": "Open Mappings File Editor",
"lambdacontrols.menu.mouse_speed": "Mouse Speed",
"lambdacontrols.menu.reacharound.horizontal": "Front Block Placing",
"lambdacontrols.menu.reacharound.vertical": "Vertical Reacharound",
@@ -101,6 +105,7 @@
"lambdacontrols.menu.title.gameplay": "Gameplay Options",
"lambdacontrols.menu.title.general": "General Options",
"lambdacontrols.menu.title.hud": "HUD Options",
"lambdacontrols.menu.title.mappings.string": "Mappings File Editor",
"lambdacontrols.menu.unfocused_input": "Unfocused Input",
"lambdacontrols.menu.virtual_mouse": "Virtual Mouse",
"lambdacontrols.menu.virtual_mouse.skin": "Virtual Mouse Skin",

View File

@@ -0,0 +1,130 @@
{
"key.lambdacontrols.look_down": "Mira hacia abajo",
"key.lambdacontrols.look_left": "Mira a la izquierda",
"key.lambdacontrols.look_right": "Mira a la derecha",
"key.lambdacontrols.look_up": "Mira a la arriba",
"lambdacontrols.action.attack": "Ataque",
"lambdacontrols.action.back": "Caminar hacia atrás",
"lambdacontrols.action.chat": "Abrir chat",
"lambdacontrols.action.drop_item": "Tirar ítem",
"lambdacontrols.action.exit": "Salir",
"lambdacontrols.action.forward": "Caminar hacia delante",
"lambdacontrols.action.hit": "Golpear",
"lambdacontrols.action.hotbar_left": "Hotbar a la izquierda",
"lambdacontrols.action.hotbar_right": "Hotbar a la derecha",
"lambdacontrols.action.inventory": "Inventario",
"lambdacontrols.action.jump": "Saltar",
"lambdacontrols.action.left": "Caminar hacia la izquierda",
"lambdacontrols.action.pause_game": "Pausar juego",
"lambdacontrols.action.pick_block": "Recoger bloque",
"lambdacontrols.action.pickup": "Recoger",
"lambdacontrols.action.pickup_all": "Recoger todo",
"lambdacontrols.action.place": "Poner",
"lambdacontrols.action.player_list": "Lista de jugadores",
"lambdacontrols.action.quick_move": "Mover items rápidamente",
"lambdacontrols.action.right": "Caminar hacia la derecha",
"lambdacontrols.action.screenshot": "Tomar captura de pantalla",
"lambdacontrols.action.sneak": "Agacharse",
"lambdacontrols.action.sprint": "Correr",
"lambdacontrols.action.swap_hands": "Intercambiar manos",
"lambdacontrols.action.toggle_perspective": "Cambiar perspectiva",
"lambdacontrols.action.toggle_smooth_camera": "Cambiar cámara cinematográfica",
"lambdacontrols.action.use": "Usar",
"lambdacontrols.action.zoom": "Zoom",
"lambdacontrols.action.zoom.in": "Aumentar zoom",
"lambdacontrols.action.zoom.out": "Disminuir zoom",
"lambdacontrols.action.zoom.reset": "Restablecer zoom",
"lambdacontrols.button.a": "A",
"lambdacontrols.button.b": "B",
"lambdacontrols.button.x": "X",
"lambdacontrols.button.y": "Y",
"lambdacontrols.button.left_bumper": "Bumper izquierda",
"lambdacontrols.button.right_bumper": "Bumper derecha",
"lambdacontrols.button.back": "Regresar",
"lambdacontrols.button.start": "Iniciar",
"lambdacontrols.button.guide": "Guía",
"lambdacontrols.button.left_thumb": "Joystick izquierda",
"lambdacontrols.button.right_thumb": "Joystick derecha",
"lambdacontrols.button.dpad_up": "Cruceta arriba",
"lambdacontrols.button.dpad_right": "Cruceta derecha",
"lambdacontrols.button.dpad_down": "Cruceta abajo",
"lambdacontrols.button.dpad_left": "Cruceta izquierda",
"lambdacontrols.axis.left_x+": "Izquierda X+",
"lambdacontrols.axis.left_y+": "Izquierda Y+",
"lambdacontrols.axis.right_x+": "Derecha X+",
"lambdacontrols.axis.right_y+": "Derecha Y+",
"lambdacontrols.axis.left_trigger": "Gatillo izquierda",
"lambdacontrols.axis.right_trigger": "Gatillo derecha",
"lambdacontrols.axis.left_x-": "Izquierda X-",
"lambdacontrols.axis.left_y-": "Izquierda Y-",
"lambdacontrols.axis.right_x-": "Derecha X-",
"lambdacontrols.axis.right_y-": "Derecha Y-",
"lambdacontrols.button.unknown": "Desconocido (%d)",
"lambdacontrols.controller.connected": "Controlador %d conectado.",
"lambdacontrols.controller.disconnected": "Controlador %d desconectado.",
"lambdacontrols.controller.mappings.1": "Para configurar las asignaciones del controlador, utilice %sSDL2 Gamepad Tool%s",
"lambdacontrols.controller.mappings.3": "y poner el mapeo de asignaciones en `%s.minecraft/config/gamecontrollerdb.txt%s`.",
"lambdacontrols.controller.mappings.updated": "Mapeo actualizados!",
"lambdacontrols.controller_type.default": "por defecto",
"lambdacontrols.controller_type.dualshock": "DualShock",
"lambdacontrols.controller_type.switch": "Switch",
"lambdacontrols.controller_type.xbox": "Xbox",
"lambdacontrols.controller_type.steam": "Steam",
"lambdacontrols.controller_type.ouya": "OUYA",
"lambdacontrols.controls_mode.default": "Teclado/Ratón",
"lambdacontrols.controls_mode.controller": "Controlador",
"lambdacontrols.controls_mode.touchscreen": "Pantalla táctil",
"lambdacontrols.hud_side.left": "izquierda",
"lambdacontrols.hud_side.right": "derecha",
"lambdacontrols.menu.auto_switch_mode": "Modo de cambio automático",
"lambdacontrols.menu.controller": "Controlador",
"lambdacontrols.menu.controller2": "Segundo controlador",
"lambdacontrols.menu.controller_type": "Tipo de controlador",
"lambdacontrols.menu.controls_mode": "Modo",
"lambdacontrols.menu.dead_zone": "Zona muerta",
"lambdacontrols.menu.fast_block_placing": "Colocación rápida de bloques",
"lambdacontrols.menu.fly_drifting": "Fly Drifting",
"lambdacontrols.menu.fly_drifting_vertical": "Vertical Fly Drifting",
"lambdacontrols.menu.hud_enable": "Habilitar HUD",
"lambdacontrols.menu.hud_side": "Lado de HUD",
"lambdacontrols.menu.invert_right_x_axis": "Invertir derecha X",
"lambdacontrols.menu.invert_right_y_axis": "Invertir derecha Y",
"lambdacontrols.menu.keyboard_controls": "Controles del teclado...",
"lambdacontrols.menu.mouse_speed": "Velocidad del ratón",
"lambdacontrols.menu.reacharound.horizontal": "Colocación de bloque frontal",
"lambdacontrols.menu.reacharound.vertical": "Alcance vertical",
"lambdacontrols.menu.reload_controller_mappings": "Recargar asignaciones de controlador",
"lambdacontrols.menu.rotation_speed": "Velocidad de rotación",
"lambdacontrols.menu.title": "LambdaControls - Configuraciones",
"lambdacontrols.menu.title.controller": "Opciones de controlador",
"lambdacontrols.menu.title.controller_controls": "Controles de controlador",
"lambdacontrols.menu.title.gameplay": "Opciones de juego",
"lambdacontrols.menu.title.general": "Opciones generales",
"lambdacontrols.menu.title.hud": "Opciones de HUD",
"lambdacontrols.menu.unfocused_input": "Entrada desenfocada",
"lambdacontrols.menu.virtual_mouse": "Ratón virtual",
"lambdacontrols.menu.virtual_mouse.skin": "Piel de ratón virtual",
"lambdacontrols.narrator.unbound": "Resetear %s",
"lambdacontrols.not_bound": "No ligado",
"lambdacontrols.tooltip.auto_switch_mode": "Si el modo de controles debe cambiarse a Controlador automáticamente si hay uno conectado.",
"lambdacontrols.tooltip.controller2": "Segundo controlador a uso, que permite el soporte de Joy-Cons por ejemplo.",
"lambdacontrols.tooltip.controller_type": "El tipo de controlador para mostrar los botones correctos.",
"lambdacontrols.tooltip.controls_mode": "El modo de controles.",
"lambdacontrols.tooltip.dead_zone": "La zona muerta para los sticks analógicos del controlador.",
"lambdacontrols.tooltip.fast_block_placing": "Mientras vuela en modo creativo, permite la colocación rápida de bloques dependiendo su velocidad. §cEn algunos servidores, esto podría considerarse como trampa.",
"lambdacontrols.tooltip.fly_drifting": "Mientras vuela, habilita la deriva/inercia de vainilla.",
"lambdacontrols.tooltip.fly_drifting_vertical": "Mientras vuela, habilita la deriva/inercia vertical de vainilla.",
"lambdacontrols.tooltip.hud_enable": "Alterna el indicador del botón del controlador en pantalla.",
"lambdacontrols.tooltip.hud_side": "La posición del HUD.",
"lambdacontrols.tooltip.mouse_speed": "La velocidad del ratón emulada del controlador.",
"lambdacontrols.tooltip.reacharound.horizontal": "Habilita la colocación del bloque frontal, §cpodría considerarse trampa en algunos servidores§r.",
"lambdacontrols.tooltip.reacharound.vertical": "Habilita el alcance vertical, §cpodría considerarse trampa en algunos servidores§r.",
"lambdacontrols.tooltip.reload_controller_mappings": "Vuelve a cargar el archivo de asignaciones del controlador.",
"lambdacontrols.tooltip.rotation_speed": "La velocidad de rotación de la cámara en modo controlador.",
"lambdacontrols.tooltip.unfocused_input": "Habilita entrada del controlador cuando la ventana no está enfocada.",
"lambdacontrols.tooltip.virtual_mouse": "Habilite el ratón virtual que es útil en el caso de una pantalla dividida.",
"lambdacontrols.virtual_mouse.skin.default_light": "Ligera por defecto",
"lambdacontrols.virtual_mouse.skin.default_dark": "Oscura por defecto",
"lambdacontrols.virtual_mouse.skin.second_light": "Ligera segundario",
"lambdacontrols.virtual_mouse.skin.second_dark": "Oscura segundario"
}

View File

@@ -3,6 +3,7 @@
"key.lambdacontrols.look_left": "Regarder à gauche",
"key.lambdacontrols.look_right": "Regarder à droite",
"key.lambdacontrols.look_up": "Regarder en haut",
"key.lambdacontrols.ring": "Affiche l'anneau de contrôle",
"lambdacontrols.action.attack": "Attaquer",
"lambdacontrols.action.back": "Reculer",
"lambdacontrols.action.chat": "Ouvrir le tchat",
@@ -31,12 +32,15 @@
"lambdacontrols.action.toggle_smooth_camera": "Basculer en mode cinématique",
"lambdacontrols.action.use": "Utiliser",
"lambdacontrols.action.zoom": "Zoom",
"lambdacontrols.action.zoom.in": "Augmenter le zoom",
"lambdacontrols.action.zoom.out": "Diminuer le zoom",
"lambdacontrols.action.zoom.reset": "Remettre le zoom à zéro",
"lambdacontrols.button.a": "A",
"lambdacontrols.button.b": "B",
"lambdacontrols.button.x": "X",
"lambdacontrols.button.y": "Y",
"lambdacontrols.button.left_bumper": "Gâchette haute gauche",
"lambdacontrols.button.right_bumper": "Gâchette haute droite",
"lambdacontrols.button.left_bumper": "Gâchette gauche",
"lambdacontrols.button.right_bumper": "Gâchette droite",
"lambdacontrols.button.back": "Retour",
"lambdacontrols.button.start": "Touche Menu",
"lambdacontrols.button.guide": "Guide",
@@ -61,6 +65,8 @@
"lambdacontrols.controller.disconnected": "Manette %d déconnecté.",
"lambdacontrols.controller.mappings.1": "Pour configurer les correspondances de la manette, veuillez utiliser %sSDL2 Gamepad Tool%s",
"lambdacontrols.controller.mappings.3": "et mettez les correspondances dans le fichier `%s.minecraft/config/gamecontrollerdb.txt%s`.",
"lambdacontrols.controller.mappings.error": "Une erreur est apparue pendant le chargement des manettes.",
"lambdacontrols.controller.mappings.error.write": "Une erreur est apparue pendant l'écriture des manettes au fichier.",
"lambdacontrols.controller.mappings.updated": "Configuration des manettes mise à jour!",
"lambdacontrols.controller_type.default": "default",
"lambdacontrols.controller_type.dualshock": "DualShock",
@@ -79,6 +85,7 @@
"lambdacontrols.menu.controller_type": "Type de manette",
"lambdacontrols.menu.controls_mode": "Mode",
"lambdacontrols.menu.dead_zone": "Zone morte",
"lambdacontrols.menu.fast_block_placing": "Placement rapide de blocs",
"lambdacontrols.menu.fly_drifting": "Inertie de vol",
"lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol",
"lambdacontrols.menu.hud_enable": "Activer le HUD",
@@ -86,10 +93,11 @@
"lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)",
"lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)",
"lambdacontrols.menu.keyboard_controls": "Contrôles clavier...",
"lambdacontrols.menu.mappings.open_input_str": "Ouvrir l'éditeur de fichier des manettes",
"lambdacontrols.menu.mouse_speed": "Vitesse de la souris",
"lambdacontrols.menu.reacharound.horizontal": "Placement avant de bloc",
"lambdacontrols.menu.reacharound.vertical": "Placement vertical",
"lambdacontrols.menu.reload_controller_mappings": "Recharge la configuration des manettes",
"lambdacontrols.menu.reload_controller_mappings": "Recharger les manettes",
"lambdacontrols.menu.rotation_speed": "Vitesse de rotation",
"lambdacontrols.menu.title": "LambdaControls - Paramètres",
"lambdacontrols.menu.title.controller": "Options de manettes",
@@ -97,6 +105,7 @@
"lambdacontrols.menu.title.gameplay": "Options de Gameplay",
"lambdacontrols.menu.title.general": "Options générales",
"lambdacontrols.menu.title.hud": "Options du HUD",
"lambdacontrols.menu.title.mappings.string": "Éditeur du fichier des manettes",
"lambdacontrols.menu.unfocused_input": "Entrée en fond",
"lambdacontrols.menu.virtual_mouse": "Souris virtuelle",
"lambdacontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle",

View File

@@ -3,6 +3,7 @@
"key.lambdacontrols.look_left": "Regarder à gauche",
"key.lambdacontrols.look_right": "Regarder à droite",
"key.lambdacontrols.look_up": "Regarder en haut",
"key.lambdacontrols.ring": "Affiche l'anneau de contrôle",
"lambdacontrols.action.attack": "Attaquer",
"lambdacontrols.action.back": "Reculer",
"lambdacontrols.action.chat": "Ouvrir le tchat",
@@ -31,12 +32,15 @@
"lambdacontrols.action.toggle_smooth_camera": "Basculer en mode cinématique",
"lambdacontrols.action.use": "Utiliser",
"lambdacontrols.action.zoom": "Zoom",
"lambdacontrols.action.zoom.in": "Augmenter le zoom",
"lambdacontrols.action.zoom.out": "Diminuer le zoom",
"lambdacontrols.action.zoom.reset": "Remettre le zoom à zéro",
"lambdacontrols.button.a": "A",
"lambdacontrols.button.b": "B",
"lambdacontrols.button.x": "X",
"lambdacontrols.button.y": "Y",
"lambdacontrols.button.left_bumper": "Gâchette haute gauche",
"lambdacontrols.button.right_bumper": "Gâchette haute droite",
"lambdacontrols.button.left_bumper": "Gâchette gauche",
"lambdacontrols.button.right_bumper": "Gâchette droite",
"lambdacontrols.button.back": "Retour",
"lambdacontrols.button.start": "Touche Menu",
"lambdacontrols.button.guide": "Guide",
@@ -61,6 +65,8 @@
"lambdacontrols.controller.disconnected": "Manette %d déconnecté.",
"lambdacontrols.controller.mappings.1": "Pour configurer les correspondances de la manette, veuillez utiliser %sSDL2 Gamepad Tool%s",
"lambdacontrols.controller.mappings.3": "et mettez les correspondances dans le fichier `%s.minecraft/config/gamecontrollerdb.txt%s`.",
"lambdacontrols.controller.mappings.error": "Une erreur est apparue pendant le chargement des manettes.",
"lambdacontrols.controller.mappings.error.write": "Une erreur est apparue pendant l'écriture des manettes au fichier.",
"lambdacontrols.controller.mappings.updated": "Configuration des manettes mise à jour!",
"lambdacontrols.controller_type.default": "default",
"lambdacontrols.controller_type.dualshock": "DualShock",
@@ -79,6 +85,7 @@
"lambdacontrols.menu.controller_type": "Type de manette",
"lambdacontrols.menu.controls_mode": "Mode",
"lambdacontrols.menu.dead_zone": "Zone morte",
"lambdacontrols.menu.fast_block_placing": "Placement rapide de blocs",
"lambdacontrols.menu.fly_drifting": "Inertie de vol",
"lambdacontrols.menu.fly_drifting_vertical": "Inertie verticale de vol",
"lambdacontrols.menu.hud_enable": "Activer le HUD",
@@ -86,10 +93,11 @@
"lambdacontrols.menu.invert_right_x_axis": "Inverser le stick droit (X)",
"lambdacontrols.menu.invert_right_y_axis": "Inverser le stick droit (Y)",
"lambdacontrols.menu.keyboard_controls": "Contrôles clavier...",
"lambdacontrols.menu.mappings.open_input_str": "Ouvrir l'éditeur de fichier des manettes",
"lambdacontrols.menu.mouse_speed": "Vitesse de la souris",
"lambdacontrols.menu.reacharound.horizontal": "Placement avant de bloc",
"lambdacontrols.menu.reacharound.vertical": "Placement vertical",
"lambdacontrols.menu.reload_controller_mappings": "Recharge la configuration des manettes",
"lambdacontrols.menu.reload_controller_mappings": "Recharger les manettes",
"lambdacontrols.menu.rotation_speed": "Vitesse de rotation",
"lambdacontrols.menu.title": "LambdaControls - Paramètres",
"lambdacontrols.menu.title.controller": "Options de manettes",
@@ -97,6 +105,7 @@
"lambdacontrols.menu.title.gameplay": "Options de Gameplay",
"lambdacontrols.menu.title.general": "Options générales",
"lambdacontrols.menu.title.hud": "Options du HUD",
"lambdacontrols.menu.title.mappings.string": "Éditeur du fichier des manettes",
"lambdacontrols.menu.unfocused_input": "Entrée en fond",
"lambdacontrols.menu.virtual_mouse": "Souris virtuelle",
"lambdacontrols.menu.virtual_mouse.skin": "Apparence souris virtuelle",

View File

@@ -0,0 +1,130 @@
{
"key.lambdacontrols.look_down": "视角下移",
"key.lambdacontrols.look_left": "视角左移",
"key.lambdacontrols.look_right": "视角右移",
"key.lambdacontrols.look_up": "视角上移",
"lambdacontrols.action.attack": "攻击",
"lambdacontrols.action.back": "向后移动",
"lambdacontrols.action.chat": "打开聊天栏",
"lambdacontrols.action.drop_item": "丢弃所选物品",
"lambdacontrols.action.exit": "退出",
"lambdacontrols.action.forward": "向前移动",
"lambdacontrols.action.hit": "挖掘",
"lambdacontrols.action.hotbar_left": "向左循环选择快捷栏",
"lambdacontrols.action.hotbar_right": "向右循环选择快捷栏",
"lambdacontrols.action.inventory": "物品栏",
"lambdacontrols.action.jump": "跳跃",
"lambdacontrols.action.left": "向左移动",
"lambdacontrols.action.pause_game": "暂停游戏",
"lambdacontrols.action.pick_block": "选取方块",
"lambdacontrols.action.pickup": "拿取一个/拿取一半",
"lambdacontrols.action.pickup_all": "拿取一组/拿取全部",
"lambdacontrols.action.place": "放置方块",
"lambdacontrols.action.player_list": "玩家列表",
"lambdacontrols.action.quick_move": "快速移动物品",
"lambdacontrols.action.right": "向右移动",
"lambdacontrols.action.screenshot": "截图",
"lambdacontrols.action.sneak": "潜行",
"lambdacontrols.action.sprint": "疾跑",
"lambdacontrols.action.swap_hands": "与副手交换",
"lambdacontrols.action.toggle_perspective": "切换视角",
"lambdacontrols.action.toggle_smooth_camera": "切换电影视角",
"lambdacontrols.action.use": "使用物品/放置方块",
"lambdacontrols.action.zoom": "视野缩放",
"lambdacontrols.action.zoom.in": "缩放时将视野推近",
"lambdacontrols.action.zoom.out": "缩放时将视野拉远",
"lambdacontrols.action.zoom.reset": "缩放时重置缩放距离",
"lambdacontrols.button.a": "A",
"lambdacontrols.button.b": "B",
"lambdacontrols.button.x": "X",
"lambdacontrols.button.y": "Y",
"lambdacontrols.button.left_bumper": "左肩键",
"lambdacontrols.button.right_bumper": "右肩键",
"lambdacontrols.button.back": "选择键",
"lambdacontrols.button.start": "开始键",
"lambdacontrols.button.guide": "功能键",
"lambdacontrols.button.left_thumb": "左摇杆(按压)",
"lambdacontrols.button.right_thumb": "右摇杆(按压)",
"lambdacontrols.button.dpad_up": "十字键上",
"lambdacontrols.button.dpad_right": "十字键右",
"lambdacontrols.button.dpad_down": "十字键下",
"lambdacontrols.button.dpad_left": "十字键左",
"lambdacontrols.axis.left_x+": "左摇杆右X轴正向",
"lambdacontrols.axis.left_y+": "左摇杆上Y轴正向",
"lambdacontrols.axis.right_x+": "右摇杆右X轴正向",
"lambdacontrols.axis.right_y+": "右摇杆上Y轴正向",
"lambdacontrols.axis.left_trigger": "左扳机键",
"lambdacontrols.axis.right_trigger": "右扳机键",
"lambdacontrols.axis.left_x-": "左摇杆左X轴负向",
"lambdacontrols.axis.left_y-": "左摇杆下Y轴负向",
"lambdacontrols.axis.right_x-": "右摇杆左X轴负向",
"lambdacontrols.axis.right_y-": "右摇杆下Y轴负向",
"lambdacontrols.button.unknown": "未知(%d",
"lambdacontrols.controller.connected": "手柄%d已连接。",
"lambdacontrols.controller.disconnected": "手柄%d已断开。",
"lambdacontrols.controller.mappings.1": "请使用%sSDL2 Gamepad Tool%s配置手柄键位映射",
"lambdacontrols.controller.mappings.3": "并将键位映射文件放入此路径:`%s.minecraft/config/gamecontrollerdb.txt%s`。",
"lambdacontrols.controller.mappings.updated": "键位映射已更新!",
"lambdacontrols.controller_type.default": "默认",
"lambdacontrols.controller_type.dualshock": "DualShock",
"lambdacontrols.controller_type.switch": "Switch",
"lambdacontrols.controller_type.xbox": "Xbox",
"lambdacontrols.controller_type.steam": "Steam",
"lambdacontrols.controller_type.ouya": "OUYA",
"lambdacontrols.controls_mode.default": "键鼠",
"lambdacontrols.controls_mode.controller": "手柄",
"lambdacontrols.controls_mode.touchscreen": "触摸屏",
"lambdacontrols.hud_side.left": "左侧",
"lambdacontrols.hud_side.right": "右侧",
"lambdacontrols.menu.auto_switch_mode": "自动切换模式",
"lambdacontrols.menu.controller": "手柄",
"lambdacontrols.menu.controller2": "额外手柄",
"lambdacontrols.menu.controller_type": "手柄类型",
"lambdacontrols.menu.controls_mode": "模式",
"lambdacontrols.menu.dead_zone": "摇杆死区",
"lambdacontrols.menu.fast_block_placing": "方块快速放置",
"lambdacontrols.menu.fly_drifting": "水平方向飞行惯性",
"lambdacontrols.menu.fly_drifting_vertical": "垂直方向飞行惯性",
"lambdacontrols.menu.hud_enable": "启用HUD",
"lambdacontrols.menu.hud_side": "HUD位置",
"lambdacontrols.menu.invert_right_x_axis": "反转右摇杆X轴",
"lambdacontrols.menu.invert_right_y_axis": "反转右摇杆Y轴",
"lambdacontrols.menu.keyboard_controls": "键盘控制...",
"lambdacontrols.menu.mouse_speed": "鼠标移动速度",
"lambdacontrols.menu.reacharound.horizontal": "水平方向方块放置辅助",
"lambdacontrols.menu.reacharound.vertical": "垂直方向方块放置辅助",
"lambdacontrols.menu.reload_controller_mappings": "重新加载手柄键位映射",
"lambdacontrols.menu.rotation_speed": "镜头旋转速度",
"lambdacontrols.menu.title": "LambdaControls - 设置",
"lambdacontrols.menu.title.controller": "手柄选项",
"lambdacontrols.menu.title.controller_controls": "手柄控制",
"lambdacontrols.menu.title.gameplay": "游戏内容选项",
"lambdacontrols.menu.title.general": "通用选项",
"lambdacontrols.menu.title.hud": "HUD选项",
"lambdacontrols.menu.unfocused_input": "非活动状态输入",
"lambdacontrols.menu.virtual_mouse": "虚拟鼠标",
"lambdacontrols.menu.virtual_mouse.skin": "虚拟鼠标指针样式",
"lambdacontrols.narrator.unbound": "取消绑定 %s",
"lambdacontrols.not_bound": "未绑定",
"lambdacontrols.tooltip.auto_switch_mode": "如果已有手柄连接,则自动切换为手柄操作模式。",
"lambdacontrols.tooltip.controller2": "使用额外的手柄比如将一左一右的两个Joy-Con合为一个功能完全的手柄。",
"lambdacontrols.tooltip.controller_type": "选择手柄类型,以显示对应的按键图标。",
"lambdacontrols.tooltip.controls_mode": "操作模式",
"lambdacontrols.tooltip.dead_zone": "手柄摇杆的死区,死区决定摇杆要偏移中心位置多远才能让摇杆输入有效。",
"lambdacontrols.tooltip.fast_block_placing": "在创造模式中处于飞行状态时可以根据你飞行的速度快速放置方块。§c在部分服务器可能会被认定为作弊。",
"lambdacontrols.tooltip.fly_drifting": "处于飞行状态时,启用原版的水平方向飞行惯性(缓停滑行)。",
"lambdacontrols.tooltip.fly_drifting_vertical": "处于飞行状态时,启用原版的垂直方向飞行惯性(缓停滑行)。",
"lambdacontrols.tooltip.hud_enable": "显示手柄按键操作提示。",
"lambdacontrols.tooltip.hud_side": "HUD的位置位于画面的哪一侧。",
"lambdacontrols.tooltip.mouse_speed": "手柄模拟的鼠标的移动速度。",
"lambdacontrols.tooltip.reacharound.horizontal": "启用水平方向方块放置辅助可在脚下方块的前方放置方块。§c在部分服务器可能会被认定为作弊。",
"lambdacontrols.tooltip.reacharound.vertical": "启用垂直方向方块放置辅助可在脚下方块的下方放置方块。§c在部分服务器可能会被认定为作弊。",
"lambdacontrols.tooltip.reload_controller_mappings": "重新加载手柄的按键映射文件。",
"lambdacontrols.tooltip.rotation_speed": "手柄操作模式下的镜头旋转速度。",
"lambdacontrols.tooltip.unfocused_input": "即使游戏窗口处于非活动状态,也允许手柄进行按键输入。",
"lambdacontrols.tooltip.virtual_mouse": "启用虚拟鼠标,在分屏的情况下很有用。",
"lambdacontrols.virtual_mouse.skin.default_light": "默认样式(白色)",
"lambdacontrols.virtual_mouse.skin.default_dark": "默认样式(黑色)",
"lambdacontrols.virtual_mouse.skin.second_light": "额外样式(白色)",
"lambdacontrols.virtual_mouse.skin.second_dark": "额外样式(黑色)"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -4,6 +4,8 @@
controls = "default"
# Auto switch mode.
auto_switch_mode = false
# Debug mode
debug = false
[hud]
# Enables the HUD.

View File

@@ -31,10 +31,10 @@
"lambdacontrols_compat.mixins.json"
],
"depends": {
"fabricloader": ">=0.8.0",
"fabric": "*",
"minecraft": ">=1.16",
"spruceui": ">=1.5.2"
"fabricloader": ">=0.9.0",
"fabric": ">=0.4.0",
"minecraft": ">=1.16.2",
"spruceui": ">=1.6.3"
},
"recommends": {
"modmenu": ">=1.12.2"
@@ -49,7 +49,6 @@
"optifabric": "*"
},
"custom": {
"modmenu:clientsideOnly": true,
"modupdater": {
"strategy": "curseforge",
"projectID": 354231

View File

@@ -4,6 +4,8 @@
"plugin": "me.lambdaurora.lambdacontrols.client.compat.LambdaControlsMixinPlugin",
"compatibilityLevel": "JAVA_8",
"client": [
"EntryListWidgetAccessor",
"EntryWidgetAccessor",
"RecipeViewingScreenAccessor",
"VillagerRecipeViewingScreenAccessor"
],

View File

@@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.16.1
yarn_mappings=1.16.1+build.21:v2
loader_version=0.9.0+build.204
minecraft_version=1.16.2
yarn_mappings=1.16.2+build.25
loader_version=0.9.1+build.205
# Mod Properties
mod_version = 1.4.1
mod_version = 1.5.0
maven_group = me.lambdaurora.lambdacontrols
archives_base_name = lambdacontrols
# 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.15.0+build.379-1.16.1
spruceui_version=1.5.9
modmenu_version=1.12.2+build.17
fabric_version=0.17.2+build.396-1.16
spruceui_version=1.6.4
modmenu_version=1.14.6+build.31

View File

@@ -21,6 +21,8 @@ dependencies {
}
api 'org.spigotmc:spigot-api:1.15.1-R0.1-SNAPSHOT'
api 'io.netty:netty-all:4.1.28.Final'
implementation "com.electronwill.night-config:core:3.5.3"
implementation "com.electronwill.night-config:toml:3.5.3"
}
processResources {

View File

@@ -36,6 +36,6 @@ public class LambdaControlsConfig
configDir.mkdirs();
this.config.load();
this.plugin.log("Configuration loaded.");
LambdaControlsFeature.FRONT_BLOCK_PLACING.setAllowed(this.config.getOrElse("gameplay.front_block_placing", DEFAULT_FRONT_BLOCK_PLACING));
LambdaControlsFeature.HORIZONTAL_REACHAROUND.setAllowed(this.config.getOrElse("gameplay.front_block_placing", DEFAULT_FRONT_BLOCK_PLACING));
}
}

View File

@@ -57,7 +57,7 @@ public class LambdaControlsSpigot extends JavaPlugin implements PluginMessageLis
PLAYERS_CONTROLS_MODE.put(player, ControlsMode.DEFAULT);
this.requestPlayerControlsMode(player);
this.updatePlayerFeature(player, LambdaControlsFeature.FRONT_BLOCK_PLACING);
this.updatePlayerFeature(player, LambdaControlsFeature.HORIZONTAL_REACHAROUND);
});
}
@@ -108,7 +108,7 @@ public class LambdaControlsSpigot extends JavaPlugin implements PluginMessageLis
PlayerChangeControlsModeEvent event = new PlayerChangeControlsModeEvent(player, controlsMode);
this.getServer().getPluginManager().callEvent(event);
});
this.updatePlayerFeature(player, LambdaControlsFeature.FRONT_BLOCK_PLACING);
this.updatePlayerFeature(player, LambdaControlsFeature.HORIZONTAL_REACHAROUND);
} else if (channel.equals(CONTROLS_MODE_CHANNEL.toString())) {
NettyPacketBuffer buffer = new NettyPacketBuffer(Unpooled.copiedBuffer(message));
ControlsMode.byId(buffer.readString(32)).ifPresent(controlsMode -> {