mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
rewind barebones
This commit is contained in:
parent
c6c1449a84
commit
e6b5dbbb25
9 changed files with 317 additions and 10 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package src;
|
package src;
|
||||||
|
|
||||||
|
import rewind.RewindManager;
|
||||||
import Macros.MarbleWorldMacros;
|
import Macros.MarbleWorldMacros;
|
||||||
import shapes.PushButton;
|
import shapes.PushButton;
|
||||||
#if js
|
#if js
|
||||||
|
|
@ -179,6 +180,10 @@ class MarbleWorld extends Scheduler {
|
||||||
public var isWatching:Bool = false;
|
public var isWatching:Bool = false;
|
||||||
public var isRecording:Bool = false;
|
public var isRecording:Bool = false;
|
||||||
|
|
||||||
|
// Rewind
|
||||||
|
public var rewindManager:RewindManager;
|
||||||
|
public var rewinding:Bool = false;
|
||||||
|
|
||||||
// Loading
|
// Loading
|
||||||
var resourceLoadFuncs:Array<(() -> Void)->Void> = [];
|
var resourceLoadFuncs:Array<(() -> Void)->Void> = [];
|
||||||
|
|
||||||
|
|
@ -205,6 +210,7 @@ class MarbleWorld extends Scheduler {
|
||||||
this.game = mission.game.toLowerCase();
|
this.game = mission.game.toLowerCase();
|
||||||
this.replay = new Replay(mission.path, mission.isClaMission ? mission.id : 0);
|
this.replay = new Replay(mission.path, mission.isClaMission ? mission.id : 0);
|
||||||
this.isRecording = record;
|
this.isRecording = record;
|
||||||
|
this.rewindManager = new RewindManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function init() {
|
public function init() {
|
||||||
|
|
@ -448,6 +454,8 @@ class MarbleWorld extends Scheduler {
|
||||||
} else
|
} else
|
||||||
this.replay.rewind();
|
this.replay.rewind();
|
||||||
|
|
||||||
|
this.rewindManager.clear();
|
||||||
|
|
||||||
this.timeState.currentAttemptTime = 0;
|
this.timeState.currentAttemptTime = 0;
|
||||||
this.timeState.gameplayClock = 0;
|
this.timeState.gameplayClock = 0;
|
||||||
this.bonusTime = 0;
|
this.bonusTime = 0;
|
||||||
|
|
@ -997,6 +1005,23 @@ class MarbleWorld extends Scheduler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Key.isDown(Key.R)) {
|
||||||
|
this.rewinding = true;
|
||||||
|
} else {
|
||||||
|
this.rewinding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.rewinding) {
|
||||||
|
var rframe = rewindManager.getNextRewindFrame(timeState.currentAttemptTime - dt);
|
||||||
|
if (rframe != null) {
|
||||||
|
var actualDt = timeState.currentAttemptTime - rframe.timeState.currentAttemptTime - dt;
|
||||||
|
dt = actualDt;
|
||||||
|
rewindManager.applyFrame(rframe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dt < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
ProfilerUI.measure("updateTimer");
|
ProfilerUI.measure("updateTimer");
|
||||||
this.updateTimer(dt);
|
this.updateTimer(dt);
|
||||||
|
|
||||||
|
|
@ -1080,6 +1105,9 @@ class MarbleWorld extends Scheduler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.rewinding)
|
||||||
|
this.rewindManager.recordFrame();
|
||||||
|
|
||||||
this.updateTexts();
|
this.updateTexts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
83
src/rewind/RewindFrame.hx
Normal file
83
src/rewind/RewindFrame.hx
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
package rewind;
|
||||||
|
|
||||||
|
import src.PathedInterior.PIState;
|
||||||
|
import shapes.PowerUp;
|
||||||
|
import h3d.Vector;
|
||||||
|
import h3d.Quat;
|
||||||
|
import src.TimeState;
|
||||||
|
|
||||||
|
@:publicFields
|
||||||
|
class RewindFrame {
|
||||||
|
var timeState:TimeState;
|
||||||
|
var marblePosition:Vector;
|
||||||
|
var marbleOrientation:Quat;
|
||||||
|
var marbleVelocity:Vector;
|
||||||
|
var marbleAngularVelocity:Vector;
|
||||||
|
var marblePowerup:PowerUp;
|
||||||
|
var bonusTime:Float;
|
||||||
|
var mpStates:Array<{
|
||||||
|
curState:PIState,
|
||||||
|
prevState:PIState,
|
||||||
|
stopped:Bool,
|
||||||
|
stopTime:Float
|
||||||
|
}>;
|
||||||
|
var gemCount:Int;
|
||||||
|
var gemStates:Array<Bool>;
|
||||||
|
var powerupStates:Array<Float>;
|
||||||
|
var landMineStates:Array<Float>;
|
||||||
|
var activePowerupStates:Array<Float>;
|
||||||
|
var currentUp:Vector;
|
||||||
|
var trapdoorStates:Array<{lastContactTime:Float, lastDirection:Int, lastCompletion:Float}>;
|
||||||
|
var lastContactNormal:Vector;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
|
||||||
|
public function clone() {
|
||||||
|
var c = new RewindFrame();
|
||||||
|
c.timeState = timeState.clone();
|
||||||
|
c.marblePosition = marblePosition.clone();
|
||||||
|
c.marbleOrientation = marbleOrientation.clone();
|
||||||
|
c.marbleVelocity = marbleVelocity.clone();
|
||||||
|
c.marbleAngularVelocity = marbleAngularVelocity.clone();
|
||||||
|
c.marblePowerup = marblePowerup;
|
||||||
|
c.bonusTime = bonusTime;
|
||||||
|
c.gemCount = gemCount;
|
||||||
|
c.gemStates = gemStates.copy();
|
||||||
|
c.powerupStates = powerupStates.copy();
|
||||||
|
c.landMineStates = landMineStates.copy();
|
||||||
|
c.activePowerupStates = activePowerupStates.copy();
|
||||||
|
c.currentUp = currentUp.clone();
|
||||||
|
c.lastContactNormal = lastContactNormal.clone();
|
||||||
|
c.mpStates = [];
|
||||||
|
for (s in mpStates) {
|
||||||
|
c.mpStates.push({
|
||||||
|
curState: {
|
||||||
|
currentTime: s.curState.currentTime,
|
||||||
|
targetTime: s.curState.targetTime,
|
||||||
|
velocity: s.curState.velocity.clone(),
|
||||||
|
currentPosition: s.curState.currentPosition.clone(),
|
||||||
|
prevPosition: s.curState.prevPosition.clone(),
|
||||||
|
changeTime: s.curState.changeTime,
|
||||||
|
},
|
||||||
|
stopTime: s.stopTime,
|
||||||
|
stopped: s.stopped,
|
||||||
|
prevState: s.prevState != null ? {
|
||||||
|
currentTime: s.prevState.currentTime,
|
||||||
|
targetTime: s.prevState.targetTime,
|
||||||
|
velocity: s.prevState.velocity.clone(),
|
||||||
|
currentPosition: s.prevState.currentPosition.clone(),
|
||||||
|
prevPosition: s.prevState.prevPosition.clone(),
|
||||||
|
changeTime: s.prevState.changeTime,
|
||||||
|
} : null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
c.trapdoorStates = [];
|
||||||
|
for (s in trapdoorStates) {
|
||||||
|
c.trapdoorStates.push({
|
||||||
|
lastContactTime: s.lastContactTime,
|
||||||
|
lastDirection: s.lastDirection,
|
||||||
|
lastCompletion: s.lastCompletion,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
193
src/rewind/RewindManager.hx
Normal file
193
src/rewind/RewindManager.hx
Normal file
|
|
@ -0,0 +1,193 @@
|
||||||
|
package rewind;
|
||||||
|
|
||||||
|
import shapes.PowerUp;
|
||||||
|
import shapes.LandMine;
|
||||||
|
import src.MarbleWorld;
|
||||||
|
import shapes.Trapdoor;
|
||||||
|
import src.Util;
|
||||||
|
|
||||||
|
class RewindManager {
|
||||||
|
var frames:Array<RewindFrame> = [];
|
||||||
|
var level:MarbleWorld;
|
||||||
|
|
||||||
|
public function new(level:MarbleWorld) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function recordFrame() {
|
||||||
|
var rf = new RewindFrame();
|
||||||
|
rf.timeState = level.timeState.clone();
|
||||||
|
rf.marblePosition = level.marble.getAbsPos().getPosition().clone();
|
||||||
|
rf.marbleOrientation = level.marble.getRotationQuat().clone();
|
||||||
|
rf.marbleVelocity = level.marble.velocity.clone();
|
||||||
|
rf.marbleAngularVelocity = level.marble.omega.clone();
|
||||||
|
rf.marblePowerup = level.marble.heldPowerup;
|
||||||
|
rf.bonusTime = level.bonusTime;
|
||||||
|
rf.gemCount = level.gemCount;
|
||||||
|
rf.gemStates = level.gems.map(x -> x.pickedUp);
|
||||||
|
rf.activePowerupStates = [@:privateAccess
|
||||||
|
level.marble.superBounceEnableTime, @:privateAccess
|
||||||
|
level.marble.shockAbsorberEnableTime, @:privateAccess
|
||||||
|
level.marble.helicopterEnableTime, @:privateAccess
|
||||||
|
level.marble.megaMarbleEnableTime
|
||||||
|
];
|
||||||
|
rf.currentUp = level.currentUp.clone();
|
||||||
|
rf.lastContactNormal = level.marble.lastContactNormal.clone();
|
||||||
|
rf.mpStates = level.pathedInteriors.map(x -> {
|
||||||
|
return {
|
||||||
|
curState: {
|
||||||
|
currentTime: x.currentTime,
|
||||||
|
targetTime: x.targetTime,
|
||||||
|
velocity: x.velocity.clone(),
|
||||||
|
currentPosition: x.currentPosition.clone(),
|
||||||
|
prevPosition: x.prevPosition.clone(),
|
||||||
|
changeTime: x.changeTime,
|
||||||
|
},
|
||||||
|
stopTime: @:privateAccess x.stopTime,
|
||||||
|
stopped: @:privateAccess x.stopped,
|
||||||
|
prevState: @:privateAccess x.previousState != null ? {
|
||||||
|
currentTime: @:privateAccess x.previousState.currentTime,
|
||||||
|
targetTime: @:privateAccess x.previousState.targetTime,
|
||||||
|
velocity: @:privateAccess x.previousState.velocity.clone(),
|
||||||
|
currentPosition: @:privateAccess x.previousState.currentPosition.clone(),
|
||||||
|
prevPosition: @:privateAccess x.previousState.prevPosition.clone(),
|
||||||
|
changeTime: @:privateAccess x.previousState.changeTime,
|
||||||
|
} : null,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rf.powerupStates = [];
|
||||||
|
rf.landMineStates = [];
|
||||||
|
rf.trapdoorStates = [];
|
||||||
|
for (dts in level.dtsObjects) {
|
||||||
|
if (dts is PowerUp) {
|
||||||
|
var pow:PowerUp = cast dts;
|
||||||
|
rf.powerupStates.push(pow.lastPickUpTime);
|
||||||
|
}
|
||||||
|
if (dts is LandMine) {
|
||||||
|
var lm:LandMine = cast dts;
|
||||||
|
rf.landMineStates.push(lm.disappearTime);
|
||||||
|
}
|
||||||
|
if (dts is Trapdoor) {
|
||||||
|
var td:Trapdoor = cast dts;
|
||||||
|
rf.trapdoorStates.push({
|
||||||
|
lastCompletion: td.lastCompletion,
|
||||||
|
lastDirection: td.lastDirection,
|
||||||
|
lastContactTime: td.lastContactTime
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frames.push(rf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyFrame(rf:RewindFrame) {
|
||||||
|
level.timeState = rf.timeState.clone();
|
||||||
|
level.marble.setPosition(rf.marblePosition.x, rf.marblePosition.y, rf.marblePosition.z);
|
||||||
|
level.marble.setRotationQuat(rf.marbleOrientation.clone());
|
||||||
|
level.marble.velocity.set(rf.marbleVelocity.x, rf.marbleVelocity.y, rf.marbleVelocity.z);
|
||||||
|
level.marble.omega.set(rf.marbleAngularVelocity.x, rf.marbleAngularVelocity.y, rf.marbleAngularVelocity.z);
|
||||||
|
|
||||||
|
if (level.marble.heldPowerup == null) {
|
||||||
|
if (rf.marblePowerup != null) {
|
||||||
|
level.pickUpPowerUp(rf.marblePowerup);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rf.marblePowerup == null) {
|
||||||
|
level.deselectPowerUp();
|
||||||
|
} else {
|
||||||
|
level.pickUpPowerUp(rf.marblePowerup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level.bonusTime = rf.bonusTime;
|
||||||
|
level.gemCount = rf.gemCount;
|
||||||
|
@:privateAccess level.playGui.formatGemCounter(level.gemCount, level.totalGems);
|
||||||
|
for (i in 0...rf.gemStates.length) {
|
||||||
|
level.gems[i].setHide(rf.gemStates[i]);
|
||||||
|
}
|
||||||
|
@:privateAccess level.marble.superBounceEnableTime = rf.activePowerupStates[0];
|
||||||
|
@:privateAccess level.marble.shockAbsorberEnableTime = rf.activePowerupStates[1];
|
||||||
|
@:privateAccess level.marble.helicopterEnableTime = rf.activePowerupStates[2];
|
||||||
|
@:privateAccess level.marble.megaMarbleEnableTime = rf.activePowerupStates[3];
|
||||||
|
|
||||||
|
if (level.currentUp.x != rf.currentUp.x || level.currentUp.y != rf.currentUp.y || level.currentUp.z != rf.currentUp.z) {
|
||||||
|
level.setUp(rf.currentUp, level.timeState);
|
||||||
|
// Hacky things
|
||||||
|
@:privateAccess level.orientationChangeTime = level.timeState.currentAttemptTime - 300;
|
||||||
|
var oldorient = level.newOrientationQuat;
|
||||||
|
level.newOrientationQuat = @:privateAccess level.oldOrientationQuat;
|
||||||
|
@:privateAccess level.oldOrientationQuat = oldorient;
|
||||||
|
}
|
||||||
|
|
||||||
|
var gravitycompletion = Util.clamp((level.timeState.currentAttemptTime - @:privateAccess level.orientationChangeTime) / 300, 0, 1);
|
||||||
|
if (gravitycompletion == 0) {
|
||||||
|
level.newOrientationQuat = @:privateAccess level.oldOrientationQuat;
|
||||||
|
@:privateAccess level.orientationChangeTime = -1e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
level.currentUp.set(rf.currentUp.x, rf.currentUp.y, rf.currentUp.z);
|
||||||
|
level.marble.lastContactNormal.set(rf.lastContactNormal.x, rf.lastContactNormal.y, rf.lastContactNormal.z);
|
||||||
|
for (i in 0...rf.mpStates.length) {
|
||||||
|
level.pathedInteriors[i].currentTime = rf.mpStates[i].curState.currentTime;
|
||||||
|
level.pathedInteriors[i].targetTime = rf.mpStates[i].curState.targetTime;
|
||||||
|
level.pathedInteriors[i].velocity.set(rf.mpStates[i].curState.velocity.x, rf.mpStates[i].curState.velocity.y, rf.mpStates[i].curState.velocity.z);
|
||||||
|
level.pathedInteriors[i].currentPosition.set(rf.mpStates[i].curState.currentPosition.x, rf.mpStates[i].curState.currentPosition.y,
|
||||||
|
rf.mpStates[i].curState.currentPosition.z);
|
||||||
|
level.pathedInteriors[i].prevPosition.set(rf.mpStates[i].curState.prevPosition.x, rf.mpStates[i].curState.prevPosition.y,
|
||||||
|
rf.mpStates[i].curState.prevPosition.z);
|
||||||
|
level.pathedInteriors[i].changeTime = rf.mpStates[i].curState.changeTime;
|
||||||
|
@:privateAccess level.pathedInteriors[i].stopTime = rf.mpStates[i].stopTime;
|
||||||
|
@:privateAccess level.pathedInteriors[i].stopped = rf.mpStates[i].stopped;
|
||||||
|
if (rf.mpStates[i].prevState != null) {
|
||||||
|
@:privateAccess level.pathedInteriors[i].previousState.currentTime = rf.mpStates[i].prevState.currentTime;
|
||||||
|
@:privateAccess level.pathedInteriors[i].previousState.targetTime = rf.mpStates[i].prevState.targetTime;
|
||||||
|
@:privateAccess level.pathedInteriors[i].previousState.velocity.set(rf.mpStates[i].prevState.velocity.x, rf.mpStates[i].prevState.velocity.y,
|
||||||
|
rf.mpStates[i].prevState.velocity.z);
|
||||||
|
@:privateAccess level.pathedInteriors[i].previousState.currentPosition.set(rf.mpStates[i].prevState.currentPosition.x,
|
||||||
|
rf.mpStates[i].prevState.currentPosition.y, rf.mpStates[i].prevState.currentPosition.z);
|
||||||
|
@:privateAccess level.pathedInteriors[i].previousState.prevPosition.set(rf.mpStates[i].prevState.prevPosition.x,
|
||||||
|
rf.mpStates[i].prevState.prevPosition.y, rf.mpStates[i].prevState.prevPosition.z);
|
||||||
|
@:privateAccess level.pathedInteriors[i].previousState.changeTime = rf.mpStates[i].prevState.changeTime;
|
||||||
|
} else {
|
||||||
|
@:privateAccess level.pathedInteriors[i].previousState = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var pstates = rf.powerupStates.copy();
|
||||||
|
var lmstates = rf.landMineStates.copy();
|
||||||
|
var tstates = rf.trapdoorStates.copy();
|
||||||
|
for (dts in level.dtsObjects) {
|
||||||
|
if (dts is PowerUp) {
|
||||||
|
var pow:PowerUp = cast dts;
|
||||||
|
pow.lastPickUpTime = pstates.shift();
|
||||||
|
}
|
||||||
|
if (dts is LandMine) {
|
||||||
|
var lm:LandMine = cast dts;
|
||||||
|
lm.disappearTime = lmstates.shift();
|
||||||
|
}
|
||||||
|
if (dts is Trapdoor) {
|
||||||
|
var td:Trapdoor = cast dts;
|
||||||
|
var tdState = tstates.shift();
|
||||||
|
td.lastCompletion = tdState.lastCompletion;
|
||||||
|
td.lastDirection = tdState.lastDirection;
|
||||||
|
td.lastContactTime = tdState.lastContactTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNextRewindFrame(absTime:Float):RewindFrame {
|
||||||
|
if (frames.length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var topFrame = frames[frames.length - 1];
|
||||||
|
while (topFrame.timeState.currentAttemptTime > absTime) {
|
||||||
|
frames.pop();
|
||||||
|
if (frames.length == 0)
|
||||||
|
return null;
|
||||||
|
topFrame = frames[frames.length - 1];
|
||||||
|
}
|
||||||
|
return topFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clear() {
|
||||||
|
frames = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,9 +27,11 @@ class AntiGravity extends PowerUp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function use(timeState:TimeState) {
|
public function use(timeState:TimeState) {
|
||||||
var direction = new Vector(0, 0, -1);
|
if (!this.level.rewinding) {
|
||||||
direction.transform(this.getRotationQuat().toMatrix());
|
var direction = new Vector(0, 0, -1);
|
||||||
this.level.setUp(direction, timeState);
|
direction.transform(this.getRotationQuat().toMatrix());
|
||||||
|
this.level.setUp(direction, timeState);
|
||||||
|
}
|
||||||
// marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity
|
// marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity
|
||||||
// if (!this.level.rewinding)
|
// if (!this.level.rewinding)
|
||||||
// AudioManager.play(this.sounds[1]);
|
// AudioManager.play(this.sounds[1]);
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class Gem extends DtsObject {
|
||||||
|
|
||||||
override function onMarbleInside(timeState:TimeState) {
|
override function onMarbleInside(timeState:TimeState) {
|
||||||
super.onMarbleInside(timeState);
|
super.onMarbleInside(timeState);
|
||||||
if (this.pickedUp)
|
if (this.pickedUp || this.level.rewinding)
|
||||||
return;
|
return;
|
||||||
this.pickedUp = true;
|
this.pickedUp = true;
|
||||||
this.setOpacity(0); // Hide the gem
|
this.setOpacity(0); // Hide the gem
|
||||||
|
|
|
||||||
|
|
@ -122,13 +122,13 @@ class LandMine extends DtsObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
override function onMarbleContact(timeState:TimeState, ?contact:CollisionInfo) {
|
override function onMarbleContact(timeState:TimeState, ?contact:CollisionInfo) {
|
||||||
if (this.isCollideable) {
|
if (this.isCollideable && !this.level.rewinding) {
|
||||||
// marble.velocity = marble.velocity.add(vec);
|
// marble.velocity = marble.velocity.add(vec);
|
||||||
this.disappearTime = timeState.timeSinceLoad;
|
this.disappearTime = timeState.timeSinceLoad;
|
||||||
this.setCollisionEnabled(false);
|
this.setCollisionEnabled(false);
|
||||||
|
|
||||||
// if (!this.level.rewinding)
|
if (!this.level.rewinding)
|
||||||
AudioManager.playSound(ResourceLoader.getResource("data/sound/explode1.wav", ResourceLoader.getAudio, this.soundResources));
|
AudioManager.playSound(ResourceLoader.getResource("data/sound/explode1.wav", ResourceLoader.getAudio, this.soundResources));
|
||||||
this.level.particleManager.createEmitter(landMineParticle, landMineParticleData, this.getAbsPos().getPosition());
|
this.level.particleManager.createEmitter(landMineParticle, landMineParticleData, this.getAbsPos().getPosition());
|
||||||
this.level.particleManager.createEmitter(landMineSmokeParticle, landMineSmokeParticleData, this.getAbsPos().getPosition());
|
this.level.particleManager.createEmitter(landMineSmokeParticle, landMineSmokeParticleData, this.getAbsPos().getPosition());
|
||||||
this.level.particleManager.createEmitter(landMineSparksParticle, landMineSparkParticleData, this.getAbsPos().getPosition());
|
this.level.particleManager.createEmitter(landMineSparksParticle, landMineSparkParticleData, this.getAbsPos().getPosition());
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ class Nuke extends DtsObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
override function onMarbleContact(timeState:TimeState, ?contact:CollisionInfo) {
|
override function onMarbleContact(timeState:TimeState, ?contact:CollisionInfo) {
|
||||||
if (this.isCollideable) {
|
if (this.isCollideable && !this.level.rewinding) {
|
||||||
// marble.velocity = marble.velocity.add(vec);
|
// marble.velocity = marble.velocity.add(vec);
|
||||||
this.disappearTime = timeState.timeSinceLoad;
|
this.disappearTime = timeState.timeSinceLoad;
|
||||||
this.setCollisionEnabled(false);
|
this.setCollisionEnabled(false);
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ abstract class PowerUp extends DtsObject {
|
||||||
if (this.element.showhelponpickup == "1" && !this.autoUse)
|
if (this.element.showhelponpickup == "1" && !this.autoUse)
|
||||||
this.level.displayHelp('Press <func:bind mousefire> to use the ${this.pickUpName}!');
|
this.level.displayHelp('Press <func:bind mousefire> to use the ${this.pickUpName}!');
|
||||||
|
|
||||||
if (pickupSound != null) {
|
if (pickupSound != null && !this.level.rewinding) {
|
||||||
AudioManager.playSound(pickupSound);
|
AudioManager.playSound(pickupSound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ class TimeTravel extends PowerUp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function use(time:TimeState) {
|
public function use(time:TimeState) {
|
||||||
level.addBonusTime(this.timeBonus);
|
if (!this.level.rewinding)
|
||||||
|
level.addBonusTime(this.timeBonus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue