fix some rewind bugs and add replay support for rewind

This commit is contained in:
RandomityGuy 2023-05-08 01:10:58 +05:30
parent 4974586c31
commit e581be7c08
4 changed files with 75 additions and 14 deletions

View file

@ -158,6 +158,9 @@ class MarbleWorld extends Scheduler {
var textureResources:Array<Resource<h3d.mat.Texture>> = [];
var soundResources:Array<Resource<Sound>> = [];
var oobSchedule:Float;
var oobSchedule2:Float;
var lock:Bool = false;
public function new(scene:Scene, scene2d:h2d.Scene, mission:Mission, record:Bool = false) {
@ -909,8 +912,22 @@ class MarbleWorld extends Scheduler {
if (!_ready) {
return;
}
var realDt = dt;
if (Key.isDown(Settings.controlsSettings.rewind) && Settings.optionsSettings.rewindEnabled && !this.isWatching) {
this.rewinding = true;
} else {
this.rewinding = false;
if (Key.isReleased(Settings.controlsSettings.rewind)) {
if (this.isRecording) {
this.replay.spliceReplay(timeState.currentAttemptTime);
}
}
}
if (!this.isWatching) {
if (this.isRecording) {
if (this.isRecording && !this.rewinding) {
this.replay.startFrame();
}
} else {
@ -931,15 +948,7 @@ class MarbleWorld extends Scheduler {
}
}
var realDt = dt;
if (Key.isDown(Key.R)) {
this.rewinding = true;
} else {
this.rewinding = false;
}
if (this.rewinding) {
if (this.rewinding && !this.isWatching) {
var rframe = rewindManager.getNextRewindFrame(timeState.currentAttemptTime - dt * rewindManager.timeScale);
if (rframe != null) {
var actualDt = timeState.currentAttemptTime - rframe.timeState.currentAttemptTime - dt * rewindManager.timeScale;
@ -981,12 +990,12 @@ class MarbleWorld extends Scheduler {
AudioManager.update(this.scene);
if (!this.isWatching) {
if (this.isRecording) {
if (this.isRecording && !this.rewinding) {
this.replay.endFrame();
}
}
if (!this.rewinding)
if (!this.rewinding && Settings.optionsSettings.rewindEnabled)
this.rewindManager.recordFrame();
if (this.outOfBounds
@ -1462,11 +1471,11 @@ class MarbleWorld extends Scheduler {
playGui.setCenterText('outofbounds');
AudioManager.playSound(ResourceLoader.getResource('data/sound/whoosh.wav', ResourceLoader.getAudio, this.soundResources));
// if (this.replay.mode != = 'playback')
this.schedule(this.timeState.currentAttemptTime + 2, () -> {
this.oobSchedule = this.schedule(this.timeState.currentAttemptTime + 2, () -> {
playGui.setCenterText('none');
return null;
});
this.schedule(this.timeState.currentAttemptTime + 2.5, () -> {
this.oobSchedule2 = this.schedule(this.timeState.currentAttemptTime + 2.5, () -> {
this.restart();
return null;
});

View file

@ -223,12 +223,16 @@ class Replay {
}
public function recordTimeState(time:Float, clockTime:Float, bonusTime:Float) {
if (currentRecordFrame == null)
return;
currentRecordFrame.time = time;
currentRecordFrame.clockTime = clockTime;
currentRecordFrame.bonusTime = bonusTime;
}
public function recordMarbleState(position:Vector, velocity:Vector, orientation:Quat, angularVelocity:Vector) {
if (currentRecordFrame == null)
return;
currentRecordFrame.marblePosition = position.clone();
currentRecordFrame.marbleVelocity = velocity.clone();
currentRecordFrame.marbleOrientation = orientation.clone();
@ -236,6 +240,8 @@ class Replay {
}
public function recordMarbleStateFlags(jumped:Bool, usedPowerup:Bool, instantTeleport:Bool) {
if (currentRecordFrame == null)
return;
if (jumped)
currentRecordFrame.marbleStateFlags.set(Jumped);
if (usedPowerup)
@ -245,26 +251,36 @@ class Replay {
}
public function recordMarbleInput(x:Float, y:Float) {
if (currentRecordFrame == null)
return;
currentRecordFrame.marbleX = x;
currentRecordFrame.marbleY = y;
}
public function recordCameraState(pitch:Float, yaw:Float) {
if (currentRecordFrame == null)
return;
currentRecordFrame.cameraPitch = pitch;
currentRecordFrame.cameraYaw = yaw;
}
public function recordTrapdoorState(lastContactTime:Float, lastDirection:Int, lastCompletion:Float) {
if (currentRecordFrame == null)
return;
initialState.trapdoorLastContactTimes.push(lastContactTime);
initialState.trapdoorLastDirections.push(lastDirection);
initialState.trapdoorLastCompletions.push(lastCompletion);
}
public function recordLandMineState(disappearTime:Float) {
if (currentRecordFrame == null)
return;
initialState.landMineDisappearTimes.push(disappearTime);
}
public function recordPushButtonState(lastContactTime:Float) {
if (currentRecordFrame == null)
return;
initialState.pushButtonContactTimes.push(lastContactTime);
}
@ -320,6 +336,24 @@ class Replay {
this.currentPlaybackFrameIdx = 0;
}
public function spliceReplay(cutAfterTime:Float) {
if (this.frames.length > 0) {
var curframe = this.frames[this.frames.length - 1];
while (curframe.time > cutAfterTime && this.frames.length > 0) {
this.frames.pop();
curframe = this.frames[this.frames.length - 1];
}
}
if (this.initialState.randomGenTimes.length > 0) {
var rtimeIdx = this.initialState.randomGenTimes.length - 1;
while (this.initialState.randomGenTimes[rtimeIdx] > cutAfterTime && this.initialState.randomGenTimes.length > 0) {
this.initialState.randomGenTimes.pop();
this.initialState.randomGens.pop();
rtimeIdx = this.initialState.randomGenTimes.length - 1;
}
}
}
public function write() {
var bw = new BytesWriter();

View file

@ -33,6 +33,7 @@ typedef OptionsSettings = {
var soundVolume:Float;
var vsync:Bool;
var fovX:Int;
var rewindEnabled:Bool;
}
typedef ControlsSettings = {
@ -89,6 +90,7 @@ class Settings {
musicVolume: 1,
soundVolume: 0.7,
fovX: 90,
rewindEnabled: false,
vsync: #if js true #end
#if hl
false
@ -249,16 +251,24 @@ class Settings {
optionsSettings = json.options;
if (optionsSettings.fovX == 0 #if js || optionsSettings.fovX == null #end)
optionsSettings.fovX = 90;
if (optionsSettings.rewindEnabled == false #if js || optionsSettings.rewindEnabled == null #end)
optionsSettings.rewindEnabled = false;
controlsSettings = json.controls;
if (json.touch != null) {
touchSettings = json.touch;
}
if (controlsSettings.rewind == 0) {
controlsSettings.rewind = Key.R;
}
if (json.gamepad != null) {
gamepadSettings = json.gamepad;
}
if (controlsSettings.rewind == null) {
controlsSettings.rewind = Key.R;
}
if (optionsSettings.rewindEnabled == null) {
optionsSettings.rewindEnabled = false;
}
progression = json.progression;
highscoreName = json.highscoreName;
} else {

View file

@ -204,6 +204,14 @@ class RewindManager {
td.lastContactTime = tdState.lastContactTime;
}
}
if (!rf.oobState.oob) {
@:privateAccess level.cancel(level.oobSchedule);
@:privateAccess level.cancel(level.oobSchedule2);
} else {
level.goOutOfBounds();
}
level.outOfBounds = rf.oobState.oob;
level.marble.camera.oob = rf.oobState.oob;
level.outOfBoundsTime = rf.oobState.timeState != null ? rf.oobState.timeState.clone() : null;