Warning, GIGANTIC COMMIT!

Replaced Keyframe subclasses with Generic Types of Keyframe and replaced all instanceof calls
Replaced implementations of Linear and Spline interpolation to interpolate any Object that extends KeyframeValue and contains at least one public double Field. I'll need this for Keyframe interpolation in CustomImageObject Transformations
Made MarkerKeyframe *no* subclass of Keyframe to avoid conflicts with PositionKeyframe in instanceof checks for Keyframe#getValue
Created KeyframeList which extends ArrayList to provide some helping functions which DRY up the ReplayHandler
Split up ReplayHandler's keyframeList into timeKeyframeList and positionKeyframeList
This commit is contained in:
CrushedPixel
2015-07-08 04:13:24 +02:00
parent 89cc6938f8
commit 5100b63964
35 changed files with 765 additions and 1117 deletions

View File

@@ -3,10 +3,12 @@ package eu.crushedpixel.replaymod.replay;
import com.mojang.authlib.GameProfile;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.assets.AssetRepository;
import eu.crushedpixel.replaymod.assets.CustomImageObject;
import eu.crushedpixel.replaymod.entities.CameraEntity;
import eu.crushedpixel.replaymod.events.KeyframesModifyEvent;
import eu.crushedpixel.replaymod.events.ReplayExitEvent;
import eu.crushedpixel.replaymod.holders.*;
import eu.crushedpixel.replaymod.interpolation.KeyframeList;
import eu.crushedpixel.replaymod.registry.PlayerHandler;
import eu.crushedpixel.replaymod.settings.RenderOptions;
import eu.crushedpixel.replaymod.utils.ReplayFile;
@@ -41,15 +43,22 @@ public class ReplayHandler {
private static Minecraft mc = Minecraft.getMinecraft();
private static OpenEmbeddedChannel channel;
private static int realTimelinePosition = 0;
private static Keyframe selectedKeyframe;
private static MarkerKeyframe selectedMarkerKeyframe;
private static boolean inPath = false;
private static CameraEntity cameraEntity;
private static List<Keyframe> keyframes = new ArrayList<Keyframe>();
private static KeyframeList<Keyframe<Position>> positionKeyframes = new KeyframeList<Keyframe<Position>>();
private static KeyframeList<Keyframe<TimestampValue>> timeKeyframes = new KeyframeList<Keyframe<TimestampValue>>();
private static boolean inReplay = false;
private static Entity currentEntity = null;
private static Position lastPosition = null;
private static MarkerKeyframe[] initialMarkers = new MarkerKeyframe[0];
private static List<MarkerKeyframe> markerKeyframes = new ArrayList<MarkerKeyframe>();
private static float cameraTilt = 0;
@@ -85,18 +94,12 @@ public class ReplayHandler {
}
public static MarkerKeyframe[] getMarkers() {
List<MarkerKeyframe> markers = new ArrayList<MarkerKeyframe>();
for(Keyframe kf : keyframes) {
if(kf instanceof MarkerKeyframe) markers.add((MarkerKeyframe)kf);
}
return markers.toArray(new MarkerKeyframe[markers.size()]);
return markerKeyframes.toArray(new MarkerKeyframe[markerKeyframes.size()]);
}
public static void setMarkers(MarkerKeyframe[] m, boolean write) {
for(Keyframe kf : new ArrayList<Keyframe>(keyframes)) {
if(kf instanceof MarkerKeyframe) keyframes.remove(kf);
}
Collections.addAll(keyframes, m);
markerKeyframes.clear();
Collections.addAll(markerKeyframes, m);
if(write) {
try {
@@ -109,8 +112,6 @@ public class ReplayHandler {
e.printStackTrace();
}
}
FMLCommonHandler.instance().bus().post(new KeyframesModifyEvent(keyframes));
}
public static void useKeyframePresetFromRepository(int index) {
@@ -118,15 +119,17 @@ public class ReplayHandler {
}
public static void useKeyframePreset(Keyframe[] kfs) {
MarkerKeyframe[] markers = getMarkers();
positionKeyframes.clear();
timeKeyframes.clear();
for(Keyframe kf : kfs) {
if(kf.getValue() instanceof Position) {
positionKeyframes.add(kf);
} else if(kf.getValue() instanceof TimestampValue) {
timeKeyframes.add(kf);
}
}
keyframes = new ArrayList<Keyframe>(Arrays.asList(kfs));
Collections.addAll(keyframes, markers);
if(!(selectedKeyframe instanceof MarkerKeyframe)) selectedKeyframe = null;
FMLCommonHandler.instance().bus().post(new KeyframesModifyEvent(keyframes));
fireKeyframesModifyEvent();
}
public static void spectateEntity(Entity e) {
@@ -143,7 +146,7 @@ public class ReplayHandler {
public static void spectateCamera() {
if(currentEntity != null) {
Position prev = new Position(currentEntity);
Position prev = new Position(currentEntity, false);
cameraEntity.movePath(prev);
}
currentEntity = cameraEntity;
@@ -222,136 +225,75 @@ public class ReplayHandler {
cameraTilt += tilt;
}
public static void sortKeyframes() {
Collections.sort(keyframes, new KeyframeComparator());
public static void toggleMarker() {
if(selectedMarkerKeyframe != null) markerKeyframes.remove(selectedMarkerKeyframe);
else {
Position pos = new Position(mc.getRenderViewEntity(), false);
int timestamp = ReplayMod.replaySender.currentTimeStamp();
markerKeyframes.add(new MarkerKeyframe(timestamp, pos, null));
}
}
public static void toggleMarker() {
if(selectedKeyframe instanceof MarkerKeyframe) removeKeyframe(selectedKeyframe);
else {
Position pos = new Position(mc.getRenderViewEntity());
int timestamp = ReplayMod.replaySender.currentTimeStamp();
addKeyframe(new MarkerKeyframe(pos, timestamp, null));
public static void addTimeKeyframe(Keyframe<TimestampValue> keyframe) {
timeKeyframes.add(keyframe);
selectKeyframe(keyframe);
fireKeyframesModifyEvent();
}
public static void addPositionKeyframe(Keyframe<Position> keyframe) {
positionKeyframes.add(keyframe);
selectKeyframe(keyframe);
Float a = null;
Float b;
for(Keyframe kf : positionKeyframes) {
if(!(kf.getValue() instanceof Position)) continue;
Keyframe<Position> pkf = (Keyframe<Position>)kf;
Position pos = pkf.getValue();
b = (float)pos.getYaw() % 360;
if(a != null) {
float diff = b-a;
if(Math.abs(diff) > 180) {
b = a - (360 - diff) % 360;
pos.setYaw(b);
pkf.setValue(pos);
}
}
a = b;
}
fireKeyframesModifyEvent();
}
public static void addKeyframe(Keyframe keyframe) {
keyframes.add(keyframe);
selectKeyframe(keyframe);
if(keyframe instanceof PositionKeyframe) {
Float a = null;
Float b;
for(Keyframe kf : keyframes) {
if(!(kf instanceof PositionKeyframe)) continue;
PositionKeyframe pkf = (PositionKeyframe)kf;
Position pos = pkf.getPosition();
b = pos.getYaw() % 360;
if(a != null) {
float diff = b-a;
if(Math.abs(diff) > 180) {
b = a - (360 - diff) % 360;
pos.setYaw(b);
pkf.setPosition(pos);
}
}
a = b;
}
if(keyframe.getValue() instanceof Position) {
addPositionKeyframe(keyframe);
} else if(keyframe.getValue() instanceof TimestampValue) {
addTimeKeyframe(keyframe);
}
FMLCommonHandler.instance().bus().post(new KeyframesModifyEvent(keyframes));
}
public static void removeKeyframe(Keyframe keyframe) {
keyframes.remove(keyframe);
if(keyframe.getValue() instanceof Position) {
positionKeyframes.remove(keyframe);
} else if(keyframe.getValue() instanceof TimestampValue) {
timeKeyframes.remove(keyframe);
}
if(keyframe == selectedKeyframe) {
selectKeyframe(null);
} else {
sortKeyframes();
}
FMLCommonHandler.instance().bus().post(new KeyframesModifyEvent(keyframes));
}
public static int getKeyframeIndex(TimeKeyframe timeKeyframe) {
int index = 0;
for(Keyframe kf : keyframes) {
if(kf == timeKeyframe) return index;
else if(kf instanceof TimeKeyframe) index++;
}
return -1;
}
public static int getKeyframeIndex(PositionKeyframe posKeyframe) {
int index = 0;
for(Keyframe kf : keyframes) {
if(kf == posKeyframe) return index;
else if(kf instanceof PositionKeyframe) index++;
}
return -1;
}
public static int getPosKeyframeCount() {
int size = 0;
for(Keyframe kf : keyframes) {
if(kf instanceof PositionKeyframe) size++;
}
return size;
}
public static int getTimeKeyframeCount() {
int size = 0;
for(Keyframe kf : keyframes) {
if(kf instanceof TimeKeyframe) size++;
}
return size;
}
public static TimeKeyframe getClosestTimeKeyframeForRealTime(int realTime, int tolerance) {
List<TimeKeyframe> found = new ArrayList<TimeKeyframe>();
for(Keyframe kf : keyframes) {
if(!(kf instanceof TimeKeyframe)) continue;
if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
found.add((TimeKeyframe) kf);
}
}
TimeKeyframe closest = null;
for(TimeKeyframe kf : found) {
if(closest == null || Math.abs(closest.getTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) {
closest = kf;
}
}
return closest;
}
public static PositionKeyframe getClosestPlaceKeyframeForRealTime(int realTime, int tolerance) {
List<PositionKeyframe> found = new ArrayList<PositionKeyframe>();
for(Keyframe kf : keyframes) {
if(!(kf instanceof PositionKeyframe)) continue;
if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
found.add((PositionKeyframe) kf);
}
}
PositionKeyframe closest = null;
for(PositionKeyframe kf : found) {
if(closest == null || Math.abs(closest.getRealTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) {
closest = kf;
}
}
return closest;
fireKeyframesModifyEvent();
}
public static MarkerKeyframe getClosestMarkerForRealTime(int realTime, int tolerance) {
List<MarkerKeyframe> found = new ArrayList<MarkerKeyframe>();
for(Keyframe kf : keyframes) {
if(!(kf instanceof MarkerKeyframe)) continue;
for(MarkerKeyframe kf : markerKeyframes) {
if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
found.add((MarkerKeyframe) kf);
found.add(kf);
}
}
@@ -365,76 +307,11 @@ public class ReplayHandler {
return closest;
}
public static PositionKeyframe getPreviousPositionKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
PositionKeyframe backup = null;
List<PositionKeyframe> found = new ArrayList<PositionKeyframe>();
for(Keyframe kf : keyframes) {
if(!(kf instanceof PositionKeyframe)) continue;
if(kf.getRealTimestamp() < realTime) {
found.add((PositionKeyframe)kf);
} else if(kf.getRealTimestamp() == realTime) {
backup = (PositionKeyframe)kf;
}
}
if(found.size() > 0)
return found.get(found.size() - 1); //last element is nearest
else return backup;
}
public static PositionKeyframe getNextPositionKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
PositionKeyframe backup = null;
for(Keyframe kf : keyframes) {
if(!(kf instanceof PositionKeyframe)) continue;
if(kf.getRealTimestamp() > realTime) {
return (PositionKeyframe)kf; //first found element is next
} else if(kf.getRealTimestamp() == realTime) {
backup = (PositionKeyframe)kf;
}
}
return backup;
}
public static TimeKeyframe getPreviousTimeKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
TimeKeyframe backup = null;
List<TimeKeyframe> found = new ArrayList<TimeKeyframe>();
for(Keyframe kf : keyframes) {
if(!(kf instanceof TimeKeyframe)) continue;
if(kf.getRealTimestamp() < realTime) {
found.add((TimeKeyframe)kf);
} else if(kf.getRealTimestamp() == realTime) {
backup = (TimeKeyframe)kf;
}
}
if(found.size() > 0)
return found.get(found.size() - 1); //last element is nearest
else return backup;
}
public static TimeKeyframe getNextTimeKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
TimeKeyframe backup = null;
for(Keyframe kf : keyframes) {
if(!(kf instanceof TimeKeyframe)) continue;
if(kf.getRealTimestamp() > realTime) {
return (TimeKeyframe) kf; //first found element is next
} else if(kf.getRealTimestamp() == realTime) {
backup = (TimeKeyframe)kf;
}
}
return backup;
}
public static MarkerKeyframe getPreviousMarkerKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
if(markerKeyframes.isEmpty()) return null;
MarkerKeyframe backup = null;
List<MarkerKeyframe> found = new ArrayList<MarkerKeyframe>();
for(Keyframe kf : keyframes) {
if(!(kf instanceof MarkerKeyframe)) continue;
for(MarkerKeyframe kf : markerKeyframes) {
if(kf.getRealTimestamp() < realTime) {
found.add((MarkerKeyframe)kf);
} else if(kf.getRealTimestamp() == realTime) {
@@ -448,21 +325,32 @@ public class ReplayHandler {
}
public static MarkerKeyframe getNextMarkerKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
if(markerKeyframes.isEmpty()) return null;
MarkerKeyframe backup = null;
for(Keyframe kf : keyframes) {
if(!(kf instanceof MarkerKeyframe)) continue;
for(MarkerKeyframe kf : markerKeyframes) {
if(kf.getRealTimestamp() > realTime) {
return (MarkerKeyframe) kf; //first found element is next
return kf; //first found element is next
} else if(kf.getRealTimestamp() == realTime) {
backup = (MarkerKeyframe)kf;
backup = kf;
}
}
return backup;
}
public static List<Keyframe> getKeyframes() {
return new ArrayList<Keyframe>(keyframes);
public static KeyframeList<Keyframe<Position>> getPositionKeyframes() {
return positionKeyframes;
}
public static KeyframeList<Keyframe<TimestampValue>> getTimeKeyframes() {
return timeKeyframes;
}
public static KeyframeList<Keyframe> getAllKeyframes() {
KeyframeList keyframeList = new KeyframeList();
keyframeList.addAll(positionKeyframes);
keyframeList.addAll(timeKeyframes);
return keyframeList;
}
public static void resetKeyframes(final boolean resetMarkers, boolean callback) {
@@ -483,19 +371,15 @@ public class ReplayHandler {
}
private static void resetKeyframes(boolean resetMarkers) {
MarkerKeyframe[] markers = getMarkers();
keyframes = new ArrayList<Keyframe>();
timeKeyframes.clear();
positionKeyframes.clear();
selectKeyframe(null);
if(!resetMarkers) {
Collections.addAll(keyframes, markers);
if(!(selectedKeyframe instanceof MarkerKeyframe))
selectKeyframe(null);
} else {
selectKeyframe(null);
if(resetMarkers) {
markerKeyframes.clear();
}
FMLCommonHandler.instance().bus().post(new KeyframesModifyEvent(keyframes));
fireKeyframesModifyEvent();
}
public static boolean isSelected(Keyframe kf) {
@@ -504,7 +388,6 @@ public class ReplayHandler {
public static void selectKeyframe(Keyframe kf) {
selectedKeyframe = kf;
sortKeyframes();
}
public static boolean isInReplay() {
@@ -681,44 +564,6 @@ public class ReplayHandler {
return currentReplayFile == null ? null : currentReplayFile.getFile();
}
public static TimeKeyframe getFirstTimeKeyframe() {
Keyframe sel = getSelectedKeyframe();
sortKeyframes();
for(Keyframe k : getKeyframes()) {
if(k instanceof TimeKeyframe) {
selectKeyframe(sel);
return (TimeKeyframe)k;
}
}
selectKeyframe(sel);
return null;
}
public static PositionKeyframe getFirstPositionKeyframe() {
Keyframe sel = getSelectedKeyframe();
sortKeyframes();
for(Keyframe k : getKeyframes()) {
if(k instanceof PositionKeyframe) {
selectKeyframe(sel);
return (PositionKeyframe)k;
}
}
selectKeyframe(sel);
return null;
}
public static TimeKeyframe getLastTimeKeyframe() {
ArrayList<Keyframe> rev = new ArrayList<Keyframe>(getKeyframes());
Collections.reverse(rev);
for(Keyframe k : rev) {
if(k instanceof TimeKeyframe) {
return (TimeKeyframe)k;
}
}
return null;
}
public static void syncTimeCursor(boolean shiftMode) {
selectKeyframe(null);
@@ -726,21 +571,21 @@ public class ReplayHandler {
int prevTime, prevRealTime;
TimeKeyframe keyframe;
Keyframe<TimestampValue> keyframe;
//if shift is down, it will refer to the previous Time Keyframe instead of the last one
if(shiftMode) {
int realTime = getRealTimelineCursor();
keyframe = getPreviousTimeKeyframe(realTime);
keyframe = timeKeyframes.getPreviousKeyframe(realTime);
} else {
keyframe = getLastTimeKeyframe();
keyframe = timeKeyframes.last();
}
if(keyframe == null) {
prevTime = 0;
prevRealTime = 0;
} else {
prevTime = keyframe.getTimestamp();
prevTime = (int)keyframe.getValue().value;
prevRealTime = keyframe.getRealTimestamp();
}
@@ -760,4 +605,9 @@ public class ReplayHandler {
public static void setCustomImageObjects(List<CustomImageObject> objects) {
customImageObjects = objects;
}
public static void fireKeyframesModifyEvent() {
FMLCommonHandler.instance().bus().post(new KeyframesModifyEvent(positionKeyframes, timeKeyframes));
}
}

View File

@@ -4,11 +4,9 @@ import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.chat.ChatMessageHandler.ChatMessageType;
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.holders.TimestampValue;
import eu.crushedpixel.replaymod.interpolation.GenericLinearInterpolation;
import eu.crushedpixel.replaymod.interpolation.GenericSplineInterpolation;
import eu.crushedpixel.replaymod.settings.RenderOptions;
import eu.crushedpixel.replaymod.timer.EnchantmentTimer;
import eu.crushedpixel.replaymod.timer.ReplayTimer;
@@ -28,9 +26,9 @@ public class ReplayProcess {
private static boolean linear = false;
private static SplinePoint motionSpline = null;
private static LinearPoint motionLinear = null;
private static LinearTimestamp timeLinear = null;
private static GenericSplineInterpolation<Position> motionSpline = null;
private static GenericLinearInterpolation<Position> motionLinear = null;
private static GenericLinearInterpolation<TimestampValue> timeLinear = null;
private static double previousReplaySpeed = 0;
@@ -77,20 +75,19 @@ public class ReplayProcess {
ReplayMod.chatMessageHandler.initialize();
//if not enough keyframes, abort and leave chat message
if(ReplayHandler.getPosKeyframeCount() < 2 || ReplayHandler.getTimeKeyframeCount() < 1) {
if(ReplayHandler.getPositionKeyframes().size() < 2 || ReplayHandler.getTimeKeyframes().size() < 1) {
ReplayMod.chatMessageHandler.addLocalizedChatMessage("replaymod.chat.morekeyframes", ChatMessageType.WARNING);
return;
}
ReplayHandler.sortKeyframes();
ReplayHandler.setInPath(true);
ReplayMod.replaySender.setAsyncMode(false);
if (renderOptions == null) {
//gets first Timestamp and sets Replay Time to it
TimeKeyframe tf = ReplayHandler.getFirstTimeKeyframe();
//gets first Value and sets Replay Time to it
Keyframe<TimestampValue> tf = ReplayHandler.getTimeKeyframes().first();
if (tf != null) {
int ts = tf.getTimestamp();
int ts = (int)tf.getValue().value;
if (ts < ReplayMod.replaySender.currentTimeStamp()) {
mc.displayGuiScreen(null);
}
@@ -165,37 +162,29 @@ public class ReplayProcess {
if(justCheck) return;
int posCount = ReplayHandler.getPosKeyframeCount();
int timeCount = ReplayHandler.getTimeKeyframeCount();
int posCount = ReplayHandler.getPositionKeyframes().size();
int timeCount = ReplayHandler.getTimeKeyframes().size();
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);
}
motionSpline = new GenericSplineInterpolation<Position>();
for(Keyframe<Position> kf : ReplayHandler.getPositionKeyframes()) {
motionSpline.addPoint(kf.getValue());
}
}
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);
}
motionLinear = new GenericLinearInterpolation<Position>();
for(Keyframe<Position> kf : ReplayHandler.getPositionKeyframes()) {
motionLinear.addPoint(kf.getValue());
}
}
if(timeLinear == null) {
timeLinear = new LinearTimestamp();
for(Keyframe kf : ReplayHandler.getKeyframes()) {
if(kf instanceof TimeKeyframe) {
timeLinear.addPoint(((TimeKeyframe) kf).getTimestamp());
timeLinear = new GenericLinearInterpolation<TimestampValue>();
for(Keyframe<TimestampValue> kf : ReplayHandler.getTimeKeyframes()) {
if(kf.getValue() instanceof TimestampValue) {
timeLinear.addPoint(kf.getValue());
}
}
}
@@ -211,16 +200,15 @@ public class ReplayProcess {
int curRealReplayTime = (int) (lastRealReplayTime + timeStep);
PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime);
PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime);
Keyframe<Position> lastPos = ReplayHandler.getPositionKeyframes().getPreviousKeyframe(curRealReplayTime);
Keyframe<Position> nextPos = ReplayHandler.getPositionKeyframes().getNextKeyframe(curRealReplayTime);
boolean spectating = false;
//if it's between two spectator keyframes sharing the same entity, spectate this entity
if(lastPos != null && nextPos != null) {
if(lastPos.getSpectatedEntityID() != null && nextPos.getSpectatedEntityID() != null) {
if(lastPos.getSpectatedEntityID().equals(nextPos.getSpectatedEntityID())) {
if(lastPos.getValue().getSpectatedEntityID() != null && nextPos.getValue().getSpectatedEntityID() != null) {
if(lastPos.getValue().getSpectatedEntityID().equals(nextPos.getValue().getSpectatedEntityID())) {
spectating = true;
}
}
@@ -245,8 +233,8 @@ public class ReplayProcess {
}
}
TimeKeyframe lastTime = ReplayHandler.getPreviousTimeKeyframe(curRealReplayTime);
TimeKeyframe nextTime = ReplayHandler.getNextTimeKeyframe(curRealReplayTime);
Keyframe<TimestampValue> lastTime = ReplayHandler.getTimeKeyframes().getPreviousKeyframe(curRealReplayTime);
Keyframe<TimestampValue> nextTime = ReplayHandler.getTimeKeyframes().getNextKeyframe(curRealReplayTime);
int lastTimeStamp = 0;
int nextTimeStamp = 0;
@@ -271,7 +259,7 @@ public class ReplayProcess {
}
if(!(nextTime == null || lastTime == null)) {
curSpeed = ((double) ((nextTime.getTimestamp() - lastTime.getTimestamp()))) / ((double) ((nextTimeStamp - lastTimeStamp)));
curSpeed = ((double) (((int)nextTime.getValue().value - (int)lastTime.getValue().value))) / ((double) ((nextTimeStamp - lastTimeStamp)));
}
if(lastTimeStamp == nextTimeStamp) {
@@ -292,47 +280,46 @@ public class ReplayProcess {
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);
float splinePos = ((float) ReplayHandler.getPositionKeyframes().indexOf(lastPos) + currentPosStepPerc) / (float) (posCount - 1);
float timePos = ((float) ReplayHandler.getTimeKeyframes().indexOf(lastTime) + currentTimeStepPerc) / (float) (timeCount - 1);
if(!spectating) {
ReplayHandler.spectateCamera();
Position pos = null;
Position pos = new Position();
if(posCount > 1) {
if(!linear) {
pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos)));
motionSpline.applyPoint(Math.max(0, Math.min(1, splinePos)), pos);
} else {
pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos)));
motionLinear.applyPoint(Math.max(0, Math.min(1, splinePos)), pos);
}
} else {
if(posCount == 1) {
PositionKeyframe keyframe = ReplayHandler.getFirstPositionKeyframe();
Keyframe<Position> keyframe = ReplayHandler.getPositionKeyframes().first();
assert keyframe != null;
pos = keyframe.getPosition();
pos = keyframe.getValue();
}
}
if(pos != null) {
ReplayHandler.setCameraTilt(pos.getRoll());
ReplayHandler.setCameraTilt((float)pos.getRoll());
ReplayHandler.getCameraEntity().movePath(pos);
}
} else {
ReplayHandler.spectateEntity(mc.theWorld.getEntityByID(lastPos.getSpectatedEntityID()));
ReplayHandler.spectateEntity(mc.theWorld.getEntityByID(lastPos.getValue().getSpectatedEntityID()));
}
Integer curTimestamp = null;
if(timeLinear != null && timeCount > 1) {
curTimestamp = timeLinear.getPoint(Math.max(0, Math.min(1, timePos)));
TimestampValue timestampValue = new TimestampValue();
timeLinear.applyPoint(Math.max(0, Math.min(1, timePos)), timestampValue);
curTimestamp = (int) timestampValue.value;
}
if(!isVideoRecording()) ReplayMod.replaySender.setReplaySpeed(curSpeed);
//if(curSpeed > 0)
if(curTimestamp != null)
ReplayMod.replaySender.sendPacketsTill(curTimestamp);
//splinePos = (index of last entry + add) / total entries
lastRealReplayTime = curRealReplayTime;
lastRealTime = curTime;

View File

@@ -69,7 +69,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
protected boolean asyncMode;
/**
* Timestamp of the last packet sent in milliseconds since the start.
* Value of the last packet sent in milliseconds since the start.
*/
protected int lastTimeStamp;
@@ -91,7 +91,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
/**
* The next packet that should be sent.
* This is required as some actions such as jumping to a specified timestamp have to peek at the next packet.
* This is required as some actions such as jumping to a specified value have to peek at the next packet.
*/
protected PacketData nextPacket;
@@ -188,8 +188,8 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
/**
* Return the timestamp of the last packet sent.
* @return The timestamp in milliseconds since the start of the replay
* Return the value of the last packet sent.
* @return The value in milliseconds since the start of the replay
*/
public int currentTimeStamp() {
return lastTimeStamp;
@@ -450,7 +450,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
private long lastPacketSent;
/**
* There is no waiting performed until a packet with at least this timestamp is reached (but not yet sent).
* There is no waiting performed until a packet with at least this value is reached (but not yet sent).
* If this is -1, then timing is normal.
*/
private long desiredTimeStamp = -1;
@@ -573,7 +573,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
/**
* Return whether this replay sender is currently rushing. When rushing, all packets are sent without waiting until
* a specified timestamp is passed.
* a specified value is passed.
* @return {@code true} if currently rushing, {@code false} otherwise
*/
public boolean isHurrying() {
@@ -588,19 +588,19 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
/**
* Return the timestamp to which this replay sender is currently rushing. All packets with an lower or equal
* timestamp will be sent out without any sleeping.
* @return The timestamp in milliseconds since the start of the replay
* Return the value to which this replay sender is currently rushing. All packets with an lower or equal
* value will be sent out without any sleeping.
* @return The value in milliseconds since the start of the replay
*/
public long getDesiredTimestamp() {
return desiredTimeStamp;
}
/**
* Jumps to the specified timestamp when in async mode by rushing all packets until one with a timestamp greater
* than the specified timestamp is found.
* If the timestamp has already passed, this causes the replay to restart and then rush all packets.
* @param millis Timestamp in milliseconds since the start of the replay
* Jumps to the specified value when in async mode by rushing all packets until one with a value greater
* than the specified value is found.
* If the value has already passed, this causes the replay to restart and then rush all packets.
* @param millis Value in milliseconds since the start of the replay
*/
public void jumpToTime(int millis) {
Preconditions.checkState(asyncMode, "Can only jump in async mode. Use sendPacketsTill(int) instead.");
@@ -632,9 +632,9 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
/////////////////////////////////////////////////////////
/**
* Sends all packets until the specified timestamp is reached (inclusive).
* If the timestamp is smaller than the last packet sent, the replay is restarted from the beginning.
* @param timestamp The timestamp in milliseconds since the beginning of this replay
* Sends all packets until the specified value is reached (inclusive).
* If the value is smaller than the last packet sent, the replay is restarted from the beginning.
* @param timestamp The value in milliseconds since the beginning of this replay
*/
public void sendPacketsTill(int timestamp) {
Preconditions.checkState(!asyncMode, "This method cannot be used in async mode. Use jumpToTime(int) instead.");
@@ -682,7 +682,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
// Process packet
channelRead(ctx, pd.getByteArray());
// Store last timestamp
// Store last value
lastTimeStamp = nextTimeStamp;
} catch (EOFException eof) {
// Shit! We hit the end before finishing our job! What shall we do now?