diff --git a/src/main/java/com/replaymod/replay/mixin/ClientWorldAccessor.java b/src/main/java/com/replaymod/replay/mixin/ClientWorldAccessor.java new file mode 100644 index 00000000..ba16ed59 --- /dev/null +++ b/src/main/java/com/replaymod/replay/mixin/ClientWorldAccessor.java @@ -0,0 +1,13 @@ +package com.replaymod.replay.mixin; + +import net.minecraft.client.world.ClientWorld; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ClientWorld.class) +public interface ClientWorldAccessor { + //#if MC>=11800 + //$$ @Accessor + //$$ net.minecraft.world.EntityList getEntityList(); + //#endif +} diff --git a/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java b/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java new file mode 100644 index 00000000..464bb200 --- /dev/null +++ b/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java @@ -0,0 +1 @@ +// 1.18+ only diff --git a/src/main/resources/mixins.replay.replaymod.json b/src/main/resources/mixins.replay.replaymod.json index feb30fa7..6a481a03 100644 --- a/src/main/resources/mixins.replay.replaymod.json +++ b/src/main/resources/mixins.replay.replaymod.json @@ -6,6 +6,9 @@ "server": [], "client": [ "Mixin_FixNPCSkinCaching", + //#if MC>=11800 + //$$ "Mixin_FixEntityNotTracking", + //#endif //#if MC>=11600 "Mixin_MoveRealmsButton", //#endif @@ -13,6 +16,7 @@ "MixinCamera", "MixinInGameHud", //#endif + "ClientWorldAccessor", "EntityLivingBaseAccessor", //#if MC>=11400 "Mixin_ShowSpectatedHand_NoOF", diff --git a/versions/1.18/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java b/versions/1.18/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java new file mode 100644 index 00000000..1d95dd1b --- /dev/null +++ b/versions/1.18/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java @@ -0,0 +1,38 @@ +package com.replaymod.replay.mixin; + +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.Vec3d; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(ClientPlayNetworkHandler.class) +public class Mixin_FixEntityNotTracking { + @ModifyVariable(method = { "onEntityPosition", "onEntity", "onEntityPassengersSet" }, at = @At("RETURN"), ordinal = 0) + private Entity updatePositionIfNotTracked$0(Entity entity) { + if (entity != null) { + entity.streamSelfAndPassengers().forEach(this::updatePositionIfNotTracked); + } + return entity; + } + + private void updatePositionIfNotTracked(Entity entity) { + if (entity != null && entity.world instanceof ClientWorldAccessor world) { + if (!world.getEntityList().has(entity)) { + // Skip interpolation of position updates coming from server + // (See: newX in EntityLivingBase or otherPlayerMPX in EntityOtherPlayerMP) + int ticks = 0; + Vec3d prevPos; + do { + prevPos = entity.getPos(); + if (entity.hasVehicle()) { + entity.tickRiding(); + } else { + entity.tick(); + } + } while (prevPos.squaredDistanceTo(entity.getPos()) > 0.0001 && ticks++ < 100); + } + } + } +}