Rewrote a lot of the Settings code Started destroying the ReplayProcess, gonna fix that ASAP
356 lines
10 KiB
Java
Executable File
356 lines
10 KiB
Java
Executable File
package eu.crushedpixel.replaymod.replay;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
import java.lang.reflect.Field;
|
|
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.GuiScreen;
|
|
import net.minecraft.client.renderer.ChunkRenderContainer;
|
|
import net.minecraft.client.renderer.RenderGlobal;
|
|
import net.minecraft.client.renderer.chunk.RenderChunk;
|
|
import eu.crushedpixel.replaymod.ReplayMod;
|
|
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
|
|
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
|
|
import eu.crushedpixel.replaymod.gui.GuiCancelRender;
|
|
import eu.crushedpixel.replaymod.holders.Keyframe;
|
|
import eu.crushedpixel.replaymod.holders.Position;
|
|
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
|
|
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
|
import eu.crushedpixel.replaymod.interpolation.LinearPoint;
|
|
import eu.crushedpixel.replaymod.interpolation.LinearTimestamp;
|
|
import eu.crushedpixel.replaymod.interpolation.SplinePoint;
|
|
import eu.crushedpixel.replaymod.reflection.MCPNames;
|
|
import eu.crushedpixel.replaymod.timer.EnchantmentTimer;
|
|
import eu.crushedpixel.replaymod.timer.MCTimerHandler;
|
|
import eu.crushedpixel.replaymod.video.ScreenCapture;
|
|
import eu.crushedpixel.replaymod.video.VideoWriter;
|
|
|
|
public class ReplayProcess {
|
|
|
|
private static Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
private static long startRealTime;
|
|
private static int lastRealReplayTime;
|
|
private static long lastRealTime = 0;
|
|
|
|
private static boolean linear = false;
|
|
|
|
private static Position lastPosition = null;
|
|
private static int lastTimestamp = -1;
|
|
|
|
private static SplinePoint motionSpline = null;
|
|
private static LinearPoint motionLinear = null;
|
|
private static LinearTimestamp timeLinear = null;
|
|
|
|
private static double lastSpeed = 1f;
|
|
|
|
private static double previousReplaySpeed = 0;
|
|
|
|
private static boolean calculated = false;
|
|
|
|
private static boolean isVideoRecording = false;
|
|
|
|
public static boolean isVideoRecording() {
|
|
return isVideoRecording;
|
|
}
|
|
|
|
public static void startReplayProcess(boolean record) {
|
|
ReplayHandler.selectKeyframe(null);
|
|
|
|
isVideoRecording = record;
|
|
lastPosition = null;
|
|
motionSpline = null;
|
|
motionLinear = null;
|
|
timeLinear = null;
|
|
calculated = false;
|
|
requestFinish = false;
|
|
|
|
ChatMessageRequests.initialize();
|
|
if(ReplayHandler.getPosKeyframeCount() < 2 && ReplayHandler.getTimeKeyframeCount() < 2) {
|
|
ChatMessageRequests.addChatMessage("At least 2 position or time keyframes required!", ChatMessageType.WARNING);
|
|
return;
|
|
}
|
|
|
|
blocked = deepBlock = false;
|
|
|
|
startRealTime = System.currentTimeMillis();
|
|
lastRealTime = startRealTime;
|
|
lastRealReplayTime = 0;
|
|
lastTimestamp = -1;
|
|
lastSpeed = 1f;
|
|
linear = ReplayMod.replaySettings.isLinearMovement();
|
|
ReplayHandler.sortKeyframes();
|
|
ReplayHandler.setInPath(true);
|
|
previousReplaySpeed = ReplayHandler.getSpeed();
|
|
|
|
EnchantmentTimer.resetRecordingTime();
|
|
|
|
TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1);
|
|
if(tf != null) {
|
|
int ts = tf.getTimestamp();
|
|
if(ts < ReplayHandler.getReplayTime()) {
|
|
mc.displayGuiScreen(null);
|
|
}
|
|
ReplayHandler.setReplayTime(ts);
|
|
}
|
|
|
|
ChatMessageRequests.addChatMessage("Replay started!", ChatMessageType.INFORMATION);
|
|
|
|
mc.renderGlobal.loadRenderers();
|
|
|
|
if(isVideoRecording()) {
|
|
MCTimerHandler.setTimerSpeed(1f);
|
|
MCTimerHandler.setPassiveTimer();
|
|
}
|
|
}
|
|
|
|
public static void stopReplayProcess(boolean finished) {
|
|
if(!ReplayHandler.isInPath()) return;
|
|
if(finished) ChatMessageRequests.addChatMessage("Replay finished!", ChatMessageType.INFORMATION);
|
|
else {
|
|
ChatMessageRequests.addChatMessage("Replay stopped!", ChatMessageType.INFORMATION);
|
|
if(isVideoRecording()) {
|
|
VideoWriter.abortRecording();
|
|
}
|
|
}
|
|
ReplayHandler.setInPath(false);
|
|
MCTimerHandler.setActiveTimer();
|
|
ReplayHandler.setSpeed(previousReplaySpeed);
|
|
//ReplayHandler.setSpeed(0);
|
|
}
|
|
|
|
private static boolean blocked = false;
|
|
private static boolean deepBlock = false;
|
|
|
|
private static boolean requestFinish = false;
|
|
|
|
public static void unblockAndTick(boolean justCheck) {
|
|
if(!deepBlock) blocked = false;
|
|
if(!blocked || !isVideoRecording())
|
|
ReplayProcess.tickReplay(justCheck);
|
|
}
|
|
|
|
public static void tickReplay(boolean justCheck) {
|
|
pathTick(isVideoRecording(), justCheck);
|
|
}
|
|
|
|
private static void pathTick(boolean recording, boolean justCheck) {
|
|
if(ReplayHandler.isHurrying()) {
|
|
lastRealTime = System.currentTimeMillis();
|
|
return;
|
|
}
|
|
|
|
if(recording && ((ReplayMod.replaySettings.getWaitForChunks() && RenderChunk.renderChunksUpdated != 0) || mc.currentScreen instanceof GuiCancelRender)) {
|
|
MCTimerHandler.setTimerSpeed(0f);
|
|
MCTimerHandler.setPartialTicks(0f);
|
|
MCTimerHandler.setRenderPartialTicks(0f);
|
|
MCTimerHandler.setTicks(0);
|
|
return;
|
|
} else if (recording && ReplayMod.replaySettings.getWaitForChunks()) {
|
|
MCTimerHandler.setTimerSpeed((float)lastSpeed);
|
|
}
|
|
|
|
|
|
if(justCheck) return;
|
|
|
|
if(recording) {
|
|
if(blocked) return;
|
|
|
|
deepBlock = true;
|
|
blocked = true;
|
|
}
|
|
|
|
int posCount = ReplayHandler.getPosKeyframeCount();
|
|
int timeCount = ReplayHandler.getTimeKeyframeCount();
|
|
|
|
if(!linear && motionSpline == null) {
|
|
//set up spline path
|
|
motionSpline = new SplinePoint();
|
|
for(Keyframe kf : ReplayHandler.getKeyframes()) {
|
|
if(kf instanceof PositionKeyframe) {
|
|
PositionKeyframe pkf = (PositionKeyframe)kf;
|
|
Position pos = pkf.getPosition();
|
|
motionSpline.addPoint(pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(linear && motionLinear == null) {
|
|
//set up linear path
|
|
motionLinear = new LinearPoint();
|
|
for(Keyframe kf : ReplayHandler.getKeyframes()) {
|
|
if(kf instanceof PositionKeyframe) {
|
|
PositionKeyframe pkf = (PositionKeyframe)kf;
|
|
Position pos = pkf.getPosition();
|
|
motionLinear.addPoint(pos);
|
|
}
|
|
}
|
|
}
|
|
if(timeLinear == null) {
|
|
timeLinear = new LinearTimestamp();
|
|
for(Keyframe kf : ReplayHandler.getKeyframes()) {
|
|
if(kf instanceof TimeKeyframe) {
|
|
timeLinear.addPoint(((TimeKeyframe)kf).getTimestamp());
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!calculated) {
|
|
calculated = true;
|
|
if(posCount > 1 && motionSpline != null)
|
|
motionSpline.calcSpline();
|
|
}
|
|
|
|
long curTime = System.currentTimeMillis();
|
|
long timeStep;
|
|
if(recording) {
|
|
timeStep = 1000/ReplayMod.replaySettings.getVideoFramerate();
|
|
} else {
|
|
timeStep = curTime - lastRealTime;
|
|
}
|
|
|
|
int curRealReplayTime = (int)(lastRealReplayTime + timeStep);
|
|
|
|
PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime);
|
|
PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime);
|
|
|
|
ReplayHandler.setRealTimelineCursor(curRealReplayTime);
|
|
|
|
int lastPosStamp = 0;
|
|
int nextPosStamp = 0;
|
|
|
|
if(nextPos != null || lastPos != null) {
|
|
if(nextPos != null) {
|
|
nextPosStamp = nextPos.getRealTimestamp();
|
|
} else {
|
|
nextPosStamp = lastPos.getRealTimestamp();
|
|
}
|
|
|
|
if(lastPos != null) {
|
|
lastPosStamp = lastPos.getRealTimestamp();
|
|
} else {
|
|
lastPosStamp = nextPos.getRealTimestamp();
|
|
}
|
|
}
|
|
|
|
TimeKeyframe lastTime = ReplayHandler.getPreviousTimeKeyframe(curRealReplayTime);
|
|
TimeKeyframe nextTime = ReplayHandler.getNextTimeKeyframe(curRealReplayTime);
|
|
|
|
int lastTimeStamp = 0;
|
|
int nextTimeStamp = 0;
|
|
|
|
double curSpeed = 0;
|
|
|
|
if(timeCount > 1 && (nextTime != null || lastTime != null)) {
|
|
|
|
if(nextTime != null && lastTime != null && nextTime.getRealTimestamp() == lastTime.getRealTimestamp()) {
|
|
curSpeed = 0;
|
|
} else {
|
|
if(nextTime != null) {
|
|
nextTimeStamp = nextTime.getRealTimestamp();
|
|
} else {
|
|
nextTimeStamp = lastTime.getRealTimestamp();
|
|
}
|
|
|
|
if(lastTime != null) {
|
|
lastTimeStamp = lastTime.getRealTimestamp();
|
|
} else {
|
|
lastTimeStamp = nextTime.getRealTimestamp();
|
|
}
|
|
|
|
if(!(nextTime == null || lastTime == null)) {
|
|
if(lastTimeStamp == nextTimeStamp) curSpeed = 0f;
|
|
else curSpeed = ((double)((nextTime.getTimestamp()-lastTime.getTimestamp())))/((double)((nextTimeStamp-lastTimeStamp)));
|
|
}
|
|
|
|
if(lastTimeStamp == nextTimeStamp) {
|
|
curSpeed = 0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
int currentPosDiff = nextPosStamp - lastPosStamp;
|
|
int currentPos = curRealReplayTime - lastPosStamp;
|
|
|
|
float currentPosStepPerc = (float)currentPos/(float)currentPosDiff; //The percentage of the travelled path between the current positions
|
|
if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0;
|
|
|
|
int currentTimeDiff = nextTimeStamp - lastTimeStamp;
|
|
int currentTime = curRealReplayTime - lastTimeStamp;
|
|
|
|
float currentTimeStepPerc = (float)currentTime/(float)currentTimeDiff; //The percentage of the travelled path between the current timestamps
|
|
if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0;
|
|
|
|
float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc)/(float)(posCount-1);
|
|
float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc)/(float)(timeCount-1);
|
|
|
|
Position pos = null;
|
|
if(posCount > 1) {
|
|
if(!linear) {
|
|
pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos)));
|
|
} else {
|
|
pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos)));
|
|
}
|
|
} else {
|
|
if(posCount == 1) {
|
|
pos = ReplayHandler.getNextPositionKeyframe(-1).getPosition();
|
|
}
|
|
}
|
|
|
|
Integer curPos = null;
|
|
if(timeLinear != null && timeCount > 1) {
|
|
curPos = timeLinear.getPoint(Math.max(0, Math.min(1, timePos)));
|
|
}
|
|
|
|
if(pos != null) {
|
|
ReplayHandler.getCameraEntity().movePath(pos);
|
|
}
|
|
|
|
if(curSpeed > 0) {
|
|
ReplayHandler.setSpeed(curSpeed);
|
|
lastSpeed = curSpeed;
|
|
}
|
|
|
|
if(recording) {
|
|
MCTimerHandler.updateTimer((1f/ReplayMod.replaySettings.getVideoFramerate()));
|
|
EnchantmentTimer.increaseRecordingTime((1000/ReplayMod.replaySettings.getVideoFramerate()));
|
|
}
|
|
|
|
if(curPos != null && curPos != ReplayHandler.getDesiredTimestamp()) ReplayHandler.setReplayTime(curPos);
|
|
|
|
//splinePos = (index of last entry + add) / total entries
|
|
|
|
lastRealReplayTime = curRealReplayTime;
|
|
lastRealTime = curTime;
|
|
|
|
if(isVideoRecording()) {
|
|
try {
|
|
if(!VideoWriter.isRecording() && ReplayHandler.isInPath()) {
|
|
VideoWriter.startRecording(mc.displayWidth, mc.displayHeight);
|
|
} else {
|
|
final BufferedImage screen = ScreenCapture.captureScreen();
|
|
VideoWriter.writeImage(screen);
|
|
}
|
|
} catch(Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
if(requestFinish) {
|
|
stopReplayProcess(true);
|
|
requestFinish = false;
|
|
if(recording) {
|
|
VideoWriter.endRecording();
|
|
}
|
|
}
|
|
|
|
if((splinePos >= 1 || posCount <= 1) && (timePos >= 1 || timeCount <= 1)) {
|
|
requestFinish = true;
|
|
}
|
|
|
|
if(recording) {
|
|
deepBlock = false;
|
|
}
|
|
}
|
|
}
|