From 3aaa419bd41cba42d98c2b7e487c97c98d1e3209 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Sun, 7 May 2023 19:25:38 +0530 Subject: [PATCH] rewind support for everything else --- src/Main.hx | 7 ++++++ src/Marble.hx | 2 +- src/MarbleWorld.hx | 10 ++++++--- src/rewind/RewindFrame.hx | 34 +++++++++++++++++++++++++++++ src/rewind/RewindManager.hx | 43 +++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/Main.hx b/src/Main.hx index 77d45ecd..d2bc95e0 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -30,6 +30,8 @@ class Main extends hxd.App { var frameByFrame:Bool = false; + // var timeAccumulator:Float = 0.0; + override function init() { super.init(); @@ -119,6 +121,11 @@ class Main extends hxd.App { ProfilerUI.measure("updateBegin"); // try { + // timeAccumulator += dt; + // while (timeAccumulator > 1 / 60) { + // marbleGame.update(1 / 60); + // timeAccumulator -= 1 / 60; + // } marbleGame.update(dt); // } catch (e) { // Console.error(e.message); diff --git a/src/Marble.hx b/src/Marble.hx index 3cba808b..52312ec3 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -1811,7 +1811,7 @@ class Marble extends GameObject { this.omega = expectedOmega; } - if (this.controllable) { + if (this.controllable && !this.level.rewinding) { this.camera.update(timeState.currentAttemptTime, timeState.dt); } diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 78e08a57..42b24927 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1014,9 +1014,9 @@ class MarbleWorld extends Scheduler { } if (this.rewinding) { - var rframe = rewindManager.getNextRewindFrame(timeState.currentAttemptTime - dt); + var rframe = rewindManager.getNextRewindFrame(timeState.currentAttemptTime - dt * rewindManager.timeScale); if (rframe != null) { - var actualDt = timeState.currentAttemptTime - rframe.timeState.currentAttemptTime - dt; + var actualDt = timeState.currentAttemptTime - rframe.timeState.currentAttemptTime - dt * rewindManager.timeScale; dt = actualDt; rewindManager.applyFrame(rframe); } @@ -1084,11 +1084,15 @@ class MarbleWorld extends Scheduler { for (marble in marbles) { marble.update(timeState, collisionWorld, this.pathedInteriors); } + if (this.rewinding) { + // Update camera separately + marble.camera.update(timeState.currentAttemptTime, realDt); + } ProfilerUI.measure("updateInstances"); this.instanceManager.render(); ProfilerUI.measure("updateParticles"); if (this.rewinding) { - this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt); + this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt * rewindManager.timeScale); } else this.particleManager.update(1000 * timeState.timeSinceLoad, dt); ProfilerUI.measure("updatePlayGui"); diff --git a/src/rewind/RewindFrame.hx b/src/rewind/RewindFrame.hx index c5698f2e..9edf4215 100644 --- a/src/rewind/RewindFrame.hx +++ b/src/rewind/RewindFrame.hx @@ -1,10 +1,14 @@ package rewind; +import mis.MissionElement.MissionElementBase; +import triggers.CheckpointTrigger; import src.PathedInterior.PIState; import shapes.PowerUp; import h3d.Vector; import h3d.Quat; import src.TimeState; +import src.DtsObject; +import shapes.Gem; @:publicFields class RewindFrame { @@ -29,6 +33,20 @@ class RewindFrame { var currentUp:Vector; var trapdoorStates:Array<{lastContactTime:Float, lastDirection:Int, lastCompletion:Float}>; var lastContactNormal:Vector; + var blastAmt:Float; + var oobState:{ + oob:Bool, + timeState:TimeState + }; + + var checkpointState:{ + currentCheckpoint:{obj:DtsObject, elem:MissionElementBase}, + currentCheckpointTrigger:CheckpointTrigger, + checkpointCollectedGems:Map, + checkpointHeldPowerup:PowerUp, + checkpointUp:Vector, + checkpointBlast:Float + }; public function new() {} @@ -79,5 +97,21 @@ class RewindFrame { lastCompletion: s.lastCompletion, }); } + c.blastAmt = blastAmt; + c.oobState = { + oob: oobState.oob, + timeState: oobState.timeState.clone() + }; + c.checkpointState = { + currentCheckpoint: checkpointState.currentCheckpoint != null ? { + obj: checkpointState.currentCheckpoint.obj, + elem: checkpointState.currentCheckpoint.elem, + } : null, + currentCheckpointTrigger: checkpointState.currentCheckpointTrigger, + checkpointCollectedGems: checkpointState.checkpointCollectedGems.copy(), + checkpointHeldPowerup: checkpointState.checkpointHeldPowerup, + checkpointUp: checkpointState.checkpointUp != null ? checkpointState.checkpointUp.clone() : null, + checkpointBlast: checkpointState.checkpointBlast, + }; } } diff --git a/src/rewind/RewindManager.hx b/src/rewind/RewindManager.hx index d005566c..9f0ecde2 100644 --- a/src/rewind/RewindManager.hx +++ b/src/rewind/RewindManager.hx @@ -4,12 +4,16 @@ import shapes.PowerUp; import shapes.LandMine; import src.MarbleWorld; import shapes.Trapdoor; +import shapes.PushButton; import src.Util; +import shapes.Nuke; class RewindManager { var frames:Array = []; var level:MarbleWorld; + public var timeScale:Float = 1; + public function new(level:MarbleWorld) { this.level = level; } @@ -63,10 +67,18 @@ class RewindManager { var pow:PowerUp = cast dts; rf.powerupStates.push(pow.lastPickUpTime); } + if (dts is PushButton) { + var pow:PushButton = cast dts; + rf.powerupStates.push(pow.lastContactTime); + } if (dts is LandMine) { var lm:LandMine = cast dts; rf.landMineStates.push(lm.disappearTime); } + if (dts is Nuke) { + var lm:Nuke = cast dts; + rf.landMineStates.push(lm.disappearTime); + } if (dts is Trapdoor) { var td:Trapdoor = cast dts; rf.trapdoorStates.push({ @@ -76,6 +88,19 @@ class RewindManager { }); } } + rf.blastAmt = level.blastAmount; + rf.oobState = { + oob: level.outOfBounds, + timeState: level.outOfBoundsTime != null ? level.outOfBoundsTime.clone() : null + }; + rf.checkpointState = { + currentCheckpoint: @:privateAccess level.currentCheckpoint, + currentCheckpointTrigger: @:privateAccess level.currentCheckpointTrigger, + checkpointBlast: @:privateAccess level.cheeckpointBlast, + checkpointCollectedGems: @:privateAccess level.checkpointCollectedGems.copy(), + checkpointHeldPowerup: @:privateAccess level.checkpointHeldPowerup, + checkpointUp: @:privateAccess level.checkpointUp != null ? @:privateAccess level.checkpointUp.clone() : null, + }; frames.push(rf); } @@ -159,10 +184,18 @@ class RewindManager { var pow:PowerUp = cast dts; pow.lastPickUpTime = pstates.shift(); } + if (dts is PushButton) { + var pow:PushButton = cast dts; + pow.lastContactTime = pstates.shift(); + } if (dts is LandMine) { var lm:LandMine = cast dts; lm.disappearTime = lmstates.shift(); } + if (dts is Nuke) { + var lm:Nuke = cast dts; + lm.disappearTime = lmstates.shift(); + } if (dts is Trapdoor) { var td:Trapdoor = cast dts; var tdState = tstates.shift(); @@ -171,6 +204,16 @@ class RewindManager { td.lastContactTime = tdState.lastContactTime; } } + level.outOfBounds = rf.oobState.oob; + level.marble.camera.oob = rf.oobState.oob; + level.outOfBoundsTime = rf.oobState.timeState != null ? rf.oobState.timeState.clone() : null; + level.blastAmount = rf.blastAmt; + @:privateAccess level.checkpointUp = rf.checkpointState.checkpointUp; + @:privateAccess level.checkpointCollectedGems = rf.checkpointState.checkpointCollectedGems; + @:privateAccess level.cheeckpointBlast = rf.checkpointState.checkpointBlast; + @:privateAccess level.checkpointHeldPowerup = rf.checkpointState.checkpointHeldPowerup; + @:privateAccess level.currentCheckpoint = rf.checkpointState.currentCheckpoint; + @:privateAccess level.currentCheckpointTrigger = rf.checkpointState.currentCheckpointTrigger; } public function getNextRewindFrame(absTime:Float):RewindFrame {