Sync world border animation & movement to Replay speed

Fixes an issue where the world border would move at normal speed when speeding up or slowing down the replay, and also at an incorrect speed when rendering the replay, causing it to get out of sync with the rest of the world.

Co-authored-by: Jonas Herzig <me@johni0702.de>
This commit is contained in:
Jochem
2022-03-06 13:39:49 +01:00
committed by Jonas Herzig
co-authored by Jonas Herzig
parent fe67d7fa14
commit d9da2e135c
3 changed files with 69 additions and 0 deletions
@@ -0,0 +1,38 @@
package com.replaymod.replay.mixin.world_border;
import com.replaymod.core.versions.MCVer;
import com.replaymod.replay.ReplayHandler;
import com.replaymod.replay.ReplayModReplay;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
/**
* Normally Minecraft's world border movement is based off real time;
* this redirect ensures that it is synced with the time in the Replay instead.
*/
//#if MC>=11400
// FIXME: preprocessor should be able to remap between fabric and forge
//#if FABRIC
@Mixin(targets = "net.minecraft.world.border.WorldBorder.MovingArea")
//#else
//$$ @Mixin(targets = "net.minecraft.world.border.WorldBorder.MovingBorderInfo")
//#endif
//#else
//$$ @Mixin(net.minecraft.world.border.WorldBorder.class)
//#endif
public class Mixin_UseReplayTime_ForMovement {
//#if MC>=11400
@Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Util;getMeasuringTimeMs()J"))
//#else
//$$ @Redirect(method = "*", at = @At(value = "INVOKE", target = "Ljava/lang/System;currentTimeMillis()J"))
//#endif
private long getWorldBorderTime() {
ReplayHandler replayHandler = ReplayModReplay.instance.getReplayHandler();
if (replayHandler != null) {
return replayHandler.getReplaySender().currentTimeStamp();
}
return MCVer.milliTime();
}
}
@@ -0,0 +1,29 @@
package com.replaymod.replay.mixin.world_border;
import com.replaymod.core.versions.MCVer;
import com.replaymod.replay.ReplayHandler;
import com.replaymod.replay.ReplayModReplay;
import net.minecraft.client.render.WorldRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
/**
* Normally Minecraft's world border texture animation is based off real time;
* this redirect ensures that it is synced with the time in the Replay instead.
*/
@Mixin(WorldRenderer.class)
public class Mixin_UseReplayTime_ForTexture {
//#if MC>=11400
@Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Util;getMeasuringTimeMs()J"))
//#else
//$$ @Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;getSystemTime()J"))
//#endif
private long getWorldBorderTime() {
ReplayHandler replayHandler = ReplayModReplay.instance.getReplayHandler();
if (replayHandler != null) {
return replayHandler.getReplaySender().currentTimeStamp();
}
return MCVer.milliTime();
}
}
@@ -7,6 +7,8 @@
"client": [ "client": [
"entity_tracking.Mixin_EntityExt", "entity_tracking.Mixin_EntityExt",
"entity_tracking.Mixin_FixPartialUpdates", "entity_tracking.Mixin_FixPartialUpdates",
"world_border.Mixin_UseReplayTime_ForMovement",
"world_border.Mixin_UseReplayTime_ForTexture",
"Mixin_FixNPCSkinCaching", "Mixin_FixNPCSkinCaching",
//#if MC>=11800 //#if MC>=11800
//$$ "Mixin_FixEntityNotTracking", //$$ "Mixin_FixEntityNotTracking",