diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/constants/MixinEntity.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/constants/MixinEntity.java index ef92ab7b3..70034bef3 100644 --- a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/constants/MixinEntity.java +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/constants/MixinEntity.java @@ -23,7 +23,9 @@ import com.viaversion.viafabricplus.protocoltranslator.ProtocolTranslator; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Constant; @@ -45,12 +47,33 @@ private double fixBlockCollisionMargin(double constant) { } } - @ModifyConstant(method = "getInputVector", constant = @Constant(doubleValue = 1E-7)) - private static double fixVelocityEpsilon(double epsilon) { + @Inject(method = "getInputVector", at = @At("HEAD"), cancellable = true) + private static void fixInputVector(Vec3 input, float speed, float yRot, CallbackInfoReturnable cir) { if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) { - return 1E-4; - } else { - return epsilon; + float x = (float) input.x; + float z = (float) input.z; + + float length = x * x + z * z; + + if (length < 1.0E-4F) { + cir.setReturnValue(Vec3.ZERO); + } + + length = Math.max(Mth.sqrt(length), 1.0F); + + final float scale = speed / length; + + x *= scale; + z *= scale; + + final float sin = Mth.sin(yRot * (float) (Math.PI / 180.0)); + final float cos = Mth.cos(yRot * (float) (Math.PI / 180.0)); + + cir.setReturnValue(new Vec3( + x * cos - z * sin, + input.y, + z * cos + x * sin + )); } } diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/limitation/MixinLivingEntity.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/limitation/MixinLivingEntity.java index d0cf71912..29bf11059 100644 --- a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/limitation/MixinLivingEntity.java +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/movement/limitation/MixinLivingEntity.java @@ -35,8 +35,10 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyConstant; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntity.class) public abstract class MixinLivingEntity extends Entity { @@ -45,6 +47,12 @@ public MixinLivingEntity(EntityType type, Level world) { super(type, world); } + @Shadow + public abstract float getSpeed(); + + @Shadow + protected abstract float getFlyingSpeed(); + @Shadow public abstract boolean hasEffect(Holder effect); @@ -57,6 +65,15 @@ private double allowFrictionLessThan(double constant) { } } + @Inject(method = "getFrictionInfluencedSpeed", at = @At("HEAD"), cancellable = true) + private void modifyFrictionInfluencedSpeed(float blockFriction, CallbackInfoReturnable cir) { + if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) { + float drag = this.onGround() ? blockFriction * 0.91F : 0.91F; + float accel = 0.16277136F / (drag * drag * drag); + cir.setReturnValue(this.onGround() ? this.getSpeed() * accel : this.getFlyingSpeed()); + } + } + @Redirect(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;is(Ljava/lang/Object;)Z")) private boolean useEuclideanDistanceCalculation(LivingEntity instance, Object o) { if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_21_4)) {