1
0
mirror of https://github.com/chylex/Better-Controls.git synced 2025-04-28 18:15:46 +02:00

Redo flight speed logic to support vanilla spectator speed boost

Closes 
This commit is contained in:
chylex 2023-06-16 03:27:43 +02:00
parent 7f9992a190
commit 21aa005bc4
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
6 changed files with 104 additions and 87 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}
}

View File

@ -2,13 +2,18 @@ package chylex.bettercontrols.player;
import chylex.bettercontrols.BetterControlsCommon;
import chylex.bettercontrols.config.BetterControlsConfig;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
final class FlightHelper {
public final class FlightHelper {
private FlightHelper() {}
private static final float BASE_FLIGHT_SPEED = 0.05F;
private static final float BASE_VERTICAL_VELOCITY = 3F;
private static final KeyMapping KEY_SPRINT = Minecraft.getInstance().options.keySprint;
private static boolean isSprinting() {
return KEY_SPRINT.isDown();
}
private static BetterControlsConfig cfg() {
return BetterControlsCommon.getConfig();
@ -22,44 +27,24 @@ final class FlightHelper {
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 (boost) {
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpCreativeSprinting;
}
else {
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpCreativeDefault;
}
return isSprinting() ? cfg().flightSpeedMpCreativeSprinting : cfg().flightSpeedMpCreativeDefault;
}
else if (player.isSpectator()) {
if (boost) {
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpSpectatorSprinting;
}
else {
return BASE_FLIGHT_SPEED * cfg().flightSpeedMpSpectatorDefault;
}
return isSprinting() ? cfg().flightSpeedMpSpectatorSprinting : cfg().flightSpeedMpSpectatorDefault;
}
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 (isSprinting) {
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostCreativeSprinting;
}
else {
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostCreativeDefault;
}
return isSprinting() ? cfg().flightVerticalBoostCreativeSprinting : cfg().flightVerticalBoostCreativeDefault;
}
else if (player.isSpectator()) {
if (isSprinting) {
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostSpectatorSprinting;
}
else {
return BASE_VERTICAL_VELOCITY * cfg().flightVerticalBoostSpectatorDefault;
}
return isSprinting() ? cfg().flightVerticalBoostSpectatorSprinting : cfg().flightVerticalBoostSpectatorDefault;
}
else {
return 0F;

View File

@ -163,32 +163,6 @@ public final class PlayerTicker {
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 (wasHittingObstacle != player.horizontalCollision) {
if (!wasHittingObstacle) {

View File

@ -13,10 +13,11 @@
"HookClientPlayerFOV",
"HookClientPlayerInputTick",
"HookClientPlayerTick",
"HookClientPlayerVerticalFlightSpeed",
"HookControlsListWidget",
"HookControlsScreen",
"HookLoadGameOptions",
"HookPlayerFlightSpeed",
"HookPlayerHorizontalFlightSpeed",
"HookStickyKeyBindingState",
"HookToggleOptionButtons"
],