processor, FrameConsumer consumer) {
+ public Pipeline(WorldRenderer worldRenderer, FrameCapturer capturer, FrameProcessor processor, FrameConsumer consumer) {
+ this.worldRenderer = worldRenderer;
this.capturer = capturer;
this.processor = processor;
this.consumer = consumer;
@@ -81,6 +84,7 @@ public class Pipeline implements Runnable {
}
try {
+ worldRenderer.close();
capturer.close();
processor.close();
consumer.close();
diff --git a/src/main/java/com/replaymod/render/rendering/Pipelines.java b/src/main/java/com/replaymod/render/rendering/Pipelines.java
index 51437bfb..51c4a2a8 100644
--- a/src/main/java/com/replaymod/render/rendering/Pipelines.java
+++ b/src/main/java/com/replaymod/render/rendering/Pipelines.java
@@ -10,6 +10,7 @@ import com.replaymod.render.capturer.SimpleOpenGlFrameCapturer;
import com.replaymod.render.capturer.SimplePboOpenGlFrameCapturer;
import com.replaymod.render.capturer.StereoscopicOpenGlFrameCapturer;
import com.replaymod.render.capturer.StereoscopicPboOpenGlFrameCapturer;
+import com.replaymod.render.capturer.WorldRenderer;
import com.replaymod.render.frame.CubicOpenGlFrame;
import com.replaymod.render.frame.ODSOpenGlFrame;
import com.replaymod.render.frame.OpenGlFrame;
@@ -45,66 +46,72 @@ public class Pipelines {
public static Pipeline newDefaultPipeline(RenderInfo renderInfo, FrameConsumer consumer) {
RenderSettings settings = renderInfo.getRenderSettings();
+ WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
FrameCapturer capturer;
if (PixelBufferObject.SUPPORTED) {
- capturer = new SimplePboOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo);
+ capturer = new SimplePboOpenGlFrameCapturer(worldRenderer, renderInfo);
} else {
- capturer = new SimpleOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo);
+ capturer = new SimpleOpenGlFrameCapturer(worldRenderer, renderInfo);
}
- return new Pipeline<>(capturer, new OpenGlToRGBProcessor(), consumer);
+ return new Pipeline<>(worldRenderer, capturer, new OpenGlToRGBProcessor(), consumer);
}
public static Pipeline newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer consumer) {
RenderSettings settings = renderInfo.getRenderSettings();
+ WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
FrameCapturer capturer;
if (PixelBufferObject.SUPPORTED) {
- capturer = new StereoscopicPboOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo);
+ capturer = new StereoscopicPboOpenGlFrameCapturer(worldRenderer, renderInfo);
} else {
- capturer = new StereoscopicOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo);
+ capturer = new StereoscopicOpenGlFrameCapturer(worldRenderer, renderInfo);
}
- return new Pipeline<>(capturer, new StereoscopicToRGBProcessor(), consumer);
+ return new Pipeline<>(worldRenderer, capturer, new StereoscopicToRGBProcessor(), consumer);
}
public static Pipeline newCubicPipeline(RenderInfo renderInfo, FrameConsumer consumer) {
RenderSettings settings = renderInfo.getRenderSettings();
+ WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
FrameCapturer capturer;
if (PixelBufferObject.SUPPORTED) {
- capturer = new CubicPboOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo, settings.getVideoWidth() / 4);
+ capturer = new CubicPboOpenGlFrameCapturer(worldRenderer, renderInfo, settings.getVideoWidth() / 4);
} else {
- capturer = new CubicOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo, settings.getVideoWidth() / 4);
+ capturer = new CubicOpenGlFrameCapturer(worldRenderer, renderInfo, settings.getVideoWidth() / 4);
}
- return new Pipeline<>(capturer, new CubicToRGBProcessor(), consumer);
+ return new Pipeline<>(worldRenderer, capturer, new CubicToRGBProcessor(), consumer);
}
public static Pipeline newEquirectangularPipeline(RenderInfo renderInfo, FrameConsumer consumer) {
RenderSettings settings = renderInfo.getRenderSettings();
+ WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
EquirectangularToRGBProcessor processor = new EquirectangularToRGBProcessor(settings.getVideoWidth(),
settings.getVideoHeight(), settings.getSphericalFovX());
FrameCapturer capturer;
if (PixelBufferObject.SUPPORTED) {
- capturer = new CubicPboOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo, processor.getFrameSize());
+ capturer = new CubicPboOpenGlFrameCapturer(worldRenderer, renderInfo, processor.getFrameSize());
} else {
- capturer = new CubicOpenGlFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo, processor.getFrameSize());
+ capturer = new CubicOpenGlFrameCapturer(worldRenderer, renderInfo, processor.getFrameSize());
}
- return new Pipeline<>(capturer, processor, consumer);
+ return new Pipeline<>(worldRenderer, capturer, processor, consumer);
}
public static Pipeline newODSPipeline(RenderInfo renderInfo, FrameConsumer consumer) {
RenderSettings settings = renderInfo.getRenderSettings();
+ WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
ODSToRGBProcessor processor = new ODSToRGBProcessor(settings.getVideoWidth(),
settings.getVideoHeight(), settings.getSphericalFovX());
FrameCapturer capturer =
- new ODSFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo, processor.getFrameSize());
- return new Pipeline<>(capturer, processor, consumer);
+ new ODSFrameCapturer(worldRenderer, renderInfo, processor.getFrameSize());
+ return new Pipeline<>(worldRenderer, capturer, processor, consumer);
}
public static Pipeline newBlendPipeline(RenderInfo renderInfo) {
RenderSettings settings = renderInfo.getRenderSettings();
- FrameCapturer capturer = new BlendFrameCapturer(new EntityRendererHandler(settings, renderInfo), renderInfo);
+ WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
+ FrameCapturer capturer = new BlendFrameCapturer(worldRenderer, renderInfo);
FrameConsumer consumer = new FrameConsumer() {
@Override
public void consume(RGBFrame frame) {
@@ -114,6 +121,6 @@ public class Pipelines {
public void close() {
}
};
- return new Pipeline<>(capturer, new DummyProcessor<>(), consumer);
+ return new Pipeline<>(worldRenderer, capturer, new DummyProcessor<>(), consumer);
}
}
diff --git a/src/main/java/com/replaymod/replay/FullReplaySender.java b/src/main/java/com/replaymod/replay/FullReplaySender.java
index 953cf7f2..c5ee6517 100644
--- a/src/main/java/com/replaymod/replay/FullReplaySender.java
+++ b/src/main/java/com/replaymod/replay/FullReplaySender.java
@@ -729,10 +729,12 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
final PlayerPositionLookS2CPacket ppl = (PlayerPositionLookS2CPacket) p;
if(!hasWorldLoaded) hasWorldLoaded = true;
- if (mc.currentScreen instanceof DownloadingTerrainScreen) {
- // Close the world loading screen manually in case we swallow the packet
- mc.openScreen(null);
- }
+ ReplayMod.instance.runLater(() -> {
+ if (mc.currentScreen instanceof DownloadingTerrainScreen) {
+ // Close the world loading screen manually in case we swallow the packet
+ mc.openScreen(null);
+ }
+ });
if(replayHandler.shouldSuppressCameraMovements()) return null;
diff --git a/src/main/java/com/replaymod/replay/ReplayHandler.java b/src/main/java/com/replaymod/replay/ReplayHandler.java
index 3cec022f..d20a7f41 100644
--- a/src/main/java/com/replaymod/replay/ReplayHandler.java
+++ b/src/main/java/com/replaymod/replay/ReplayHandler.java
@@ -519,10 +519,6 @@ public class ReplayHandler {
return spectating;
}
- public void setTargetPosition(Location pos) {
- targetCameraPosition = pos;
- }
-
public void moveCameraToTargetPosition() {
CameraEntity cam = getCameraEntity();
if (cam != null && targetCameraPosition != null) {
@@ -592,7 +588,7 @@ public class ReplayHandler {
}
}
- long diff = targetTime - replaySender.getDesiredTimestamp();
+ long diff = targetTime - (replaySender.isHurrying() ? replaySender.getDesiredTimestamp() : replaySender.currentTimeStamp());
if (diff != 0) {
if (diff > 0 && diff < 5000) { // Small difference and no time travel
replaySender.jumpToTime(targetTime);
diff --git a/src/main/java/com/replaymod/replay/camera/CameraEntity.java b/src/main/java/com/replaymod/replay/camera/CameraEntity.java
index c6a298f2..d8b999b8 100644
--- a/src/main/java/com/replaymod/replay/camera/CameraEntity.java
+++ b/src/main/java/com/replaymod/replay/camera/CameraEntity.java
@@ -74,11 +74,13 @@ import net.minecraft.util.Hand;
//#if MC>=10800
import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.client.render.entity.PlayerModelPart;
//#else
//$$ import net.minecraft.client.entity.EntityClientPlayerMP;
//$$ import net.minecraft.util.Session;
//#endif
+import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
@@ -98,6 +100,8 @@ public class CameraEntity
//$$ extends EntityClientPlayerMP
//#endif
{
+ private static final UUID CAMERA_UUID = UUID.nameUUIDFromBytes("ReplayModCamera".getBytes(StandardCharsets.UTF_8));
+
/**
* Roll of this camera in degrees.
*/
@@ -154,6 +158,11 @@ public class CameraEntity
, false
//#endif
);
+ //#if MC>=10900
+ setUuid(CAMERA_UUID);
+ //#else
+ //$$ entityUniqueID = CAMERA_UUID;
+ //#endif
eventHandler.register();
if (ReplayModReplay.instance.getReplayHandler().getSpectatedUUID() == null) {
cameraController = ReplayModReplay.instance.createCameraController(this);
@@ -423,6 +432,15 @@ public class CameraEntity
}
return super.getModel();
}
+
+ @Override
+ public boolean isPartVisible(PlayerModelPart modelPart) {
+ Entity view = getRenderViewEntity(this.client);
+ if (view != this && view instanceof PlayerEntity) {
+ return ((PlayerEntity) view).isPartVisible(modelPart);
+ }
+ return super.isPartVisible(modelPart);
+ }
//#endif
@Override
diff --git a/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java b/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java
index d312d670..f1c140b4 100644
--- a/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java
+++ b/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java
@@ -4,6 +4,7 @@ import com.replaymod.core.ReplayMod;
import com.replaymod.core.versions.MCVer.Keyboard;
import com.replaymod.replay.ReplayHandler;
import com.replaymod.replay.ReplayModReplay;
+import com.replaymod.replay.camera.CameraEntity;
import com.replaymod.replaystudio.data.Marker;
import com.replaymod.replaystudio.util.Location;
import de.johni0702.minecraft.gui.GuiRenderer;
@@ -168,11 +169,14 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline im
} else if (button == 1) { // Right click
selectedMarker = null;
if (replayHandler != null) {
- replayHandler.setTargetPosition(new Location(
- marker.getX(), marker.getY(), marker.getZ(),
- marker.getPitch(), marker.getYaw()
- ));
- replayHandler.doJump(marker.getTime(), false);
+ CameraEntity cameraEntity = replayHandler.getCameraEntity();
+ if (cameraEntity != null) {
+ cameraEntity.setCameraPosRot(new Location(
+ marker.getX(), marker.getY(), marker.getZ(),
+ marker.getYaw(), marker.getPitch()
+ ));
+ }
+ replayHandler.doJump(marker.getTime(), true);
} else {
setCursorPosition(marker.getTime());
}
diff --git a/src/main/java/com/replaymod/replay/mixin/Mixin_MoveRealmsButton.java b/src/main/java/com/replaymod/replay/mixin/Mixin_MoveRealmsButton.java
new file mode 100644
index 00000000..12f19084
--- /dev/null
+++ b/src/main/java/com/replaymod/replay/mixin/Mixin_MoveRealmsButton.java
@@ -0,0 +1,20 @@
+//#if MC>=11600
+package com.replaymod.replay.mixin;
+
+import net.minecraft.client.gui.screen.TitleScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+
+@Mixin(TitleScreen.class)
+public abstract class Mixin_MoveRealmsButton {
+ @ModifyArg(
+ method = "init",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;init(Lnet/minecraft/client/MinecraftClient;II)V"),
+ index = 2
+ )
+ private int adjustRealmsButton(int height) {
+ return height - 24 * 4;
+ }
+}
+//#endif
diff --git a/src/main/resources/mixins.replay.replaymod.json b/src/main/resources/mixins.replay.replaymod.json
index 67b9da55..ff2737f1 100644
--- a/src/main/resources/mixins.replay.replaymod.json
+++ b/src/main/resources/mixins.replay.replaymod.json
@@ -5,6 +5,9 @@
"mixins": [],
"server": [],
"client": [
+ //#if MC>=11600
+ "Mixin_MoveRealmsButton",
+ //#endif
//#if MC>=11400
"MixinCamera",
"MixinInGameHud",
diff --git a/version.txt b/version.txt
index 79a61441..59aa62c1 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-2.4.4
+2.4.5
diff --git a/versions/1.8.9/mapping.txt b/versions/1.8.9/mapping.txt
index 96c38ef4..43123ad0 100644
--- a/versions/1.8.9/mapping.txt
+++ b/versions/1.8.9/mapping.txt
@@ -1,3 +1,4 @@
+net.minecraft.entity.player.EntityPlayer isWearing() func_175148_a()
net.minecraft.client.renderer.WorldRenderer begin() startDrawing()
net.minecraft.network.play.server.S38PacketPlayerListItem getAction() func_179768_b()
net.minecraft.network.play.server.S40PacketDisconnect getReason() func_149165_c()
diff --git a/versions/common.gradle b/versions/common.gradle
index b7cc1f3d..8f1bb427 100644
--- a/versions/common.gradle
+++ b/versions/common.gradle
@@ -295,7 +295,7 @@ dependencies {
shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8'
- shadow "com.github.ReplayMod:ReplayStudio:2773270", shadeExclusions
+ shadow "com.github.ReplayMod:ReplayStudio:b29955e", shadeExclusions
implementation(jGui){
transitive = false // FG 1.2 puts all MC deps into the compile configuration and we don't want to shade those