Markers are now subclasses of Keyframe
Markers can now be moved and jumped to on the Replay Timeline
This commit is contained in:
@@ -152,6 +152,12 @@ public class CameraEntity extends EntityPlayer {
|
|||||||
direction = direction.normalize().add(new Vec3(oldDir.xCoord * (motion / 4f), oldDir.yCoord * (motion / 4f), oldDir.zCoord * (motion / 4f)).normalize());
|
direction = direction.normalize().add(new Vec3(oldDir.xCoord * (motion / 4f), oldDir.yCoord * (motion / 4f), oldDir.zCoord * (motion / 4f)).normalize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void moveAbsolute(Position pos) {
|
||||||
|
this.moveAbsolute(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
rotationPitch = pos.getPitch();
|
||||||
|
rotationYaw = pos.getYaw();
|
||||||
|
}
|
||||||
|
|
||||||
public void moveAbsolute(double x, double y, double z) {
|
public void moveAbsolute(double x, double y, double z) {
|
||||||
if(ReplayHandler.isInPath()) return;
|
if(ReplayHandler.isInPath()) return;
|
||||||
this.lastTickPosX = this.prevPosX = this.posX = x;
|
this.lastTickPosX = this.prevPosX = this.posX = x;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package eu.crushedpixel.replaymod.gui.elements;
|
package eu.crushedpixel.replaymod.gui.elements;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
import eu.crushedpixel.replaymod.gui.GuiEditKeyframe;
|
import eu.crushedpixel.replaymod.gui.GuiEditKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.Keyframe;
|
import eu.crushedpixel.replaymod.holders.Keyframe;
|
||||||
|
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
|
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
||||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||||
@@ -16,15 +18,23 @@ public class GuiKeyframeTimeline extends GuiTimeline {
|
|||||||
private static final int KEYFRAME_TIME_Y = 25;
|
private static final int KEYFRAME_TIME_Y = 25;
|
||||||
private static final int KEYFRAME_SPEC_X = 74;
|
private static final int KEYFRAME_SPEC_X = 74;
|
||||||
private static final int KEYFRAME_SPEC_Y = 30;
|
private static final int KEYFRAME_SPEC_Y = 30;
|
||||||
|
private static final int KEYFRAME_MARKER_X = 40;
|
||||||
|
private static final int KEYFRAME_MARKER_Y = 39;
|
||||||
|
|
||||||
private Keyframe clickedKeyFrame;
|
private Keyframe clickedKeyFrame;
|
||||||
private long clickTime;
|
private long clickTime;
|
||||||
private boolean dragging;
|
private boolean dragging;
|
||||||
|
private boolean markerKeyframes;
|
||||||
|
private boolean timeKeyframes;
|
||||||
|
private boolean placeKeyframes;
|
||||||
|
|
||||||
public GuiKeyframeTimeline(int positionX, int positionY, int width) {
|
public GuiKeyframeTimeline(int positionX, int positionY, int width, boolean showMarkers,
|
||||||
|
boolean showMarkerKeyframes, boolean showPlaceKeyframes, boolean showTimeKeyframes) {
|
||||||
super(positionX, positionY, width);
|
super(positionX, positionY, width);
|
||||||
showMarkers = true;
|
this.showMarkers = showMarkers;
|
||||||
showMarkerIndicators = false;
|
this.markerKeyframes = showMarkerKeyframes;
|
||||||
|
this.timeKeyframes = showTimeKeyframes;
|
||||||
|
this.placeKeyframes = showPlaceKeyframes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -34,13 +44,15 @@ public class GuiKeyframeTimeline extends GuiTimeline {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tolerance = (int) (2 * Math.round(zoom * timelineLength / width));
|
int tolerance = (int)(2 * Math.round(zoom * timelineLength / width));
|
||||||
|
|
||||||
Keyframe closest;
|
Keyframe closest;
|
||||||
if (mouseY >= positionY + BORDER_TOP + 5) {
|
if (mouseY >= positionY + BORDER_TOP + 5 && timeKeyframes) {
|
||||||
closest = ReplayHandler.getClosestTimeKeyframeForRealTime((int) time, tolerance);
|
closest = ReplayHandler.getClosestTimeKeyframeForRealTime((int) time, tolerance);
|
||||||
} else if (mouseY >= positionY + BORDER_TOP) {
|
} else if (mouseY >= positionY + BORDER_TOP && placeKeyframes) {
|
||||||
closest = ReplayHandler.getClosestPlaceKeyframeForRealTime((int) time, tolerance);
|
closest = ReplayHandler.getClosestPlaceKeyframeForRealTime((int) time, tolerance);
|
||||||
|
} else if (mouseY >= positionY + BORDER_TOP + 10 && markerKeyframes) {
|
||||||
|
closest = ReplayHandler.getClosestMarkerForRealTime((int) time, tolerance);
|
||||||
} else {
|
} else {
|
||||||
closest = null;
|
closest = null;
|
||||||
}
|
}
|
||||||
@@ -85,6 +97,10 @@ public class GuiKeyframeTimeline extends GuiTimeline {
|
|||||||
@Override
|
@Override
|
||||||
public void mouseRelease(Minecraft mc, int mouseX, int mouseY, int button) {
|
public void mouseRelease(Minecraft mc, int mouseX, int mouseY, int button) {
|
||||||
mouseDrag(mc, mouseX, mouseY, button);
|
mouseDrag(mc, mouseX, mouseY, button);
|
||||||
|
if(clickedKeyFrame instanceof MarkerKeyframe && dragging == false) {
|
||||||
|
ReplayMod.replaySender.jumpToTime(clickedKeyFrame.getRealTimestamp());
|
||||||
|
ReplayHandler.setLastPosition(((MarkerKeyframe)clickedKeyFrame).getPosition());
|
||||||
|
}
|
||||||
clickedKeyFrame = null;
|
clickedKeyFrame = null;
|
||||||
dragging = false;
|
dragging = false;
|
||||||
}
|
}
|
||||||
@@ -169,7 +185,8 @@ public class GuiKeyframeTimeline extends GuiTimeline {
|
|||||||
|
|
||||||
int keyframeX = getKeyframeX(kf.getRealTimestamp(), leftTime, bodyWidth, segmentLength);
|
int keyframeX = getKeyframeX(kf.getRealTimestamp(), leftTime, bodyWidth, segmentLength);
|
||||||
|
|
||||||
if (kf instanceof PositionKeyframe) {
|
if(kf instanceof PositionKeyframe) {
|
||||||
|
if(!placeKeyframes) return;
|
||||||
textureX = KEYFRAME_PLACE_X;
|
textureX = KEYFRAME_PLACE_X;
|
||||||
textureY = KEYFRAME_PLACE_Y;
|
textureY = KEYFRAME_PLACE_Y;
|
||||||
y += 0;
|
y += 0;
|
||||||
@@ -179,10 +196,16 @@ public class GuiKeyframeTimeline extends GuiTimeline {
|
|||||||
textureX = KEYFRAME_SPEC_X;
|
textureX = KEYFRAME_SPEC_X;
|
||||||
textureY = KEYFRAME_SPEC_Y;
|
textureY = KEYFRAME_SPEC_Y;
|
||||||
}
|
}
|
||||||
} else if (kf instanceof TimeKeyframe) {
|
} else if(kf instanceof TimeKeyframe) {
|
||||||
|
if(!timeKeyframes) return;
|
||||||
textureX = KEYFRAME_TIME_X;
|
textureX = KEYFRAME_TIME_X;
|
||||||
textureY = KEYFRAME_TIME_Y;
|
textureY = KEYFRAME_TIME_Y;
|
||||||
y += 5;
|
y += 5;
|
||||||
|
} else if(kf instanceof MarkerKeyframe) {
|
||||||
|
if(!markerKeyframes) return;
|
||||||
|
textureX = KEYFRAME_MARKER_X;
|
||||||
|
textureY = KEYFRAME_MARKER_Y;
|
||||||
|
y += 10;
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException("Unknown keyframe type: " + kf.getClass());
|
throw new UnsupportedOperationException("Unknown keyframe type: " + kf.getClass());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package eu.crushedpixel.replaymod.gui.elements;
|
package eu.crushedpixel.replaymod.gui.elements;
|
||||||
|
|
||||||
import eu.crushedpixel.replaymod.ReplayMod;
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
import eu.crushedpixel.replaymod.holders.Marker;
|
|
||||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.Gui;
|
import net.minecraft.client.gui.Gui;
|
||||||
|
|
||||||
@@ -27,11 +25,6 @@ public class GuiTimeline extends Gui implements GuiElement {
|
|||||||
protected static final int BORDER_RIGHT = 4;
|
protected static final int BORDER_RIGHT = 4;
|
||||||
protected static final int BODY_WIDTH = TEXTURE_WIDTH - BORDER_LEFT - BORDER_RIGHT;
|
protected static final int BODY_WIDTH = TEXTURE_WIDTH - BORDER_LEFT - BORDER_RIGHT;
|
||||||
|
|
||||||
protected static final int MARKER_TEXTURE_X = 40;
|
|
||||||
protected static final int MARKER_TEXTURE_Y = 39;
|
|
||||||
protected static final int MARKER_TEXTURE_WIDTH = 5;
|
|
||||||
protected static final int MARKER_TEXTURE_HEIGHT = 5;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current position of the cursor. Should normally be between 0 and {@link #timelineLength}.
|
* Current position of the cursor. Should normally be between 0 and {@link #timelineLength}.
|
||||||
*/
|
*/
|
||||||
@@ -59,11 +52,6 @@ public class GuiTimeline extends Gui implements GuiElement {
|
|||||||
*/
|
*/
|
||||||
public boolean showMarkers;
|
public boolean showMarkers;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to draw indicators for Replay Markers.
|
|
||||||
*/
|
|
||||||
public boolean showMarkerIndicators = true;
|
|
||||||
|
|
||||||
protected final int positionX;
|
protected final int positionX;
|
||||||
protected final int positionY;
|
protected final int positionY;
|
||||||
protected final int width;
|
protected final int width;
|
||||||
@@ -150,26 +138,6 @@ public class GuiTimeline extends Gui implements GuiElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(showMarkerIndicators) {
|
|
||||||
double segmentLength = timelineLength * zoom;
|
|
||||||
|
|
||||||
for(Marker marker : ReplayHandler.getMarkers()) {
|
|
||||||
if(marker.getTimestamp() <= rightTime && marker.getTimestamp() >= leftTime) {
|
|
||||||
int textureX = MARKER_TEXTURE_X;
|
|
||||||
int textureY = MARKER_TEXTURE_Y;
|
|
||||||
int y = positionY;
|
|
||||||
|
|
||||||
int markerX = getMarkerX(marker.getTimestamp(), leftTime, bodyWidth, segmentLength);
|
|
||||||
|
|
||||||
if(ReplayHandler.isSelected(marker)) {
|
|
||||||
textureX += MARKER_TEXTURE_WIDTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
rect(markerX - 2, y + HEIGHT - 3 - MARKER_TEXTURE_HEIGHT, textureX, textureY, MARKER_TEXTURE_WIDTH, MARKER_TEXTURE_HEIGHT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drawTimelineCursor(leftTime, rightTime, bodyWidth);
|
drawTimelineCursor(leftTime, rightTime, bodyWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import eu.crushedpixel.replaymod.gui.GuiMouseInput;
|
|||||||
import eu.crushedpixel.replaymod.gui.GuiRenderSettings;
|
import eu.crushedpixel.replaymod.gui.GuiRenderSettings;
|
||||||
import eu.crushedpixel.replaymod.gui.GuiReplaySpeedSlider;
|
import eu.crushedpixel.replaymod.gui.GuiReplaySpeedSlider;
|
||||||
import eu.crushedpixel.replaymod.gui.elements.*;
|
import eu.crushedpixel.replaymod.gui.elements.*;
|
||||||
|
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.Position;
|
import eu.crushedpixel.replaymod.holders.Position;
|
||||||
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
|
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
||||||
@@ -181,6 +182,28 @@ public class GuiReplayOverlay extends Gui {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final GuiElement buttonMarker = new DelegatingElement() {
|
||||||
|
|
||||||
|
private final GuiElement buttonNotSelected = texturedButton(BUTTON_TIME_X, BOTTOM_ROW, 0, 80, 20, new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ReplayHandler.addKeyframe(new TimeKeyframe(ReplayHandler.getRealTimelineCursor(), ReplayMod.replaySender.currentTimeStamp()));
|
||||||
|
}
|
||||||
|
}, "replaymod.gui.ingame.menu.addtimekeyframe");
|
||||||
|
|
||||||
|
private final GuiElement buttonSelected = texturedButton(BUTTON_TIME_X, BOTTOM_ROW, 0, 100, 20, new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ReplayHandler.removeKeyframe(ReplayHandler.getSelectedKeyframe());
|
||||||
|
}
|
||||||
|
}, "replaymod.gui.ingame.menu.removetimekeyframe");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GuiElement delegate() {
|
||||||
|
return ReplayHandler.getSelectedKeyframe() instanceof TimeKeyframe ? buttonSelected : buttonNotSelected;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final GuiElement buttonZoomIn = texturedButton(WIDTH - 14 - 9, BOTTOM_ROW, 40, 20, 9, new Runnable() {
|
private final GuiElement buttonZoomIn = texturedButton(WIDTH - 14 - 9, BOTTOM_ROW, 40, 20, 9, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -197,14 +220,16 @@ public class GuiReplayOverlay extends Gui {
|
|||||||
}
|
}
|
||||||
}, "replaymod.gui.ingame.menu.zoomout");
|
}, "replaymod.gui.ingame.menu.zoomout");
|
||||||
|
|
||||||
private final GuiTimeline timeline = new GuiTimeline(TIMELINE_X, TOP_ROW - 1, WIDTH - 14 - TIMELINE_X) {
|
private final GuiKeyframeTimeline timeline = new GuiKeyframeTimeline(TIMELINE_X, TOP_ROW - 1, WIDTH - 14 - TIMELINE_X, false, true, false, false) {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClick(Minecraft mc, int mouseX, int mouseY, int button) {
|
public void mouseClick(Minecraft mc, int mouseX, int mouseY, int button) {
|
||||||
performJump(timeline.getTimeAt(mouseX, mouseY));
|
super.mouseClick(mc, mouseX, mouseY, button);
|
||||||
|
if(!(ReplayHandler.getSelectedKeyframe() instanceof MarkerKeyframe))
|
||||||
|
performJump(timeline.getTimeAt(mouseX, mouseY));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final GuiKeyframeTimeline timelineReal = new GuiKeyframeTimeline(TIMELINE_REAL_X, BOTTOM_ROW - 1, TIMELINE_REAL_WIDTH);
|
private final GuiKeyframeTimeline timelineReal = new GuiKeyframeTimeline(TIMELINE_REAL_X, BOTTOM_ROW - 1, TIMELINE_REAL_WIDTH, true, false, true, true);
|
||||||
{
|
{
|
||||||
timelineReal.timelineLength = 10 * 60 * 1000;
|
timelineReal.timelineLength = 10 * 60 * 1000;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,26 @@ package eu.crushedpixel.replaymod.holders;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
|
|
||||||
public class Marker {
|
public class MarkerKeyframe extends Keyframe {
|
||||||
|
|
||||||
public Marker(Position position, int timestamp, String name) {
|
|
||||||
this.position = position;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Position position;
|
private Position position;
|
||||||
private int timestamp;
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
return new MarkerKeyframe(this.getPosition(), this.getRealTimestamp(), this.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MarkerKeyframe(Position position, int timestamp, String name) {
|
||||||
|
super(timestamp);
|
||||||
|
this.position = position;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public Position getPosition() {
|
public Position getPosition() {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@@ -29,8 +30,8 @@ public class Marker {
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o2) {
|
public boolean equals(Object o2) {
|
||||||
if(o2 == null) return false;
|
if(o2 == null) return false;
|
||||||
if(!(o2 instanceof Marker)) return false;
|
if(!(o2 instanceof MarkerKeyframe)) return false;
|
||||||
Marker m2 = (Marker)o2;
|
MarkerKeyframe m2 = (MarkerKeyframe)o2;
|
||||||
return hashCode() == m2.hashCode();
|
return hashCode() == m2.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +39,7 @@ public class Marker {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return new HashCodeBuilder(17, 37)
|
return new HashCodeBuilder(17, 37)
|
||||||
.append(position)
|
.append(position)
|
||||||
.append(timestamp)
|
.append(getRealTimestamp())
|
||||||
.append(name)
|
.append(name)
|
||||||
.toHashCode();
|
.toHashCode();
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ public class ConnectionEventHandler {
|
|||||||
public static void addMarker() {
|
public static void addMarker() {
|
||||||
if(!isRecording || packetListener == null) {
|
if(!isRecording || packetListener == null) {
|
||||||
String reason = isRecording ? " (recording)" : " (null)";
|
String reason = isRecording ? " (recording)" : " (null)";
|
||||||
logger.error("Invalid attempt to insert Marker!" + reason);
|
logger.error("Invalid attempt to insert MarkerKeyframe!" + reason);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.google.common.hash.Hashing;
|
|||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import eu.crushedpixel.replaymod.ReplayMod;
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
import eu.crushedpixel.replaymod.holders.Marker;
|
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.PacketData;
|
import eu.crushedpixel.replaymod.holders.PacketData;
|
||||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||||
@@ -35,7 +35,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
|
|||||||
protected boolean alive = true;
|
protected boolean alive = true;
|
||||||
protected DataWriter dataWriter;
|
protected DataWriter dataWriter;
|
||||||
protected Set<String> players = new HashSet<String>();
|
protected Set<String> players = new HashSet<String>();
|
||||||
protected Set<Marker> markers = new HashSet<Marker>();
|
protected Set<MarkerKeyframe> markers = new HashSet<MarkerKeyframe>();
|
||||||
private boolean singleplayer;
|
private boolean singleplayer;
|
||||||
private Gson gson = new Gson();
|
private Gson gson = new Gson();
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
|
|||||||
queue.add(data);
|
queue.add(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestFinish(Set<String> players, Set<Marker> markers) {
|
public void requestFinish(Set<String> players, Set<MarkerKeyframe> markers) {
|
||||||
active = false;
|
active = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import com.google.common.util.concurrent.Futures;
|
|||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import eu.crushedpixel.replaymod.ReplayMod;
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
|
import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
|
||||||
import eu.crushedpixel.replaymod.holders.Marker;
|
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.PacketData;
|
import eu.crushedpixel.replaymod.holders.PacketData;
|
||||||
import eu.crushedpixel.replaymod.holders.Position;
|
import eu.crushedpixel.replaymod.holders.Position;
|
||||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||||
@@ -223,7 +223,7 @@ public class PacketListener extends DataListener {
|
|||||||
Position pos = new Position(Minecraft.getMinecraft().getRenderViewEntity());
|
Position pos = new Position(Minecraft.getMinecraft().getRenderViewEntity());
|
||||||
int timestamp = (int) (System.currentTimeMillis() - startTime);
|
int timestamp = (int) (System.currentTimeMillis() - startTime);
|
||||||
|
|
||||||
Marker marker = new Marker(pos, timestamp, null);
|
MarkerKeyframe marker = new MarkerKeyframe(pos, timestamp, null);
|
||||||
|
|
||||||
markers.add(marker);
|
markers.add(marker);
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class ReplayHandler {
|
|||||||
private static float cameraTilt = 0;
|
private static float cameraTilt = 0;
|
||||||
|
|
||||||
private static KeyframeSet[] keyframeRepository = new KeyframeSet[]{};
|
private static KeyframeSet[] keyframeRepository = new KeyframeSet[]{};
|
||||||
private static Marker[] markers = new Marker[]{};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The file currently being played.
|
* The file currently being played.
|
||||||
@@ -66,10 +65,22 @@ public class ReplayHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Marker[] getMarkers() { return markers; }
|
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()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setMarkers(MarkerKeyframe[] m, boolean write) {
|
||||||
|
for(Keyframe kf : new ArrayList<Keyframe>(keyframes)) {
|
||||||
|
if(kf instanceof MarkerKeyframe) keyframes.remove(kf);
|
||||||
|
}
|
||||||
|
for(MarkerKeyframe marker : m) {
|
||||||
|
keyframes.add(marker);
|
||||||
|
}
|
||||||
|
|
||||||
public static void setMarkers(Marker[] m, boolean write) {
|
|
||||||
markers = m;
|
|
||||||
if(write) {
|
if(write) {
|
||||||
try {
|
try {
|
||||||
File tempFile = File.createTempFile(ReplayFile.ENTRY_MARKERS, "json");
|
File tempFile = File.createTempFile(ReplayFile.ENTRY_MARKERS, "json");
|
||||||
@@ -165,19 +176,7 @@ public class ReplayHandler {
|
|||||||
public static void addMarker() {
|
public static void addMarker() {
|
||||||
Position pos = new Position(mc.getRenderViewEntity());
|
Position pos = new Position(mc.getRenderViewEntity());
|
||||||
int timestamp = ReplayMod.replaySender.currentTimeStamp();
|
int timestamp = ReplayMod.replaySender.currentTimeStamp();
|
||||||
addMarker(new Marker(pos, timestamp, null));
|
addKeyframe(new MarkerKeyframe(pos, timestamp, null));
|
||||||
}
|
|
||||||
|
|
||||||
public static void addMarker(Marker marker) {
|
|
||||||
List<Marker> markerList = new ArrayList<Marker>(Arrays.asList(markers));
|
|
||||||
markerList.add(marker);
|
|
||||||
markers = markerList.toArray(new Marker[markerList.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeMarker(Marker marker) {
|
|
||||||
List<Marker> markerList = new ArrayList<Marker>(Arrays.asList(markers));
|
|
||||||
markerList.remove(marker);
|
|
||||||
markers = markerList.toArray(new Marker[markerList.size()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addKeyframe(Keyframe keyframe) {
|
public static void addKeyframe(Keyframe keyframe) {
|
||||||
@@ -287,6 +286,25 @@ public class ReplayHandler {
|
|||||||
return closest;
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MarkerKeyframe getClosestMarkerForRealTime(int realTime, int tolerance) {
|
||||||
|
List<MarkerKeyframe> found = new ArrayList<MarkerKeyframe>();
|
||||||
|
for(Keyframe kf : keyframes) {
|
||||||
|
if(!(kf instanceof MarkerKeyframe)) continue;
|
||||||
|
if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
|
||||||
|
found.add((MarkerKeyframe) kf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MarkerKeyframe closest = null;
|
||||||
|
|
||||||
|
for(MarkerKeyframe kf : found) {
|
||||||
|
if(closest == null || Math.abs(closest.getRealTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) {
|
||||||
|
closest = kf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
|
||||||
public static PositionKeyframe getPreviousPositionKeyframe(int realTime) {
|
public static PositionKeyframe getPreviousPositionKeyframe(int realTime) {
|
||||||
if(keyframes.isEmpty()) return null;
|
if(keyframes.isEmpty()) return null;
|
||||||
PositionKeyframe backup = null;
|
PositionKeyframe backup = null;
|
||||||
@@ -365,11 +383,6 @@ public class ReplayHandler {
|
|||||||
return kf == selectedKeyframe;
|
return kf == selectedKeyframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSelected(Marker marker) {
|
|
||||||
//TODO: Make marker selectable
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void selectKeyframe(Keyframe kf) {
|
public static void selectKeyframe(Keyframe kf) {
|
||||||
selectedKeyframe = kf;
|
selectedKeyframe = kf;
|
||||||
sortKeyframes();
|
sortKeyframes();
|
||||||
@@ -421,8 +434,8 @@ public class ReplayHandler {
|
|||||||
KeyframeSet[] paths = currentReplayFile.paths().get();
|
KeyframeSet[] paths = currentReplayFile.paths().get();
|
||||||
ReplayHandler.setKeyframeRepository(paths == null ? new KeyframeSet[0] : paths, false);
|
ReplayHandler.setKeyframeRepository(paths == null ? new KeyframeSet[0] : paths, false);
|
||||||
|
|
||||||
Marker[] markers = currentReplayFile.markers().get();
|
MarkerKeyframe[] markers = currentReplayFile.markers().get();
|
||||||
ReplayHandler.setMarkers(markers == null ? new Marker[0] : markers, false);
|
ReplayHandler.setMarkers(markers == null ? new MarkerKeyframe[0] : markers, false);
|
||||||
|
|
||||||
PlayerVisibility visibility = currentReplayFile.visibility().get();
|
PlayerVisibility visibility = currentReplayFile.visibility().get();
|
||||||
PlayerHandler.loadPlayerVisibilityConfiguration(visibility);
|
PlayerHandler.loadPlayerVisibilityConfiguration(visibility);
|
||||||
|
|||||||
@@ -536,9 +536,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
|||||||
if (cam != null && pos != null) {
|
if (cam != null && pos != null) {
|
||||||
// Move camera back in case we have been respawned
|
// Move camera back in case we have been respawned
|
||||||
if (Math.abs(pos.getX() - cam.posX) < ReplayMod.TP_DISTANCE_LIMIT && Math.abs(pos.getZ() - cam.posZ) < ReplayMod.TP_DISTANCE_LIMIT) {
|
if (Math.abs(pos.getX() - cam.posX) < ReplayMod.TP_DISTANCE_LIMIT && Math.abs(pos.getZ() - cam.posZ) < ReplayMod.TP_DISTANCE_LIMIT) {
|
||||||
cam.moveAbsolute(pos.getX(), pos.getY(), pos.getZ());
|
cam.moveAbsolute(pos);
|
||||||
cam.rotationPitch = pos.getPitch();
|
|
||||||
cam.rotationYaw = pos.getYaw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import eu.crushedpixel.replaymod.holders.KeyframeSet;
|
import eu.crushedpixel.replaymod.holders.KeyframeSet;
|
||||||
import eu.crushedpixel.replaymod.holders.Marker;
|
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.PlayerVisibility;
|
import eu.crushedpixel.replaymod.holders.PlayerVisibility;
|
||||||
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
@@ -129,17 +129,17 @@ public class ReplayFile extends ZipFile {
|
|||||||
return getEntry(ENTRY_MARKERS);
|
return getEntry(ENTRY_MARKERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Supplier<Marker[]> markers() {
|
public Supplier<MarkerKeyframe[]> markers() {
|
||||||
return new Supplier<Marker[]>() {
|
return new Supplier<MarkerKeyframe[]>() {
|
||||||
@Override
|
@Override
|
||||||
public Marker[] get() {
|
public MarkerKeyframe[] get() {
|
||||||
try {
|
try {
|
||||||
ZipArchiveEntry entry = markersEntry();
|
ZipArchiveEntry entry = markersEntry();
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(getInputStream(entry)));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(getInputStream(entry)));
|
||||||
return new Gson().fromJson(reader, Marker[].class);
|
return new Gson().fromJson(reader, MarkerKeyframe[].class);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package eu.crushedpixel.replaymod.utils;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import eu.crushedpixel.replaymod.ReplayMod;
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
import eu.crushedpixel.replaymod.holders.KeyframeSet;
|
import eu.crushedpixel.replaymod.holders.KeyframeSet;
|
||||||
import eu.crushedpixel.replaymod.holders.Marker;
|
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.PacketData;
|
import eu.crushedpixel.replaymod.holders.PacketData;
|
||||||
import eu.crushedpixel.replaymod.holders.PlayerVisibility;
|
import eu.crushedpixel.replaymod.holders.PlayerVisibility;
|
||||||
import eu.crushedpixel.replaymod.recording.PacketSerializer;
|
import eu.crushedpixel.replaymod.recording.PacketSerializer;
|
||||||
@@ -58,7 +58,7 @@ public class ReplayFileIO {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeReplayFile(File replayFile, File tempFile, ReplayMetaData metaData, Set<Marker> markers,
|
public static void writeReplayFile(File replayFile, File tempFile, ReplayMetaData metaData, Set<MarkerKeyframe> markers,
|
||||||
Map<String, File> resourcePacks, Map<Integer, String> resourcePackRequests) throws IOException {
|
Map<String, File> resourcePacks, Map<Integer, String> resourcePackRequests) throws IOException {
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ public class ReplayFileIO {
|
|||||||
zos.putNextEntry(new ZipEntry(ReplayFile.ENTRY_MARKERS));
|
zos.putNextEntry(new ZipEntry(ReplayFile.ENTRY_MARKERS));
|
||||||
|
|
||||||
pw = new PrintWriter(zos);
|
pw = new PrintWriter(zos);
|
||||||
pw.write(new Gson().toJson(markers.toArray(new Marker[markers.size()])));
|
pw.write(new Gson().toJson(markers.toArray(new MarkerKeyframe[markers.size()])));
|
||||||
pw.flush();
|
pw.flush();
|
||||||
zos.closeEntry();
|
zos.closeEntry();
|
||||||
}
|
}
|
||||||
@@ -332,7 +332,7 @@ public class ReplayFileIO {
|
|||||||
FileUtils.write(file, json);
|
FileUtils.write(file, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeMarkersToFile(Marker[] markers, File file) throws IOException {
|
public static void writeMarkersToFile(MarkerKeyframe[] markers, File file) throws IOException {
|
||||||
file.mkdirs();
|
file.mkdirs();
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.5 KiB |
Reference in New Issue
Block a user