mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
replay support
This commit is contained in:
parent
0c1e121a8b
commit
f820a3e41b
8 changed files with 257 additions and 93 deletions
|
|
@ -1265,6 +1265,9 @@ class Marble extends GameObject {
|
|||
}
|
||||
}
|
||||
|
||||
var stoppedPaths = false;
|
||||
var tempState = timeState.clone();
|
||||
|
||||
var intersectData = testMove(velocity, this.getAbsPos().getPosition(), timeStep, _radius, true); // this.getIntersectionTime(timeStep, velocity);
|
||||
var intersectT = intersectData.t;
|
||||
|
||||
|
|
@ -1279,7 +1282,6 @@ class Marble extends GameObject {
|
|||
// this.setPosition(intersectData.position.x, intersectData.position.y, intersectData.position.z);
|
||||
}
|
||||
|
||||
var tempState = timeState.clone();
|
||||
tempState.dt = timeStep;
|
||||
|
||||
it++;
|
||||
|
|
@ -1289,7 +1291,7 @@ class Marble extends GameObject {
|
|||
var isCentered:Bool = cmf.result;
|
||||
var aControl = cmf.aControl;
|
||||
var desiredOmega = cmf.desiredOmega;
|
||||
var stoppedPaths = false;
|
||||
|
||||
stoppedPaths = this.velocityCancel(timeState.currentAttemptTime, timeStep, isCentered, false, stoppedPaths, pathedInteriors);
|
||||
var A = this.getExternalForces(timeState.currentAttemptTime, m, timeStep);
|
||||
var retf = this.applyContactForces(timeStep, m, isCentered, aControl, desiredOmega, A);
|
||||
|
|
@ -1362,6 +1364,9 @@ class Marble extends GameObject {
|
|||
pTime.currentAttemptTime = piTime;
|
||||
this.heldPowerup.use(pTime);
|
||||
this.heldPowerup = null;
|
||||
if (this.level.isRecording) {
|
||||
this.level.replay.recordPowerupPickup(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.controllable && this.prevPos != null) {
|
||||
|
|
@ -1434,7 +1439,10 @@ class Marble extends GameObject {
|
|||
var expectedVel = this.level.replay.currentPlaybackFrame.marbleVelocity.clone();
|
||||
var expectedOmega = this.level.replay.currentPlaybackFrame.marbleAngularVelocity.clone();
|
||||
|
||||
this.getAbsPos().setPosition(expectedPos);
|
||||
this.setPosition(expectedPos.x, expectedPos.y, expectedPos.z);
|
||||
var tform = this.collider.transform;
|
||||
tform.setPosition(new Vector(expectedPos.x, expectedPos.y, expectedPos.z));
|
||||
this.collider.setTransform(tform);
|
||||
this.velocity = expectedVel;
|
||||
this.setRotationQuat(this.level.replay.currentPlaybackFrame.marbleOrientation.clone());
|
||||
this.omega = expectedOmega;
|
||||
|
|
|
|||
|
|
@ -353,16 +353,16 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
|
||||
public function restart(full:Bool = false) {
|
||||
if (!this.isWatching) {
|
||||
this.replay.clear();
|
||||
} else
|
||||
this.replay.rewind();
|
||||
|
||||
if (!full && this.currentCheckpoint != null) {
|
||||
this.loadCheckpointState();
|
||||
return 0; // Load checkpoint
|
||||
}
|
||||
|
||||
if (!this.isWatching) {
|
||||
this.replay.clear();
|
||||
} else
|
||||
this.replay.rewind();
|
||||
|
||||
this.timeState.currentAttemptTime = 0;
|
||||
this.timeState.gameplayClock = 0;
|
||||
this.bonusTime = 0;
|
||||
|
|
@ -390,29 +390,32 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
|
||||
// Record/Playback trapdoor and landmine states
|
||||
var tidx = 0;
|
||||
var lidx = 0;
|
||||
for (dtss in this.dtsObjects) {
|
||||
if (dtss is Trapdoor) {
|
||||
var trapdoor:Trapdoor = cast dtss;
|
||||
if (!this.isWatching) {
|
||||
this.replay.recordTrapdoorState(trapdoor.lastContactTime - this.timeState.timeSinceLoad, trapdoor.lastDirection, trapdoor.lastCompletion);
|
||||
} else {
|
||||
var state = this.replay.getTrapdoorState(tidx);
|
||||
trapdoor.lastContactTime = state.lastContactTime + this.timeState.timeSinceLoad;
|
||||
trapdoor.lastDirection = state.lastDirection;
|
||||
trapdoor.lastCompletion = state.lastCompletion;
|
||||
if (full) {
|
||||
var tidx = 0;
|
||||
var lidx = 0;
|
||||
for (dtss in this.dtsObjects) {
|
||||
if (dtss is Trapdoor) {
|
||||
var trapdoor:Trapdoor = cast dtss;
|
||||
if (!this.isWatching) {
|
||||
this.replay.recordTrapdoorState(trapdoor.lastContactTime - this.timeState.timeSinceLoad, trapdoor.lastDirection,
|
||||
trapdoor.lastCompletion);
|
||||
} else {
|
||||
var state = this.replay.getTrapdoorState(tidx);
|
||||
trapdoor.lastContactTime = state.lastContactTime + this.timeState.timeSinceLoad;
|
||||
trapdoor.lastDirection = state.lastDirection;
|
||||
trapdoor.lastCompletion = state.lastCompletion;
|
||||
}
|
||||
tidx++;
|
||||
}
|
||||
tidx++;
|
||||
}
|
||||
if (dtss is LandMine) {
|
||||
var landmine:LandMine = cast dtss;
|
||||
if (!this.isWatching) {
|
||||
this.replay.recordLandMineState(landmine.disappearTime - this.timeState.timeSinceLoad);
|
||||
} else {
|
||||
landmine.disappearTime = this.replay.getLandMineState(lidx) + this.timeState.timeSinceLoad;
|
||||
if (dtss is LandMine) {
|
||||
var landmine:LandMine = cast dtss;
|
||||
if (!this.isWatching) {
|
||||
this.replay.recordLandMineState(landmine.disappearTime - this.timeState.timeSinceLoad);
|
||||
} else {
|
||||
landmine.disappearTime = this.replay.getLandMineState(lidx) + this.timeState.timeSinceLoad;
|
||||
}
|
||||
lidx++;
|
||||
}
|
||||
lidx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -988,20 +991,27 @@ class MarbleWorld extends Scheduler {
|
|||
if (Key.isPressed(Settings.controlsSettings.respawn)) {
|
||||
this.respawnPressedTime = timeState.timeSinceLoad;
|
||||
this.restart();
|
||||
Settings.playStatistics.respawns++;
|
||||
if (!Settings.levelStatistics.exists(mission.path)) {
|
||||
Settings.levelStatistics.set(mission.path, {
|
||||
oobs: 0,
|
||||
respawns: 1,
|
||||
totalTime: 0,
|
||||
});
|
||||
} else {
|
||||
Settings.levelStatistics[mission.path].respawns++;
|
||||
if (!this.isWatching) {
|
||||
Settings.playStatistics.respawns++;
|
||||
|
||||
if (!Settings.levelStatistics.exists(mission.path)) {
|
||||
Settings.levelStatistics.set(mission.path, {
|
||||
oobs: 0,
|
||||
respawns: 1,
|
||||
totalTime: 0,
|
||||
});
|
||||
} else {
|
||||
Settings.levelStatistics[mission.path].respawns++;
|
||||
}
|
||||
|
||||
if (this.isRecording) {
|
||||
this.replay.endFrame();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Key.isDown(Settings.controlsSettings.respawn)) {
|
||||
if (Key.isDown(Settings.controlsSettings.respawn) && !this.isWatching) {
|
||||
if (timeState.timeSinceLoad - this.respawnPressedTime > 1.5) {
|
||||
this.restart(true);
|
||||
this.respawnPressedTime = Math.POSITIVE_INFINITY;
|
||||
|
|
@ -1010,6 +1020,17 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
|
||||
this.tickSchedule(timeState.currentAttemptTime);
|
||||
|
||||
// Replay gravity
|
||||
if (this.isWatching) {
|
||||
if (this.replay.currentPlaybackFrame.gravityChange) {
|
||||
this.setUp(this.replay.currentPlaybackFrame.gravity, timeState, this.replay.currentPlaybackFrame.gravityInstant);
|
||||
}
|
||||
if (this.replay.currentPlaybackFrame.powerupPickup != null) {
|
||||
this.pickUpPowerUpReplay(this.replay.currentPlaybackFrame.powerupPickup);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateGameState();
|
||||
ProfilerUI.measure("updateDTS");
|
||||
for (obj in dtsObjects) {
|
||||
|
|
@ -1031,17 +1052,17 @@ class MarbleWorld extends Scheduler {
|
|||
ProfilerUI.measure("updateAudio");
|
||||
AudioManager.update(this.scene);
|
||||
|
||||
if (this.outOfBounds && this.finishTime == null && Key.isDown(Settings.controlsSettings.powerup) && !this.isWatching) {
|
||||
this.restart();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isWatching) {
|
||||
if (this.isRecording) {
|
||||
this.replay.endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.outOfBounds && this.finishTime == null && Key.isDown(Settings.controlsSettings.powerup)) {
|
||||
this.restart();
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateTexts();
|
||||
}
|
||||
|
||||
|
|
@ -1412,6 +1433,18 @@ class MarbleWorld extends Scheduler {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public function pickUpPowerUpReplay(powerupIdent:String) {
|
||||
if (powerupIdent == null)
|
||||
return false;
|
||||
if (this.marble.heldPowerup != null)
|
||||
if (this.marble.heldPowerup.identifier == powerupIdent)
|
||||
return false;
|
||||
|
||||
this.playGui.setPowerupImage(powerupIdent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function pickUpPowerUp(powerUp:PowerUp) {
|
||||
if (powerUp == null)
|
||||
return false;
|
||||
|
|
@ -1421,6 +1454,9 @@ class MarbleWorld extends Scheduler {
|
|||
this.marble.heldPowerup = powerUp;
|
||||
this.playGui.setPowerupImage(powerUp.identifier);
|
||||
MarbleGame.instance.touchInput.powerupButton.setEnabled(true);
|
||||
if (this.isRecording) {
|
||||
this.replay.recordPowerupPickup(powerUp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1479,6 +1515,10 @@ class MarbleWorld extends Scheduler {
|
|||
// quatChange.initMoveTo(oldUp, vec);
|
||||
quatChange.multiply(quatChange, currentQuat);
|
||||
|
||||
if (this.isRecording) {
|
||||
this.replay.recordGravity(vec, instant);
|
||||
}
|
||||
|
||||
this.newOrientationQuat = quatChange;
|
||||
this.oldOrientationQuat = currentQuat;
|
||||
this.orientationChangeTime = instant ? -1e8 : timeState.currentAttemptTime;
|
||||
|
|
@ -1491,18 +1531,20 @@ class MarbleWorld extends Scheduler {
|
|||
this.outOfBounds = true;
|
||||
this.outOfBoundsTime = this.timeState.clone();
|
||||
this.marble.camera.oob = true;
|
||||
Settings.playStatistics.oobs++;
|
||||
if (!Settings.levelStatistics.exists(mission.path)) {
|
||||
Settings.levelStatistics.set(mission.path, {
|
||||
oobs: 1,
|
||||
respawns: 0,
|
||||
totalTime: 0,
|
||||
});
|
||||
} else {
|
||||
Settings.levelStatistics[mission.path].oobs++;
|
||||
if (!this.isWatching) {
|
||||
Settings.playStatistics.oobs++;
|
||||
if (!Settings.levelStatistics.exists(mission.path)) {
|
||||
Settings.levelStatistics.set(mission.path, {
|
||||
oobs: 1,
|
||||
respawns: 0,
|
||||
totalTime: 0,
|
||||
});
|
||||
} else {
|
||||
Settings.levelStatistics[mission.path].oobs++;
|
||||
}
|
||||
if (Settings.optionsSettings.oobInsults)
|
||||
OOBInsultGui.OOBCheck();
|
||||
}
|
||||
if (Settings.optionsSettings.oobInsults)
|
||||
OOBInsultGui.OOBCheck();
|
||||
// sky.follow = null;
|
||||
// this.oobCameraPosition = camera.position.clone();
|
||||
playGui.setCenterText('outofbounds');
|
||||
|
|
@ -1571,13 +1613,19 @@ class MarbleWorld extends Scheduler {
|
|||
this.marble.setPosition(mpos.x, mpos.y, mpos.z);
|
||||
marble.velocity.load(new Vector(0, 0, 0));
|
||||
marble.omega.load(new Vector(0, 0, 0));
|
||||
// Set camera orienation
|
||||
// Set camera orientation
|
||||
var euler = this.currentCheckpoint.obj.getRotationQuat().toEuler();
|
||||
this.marble.camera.CameraYaw = euler.z + Math.PI / 2;
|
||||
this.marble.camera.CameraPitch = 0.45;
|
||||
this.marble.camera.nextCameraYaw = this.marble.camera.CameraYaw;
|
||||
this.marble.camera.nextCameraPitch = this.marble.camera.CameraPitch;
|
||||
this.marble.camera.oob = false;
|
||||
if (this.isRecording) {
|
||||
this.replay.recordCameraState(this.marble.camera.CameraYaw, this.marble.camera.CameraPitch);
|
||||
this.replay.recordMarbleInput(0, 0);
|
||||
this.replay.recordMarbleState(mpos, marble.velocity, marble.getRotationQuat(), marble.omega);
|
||||
this.replay.recordMarbleStateFlags(false, false, true);
|
||||
}
|
||||
var gravityField = ""; // (this.currentCheckpoint.srcElement as any) ?.gravity || this.currentCheckpointTrigger?.element.gravity;
|
||||
if (this.currentCheckpoint.elem.fields.exists('gravity')) {
|
||||
gravityField = this.currentCheckpoint.elem.fields.get('gravity')[0];
|
||||
|
|
@ -1661,15 +1709,18 @@ class MarbleWorld extends Scheduler {
|
|||
|
||||
public function dispose() {
|
||||
// Gotta add the timesinceload to our stats
|
||||
Settings.playStatistics.totalTime += this.timeState.timeSinceLoad;
|
||||
if (!Settings.levelStatistics.exists(mission.path)) {
|
||||
Settings.levelStatistics.set(mission.path, {
|
||||
oobs: 0,
|
||||
respawns: 0,
|
||||
totalTime: this.timeState.timeSinceLoad,
|
||||
});
|
||||
} else {
|
||||
Settings.levelStatistics[mission.path].totalTime += this.timeState.timeSinceLoad;
|
||||
if (!this.isWatching) {
|
||||
Settings.playStatistics.totalTime += this.timeState.timeSinceLoad;
|
||||
|
||||
if (!Settings.levelStatistics.exists(mission.path)) {
|
||||
Settings.levelStatistics.set(mission.path, {
|
||||
oobs: 0,
|
||||
respawns: 0,
|
||||
totalTime: this.timeState.timeSinceLoad,
|
||||
});
|
||||
} else {
|
||||
Settings.levelStatistics[mission.path].totalTime += this.timeState.timeSinceLoad;
|
||||
}
|
||||
}
|
||||
|
||||
this.playGui.dispose();
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ class Mission {
|
|||
var ret = ResourceLoader.getResource(basename + ".png", ResourceLoader.getImage, this.imageResources).toTile();
|
||||
onLoaded(ret);
|
||||
});
|
||||
return imgFileEntry.path;
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(basename + ".jpg")) {
|
||||
imgFileEntry = ResourceLoader.fileSystem.get(basename + ".jpg");
|
||||
|
|
@ -143,14 +144,17 @@ class Mission {
|
|||
var ret = ResourceLoader.getResource(basename + ".jpg", ResourceLoader.getImage, this.imageResources).toTile();
|
||||
onLoaded(ret);
|
||||
});
|
||||
return imgFileEntry.path;
|
||||
}
|
||||
var img = new BitmapData(1, 1);
|
||||
img.setPixel(0, 0, 0);
|
||||
onLoaded(Tile.fromBitmap(img));
|
||||
return null;
|
||||
} else {
|
||||
var img = new BitmapData(1, 1);
|
||||
img.setPixel(0, 0, 0);
|
||||
onLoaded(Tile.fromBitmap(img));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import shapes.PowerUp;
|
||||
import haxe.io.BytesInput;
|
||||
import haxe.zip.Huffman;
|
||||
import haxe.io.Bytes;
|
||||
|
|
@ -29,12 +30,17 @@ class ReplayFrame {
|
|||
var marbleOrientation:Quat;
|
||||
var marbleAngularVelocity:Vector;
|
||||
var marbleStateFlags:EnumFlags<ReplayMarbleState>;
|
||||
var powerupPickup:String;
|
||||
// Camera
|
||||
var cameraPitch:Float;
|
||||
var cameraYaw:Float;
|
||||
// Input
|
||||
var marbleX:Float;
|
||||
var marbleY:Float;
|
||||
// Gravity
|
||||
var gravity:Vector;
|
||||
var gravityInstant:Bool;
|
||||
var gravityChange:Bool;
|
||||
|
||||
public function new() {}
|
||||
|
||||
|
|
@ -98,6 +104,22 @@ class ReplayFrame {
|
|||
interpFrame.marbleX = this.marbleX;
|
||||
interpFrame.marbleY = this.marbleY;
|
||||
|
||||
// Gravity
|
||||
if (this.gravityChange) {
|
||||
interpFrame.gravity = this.gravity.clone();
|
||||
interpFrame.gravityInstant = this.gravityInstant;
|
||||
interpFrame.gravityChange = true;
|
||||
}
|
||||
if (next.gravityChange) {
|
||||
interpFrame.gravity = next.gravity.clone();
|
||||
interpFrame.gravityInstant = next.gravityInstant;
|
||||
interpFrame.gravityChange = true;
|
||||
}
|
||||
|
||||
if (this.powerupPickup != null) {
|
||||
interpFrame.powerupPickup = this.powerupPickup;
|
||||
}
|
||||
|
||||
return interpFrame;
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +145,21 @@ class ReplayFrame {
|
|||
bw.writeFloat(this.cameraYaw);
|
||||
bw.writeFloat(this.marbleX);
|
||||
bw.writeFloat(this.marbleY);
|
||||
if (this.gravityChange) {
|
||||
bw.writeByte(1);
|
||||
bw.writeFloat(this.gravity.x);
|
||||
bw.writeFloat(this.gravity.y);
|
||||
bw.writeFloat(this.gravity.z);
|
||||
bw.writeByte(this.gravityInstant ? 1 : 0);
|
||||
} else {
|
||||
bw.writeByte(0);
|
||||
}
|
||||
if (this.powerupPickup != null) {
|
||||
bw.writeByte(1);
|
||||
bw.writeStr(this.powerupPickup);
|
||||
} else {
|
||||
bw.writeByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
public function read(br:BytesReader) {
|
||||
|
|
@ -138,6 +175,18 @@ class ReplayFrame {
|
|||
this.cameraYaw = br.readFloat();
|
||||
this.marbleX = br.readFloat();
|
||||
this.marbleY = br.readFloat();
|
||||
if (br.readByte() == 1) {
|
||||
this.gravity = new Vector(br.readFloat(), br.readFloat(), br.readFloat());
|
||||
this.gravityInstant = br.readByte() == 1;
|
||||
this.gravityChange = true;
|
||||
} else {
|
||||
this.gravityChange = false;
|
||||
}
|
||||
if (br.readByte() == 1) {
|
||||
this.powerupPickup = br.readStr();
|
||||
} else {
|
||||
this.powerupPickup = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +246,7 @@ class Replay {
|
|||
var currentPlaybackFrameIdx:Int;
|
||||
var currentPlaybackTime:Float;
|
||||
|
||||
var version:Int = 1;
|
||||
var version:Int = 3;
|
||||
|
||||
public function new(mission:String) {
|
||||
this.mission = mission;
|
||||
|
|
@ -235,6 +284,13 @@ class Replay {
|
|||
currentRecordFrame.marbleStateFlags.set(InstantTeleport);
|
||||
}
|
||||
|
||||
public function recordPowerupPickup(powerup:PowerUp) {
|
||||
if (powerup == null)
|
||||
currentRecordFrame.powerupPickup = ""; // Use powerup
|
||||
else
|
||||
currentRecordFrame.powerupPickup = powerup.identifier;
|
||||
}
|
||||
|
||||
public function recordMarbleInput(x:Float, y:Float) {
|
||||
currentRecordFrame.marbleX = x;
|
||||
currentRecordFrame.marbleY = y;
|
||||
|
|
@ -245,6 +301,13 @@ class Replay {
|
|||
currentRecordFrame.cameraYaw = yaw;
|
||||
}
|
||||
|
||||
public function recordGravity(gravity:Vector, instant:Bool) {
|
||||
currentRecordFrame.gravityChange = true;
|
||||
currentRecordFrame.gravity = gravity.clone();
|
||||
if (instant)
|
||||
currentRecordFrame.gravityInstant = instant;
|
||||
}
|
||||
|
||||
public function recordTrapdoorState(lastContactTime:Float, lastDirection:Int, lastCompletion:Float) {
|
||||
initialState.trapdoorLastContactTimes.push(lastContactTime);
|
||||
initialState.trapdoorLastDirections.push(lastDirection);
|
||||
|
|
@ -283,15 +346,42 @@ class Replay {
|
|||
return false;
|
||||
}
|
||||
var nextFrame = this.frames[this.currentPlaybackFrameIdx + 1];
|
||||
var stateFlags = 0;
|
||||
var nextGravityChange:Bool = false;
|
||||
var nextGravityState:{
|
||||
instant:Bool,
|
||||
gravity:Vector
|
||||
} = null;
|
||||
var powerup:String = null;
|
||||
while (nextFrame.time <= nextT) {
|
||||
this.currentPlaybackFrameIdx++;
|
||||
if (this.currentPlaybackFrameIdx + 1 >= this.frames.length) {
|
||||
return false;
|
||||
}
|
||||
var testNextFrame = this.frames[this.currentPlaybackFrameIdx + 1];
|
||||
stateFlags |= testNextFrame.marbleStateFlags.toInt();
|
||||
if (testNextFrame.gravityChange) {
|
||||
nextGravityChange = true;
|
||||
nextGravityState = {
|
||||
instant: testNextFrame.gravityInstant,
|
||||
gravity: testNextFrame.gravity.clone()
|
||||
};
|
||||
}
|
||||
if (testNextFrame.powerupPickup != null) {
|
||||
powerup = testNextFrame.powerupPickup;
|
||||
}
|
||||
startFrame = nextFrame;
|
||||
nextFrame = testNextFrame;
|
||||
}
|
||||
nextFrame.marbleStateFlags = EnumFlags.ofInt(stateFlags);
|
||||
if (nextGravityChange) {
|
||||
nextFrame.gravityChange = true;
|
||||
nextFrame.gravityInstant = nextGravityState.instant;
|
||||
nextFrame.gravity = nextGravityState.gravity.clone();
|
||||
}
|
||||
if (powerup != null) {
|
||||
nextFrame.powerupPickup = powerup;
|
||||
}
|
||||
this.currentPlaybackFrame = startFrame.interpolate(nextFrame, nextT);
|
||||
this.currentPlaybackTime += dt;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ class Util {
|
|||
'\\f' => '\x0C',
|
||||
'\\n' => '\n',
|
||||
'\\r' => '\r',
|
||||
"\\'" => "'"
|
||||
"\\'" => "'",
|
||||
"\\\"" => "\"",
|
||||
];
|
||||
|
||||
for (obj => esc in specialCases) {
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ class MainMenuGui extends GuiImage {
|
|||
#if js
|
||||
repmis = StringTools.replace(repmis, "data/", "");
|
||||
#end
|
||||
if (MissionList.missions == null)
|
||||
MissionList.buildMissionList();
|
||||
var playMis = MissionList.missions.get(repmis);
|
||||
if (playMis != null) {
|
||||
cast(this.parent, Canvas).marbleGame.watchMissionReplay(playMis, replay);
|
||||
|
|
|
|||
|
|
@ -782,8 +782,6 @@ class PlayMissionGui extends GuiImage {
|
|||
index = 0;
|
||||
}
|
||||
|
||||
var selectionChanged = currentSelection != index;
|
||||
|
||||
currentSelection = index;
|
||||
currentSelectionStatic = currentSelection;
|
||||
|
||||
|
|
@ -899,31 +897,38 @@ class PlayMissionGui extends GuiImage {
|
|||
|
||||
setScoreHover(scoreButtonHover);
|
||||
|
||||
if (selectionChanged) {
|
||||
pmPreview.bmp.tile = tmpprevtile;
|
||||
#if js
|
||||
switch (previewTimeoutHandle) {
|
||||
case None:
|
||||
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
|
||||
currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
});
|
||||
}, 75));
|
||||
case Some(previewTimeoutHandle_id):
|
||||
js.Browser.window.clearTimeout(previewTimeoutHandle_id);
|
||||
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
|
||||
currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
});
|
||||
}, 75));
|
||||
}
|
||||
#end
|
||||
#if hl
|
||||
currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
}); // Shit be sync
|
||||
#end
|
||||
// pmPreview.bmp.tile = tmpprevtile;
|
||||
#if js
|
||||
switch (previewTimeoutHandle) {
|
||||
case None:
|
||||
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
|
||||
var prevpath = currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
});
|
||||
if (prevpath != pmPreview.bmp.tile.getTexture().name) {
|
||||
pmPreview.bmp.tile = tmpprevtile;
|
||||
}
|
||||
}, 75));
|
||||
case Some(previewTimeoutHandle_id):
|
||||
js.Browser.window.clearTimeout(previewTimeoutHandle_id);
|
||||
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
|
||||
var prevpath = currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
});
|
||||
if (prevpath != pmPreview.bmp.tile.getTexture().name) {
|
||||
pmPreview.bmp.tile = tmpprevtile;
|
||||
}
|
||||
}, 75));
|
||||
}
|
||||
#end
|
||||
#if hl
|
||||
var prevpath = currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
}); // Shit be sync
|
||||
if (prevpath != pmPreview.bmp.tile.getTexture().name) {
|
||||
pmPreview.bmp.tile = tmpprevtile;
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
setCategoryFunc(currentGame, currentCategoryStatic, false);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ class TeleportTrigger extends Trigger {
|
|||
}
|
||||
this.level.marble.prevPos.load(position);
|
||||
this.level.marble.setPosition(position.x, position.y, position.z);
|
||||
if (this.level.isRecording) {
|
||||
this.level.replay.recordMarbleStateFlags(false, false, true);
|
||||
}
|
||||
|
||||
if (!MisParser.parseBoolean(chooseNonNull(this.element.keepvelocity, destination.element.keepvelocity)))
|
||||
this.level.marble.velocity.set(0, 0, 0);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue