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
2021-11-16 00:10:21 +01:00
committed by Jonas Herzig
parent fe67d7fa14
commit d9da2e135c
3 changed files with 69 additions and 0 deletions

View File

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

View File

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

View File

@@ -7,6 +7,8 @@
"client": [
"entity_tracking.Mixin_EntityExt",
"entity_tracking.Mixin_FixPartialUpdates",
"world_border.Mixin_UseReplayTime_ForMovement",
"world_border.Mixin_UseReplayTime_ForTexture",
"Mixin_FixNPCSkinCaching",
//#if MC>=11800
//$$ "Mixin_FixEntityNotTracking",