diff --git a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java index a8d725a..4426b69 100644 --- a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java +++ b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java @@ -10,11 +10,14 @@ public final class BetterControlsConfig{ private Path path; + public final KeyBindingWithModifier keyToggleSprint = new KeyBindingWithModifier("key.bettercontrols.toggle_sprint"); public boolean doubleTapForwardToSprint = true; public boolean resumeSprintingAfterHittingObstacle = false; + public final KeyBindingWithModifier keyToggleSneak = new KeyBindingWithModifier("key.bettercontrols.toggle_sneak"); public boolean sneakingMovesCameraSmoothly = true; + public final KeyBindingWithModifier keyToggleFlight = new KeyBindingWithModifier("key.bettercontrols.toggle_flight"); public boolean flyOnGroundInCreative = false; public float flightSpeedMpCreativeDefault = 1F; public float flightSpeedMpCreativeSprinting = 2F; @@ -34,6 +37,9 @@ public final class BetterControlsConfig{ public KeyBinding[] getAllKeyBindings(){ return new KeyBinding[]{ + keyToggleSprint, + keyToggleSneak, + keyToggleFlight, keyToggleWalkForward, keyToggleJump, keyOpenMenu diff --git a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java index 5254ad4..d3fddd8 100644 --- a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java +++ b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java @@ -30,11 +30,14 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js public JsonElement serialize(final BetterControlsConfig cfg, final Type typeOfSrc, final JsonSerializationContext context){ final JsonObject obj = new JsonObject(); + Json.writeKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint); Json.setBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint); Json.setBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle); + Json.writeKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak); Json.setBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly); + Json.writeKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight); Json.setBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative); Json.setFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault); Json.setFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting); @@ -53,11 +56,14 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js final BetterControlsConfig cfg = new BetterControlsConfig(); final JsonObject obj = json.getAsJsonObject(); + Json.readKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint); cfg.doubleTapForwardToSprint = Json.getBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint); cfg.resumeSprintingAfterHittingObstacle = Json.getBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle); + Json.readKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak); cfg.sneakingMovesCameraSmoothly = Json.getBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly); + Json.readKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight); cfg.flyOnGroundInCreative = Json.getBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative); cfg.flightSpeedMpCreativeDefault = Json.getFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault); cfg.flightSpeedMpCreativeSprinting = Json.getFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting); diff --git a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java index ebadc7a..6e989a8 100644 --- a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java +++ b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java @@ -44,6 +44,10 @@ public class BetterControlsScreen extends GameOptionsScreen{ private int generateSprintingOptions(int y, final List<Element> elements){ final BetterControlsConfig cfg = BetterControlsMod.config; + generateKeyBindingWithModifierOption(y, elements, Text.of("Toggle Sprint"), cfg.keyToggleSprint); + + y += ROW_HEIGHT; + generateLeftSideText(y, elements, Text.of("Double Tap 'Walk Forwards' To Sprint")); elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.doubleTapForwardToSprint, value -> cfg.doubleTapForwardToSprint = value)); @@ -59,6 +63,10 @@ public class BetterControlsScreen extends GameOptionsScreen{ private int generateSneakingOptions(int y, final List<Element> elements){ final BetterControlsConfig cfg = BetterControlsMod.config; + generateKeyBindingWithModifierOption(y, elements, Text.of("Toggle Sneak"), cfg.keyToggleSneak); + + y += ROW_HEIGHT; + generateLeftSideText(y, elements, Text.of("Move Camera Smoothly")); elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.sneakingMovesCameraSmoothly, value -> cfg.sneakingMovesCameraSmoothly = value)); @@ -83,6 +91,10 @@ public class BetterControlsScreen extends GameOptionsScreen{ new Option<>(Float.valueOf(8.00F), Text.of("8x")) ); + generateKeyBindingWithModifierOption(y, elements, Text.of("Toggle Flight (Creative)"), cfg.keyToggleFlight); + + y += ROW_HEIGHT; + generateLeftSideText(y, elements, Text.of("Fly On Ground (Creative Mode)")); elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.flyOnGroundInCreative, value -> cfg.flyOnGroundInCreative = value)); diff --git a/src/main/java/chylex/bettercontrols/player/PlayerTicker.java b/src/main/java/chylex/bettercontrols/player/PlayerTicker.java index 442ff5d..8b29478 100644 --- a/src/main/java/chylex/bettercontrols/player/PlayerTicker.java +++ b/src/main/java/chylex/bettercontrols/player/PlayerTicker.java @@ -3,11 +3,13 @@ import chylex.bettercontrols.BetterControlsMod; import chylex.bettercontrols.config.BetterControlsConfig; import chylex.bettercontrols.gui.BetterControlsScreen; import chylex.bettercontrols.input.ToggleTracker; +import chylex.bettercontrols.input.ToggleTrackerForStickyKey; import chylex.bettercontrols.mixin.AccessCameraFields; import chylex.bettercontrols.mixin.AccessClientPlayerFields; import net.minecraft.client.MinecraftClient; import net.minecraft.client.input.KeyboardInput; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.options.GameOptions; import java.lang.ref.WeakReference; public final class PlayerTicker{ @@ -37,14 +39,18 @@ public final class PlayerTicker{ // Logic + private final ToggleTracker toggleSprint = new ToggleTrackerForStickyKey(cfg().keyToggleSprint, mc().options.keySprint, toggled -> mc().options.sprintToggled = toggled); + private final ToggleTracker toggleSneak = new ToggleTrackerForStickyKey(cfg().keyToggleSneak, mc().options.keySneak, toggled -> mc().options.sneakToggled = toggled); private final ToggleTracker toggleWalkForward = new ToggleTracker(cfg().keyToggleWalkForward, mc().options.keyForward); private final ToggleTracker toggleJump = new ToggleTracker(cfg().keyToggleJump, mc().options.keyJump); + private boolean stopSprintingAfterReleasingSprintKey = false; private boolean wasHittingObstacle = false; private boolean wasSprintingBeforeHittingObstacle = false; private boolean wasSneakingBeforeTouchingGround = false; private boolean holdingSneakWhileTouchingGround = false; + private int temporaryFlyOnGroundTimer = 0; public void atHead(final ClientPlayerEntity player){ if (FlightHelper.shouldFlyOnGround(player)){ @@ -54,6 +60,24 @@ public final class PlayerTicker{ if (!cfg().doubleTapForwardToSprint){ ((AccessClientPlayerFields)player).setTicksLeftToDoubleTapSprint(0); } + + final GameOptions opts = mc().options; + final boolean wasSprintToggled = opts.sprintToggled; + final boolean isSprintToggled = toggleSprint.tick(); + + if (isSprintToggled){ + stopSprintingAfterReleasingSprintKey = false; + } + else if (wasSprintToggled){ + stopSprintingAfterReleasingSprintKey = true; + } + + if (stopSprintingAfterReleasingSprintKey && !opts.keySprint.isPressed()){ + stopSprintingAfterReleasingSprintKey = false; + player.setSprinting(false); + } + + toggleSneak.tick(); } public void afterInputAssignsPressingForward(final KeyboardInput input){ @@ -132,6 +156,32 @@ public final class PlayerTicker{ holdingSneakWhileTouchingGround = false; } + if (player.isCreative()){ + if (cfg().keyToggleFlight.wasPressed()){ + final boolean isFlying = !player.abilities.flying; + + player.abilities.flying = isFlying; + player.sendAbilitiesUpdate(); + + if (isFlying){ + temporaryFlyOnGroundTimer = 10; + } + } + + if (temporaryFlyOnGroundTimer > 0){ + if (player.isSneaking()){ + temporaryFlyOnGroundTimer = 0; + } + else{ + --temporaryFlyOnGroundTimer; + player.setOnGround(false); + } + } + } + else{ + temporaryFlyOnGroundTimer = 0; + } + if (!cfg().sneakingMovesCameraSmoothly){ final AccessCameraFields camera = (AccessCameraFields)mc().gameRenderer.getCamera(); diff --git a/src/main/resources/assets/bettercontrols/lang/en_us.json b/src/main/resources/assets/bettercontrols/lang/en_us.json index 83f8e94..160efaf 100644 --- a/src/main/resources/assets/bettercontrols/lang/en_us.json +++ b/src/main/resources/assets/bettercontrols/lang/en_us.json @@ -1,5 +1,8 @@ { "key.categories.bettercontrols": "Better Controls", + "key.bettercontrols.toggle_sprint": "Toggle Sprint", + "key.bettercontrols.toggle_sneak": "Toggle Sneak", + "key.bettercontrols.toggle_flight": "Toggle Flight", "key.bettercontrols.toggle_forward": "Toggle Walk Forwards", "key.bettercontrols.toggle_jump": "Toggle Jump", "key.bettercontrols.open_menu": "Open Menu"