From b788e4e5b43d67411c147014031baebac08bdbfc Mon Sep 17 00:00:00 2001 From: olim88 Date: Tue, 26 May 2026 15:55:57 +0100 Subject: [PATCH 1/3] sligtly improve smooth aote. Why have they suddenly started changing it all the time --- .../skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java b/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java index cc937a7b1cb..9b05e5b72bb 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java @@ -43,6 +43,8 @@ import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; +import org.jspecify.annotations.Nullable; + import java.util.List; public class PredictiveSmoothAOTE { @@ -52,8 +54,11 @@ public class PredictiveSmoothAOTE { private static final long MAX_TELEPORT_TIME = 2500; //2.5 seconds private static long startTime; + @Nullable private static Vec3 startPos; + @Nullable private static Vec3 cameraStartPos; + @Nullable private static Vec3 teleportVector; private static long lastPing; private static long currentTeleportPing; @@ -479,7 +484,7 @@ protected static Vec3 raycast(int distance, Vec3 direction, Vec3 startPos, boole } //return full distance if no collision found - return direction.scale(distance); + return direction.scale(distance).subtract(0,1,0); } /** From 65af506a79610e002554d743018cc10ff4b7c55a Mon Sep 17 00:00:00 2001 From: olim88 Date: Thu, 4 Jun 2026 14:09:52 +0100 Subject: [PATCH 2/3] Add 3rd person support for smoothing --- .../categories/UIAndVisualsCategory.java | 8 +++++ .../config/configs/UIAndVisualsConfig.java | 2 ++ .../hysky/skyblocker/mixins/CameraMixin.java | 2 +- .../mixins/EntityRendererMixin.java | 31 +++++++++++++++++++ .../teleport/PredictiveSmoothAOTE.java | 26 +++++++++++++--- .../teleport/ResponsiveSmoothAOTE.java | 29 ++++++++++++++--- .../assets/skyblocker/lang/en_us.json | 2 ++ 7 files changed, 90 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java index b851b1b463c..ac4c9840d9a 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java @@ -628,6 +628,14 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig newValue -> config.uiAndVisuals.smoothAOTE.predictive = newValue) .controller(ConfigUtils.createBooleanController()) .build()) + .option(Option.createBuilder() + .name(Component.translatable("skyblocker.config.uiAndVisuals.smoothAOTE.thirdPerson")) + .description(Component.translatable("skyblocker.config.uiAndVisuals.smoothAOTE.thirdPerson.@Tooltip")) + .binding(defaults.uiAndVisuals.smoothAOTE.thirdPerson, + () -> config.uiAndVisuals.smoothAOTE.thirdPerson, + newValue -> config.uiAndVisuals.smoothAOTE.thirdPerson = newValue) + .controller(ConfigUtils.createBooleanController()) + .build()) .option(Option.createBuilder() .name(Component.translatable("skyblocker.config.uiAndVisuals.smoothAOTE.enableWeirdTransmission")) .description(Component.translatable("skyblocker.config.uiAndVisuals.smoothAOTE.enableWeirdTransmission.@Tooltip")) diff --git a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java index f188d4179a5..eb2ef13040c 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java @@ -358,6 +358,8 @@ public static class TeleportOverlay { public static class SmoothAOTE { public boolean predictive = false; + public boolean thirdPerson = true; + public boolean enableWeirdTransmission = false; public boolean enableInstantTransmission = false; diff --git a/src/main/java/de/hysky/skyblocker/mixins/CameraMixin.java b/src/main/java/de/hysky/skyblocker/mixins/CameraMixin.java index 27232b814cd..f1b8bd3440b 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/CameraMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/CameraMixin.java @@ -20,7 +20,7 @@ public class CameraMixin { return pos; } } else { - Vec3 pos = ResponsiveSmoothAOTE.getInterpolatedPos(); + Vec3 pos = ResponsiveSmoothAOTE.getInterpolatedPos(original); if (pos != null) { return pos; } diff --git a/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java b/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java index 2624cf260fd..b30213f9b94 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java @@ -8,13 +8,17 @@ import de.hysky.skyblocker.skyblock.entity.MobBoundingBoxes; import de.hysky.skyblocker.skyblock.entity.MobGlow; import de.hysky.skyblocker.skyblock.slayers.SlayerManager; +import de.hysky.skyblocker.skyblock.teleport.PredictiveSmoothAOTE; +import de.hysky.skyblocker.skyblock.teleport.ResponsiveSmoothAOTE; import de.hysky.skyblocker.utils.Boxes; import de.hysky.skyblocker.utils.ColorUtils; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.state.EntityRenderState; import net.minecraft.network.chat.Component; import net.minecraft.util.ARGB; import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -57,6 +61,33 @@ public class EntityRendererMixin { } } + // This is meant to be separate from the previous injection for organizational purposes. + @Inject(method = "extractRenderState", at = @At(value = "TAIL")) + private void skyblocker$movePlayerRenderPos(CallbackInfo ci, @Local(name = "entity") Entity entity, @Local(name = "state") EntityRenderState state, @Local(name = "partialTicks") float partialTicks) + { + Minecraft client = Minecraft.getInstance(); + + if (entity == client.player && !client.options.getCameraType().isFirstPerson()) { + if (SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.predictive) { + Vec3 pos = PredictiveSmoothAOTE.getInterpolatedPlayerPos(); + if (pos != null ) + { + state.x = pos.x; + state.y = pos.y; + state.z = pos.z; + } + } else { + Vec3 pos = ResponsiveSmoothAOTE.getInterpolatedPlayerPos(partialTicks); + if (pos != null ) + { + state.x = pos.x; + state.y = pos.y; + state.z = pos.z; + } + } + } + } + @ModifyReturnValue(method = "getNameTag", at = @At("RETURN")) private @Nullable Component skyblocker$applyCustomName(@Nullable Component original, T entity) { Component customName = entity.skyblocker$getCustomName(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java b/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java index 9b05e5b72bb..324f661b655 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java @@ -12,6 +12,7 @@ import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.Location; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.render.RenderHelper; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.event.player.UseItemCallback; @@ -182,8 +183,8 @@ private static void calculateTeleportUse(InteractionHand hand) { return; } - // make sure the camera is not in 3rd person - if (CLIENT.options.getCameraType() != CameraType.FIRST_PERSON) { + // make sure the camera is not in 3rd person if disabled + if (CLIENT.options.getCameraType() != CameraType.FIRST_PERSON && !SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.thirdPerson) { return; } @@ -216,7 +217,7 @@ private static void calculateTeleportUse(InteractionHand hand) { if (teleportsAhead == 0 || startPos == null || teleportVector == null) { //start of teleport sequence startPos = CLIENT.player.position().add(0, Utils.getEyeHeight(CLIENT.player), 0); // the eye poss should not be affected by crouching - cameraStartPos = CLIENT.player.getEyePosition(); + cameraStartPos = RenderHelper.getCamera().position(); lastTeleportTime = System.currentTimeMillis(); // update the ping used for the teleport currentTeleportPing = lastPing; @@ -484,7 +485,12 @@ protected static Vec3 raycast(int distance, Vec3 direction, Vec3 startPos, boole } //return full distance if no collision found - return direction.scale(distance).subtract(0,1,0); + //Hypixel has started moving this a block down so do that if it's not solid + if (!isBlockFloor(BlockPos.containing(startPos.add(direction.scale(distance)).subtract(0, 1, 0)))) { + return direction.scale(distance).subtract(0, 1, 0); + } + + return direction.scale(distance); } /** @@ -533,11 +539,12 @@ private static Boolean isBlockFloor(BlockPos blockPos) { * * @return the camera position for the interpolated pos */ - + @Nullable public static Vec3 getInterpolatedPos() { if (CLIENT.player == null || teleportVector == null || startPos == null || teleportDisabled) { return null; } + //save actual Camara position long gap = System.currentTimeMillis() - startTime; //make sure the player is actually getting teleported if not disable teleporting until they are teleported again if (System.currentTimeMillis() - lastTeleportTime > Math.min(Math.max(lastPing, currentTeleportPing) + ((long) SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.maximumAddedLag * teleportsAhead), MAX_TELEPORT_TIME)) { @@ -561,6 +568,15 @@ public static Vec3 getInterpolatedPos() { return cameraStartPos.add(teleportVector.scale(percentage)); } + @Nullable + public static Vec3 getInterpolatedPlayerPos() { + if (startPos == null || CLIENT.player == null || cameraStartPos == null) return null; + Vec3 diff = startPos.subtract(0, Utils.getEyeHeight(CLIENT.player), 0).subtract(cameraStartPos); + Vec3 camara = getInterpolatedPos(); + if (camara == null) return null; + return camara.add(diff); + } + public static void updatePing(long ping) { lastPing = ping; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/teleport/ResponsiveSmoothAOTE.java b/src/main/java/de/hysky/skyblocker/skyblock/teleport/ResponsiveSmoothAOTE.java index 0253bb76224..468ed922538 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/teleport/ResponsiveSmoothAOTE.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/teleport/ResponsiveSmoothAOTE.java @@ -2,19 +2,26 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.ItemUtils; +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.minecraft.client.CameraType; import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; +import javax.annotation.Nullable; + import static de.hysky.skyblocker.skyblock.teleport.PredictiveSmoothAOTE.getItemDistance; public class ResponsiveSmoothAOTE { private static final Minecraft CLIENT = Minecraft.getInstance(); private static long startTime; + @Nullable private static Vec3 lastPosition; private static double lastProgress; + @Nullable + private static Vec3 cameraStartPos; public static void playerGoingToTeleport() { if (CLIENT.player == null || SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.maximumAddedLag == 0) return; @@ -26,15 +33,21 @@ public static void playerGoingToTeleport() { if (distance == -1) { return; } + // make sure the camera is not in 3rd person if disabled + if (CLIENT.options.getCameraType() != CameraType.FIRST_PERSON && !SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.thirdPerson) { + return; + } - Vec3 currentIntermediatePosition = getInterpolatedPos(); - lastPosition = currentIntermediatePosition == null ? CLIENT.player.getEyePosition() : currentIntermediatePosition; + Vec3 currentIntermediatePosition = getInterpolatedPos(RenderHelper.getCamera().position()); + lastPosition = currentIntermediatePosition == null ? RenderHelper.getCamera().position() : currentIntermediatePosition; lastProgress = 0; startTime = System.currentTimeMillis(); } - public static Vec3 getInterpolatedPos() { + @Nullable + public static Vec3 getInterpolatedPos(Vec3 original) { if (lastPosition == null || CLIENT.player == null) return null; + cameraStartPos = original; double progress = (double) (System.currentTimeMillis() - startTime) / SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.maximumAddedLag; //end if finished if (progress >= 1) { @@ -43,7 +56,7 @@ public static Vec3 getInterpolatedPos() { return null; } //find vector between last position and current pos - Vec3 teleportVector = CLIENT.player.getEyePosition().subtract(lastPosition); + Vec3 teleportVector = original.subtract(lastPosition); double progressDiff = progress - lastProgress; double relativeProgress = progressDiff / (1 - lastProgress); @@ -53,6 +66,14 @@ public static Vec3 getInterpolatedPos() { lastPosition = lastPosition.add(teleportVector.scale(relativeProgress)); lastProgress = progress; return lastPosition; + } + @Nullable + public static Vec3 getInterpolatedPlayerPos(float partialTicks) { + if (CLIENT.player == null || cameraStartPos == null) return null; + Vec3 diff = CLIENT.player.getPosition(partialTicks).subtract(cameraStartPos); + Vec3 camara = getInterpolatedPos(cameraStartPos); + if (camara == null) return null; + return camara.add(diff); } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index ed9d1ac0194..4b240b44af3 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -1376,6 +1376,8 @@ "skyblocker.config.uiAndVisuals.smoothAOTE.maximumAddedLag.@Tooltip": "Predictive:\nHow long the animation is allowed to get behind the game in milliseconds. (If set to 0, smoothing will not have any lag, but stuttering will likely occur. Increase this value if you're experiencing flashing.)\n\nPredictive disabled:\nduration of animation", "skyblocker.config.uiAndVisuals.smoothAOTE.predictive": "Predictive Algorithm", "skyblocker.config.uiAndVisuals.smoothAOTE.predictive.@Tooltip": "Predict where the teleport will end. This will mean there can be no added lag however it is sometimes wrong and can glitch out.", + "skyblocker.config.uiAndVisuals.smoothAOTE.thirdPerson": "Enable 3rd Person", + "skyblocker.config.uiAndVisuals.smoothAOTE.thirdPerson.@Tooltip": "Enables teleport smoothing when in 3rd person modes", "skyblocker.config.uiAndVisuals.swingOnAbilities": "Swing On Abilities", "skyblocker.config.uiAndVisuals.swingOnAbilities.@Tooltip": "Swings your hand whenever you use an item with a right-click ability.", From f05f11ef3669985b2649a2c34fccbafccf29fb56 Mon Sep 17 00:00:00 2001 From: olim88 Date: Thu, 4 Jun 2026 14:23:15 +0100 Subject: [PATCH 3/3] clean up --- .../mixins/EntityRendererMixin.java | 27 ++++++++----------- .../teleport/PredictiveSmoothAOTE.java | 5 +++- .../assets/skyblocker/lang/en_us.json | 2 +- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java b/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java index b30213f9b94..ae66b3a6c52 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/EntityRendererMixin.java @@ -63,27 +63,22 @@ public class EntityRendererMixin { // This is meant to be separate from the previous injection for organizational purposes. @Inject(method = "extractRenderState", at = @At(value = "TAIL")) - private void skyblocker$movePlayerRenderPos(CallbackInfo ci, @Local(name = "entity") Entity entity, @Local(name = "state") EntityRenderState state, @Local(name = "partialTicks") float partialTicks) - { + private void skyblocker$movePlayerRenderPos(CallbackInfo ci, @Local(name = "entity") Entity entity, @Local(name = "state") EntityRenderState state, @Local(name = "partialTicks") float partialTicks) { Minecraft client = Minecraft.getInstance(); if (entity == client.player && !client.options.getCameraType().isFirstPerson()) { + Vec3 pos; if (SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.predictive) { - Vec3 pos = PredictiveSmoothAOTE.getInterpolatedPlayerPos(); - if (pos != null ) - { - state.x = pos.x; - state.y = pos.y; - state.z = pos.z; - } + pos = PredictiveSmoothAOTE.getInterpolatedPlayerPos(); + } else { - Vec3 pos = ResponsiveSmoothAOTE.getInterpolatedPlayerPos(partialTicks); - if (pos != null ) - { - state.x = pos.x; - state.y = pos.y; - state.z = pos.z; - } + pos = ResponsiveSmoothAOTE.getInterpolatedPlayerPos(partialTicks); + } + if (pos != null) + { + state.x = pos.x; + state.y = pos.y; + state.z = pos.z; } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java b/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java index 324f661b655..25bb0d72d53 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/teleport/PredictiveSmoothAOTE.java @@ -544,7 +544,6 @@ public static Vec3 getInterpolatedPos() { if (CLIENT.player == null || teleportVector == null || startPos == null || teleportDisabled) { return null; } - //save actual Camara position long gap = System.currentTimeMillis() - startTime; //make sure the player is actually getting teleported if not disable teleporting until they are teleported again if (System.currentTimeMillis() - lastTeleportTime > Math.min(Math.max(lastPing, currentTeleportPing) + ((long) SkyblockerConfigManager.get().uiAndVisuals.smoothAOTE.maximumAddedLag * teleportsAhead), MAX_TELEPORT_TIME)) { @@ -568,6 +567,10 @@ public static Vec3 getInterpolatedPos() { return cameraStartPos.add(teleportVector.scale(percentage)); } + /** + * Get the difference between the camara and the actual player position. Then adds this to interpolated camara position + * @return Interpolated player position + */ @Nullable public static Vec3 getInterpolatedPlayerPos() { if (startPos == null || CLIENT.player == null || cameraStartPos == null) return null; diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 4b240b44af3..6a3935436b9 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -1377,7 +1377,7 @@ "skyblocker.config.uiAndVisuals.smoothAOTE.predictive": "Predictive Algorithm", "skyblocker.config.uiAndVisuals.smoothAOTE.predictive.@Tooltip": "Predict where the teleport will end. This will mean there can be no added lag however it is sometimes wrong and can glitch out.", "skyblocker.config.uiAndVisuals.smoothAOTE.thirdPerson": "Enable 3rd Person", - "skyblocker.config.uiAndVisuals.smoothAOTE.thirdPerson.@Tooltip": "Enables teleport smoothing when in 3rd person modes", + "skyblocker.config.uiAndVisuals.smoothAOTE.thirdPerson.@Tooltip": "Enables teleport smoothing when in 3rd person modes.", "skyblocker.config.uiAndVisuals.swingOnAbilities": "Swing On Abilities", "skyblocker.config.uiAndVisuals.swingOnAbilities.@Tooltip": "Swings your hand whenever you use an item with a right-click ability.",