mirror of
https://github.com/chylex/Better-Controls.git
synced 2025-05-31 22:34:04 +02:00
Implement third sprinting mode (hold key to sprint) & option to change sprinting mode when flying
This commit is contained in:
parent
a79871b690
commit
04c789a50e
src/main/java/chylex/bettercontrols
@ -1,5 +1,6 @@
|
|||||||
package chylex.bettercontrols.config;
|
package chylex.bettercontrols.config;
|
||||||
import chylex.bettercontrols.input.KeyBindingWithModifier;
|
import chylex.bettercontrols.input.KeyBindingWithModifier;
|
||||||
|
import chylex.bettercontrols.input.SprintMode;
|
||||||
import net.minecraft.client.options.KeyBinding;
|
import net.minecraft.client.options.KeyBinding;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
@ -11,14 +12,15 @@ public final class BetterControlsConfig{
|
|||||||
private Path path;
|
private Path path;
|
||||||
|
|
||||||
public final KeyBindingWithModifier keyToggleSprint = new KeyBindingWithModifier("key.bettercontrols.toggle_sprint");
|
public final KeyBindingWithModifier keyToggleSprint = new KeyBindingWithModifier("key.bettercontrols.toggle_sprint");
|
||||||
|
public SprintMode sprintMode = SprintMode.TAP_TO_START;
|
||||||
public boolean doubleTapForwardToSprint = true;
|
public boolean doubleTapForwardToSprint = true;
|
||||||
public boolean tapSprintKeyAgainToStopSprinting = false;
|
|
||||||
public boolean resumeSprintingAfterHittingObstacle = false;
|
public boolean resumeSprintingAfterHittingObstacle = false;
|
||||||
|
|
||||||
public final KeyBindingWithModifier keyToggleSneak = new KeyBindingWithModifier("key.bettercontrols.toggle_sneak");
|
public final KeyBindingWithModifier keyToggleSneak = new KeyBindingWithModifier("key.bettercontrols.toggle_sneak");
|
||||||
public boolean sneakingMovesCameraSmoothly = true;
|
public boolean sneakingMovesCameraSmoothly = true;
|
||||||
|
|
||||||
public final KeyBindingWithModifier keyToggleFlight = new KeyBindingWithModifier("key.bettercontrols.toggle_flight");
|
public final KeyBindingWithModifier keyToggleFlight = new KeyBindingWithModifier("key.bettercontrols.toggle_flight");
|
||||||
|
public SprintMode sprintModeWhileFlying = SprintMode.TAP_TO_START;
|
||||||
public boolean flyOnGroundInCreative = false;
|
public boolean flyOnGroundInCreative = false;
|
||||||
public float flightSpeedMpCreativeDefault = 1F;
|
public float flightSpeedMpCreativeDefault = 1F;
|
||||||
public float flightSpeedMpCreativeSprinting = 2F;
|
public float flightSpeedMpCreativeSprinting = 2F;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
package chylex.bettercontrols.config;
|
package chylex.bettercontrols.config;
|
||||||
|
import chylex.bettercontrols.input.SprintMode;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
@ -32,14 +33,15 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js
|
|||||||
final JsonObject obj = new JsonObject();
|
final JsonObject obj = new JsonObject();
|
||||||
|
|
||||||
Json.writeKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint);
|
Json.writeKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint);
|
||||||
|
Json.setEnum(obj, "Sprint.Mode", cfg.sprintMode);
|
||||||
Json.setBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
|
Json.setBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
|
||||||
Json.setBool(obj, "Sprint.TapToStop", cfg.tapSprintKeyAgainToStopSprinting);
|
|
||||||
Json.setBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle);
|
Json.setBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle);
|
||||||
|
|
||||||
Json.writeKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak);
|
Json.writeKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak);
|
||||||
Json.setBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly);
|
Json.setBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly);
|
||||||
|
|
||||||
Json.writeKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight);
|
Json.writeKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight);
|
||||||
|
Json.setEnum(obj, "Flight.SprintMode", cfg.sprintModeWhileFlying);
|
||||||
Json.setBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative);
|
Json.setBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative);
|
||||||
Json.setFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault);
|
Json.setFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault);
|
||||||
Json.setFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting);
|
Json.setFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting);
|
||||||
@ -58,15 +60,20 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js
|
|||||||
final BetterControlsConfig cfg = new BetterControlsConfig();
|
final BetterControlsConfig cfg = new BetterControlsConfig();
|
||||||
final JsonObject obj = json.getAsJsonObject();
|
final JsonObject obj = json.getAsJsonObject();
|
||||||
|
|
||||||
|
if (obj.has("Sprint.TapToStop") && obj.get("Sprint.TapToStop").getAsBoolean()){
|
||||||
|
cfg.sprintMode = SprintMode.TAP_TO_TOGGLE;
|
||||||
|
}
|
||||||
|
|
||||||
Json.readKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint);
|
Json.readKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint);
|
||||||
|
cfg.sprintMode = Json.getEnum(obj, "Sprint.Mode", cfg.sprintMode, SprintMode.class);
|
||||||
cfg.doubleTapForwardToSprint = Json.getBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
|
cfg.doubleTapForwardToSprint = Json.getBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
|
||||||
cfg.tapSprintKeyAgainToStopSprinting = Json.getBool(obj, "Sprint.TapToStop", cfg.tapSprintKeyAgainToStopSprinting);
|
|
||||||
cfg.resumeSprintingAfterHittingObstacle = Json.getBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle);
|
cfg.resumeSprintingAfterHittingObstacle = Json.getBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle);
|
||||||
|
|
||||||
Json.readKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak);
|
Json.readKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak);
|
||||||
cfg.sneakingMovesCameraSmoothly = Json.getBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly);
|
cfg.sneakingMovesCameraSmoothly = Json.getBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly);
|
||||||
|
|
||||||
Json.readKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight);
|
Json.readKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight);
|
||||||
|
cfg.sprintModeWhileFlying = Json.getEnum(obj, "Flight.SprintMode", cfg.sprintModeWhileFlying, SprintMode.class);
|
||||||
cfg.flyOnGroundInCreative = Json.getBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative);
|
cfg.flyOnGroundInCreative = Json.getBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative);
|
||||||
cfg.flightSpeedMpCreativeDefault = MathHelper.clamp(Json.getFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault), 0.25F, 8F);
|
cfg.flightSpeedMpCreativeDefault = MathHelper.clamp(Json.getFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault), 0.25F, 8F);
|
||||||
cfg.flightSpeedMpCreativeSprinting = MathHelper.clamp(Json.getFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting), 0.25F, 8F);
|
cfg.flightSpeedMpCreativeSprinting = MathHelper.clamp(Json.getFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting), 0.25F, 8F);
|
||||||
|
@ -31,6 +31,30 @@ final class Json{
|
|||||||
return obj.has(key) ? obj.get(key).getAsBoolean() : defaultValue;
|
return obj.has(key) ? obj.get(key).getAsBoolean() : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T>> void setEnum(final JsonObject obj, final String key, final T value){
|
||||||
|
obj.addProperty(key, value.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T>> T getEnum(final JsonObject obj, final String key, final T defaultValue, final Class<T> enumClass){
|
||||||
|
if (!obj.has(key)){
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final T[] constants = enumClass.getEnumConstants();
|
||||||
|
|
||||||
|
if (constants != null){
|
||||||
|
final String value = obj.get(key).getAsString();
|
||||||
|
|
||||||
|
for(final T constant : constants){
|
||||||
|
if (constant.name().equalsIgnoreCase(value)){
|
||||||
|
return constant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
private static final String KEY_SUFFIX = ".Key";
|
private static final String KEY_SUFFIX = ".Key";
|
||||||
private static final String MOD_SUFFIX = ".Mod";
|
private static final String MOD_SUFFIX = ".Mod";
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import chylex.bettercontrols.gui.elements.Option;
|
|||||||
import chylex.bettercontrols.gui.elements.TextWidget;
|
import chylex.bettercontrols.gui.elements.TextWidget;
|
||||||
import chylex.bettercontrols.input.KeyBindingWithModifier;
|
import chylex.bettercontrols.input.KeyBindingWithModifier;
|
||||||
import chylex.bettercontrols.input.ModifierKey;
|
import chylex.bettercontrols.input.ModifierKey;
|
||||||
|
import chylex.bettercontrols.input.SprintMode;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.Element;
|
import net.minecraft.client.gui.Element;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
@ -39,6 +40,12 @@ public class BetterControlsScreen extends GameOptionsScreen{
|
|||||||
private static final int TITLE_MARGIN_TOP = 3;
|
private static final int TITLE_MARGIN_TOP = 3;
|
||||||
private static final int ROW_HEIGHT = 22;
|
private static final int ROW_HEIGHT = 22;
|
||||||
|
|
||||||
|
private final List<Option<SprintMode>> SPRINT_MODE_OPTIONS = Arrays.asList(
|
||||||
|
new Option<>(SprintMode.TAP_TO_START, Text.of("Tap To Start Sprinting")),
|
||||||
|
new Option<>(SprintMode.TAP_TO_TOGGLE, Text.of("Tap To Start / Stop Sprinting")),
|
||||||
|
new Option<>(SprintMode.HOLD, Text.of("Hold To Sprint"))
|
||||||
|
);
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
|
|
||||||
private int generateSprintingOptions(int y, final List<Element> elements){
|
private int generateSprintingOptions(int y, final List<Element> elements){
|
||||||
@ -48,13 +55,13 @@ public class BetterControlsScreen extends GameOptionsScreen{
|
|||||||
|
|
||||||
y += ROW_HEIGHT;
|
y += ROW_HEIGHT;
|
||||||
|
|
||||||
generateLeftSideText(y, elements, Text.of("Double Tap 'Walk Forwards' To Sprint"));
|
generateLeftSideText(y, elements, Text.of("Sprint Key Mode"));
|
||||||
elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.doubleTapForwardToSprint, value -> cfg.doubleTapForwardToSprint = value));
|
elements.add(new CycleButtonWidget<>(col2(1), y, COL2_W, SPRINT_MODE_OPTIONS, cfg.sprintMode, value -> cfg.sprintMode = value));
|
||||||
|
|
||||||
y += ROW_HEIGHT;
|
y += ROW_HEIGHT;
|
||||||
|
|
||||||
generateLeftSideText(y, elements, Text.of("Tap 'Sprint' While Sprinting To Stop"));
|
generateLeftSideText(y, elements, Text.of("Double Tap 'Walk Forwards' To Sprint"));
|
||||||
elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.tapSprintKeyAgainToStopSprinting, value -> cfg.tapSprintKeyAgainToStopSprinting = value));
|
elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.doubleTapForwardToSprint, value -> cfg.doubleTapForwardToSprint = value));
|
||||||
|
|
||||||
y += ROW_HEIGHT;
|
y += ROW_HEIGHT;
|
||||||
|
|
||||||
@ -100,6 +107,11 @@ public class BetterControlsScreen extends GameOptionsScreen{
|
|||||||
|
|
||||||
y += ROW_HEIGHT;
|
y += ROW_HEIGHT;
|
||||||
|
|
||||||
|
generateLeftSideText(y, elements, Text.of("Sprint Key Mode While Flying"));
|
||||||
|
elements.add(new CycleButtonWidget<>(col2(1), y, COL2_W, SPRINT_MODE_OPTIONS, cfg.sprintModeWhileFlying, value -> cfg.sprintModeWhileFlying = value));
|
||||||
|
|
||||||
|
y += ROW_HEIGHT;
|
||||||
|
|
||||||
generateLeftSideText(y, elements, Text.of("Fly On Ground (Creative Mode)"));
|
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));
|
elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.flyOnGroundInCreative, value -> cfg.flyOnGroundInCreative = value));
|
||||||
|
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package chylex.bettercontrols.input;
|
||||||
|
|
||||||
|
public enum SprintMode{
|
||||||
|
TAP_TO_START,
|
||||||
|
TAP_TO_TOGGLE,
|
||||||
|
HOLD
|
||||||
|
}
|
@ -2,6 +2,7 @@ package chylex.bettercontrols.player;
|
|||||||
import chylex.bettercontrols.BetterControlsMod;
|
import chylex.bettercontrols.BetterControlsMod;
|
||||||
import chylex.bettercontrols.config.BetterControlsConfig;
|
import chylex.bettercontrols.config.BetterControlsConfig;
|
||||||
import chylex.bettercontrols.gui.BetterControlsScreen;
|
import chylex.bettercontrols.gui.BetterControlsScreen;
|
||||||
|
import chylex.bettercontrols.input.SprintMode;
|
||||||
import chylex.bettercontrols.input.ToggleTracker;
|
import chylex.bettercontrols.input.ToggleTracker;
|
||||||
import chylex.bettercontrols.input.ToggleTrackerForStickyKey;
|
import chylex.bettercontrols.input.ToggleTrackerForStickyKey;
|
||||||
import chylex.bettercontrols.mixin.AccessCameraFields;
|
import chylex.bettercontrols.mixin.AccessCameraFields;
|
||||||
@ -78,6 +79,15 @@ public final class PlayerTicker{
|
|||||||
((AccessClientPlayerFields)player).setTicksLeftToDoubleTapSprint(0);
|
((AccessClientPlayerFields)player).setTicksLeftToDoubleTapSprint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final SprintMode sprintMode;
|
||||||
|
|
||||||
|
if (player.abilities.flying && (player.isCreative() || player.isSpectator())){
|
||||||
|
sprintMode = cfg().sprintModeWhileFlying;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sprintMode = cfg().sprintMode;
|
||||||
|
}
|
||||||
|
|
||||||
final GameOptions opts = mc().options;
|
final GameOptions opts = mc().options;
|
||||||
final boolean wasSprintToggled = opts.sprintToggled;
|
final boolean wasSprintToggled = opts.sprintToggled;
|
||||||
final boolean isSprintToggled = toggleSprint.tick();
|
final boolean isSprintToggled = toggleSprint.tick();
|
||||||
@ -92,7 +102,7 @@ public final class PlayerTicker{
|
|||||||
if (!opts.keySprint.isPressed() && opts.keyForward.isPressed()){
|
if (!opts.keySprint.isPressed() && opts.keyForward.isPressed()){
|
||||||
temporarySprintTimer = nextTemporarySprintTimer;
|
temporarySprintTimer = nextTemporarySprintTimer;
|
||||||
}
|
}
|
||||||
else if (cfg().tapSprintKeyAgainToStopSprinting){
|
else if (sprintMode == SprintMode.TAP_TO_TOGGLE){
|
||||||
stopSprintingAfterReleasingSprintKey = true;
|
stopSprintingAfterReleasingSprintKey = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +115,7 @@ public final class PlayerTicker{
|
|||||||
stopSprintingAfterReleasingSprintKey = true;
|
stopSprintingAfterReleasingSprintKey = true;
|
||||||
waitingForSprintKeyRelease = true;
|
waitingForSprintKeyRelease = true;
|
||||||
}
|
}
|
||||||
else if (cfg().tapSprintKeyAgainToStopSprinting){
|
else if (sprintMode == SprintMode.TAP_TO_TOGGLE){
|
||||||
if (opts.keySprint.isPressed()){
|
if (opts.keySprint.isPressed()){
|
||||||
if (!waitingForSprintKeyRelease){
|
if (!waitingForSprintKeyRelease){
|
||||||
waitingForSprintKeyRelease = true;
|
waitingForSprintKeyRelease = true;
|
||||||
@ -120,6 +130,11 @@ public final class PlayerTicker{
|
|||||||
waitingForSprintKeyRelease = false;
|
waitingForSprintKeyRelease = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (sprintMode == SprintMode.HOLD){
|
||||||
|
if (opts.keySprint.isPressed()){
|
||||||
|
stopSprintingAfterReleasingSprintKey = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (stopSprintingAfterReleasingSprintKey && !opts.keySprint.isPressed()){
|
if (stopSprintingAfterReleasingSprintKey && !opts.keySprint.isPressed()){
|
||||||
stopSprintingAfterReleasingSprintKey = false;
|
stopSprintingAfterReleasingSprintKey = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user