mirror of
https://github.com/chylex/Better-Controls.git
synced 2025-04-28 09:15:45 +02:00
Redo flight speed logic to support vanilla spectator speed boost
Closes #14
This commit is contained in:
parent
7f9992a190
commit
21aa005bc4
src/main
java/chylex/bettercontrols
mixin
HookClientPlayerVerticalFlightSpeed.javaHookPlayerFlightSpeed.javaHookPlayerHorizontalFlightSpeed.java
player
resources
@ -0,0 +1,36 @@
|
|||||||
|
package chylex.bettercontrols.mixin;
|
||||||
|
|
||||||
|
import chylex.bettercontrols.player.FlightHelper;
|
||||||
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.player.Abilities;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Slice;
|
||||||
|
|
||||||
|
@SuppressWarnings("SameReturnValue")
|
||||||
|
@Mixin(LocalPlayer.class)
|
||||||
|
public abstract class HookClientPlayerVerticalFlightSpeed extends LivingEntity {
|
||||||
|
protected HookClientPlayerVerticalFlightSpeed(final EntityType<? extends LivingEntity> type, final Level world) {
|
||||||
|
super(type, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "aiStep",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Abilities;getFlyingSpeed()F"),
|
||||||
|
slice = @Slice(
|
||||||
|
from = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Abilities;flying:Z"),
|
||||||
|
to = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private float modifyVerticalFlightSpeed(final Abilities abilities) {
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
final LocalPlayer me = (LocalPlayer)(Object)this;
|
||||||
|
|
||||||
|
final float multiplier = 1F + FlightHelper.getVerticalSpeedBoost(me);
|
||||||
|
return abilities.getFlyingSpeed() * multiplier;
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
package chylex.bettercontrols.mixin;
|
|
||||||
|
|
||||||
import net.minecraft.world.entity.EntityType;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Slice;
|
|
||||||
|
|
||||||
@SuppressWarnings("SameReturnValue")
|
|
||||||
@Mixin(Player.class)
|
|
||||||
public abstract class HookPlayerFlightSpeed extends LivingEntity {
|
|
||||||
protected HookPlayerFlightSpeed(final EntityType<? extends LivingEntity> type, final Level world) {
|
|
||||||
super(type, world);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(
|
|
||||||
method = "getFlyingSpeed",
|
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;isSprinting()Z"),
|
|
||||||
slice = @Slice(
|
|
||||||
from = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Abilities;flying:Z"),
|
|
||||||
to = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Abilities;getFlyingSpeed()F")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
private boolean disableVanillaSprintBoost(final Player player) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,51 @@
|
|||||||
|
package chylex.bettercontrols.mixin;
|
||||||
|
|
||||||
|
import chylex.bettercontrols.player.FlightHelper;
|
||||||
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Slice;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@SuppressWarnings("SameReturnValue")
|
||||||
|
@Mixin(Player.class)
|
||||||
|
public abstract class HookPlayerHorizontalFlightSpeed extends LivingEntity {
|
||||||
|
protected HookPlayerHorizontalFlightSpeed(final EntityType<? extends LivingEntity> type, final Level world) {
|
||||||
|
super(type, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SimplifiableIfStatement")
|
||||||
|
@Redirect(
|
||||||
|
method = "getFlyingSpeed",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;isSprinting()Z"),
|
||||||
|
slice = @Slice(
|
||||||
|
from = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Abilities;flying:Z"),
|
||||||
|
to = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Abilities;getFlyingSpeed()F")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private boolean disableVanillaSprintBoost(final Player player) {
|
||||||
|
if (player instanceof LocalPlayer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return player.isSprinting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "getFlyingSpeed", at = @At("RETURN"), cancellable = true)
|
||||||
|
private void modifyHorizontalFlyingSpeed(final CallbackInfoReturnable<Float> cir) {
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
final Player me = (Player)(Object)this;
|
||||||
|
|
||||||
|
if (me instanceof final LocalPlayer localPlayer) {
|
||||||
|
final float multiplier = FlightHelper.getHorizontalSpeedMultiplier(localPlayer);
|
||||||
|
cir.setReturnValue(Float.valueOf(cir.getReturnValueF() * multiplier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,18 @@ package chylex.bettercontrols.player;
|
|||||||
|
|
||||||
import chylex.bettercontrols.BetterControlsCommon;
|
import chylex.bettercontrols.BetterControlsCommon;
|
||||||
import chylex.bettercontrols.config.BetterControlsConfig;
|
import chylex.bettercontrols.config.BetterControlsConfig;
|
||||||
|
import net.minecraft.client.KeyMapping;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
|
|
||||||
final class FlightHelper {
|
public final class FlightHelper {
|
||||||
private FlightHelper() {}
|
private FlightHelper() {}
|
||||||
|
|
||||||
private static final float BASE_FLIGHT_SPEED = 0.05F;
|
private static final KeyMapping KEY_SPRINT = Minecraft.getInstance().options.keySprint;
|
||||||
private static final float BASE_VERTICAL_VELOCITY = 3F;
|
|
||||||
|
private static boolean isSprinting() {
|
||||||
|
return KEY_SPRINT.isDown();
|
||||||
|
}
|
||||||
|
|
||||||
private static BetterControlsConfig cfg() {
|
private static BetterControlsConfig cfg() {
|
||||||
return BetterControlsCommon.getConfig();
|
return BetterControlsCommon.getConfig();
|
||||||
@ -22,44 +27,24 @@ final class FlightHelper {
|
|||||||
return cfg().flyOnGroundInCreative && player.isCreative() && player.getAbilities().flying;
|
return cfg().flyOnGroundInCreative && player.isCreative() && player.getAbilities().flying;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float getFlightSpeed(final LocalPlayer player, final boolean boost) {
|
public static float getHorizontalSpeedMultiplier(final LocalPlayer player) {
|
||||||
if (player.isCreative()) {
|
if (player.isCreative()) {
|
||||||
if (boost) {
|
return isSprinting() ? cfg().flightSpeedMpCreativeSprinting : cfg().flightSpeedMpCreativeDefault;
|
||||||
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpCreativeSprinting;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpCreativeDefault;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (player.isSpectator()) {
|
else if (player.isSpectator()) {
|
||||||
if (boost) {
|
return isSprinting() ? cfg().flightSpeedMpSpectatorSprinting : cfg().flightSpeedMpSpectatorDefault;
|
||||||
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpSpectatorSprinting;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpSpectatorDefault;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0F;
|
return 1F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float getExtraVerticalVelocity(final LocalPlayer player, final boolean isSprinting) {
|
public static float getVerticalSpeedBoost(final LocalPlayer player) {
|
||||||
if (player.isCreative()) {
|
if (player.isCreative()) {
|
||||||
if (isSprinting) {
|
return isSprinting() ? cfg().flightVerticalBoostCreativeSprinting : cfg().flightVerticalBoostCreativeDefault;
|
||||||
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostCreativeSprinting;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostCreativeDefault;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (player.isSpectator()) {
|
else if (player.isSpectator()) {
|
||||||
if (isSprinting) {
|
return isSprinting() ? cfg().flightVerticalBoostSpectatorSprinting : cfg().flightVerticalBoostSpectatorDefault;
|
||||||
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostSpectatorSprinting;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostSpectatorDefault;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0F;
|
return 0F;
|
||||||
|
@ -163,32 +163,6 @@ public final class PlayerTicker {
|
|||||||
input.jumping |= toggleJump.tick();
|
input.jumping |= toggleJump.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FlightHelper.isFlyingCreativeOrSpectator(player)) {
|
|
||||||
final boolean boost = KEY_SPRINT.isDown();
|
|
||||||
final float flightSpeed = FlightHelper.getFlightSpeed(player, boost);
|
|
||||||
final float verticalVelocity = FlightHelper.getExtraVerticalVelocity(player, boost);
|
|
||||||
|
|
||||||
if (flightSpeed > 0F) {
|
|
||||||
player.getAbilities().setFlyingSpeed(flightSpeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Math.abs(verticalVelocity) > 1E-5F && player == MINECRAFT.getCameraEntity()) {
|
|
||||||
int direction = 0;
|
|
||||||
|
|
||||||
if (input.shiftKeyDown) {
|
|
||||||
--direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.jumping) {
|
|
||||||
++direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direction != 0) {
|
|
||||||
player.setDeltaMovement(player.getDeltaMovement().add(0D, flightSpeed * verticalVelocity * direction, 0D));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg().resumeSprintingAfterHittingObstacle) {
|
if (cfg().resumeSprintingAfterHittingObstacle) {
|
||||||
if (wasHittingObstacle != player.horizontalCollision) {
|
if (wasHittingObstacle != player.horizontalCollision) {
|
||||||
if (!wasHittingObstacle) {
|
if (!wasHittingObstacle) {
|
||||||
|
@ -13,10 +13,11 @@
|
|||||||
"HookClientPlayerFOV",
|
"HookClientPlayerFOV",
|
||||||
"HookClientPlayerInputTick",
|
"HookClientPlayerInputTick",
|
||||||
"HookClientPlayerTick",
|
"HookClientPlayerTick",
|
||||||
|
"HookClientPlayerVerticalFlightSpeed",
|
||||||
"HookControlsListWidget",
|
"HookControlsListWidget",
|
||||||
"HookControlsScreen",
|
"HookControlsScreen",
|
||||||
"HookLoadGameOptions",
|
"HookLoadGameOptions",
|
||||||
"HookPlayerFlightSpeed",
|
"HookPlayerHorizontalFlightSpeed",
|
||||||
"HookStickyKeyBindingState",
|
"HookStickyKeyBindingState",
|
||||||
"HookToggleOptionButtons"
|
"HookToggleOptionButtons"
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user