diff --git a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java index ffd8a65..a803745 100644 --- a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java +++ b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java @@ -27,6 +27,9 @@ public final class BetterControlsConfig { public final KeyBindingWithModifier keyToggleSneak = new KeyBindingWithModifier("key.bettercontrols.toggle_sneak"); public boolean sneakingMovesCameraSmoothly = true; + public final KeyBindingWithModifier keyStartGlide = new KeyBindingWithModifier("key.bettercontrols.start_glide"); + public boolean doubleTapJumpToGlide = true; + public final KeyBindingWithModifier keyToggleFlight = new KeyBindingWithModifier("key.bettercontrols.toggle_flight"); public boolean doubleTapJumpToToggleFlight = true; public boolean disableFlightInertia = false; diff --git a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java index 033eb5e..d53425c 100644 --- a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java +++ b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java @@ -41,6 +41,9 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js Json.writeKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak); Json.setBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly); + Json.writeKeyBinding(obj, "Glide.KeyStart", cfg.keyStartGlide); + Json.setBool(obj, "Glide.DoubleTapJump", cfg.doubleTapJumpToGlide); + Json.writeKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight); Json.setBool(obj, "Flight.DoubleTapJump", cfg.doubleTapJumpToToggleFlight); Json.setBool(obj, "Flight.DisableInertia", cfg.disableFlightInertia); @@ -80,6 +83,9 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js Json.readKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak); cfg.sneakingMovesCameraSmoothly = Json.getBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly); + Json.readKeyBinding(obj, "Glide.KeyStart", cfg.keyStartGlide); + cfg.doubleTapJumpToGlide = Json.getBool(obj, "Glide.DoubleTapJump", cfg.doubleTapJumpToGlide); + Json.readKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight); cfg.doubleTapJumpToToggleFlight = Json.getBool(obj, "Flight.DoubleTapJump", cfg.doubleTapJumpToToggleFlight); cfg.disableFlightInertia = Json.getBool(obj, "Flight.DisableInertia", cfg.disableFlightInertia); diff --git a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java index 0012502..8e5a498 100644 --- a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java +++ b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java @@ -83,6 +83,18 @@ public class BetterControlsScreen extends OptionsSubScreen { return y; } + private int generateGlidingOptions(int y, List<GuiEventListener> elements) { + BetterControlsConfig cfg = BetterControlsCommon.getConfig(); + + generateKeyBindingWithModifierRow(y, elements, text("Start a Glide"), cfg.keyStartGlide); + y += ROW_HEIGHT; + + generateBooleanOptionRow(y, elements, text("Double Tap 'Jump' To Start a Glide"), cfg.doubleTapJumpToGlide, value -> cfg.doubleTapJumpToGlide = value); + y += ROW_HEIGHT; + + return y; + } + private int generateFlightOptions(int y, List<GuiEventListener> elements) { BetterControlsConfig cfg = BetterControlsCommon.getConfig(); @@ -113,7 +125,7 @@ public class BetterControlsScreen extends OptionsSubScreen { generateBooleanOptionRow(y, elements, text("Disable Field Of View Changing"), cfg.disableChangingFovWhileFlying, value -> cfg.disableChangingFovWhileFlying = value); y += ROW_HEIGHT; - generateBooleanOptionRow(y, elements, text("Fly On Ground (Creative Mode)"), cfg.flyOnGroundInCreative, value -> cfg.flyOnGroundInCreative = value); + generateBooleanOptionRow(y, elements, text("Fly On Ground (Creative)"), cfg.flyOnGroundInCreative, value -> cfg.flyOnGroundInCreative = value); y += ROW_HEIGHT; y += ROW_HEIGHT / 3; @@ -223,6 +235,9 @@ public class BetterControlsScreen extends OptionsSubScreen { elements.add(new TextWidget(0, y, ROW_WIDTH, ROW_HEIGHT, text("Sneaking"), CENTER)); y = generateSneakingOptions(y + ROW_HEIGHT, elements) + TITLE_MARGIN_TOP; + elements.add(new TextWidget(0, y, ROW_WIDTH, ROW_HEIGHT, text("Gliding"), CENTER)); + y = generateGlidingOptions(y + ROW_HEIGHT, elements) + TITLE_MARGIN_TOP; + elements.add(new TextWidget(0, y, ROW_WIDTH, ROW_HEIGHT, text("Flying"), CENTER)); y = generateFlightOptions(y + ROW_HEIGHT, elements) + TITLE_MARGIN_TOP; diff --git a/src/main/java/chylex/bettercontrols/mixin/HookPlayerGliding.java b/src/main/java/chylex/bettercontrols/mixin/HookPlayerGliding.java new file mode 100644 index 0000000..d1f8924 --- /dev/null +++ b/src/main/java/chylex/bettercontrols/mixin/HookPlayerGliding.java @@ -0,0 +1,23 @@ +package chylex.bettercontrols.mixin; + +import chylex.bettercontrols.player.FlightHelper; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import net.minecraft.client.player.LocalPlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Slice; + +@Mixin(LocalPlayer.class) +@SuppressWarnings("MethodMayBeStatic") +public abstract class HookPlayerGliding { + @ModifyExpressionValue( + method = "aiStep", + at = @At(value = "INVOKE:LAST", target = "Lnet/minecraft/world/entity/player/Input;jump()Z"), + slice = @Slice( + to = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;tryToStartFallFlying()Z") + ) + ) + private boolean shouldStartGliding(boolean isHoldingJump) { + return FlightHelper.shouldStartGliding(isHoldingJump); + } +} diff --git a/src/main/java/chylex/bettercontrols/player/FlightHelper.java b/src/main/java/chylex/bettercontrols/player/FlightHelper.java index 1344100..081fca9 100644 --- a/src/main/java/chylex/bettercontrols/player/FlightHelper.java +++ b/src/main/java/chylex/bettercontrols/player/FlightHelper.java @@ -19,6 +19,10 @@ public final class FlightHelper { return BetterControlsCommon.getConfig(); } + public static boolean shouldStartGliding(boolean isHoldingJump) { + return cfg().keyStartGlide.isDown() || (cfg().doubleTapJumpToGlide && isHoldingJump); + } + public static boolean isFlyingCreativeOrSpectator(LocalPlayer player) { return player.getAbilities().flying && (player.isCreative() || player.isSpectator()); } diff --git a/src/main/resources/bettercontrols.mixins.json b/src/main/resources/bettercontrols.mixins.json index baaac28..42e43fb 100644 --- a/src/main/resources/bettercontrols.mixins.json +++ b/src/main/resources/bettercontrols.mixins.json @@ -17,6 +17,7 @@ "HookControlsListWidget", "HookControlsScreen", "HookLoadGameOptions", + "HookPlayerGliding", "HookPlayerHorizontalFlightSpeed", "HookStickyKeyBindingState", "HookToggleOptionButtons"