mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
fix some rewind bugs and add replay support for rewind
This commit is contained in:
parent
3aaa419bd4
commit
80dba2a535
5 changed files with 97 additions and 14 deletions
|
|
@ -6,6 +6,7 @@ import sys.FileSystem;
|
|||
import mis.MisParser;
|
||||
import src.Settings;
|
||||
import src.Debug;
|
||||
import src.MarbleGame;
|
||||
|
||||
@:publicFields
|
||||
class ConsoleEntry {
|
||||
|
|
@ -142,6 +143,19 @@ class Console {
|
|||
} else {
|
||||
error("Expected one argument, got " + (cmdSplit.length - 1));
|
||||
}
|
||||
} else if (cmdType == "rewindTimeScale") {
|
||||
if (cmdSplit.length == 2) {
|
||||
var scale = Std.parseFloat(cmdSplit[1]);
|
||||
if (Math.isNaN(scale))
|
||||
scale = 1;
|
||||
if (MarbleGame.instance.world != null) {
|
||||
MarbleGame.instance.world.rewindManager.timeScale = scale;
|
||||
|
||||
log("Rewind Time scale set to " + scale);
|
||||
}
|
||||
} else {
|
||||
error("Expected one argument, got " + (cmdSplit.length - 1));
|
||||
}
|
||||
} else {
|
||||
error("Unknown command");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,6 +201,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) {
|
||||
|
|
@ -982,8 +985,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 {
|
||||
|
|
@ -1005,15 +1022,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;
|
||||
|
|
@ -1109,12 +1118,12 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
this.updateTexts();
|
||||
|
|
@ -1721,11 +1730,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;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ class ReplayInitialState {
|
|||
var landMineDisappearTimes:Array<Float> = [];
|
||||
var pushButtonContactTimes:Array<Float> = [];
|
||||
var randomGens:Array<Int> = [];
|
||||
var randomGenTimes:Array<Float> = [];
|
||||
|
||||
public function new() {}
|
||||
|
||||
|
|
@ -293,12 +294,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();
|
||||
|
|
@ -306,6 +311,8 @@ class Replay {
|
|||
}
|
||||
|
||||
public function recordMarbleStateFlags(jumped:Bool, usedPowerup:Bool, instantTeleport:Bool, usedBlast:Bool) {
|
||||
if (currentRecordFrame == null)
|
||||
return;
|
||||
if (jumped)
|
||||
currentRecordFrame.marbleStateFlags.set(Jumped);
|
||||
if (usedPowerup)
|
||||
|
|
@ -317,6 +324,8 @@ class Replay {
|
|||
}
|
||||
|
||||
public function recordPowerupPickup(powerup:PowerUp) {
|
||||
if (currentRecordFrame == null)
|
||||
return;
|
||||
if (powerup == null)
|
||||
currentRecordFrame.powerupPickup = ""; // Use powerup
|
||||
else
|
||||
|
|
@ -324,16 +333,22 @@ 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 recordGravity(gravity:Vector, instant:Bool) {
|
||||
if (currentRecordFrame == null)
|
||||
return;
|
||||
currentRecordFrame.gravityChange = true;
|
||||
currentRecordFrame.gravity = gravity.clone();
|
||||
if (instant)
|
||||
|
|
@ -341,21 +356,30 @@ class Replay {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public function recordRandomGenState(ri:Int) {
|
||||
if (currentRecordFrame == null)
|
||||
return;
|
||||
initialState.randomGens.push(ri);
|
||||
initialState.randomGenTimes.push(currentRecordFrame.time);
|
||||
}
|
||||
|
||||
public function getRandomGenState() {
|
||||
|
|
@ -442,6 +466,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();
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ typedef OptionsSettings = {
|
|||
var marbleModel:String;
|
||||
var marbleShader:String;
|
||||
var cameraDistance:Float;
|
||||
var rewindEnabled:Bool;
|
||||
}
|
||||
|
||||
typedef ControlsSettings = {
|
||||
|
|
@ -122,6 +123,7 @@ class Settings {
|
|||
marbleModel: "data/shapes/balls/ball-superball.dts",
|
||||
marbleShader: "Default",
|
||||
cameraDistance: 2.5,
|
||||
rewindEnabled: false,
|
||||
vsync: #if js true #end
|
||||
#if hl
|
||||
false
|
||||
|
|
@ -363,10 +365,15 @@ 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 (touchSettings.blastButtonPos == null) {
|
||||
touchSettings.blastButtonPos = [300, 240];
|
||||
touchSettings.blastButtonSize = 60;
|
||||
|
|
@ -401,6 +408,9 @@ class Settings {
|
|||
if (controlsSettings.rewind == null) {
|
||||
controlsSettings.rewind = Key.R;
|
||||
}
|
||||
if (optionsSettings.rewindEnabled == null) {
|
||||
optionsSettings.rewindEnabled = false;
|
||||
}
|
||||
#end
|
||||
highscoreName = json.highscoreName;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue