mirror of
https://github.com/chylex/Better-Controls.git
synced 2025-05-06 22:34:04 +02:00
Avoid wobble sprinting when resuming sprinting after hitting an obstacle, by simulating holding sprint for multiple ticks
This commit is contained in:
parent
c0e9c92197
commit
c537e037b5
src/main
java/chylex/bettercontrols
resources
@ -0,0 +1,16 @@
|
||||
package chylex.bettercontrols.mixin;
|
||||
import net.minecraft.client.options.StickyKeyBinding;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@Mixin(StickyKeyBinding.class)
|
||||
public interface AccessStickyKeyBindingStateGetter{
|
||||
@Accessor
|
||||
BooleanSupplier getToggleGetter();
|
||||
|
||||
@Accessor
|
||||
@Mutable
|
||||
void setToggleGetter(final BooleanSupplier toggleGetter);
|
||||
}
|
@ -6,11 +6,13 @@ import chylex.bettercontrols.input.ToggleTracker;
|
||||
import chylex.bettercontrols.input.ToggleTrackerForStickyKey;
|
||||
import chylex.bettercontrols.mixin.AccessCameraFields;
|
||||
import chylex.bettercontrols.mixin.AccessClientPlayerFields;
|
||||
import chylex.bettercontrols.mixin.AccessStickyKeyBindingStateGetter;
|
||||
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;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public final class PlayerTicker{
|
||||
private static PlayerTicker ticker = new PlayerTicker(null);
|
||||
@ -35,6 +37,7 @@ public final class PlayerTicker{
|
||||
|
||||
private PlayerTicker(final ClientPlayerEntity player){
|
||||
this.ref = new WeakReference<>(player);
|
||||
setup();
|
||||
}
|
||||
|
||||
// Logic
|
||||
@ -46,13 +49,26 @@ public final class PlayerTicker{
|
||||
|
||||
private boolean waitingForSprintKeyRelease = false;
|
||||
private boolean stopSprintingAfterReleasingSprintKey = false;
|
||||
|
||||
private boolean wasHittingObstacle = false;
|
||||
private boolean wasSprintingBeforeHittingObstacle = false;
|
||||
private int temporarySprintTimer = 0;
|
||||
|
||||
private boolean wasSneakingBeforeTouchingGround = false;
|
||||
private boolean holdingSneakWhileTouchingGround = false;
|
||||
private int temporaryFlyOnGroundTimer = 0;
|
||||
|
||||
private void setup(){
|
||||
final AccessStickyKeyBindingStateGetter sprint = (AccessStickyKeyBindingStateGetter)mc().options.keySprint;
|
||||
BooleanSupplier getter = sprint.getToggleGetter();
|
||||
|
||||
if (getter instanceof SprintPressGetter){
|
||||
getter = ((SprintPressGetter)getter).getWrapped();
|
||||
}
|
||||
|
||||
sprint.setToggleGetter(new SprintPressGetter(getter, () -> temporarySprintTimer > 0));
|
||||
}
|
||||
|
||||
public void atHead(final ClientPlayerEntity player){
|
||||
if (FlightHelper.shouldFlyOnGround(player)){
|
||||
player.setOnGround(false);
|
||||
@ -66,6 +82,21 @@ public final class PlayerTicker{
|
||||
final boolean wasSprintToggled = opts.sprintToggled;
|
||||
final boolean isSprintToggled = toggleSprint.tick();
|
||||
|
||||
if (temporarySprintTimer > 0){
|
||||
stopSprintingAfterReleasingSprintKey = false;
|
||||
waitingForSprintKeyRelease = false;
|
||||
|
||||
final int nextTemporarySprintTimer = temporarySprintTimer - 1;
|
||||
temporarySprintTimer = 0;
|
||||
|
||||
if (!opts.keySprint.isPressed() && opts.keyForward.isPressed()){
|
||||
temporarySprintTimer = nextTemporarySprintTimer;
|
||||
}
|
||||
else if (cfg().tapSprintKeyAgainToStopSprinting){
|
||||
stopSprintingAfterReleasingSprintKey = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSprintToggled){
|
||||
stopSprintingAfterReleasingSprintKey = false;
|
||||
waitingForSprintKeyRelease = false;
|
||||
@ -123,7 +154,7 @@ public final class PlayerTicker{
|
||||
}
|
||||
else if (wasSprintingBeforeHittingObstacle){
|
||||
wasSprintingBeforeHittingObstacle = false;
|
||||
player.setSprinting(true);
|
||||
temporarySprintTimer = 10;
|
||||
}
|
||||
|
||||
// collision also stops when the player lets go of movement keys
|
||||
|
@ -0,0 +1,21 @@
|
||||
package chylex.bettercontrols.player;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
final class SprintPressGetter implements BooleanSupplier{
|
||||
private final BooleanSupplier wrapped;
|
||||
private final BooleanSupplier or;
|
||||
|
||||
public SprintPressGetter(final BooleanSupplier wrapped, final BooleanSupplier or){
|
||||
this.wrapped = wrapped;
|
||||
this.or = or;
|
||||
}
|
||||
|
||||
public BooleanSupplier getWrapped(){
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAsBoolean(){
|
||||
return wrapped.getAsBoolean() || or.getAsBoolean();
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
"AccessControlsListKeyBinding",
|
||||
"AccessKeyBindingFields",
|
||||
"AccessScreenButtons",
|
||||
"AccessStickyKeyBindingStateGetter",
|
||||
"HookClientPlayerInputTick",
|
||||
"HookClientPlayerTick",
|
||||
"HookControlsListWidget",
|
||||
|
Loading…
Reference in New Issue
Block a user