mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-27 05:01:38 +00:00
make hunt network again, and fix marble radius for MP
This commit is contained in:
parent
d20d3a1e90
commit
141a3f892b
7 changed files with 303 additions and 91 deletions
|
|
@ -163,6 +163,9 @@ class Console {
|
||||||
} else {
|
} else {
|
||||||
error("Expected one argument, got " + (cmdSplit.length - 1));
|
error("Expected one argument, got " + (cmdSplit.length - 1));
|
||||||
}
|
}
|
||||||
|
} else if (cmdType == 'rollback') {
|
||||||
|
var t = Std.parseFloat(cmdSplit[1]);
|
||||||
|
MarbleGame.instance.world.rollback(t);
|
||||||
} else {
|
} else {
|
||||||
error("Unknown command");
|
error("Unknown command");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
158
src/Marble.hx
158
src/Marble.hx
|
|
@ -482,6 +482,11 @@ class Marble extends GameObject {
|
||||||
} else
|
} else
|
||||||
this._radius = avgRadius;
|
this._radius = avgRadius;
|
||||||
|
|
||||||
|
if (Net.isMP) {
|
||||||
|
this._radius = 0.2; // For the sake of physics
|
||||||
|
marbleDts.scale(0.2 / avgRadius);
|
||||||
|
}
|
||||||
|
|
||||||
this._prevRadius = this._radius;
|
this._prevRadius = this._radius;
|
||||||
|
|
||||||
if (isUltra) {
|
if (isUltra) {
|
||||||
|
|
@ -556,8 +561,8 @@ class Marble extends GameObject {
|
||||||
|
|
||||||
public function getMarbleAxis() {
|
public function getMarbleAxis() {
|
||||||
var motiondir = new Vector(0, -1, 0);
|
var motiondir = new Vector(0, -1, 0);
|
||||||
// if (level.isReplayingMovement)
|
if (level.isReplayingMovement)
|
||||||
// return level.currentInputMoves[1].marbleAxes;
|
return level.currentInputMoves[1].marbleAxes;
|
||||||
if (this.controllable && !this.isNetUpdate) {
|
if (this.controllable && !this.isNetUpdate) {
|
||||||
motiondir.transform(Matrix.R(0, 0, camera.CameraYaw));
|
motiondir.transform(Matrix.R(0, 0, camera.CameraYaw));
|
||||||
motiondir.transform(level.newOrientationQuat.toMatrix());
|
motiondir.transform(level.newOrientationQuat.toMatrix());
|
||||||
|
|
@ -663,6 +668,8 @@ class Marble extends GameObject {
|
||||||
var R = currentGravityDir.multiply(-this._radius);
|
var R = currentGravityDir.multiply(-this._radius);
|
||||||
var rollVelocity = this.omega.cross(R);
|
var rollVelocity = this.omega.cross(R);
|
||||||
var axes = this.getMarbleAxis();
|
var axes = this.getMarbleAxis();
|
||||||
|
// if (!level.isReplayingMovement)
|
||||||
|
// level.inputRecorder.recordAxis(axes);
|
||||||
var sideDir = axes[0];
|
var sideDir = axes[0];
|
||||||
var motionDir = axes[1];
|
var motionDir = axes[1];
|
||||||
var upDir = axes[2];
|
var upDir = axes[2];
|
||||||
|
|
@ -811,37 +818,37 @@ class Marble extends GameObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!done && itersIn < 1e4); // Maximum limit pls
|
} while (!done && itersIn < 1e4); // Maximum limit pls
|
||||||
// if (this.velocity.lengthSq() < 625) {
|
if (this.velocity.lengthSq() < 625) {
|
||||||
var gotOne = false;
|
var gotOne = false;
|
||||||
var dir = new Vector(0, 0, 0);
|
var dir = new Vector(0, 0, 0);
|
||||||
for (j in 0...contacts.length) {
|
for (j in 0...contacts.length) {
|
||||||
var dir2 = dir.add(contacts[j].normal);
|
var dir2 = dir.add(contacts[j].normal);
|
||||||
if (dir2.lengthSq() < 0.01) {
|
if (dir2.lengthSq() < 0.01) {
|
||||||
dir2.load(dir2.add(contacts[j].normal));
|
dir2.load(dir2.add(contacts[j].normal));
|
||||||
}
|
|
||||||
dir = dir2;
|
|
||||||
dir.normalize();
|
|
||||||
gotOne = true;
|
|
||||||
}
|
|
||||||
if (gotOne) {
|
|
||||||
dir.normalize();
|
|
||||||
var soFar = 0.0;
|
|
||||||
for (k in 0...contacts.length) {
|
|
||||||
var dist = this._radius - contacts[k].contactDistance;
|
|
||||||
var timeToSeparate = 0.1;
|
|
||||||
var vel = this.velocity.sub(contacts[k].velocity);
|
|
||||||
var outVel = vel.add(dir.multiply(soFar)).dot(contacts[k].normal);
|
|
||||||
if (dist > timeToSeparate * outVel) {
|
|
||||||
soFar += (dist - outVel * timeToSeparate) / timeToSeparate / contacts[k].normal.dot(dir);
|
|
||||||
}
|
}
|
||||||
|
dir = dir2;
|
||||||
|
dir.normalize();
|
||||||
|
gotOne = true;
|
||||||
|
}
|
||||||
|
if (gotOne) {
|
||||||
|
dir.normalize();
|
||||||
|
var soFar = 0.0;
|
||||||
|
for (k in 0...contacts.length) {
|
||||||
|
var dist = this._radius - contacts[k].contactDistance;
|
||||||
|
var timeToSeparate = 0.1;
|
||||||
|
var vel = this.velocity.sub(contacts[k].velocity);
|
||||||
|
var outVel = vel.add(dir.multiply(soFar)).dot(contacts[k].normal);
|
||||||
|
if (dist > timeToSeparate * outVel) {
|
||||||
|
soFar += (dist - outVel * timeToSeparate) / timeToSeparate / contacts[k].normal.dot(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (soFar < -25)
|
||||||
|
soFar = -25;
|
||||||
|
if (soFar > 25)
|
||||||
|
soFar = 25;
|
||||||
|
this.velocity.load(this.velocity.add(dir.multiply(soFar)));
|
||||||
}
|
}
|
||||||
if (soFar < -25)
|
|
||||||
soFar = -25;
|
|
||||||
if (soFar > 25)
|
|
||||||
soFar = 25;
|
|
||||||
this.velocity.load(this.velocity.add(dir.multiply(soFar)));
|
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
return stoppedPaths;
|
return stoppedPaths;
|
||||||
}
|
}
|
||||||
|
|
@ -1228,6 +1235,7 @@ class Marble extends GameObject {
|
||||||
finalT = collisionTime;
|
finalT = collisionTime;
|
||||||
currentFinalPos = position.add(relVel.multiply(finalT));
|
currentFinalPos = position.add(relVel.multiply(finalT));
|
||||||
found = true;
|
found = true;
|
||||||
|
lastContactPos = currentFinalPos.clone();
|
||||||
// iterationFound = true;
|
// iterationFound = true;
|
||||||
i += 3;
|
i += 3;
|
||||||
// Debug.drawSphere(currentFinalPos, radius);
|
// Debug.drawSphere(currentFinalPos, radius);
|
||||||
|
|
@ -1427,6 +1435,8 @@ class Marble extends GameObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function nudgeToContacts(position:Vector, radius:Float, foundContacts:Array<MarbleTestMoveFoundContact>, foundMarbles:Array<SphereCollisionEntity>) {
|
function nudgeToContacts(position:Vector, radius:Float, foundContacts:Array<MarbleTestMoveFoundContact>, foundMarbles:Array<SphereCollisionEntity>) {
|
||||||
|
if (Net.isMP)
|
||||||
|
return position;
|
||||||
var it = 0;
|
var it = 0;
|
||||||
var concernedContacts = foundContacts; // PathedInteriors have their own nudge logic
|
var concernedContacts = foundContacts; // PathedInteriors have their own nudge logic
|
||||||
var prevResolved = 0;
|
var prevResolved = 0;
|
||||||
|
|
@ -1717,36 +1727,36 @@ class Marble extends GameObject {
|
||||||
|
|
||||||
this.updateRollSound(timeState, contactTime / timeState.dt, this._slipAmount);
|
this.updateRollSound(timeState, contactTime / timeState.dt, this._slipAmount);
|
||||||
|
|
||||||
// if (this.megaMarbleUseTick > 0) {
|
if (this.megaMarbleUseTick > 0) {
|
||||||
// if (Net.isHost) {
|
if (Net.isHost) {
|
||||||
// if ((timeState.ticks - this.megaMarbleUseTick) <= 312 && this.megaMarbleUseTick > 0) {
|
if ((timeState.ticks - this.megaMarbleUseTick) <= 312 && this.megaMarbleUseTick > 0) {
|
||||||
// this._radius = 0.675;
|
this._radius = 0.675;
|
||||||
// this.collider.radius = 0.675;
|
this.collider.radius = 0.675;
|
||||||
// } else if ((timeState.ticks - this.megaMarbleUseTick) > 312) {
|
} else if ((timeState.ticks - this.megaMarbleUseTick) > 312) {
|
||||||
// this.collider.radius = this._radius = 0.3;
|
this.collider.radius = this._radius = 0.2;
|
||||||
// if (!this.isNetUpdate && this.controllable)
|
if (!this.isNetUpdate && this.controllable)
|
||||||
// AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null,
|
AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null,
|
||||||
// false);
|
false);
|
||||||
// this.megaMarbleUseTick = 0;
|
this.megaMarbleUseTick = 0;
|
||||||
// this.netFlags |= MarbleNetFlags.DoMega;
|
this.netFlags |= MarbleNetFlags.DoMega;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// if (Net.isClient) {
|
if (Net.isClient) {
|
||||||
// if (this.serverTicks - this.megaMarbleUseTick <= 312 && this.megaMarbleUseTick > 0) {
|
if (this.serverTicks - this.megaMarbleUseTick <= 312 && this.megaMarbleUseTick > 0) {
|
||||||
// this._radius = 0.675;
|
this._radius = 0.675;
|
||||||
// this.collider.radius = 0.675;
|
this.collider.radius = 0.675;
|
||||||
// } else {
|
} else {
|
||||||
// this.collider.radius = this._radius = 0.3;
|
this.collider.radius = this._radius = 0.2;
|
||||||
// if (!this.isNetUpdate && this.controllable)
|
if (!this.isNetUpdate && this.controllable)
|
||||||
// AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null,
|
AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null,
|
||||||
// false);
|
false);
|
||||||
// this.megaMarbleUseTick = 0;
|
this.megaMarbleUseTick = 0;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// if (Net.isClient && this.megaMarbleUseTick == 0) {
|
if (Net.isClient && this.megaMarbleUseTick == 0) {
|
||||||
// this.collider.radius = this._radius = 0.3;
|
this.collider.radius = this._radius = 0.2;
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (Net.isMP) {
|
if (Net.isMP) {
|
||||||
if (m.jump && this.outOfBounds) {
|
if (m.jump && this.outOfBounds) {
|
||||||
|
|
@ -2035,6 +2045,8 @@ class Marble extends GameObject {
|
||||||
if (this.controllable && !this.level.isWatching) {
|
if (this.controllable && !this.level.isWatching) {
|
||||||
move = recordMove();
|
move = recordMove();
|
||||||
}
|
}
|
||||||
|
if (level.isReplayingMovement)
|
||||||
|
move = level.currentInputMoves[1].move;
|
||||||
|
|
||||||
if (this.level.isWatching) {
|
if (this.level.isWatching) {
|
||||||
if (this.level.replay.currentPlaybackFrame.marbleStateFlags.has(Jumped))
|
if (this.level.replay.currentPlaybackFrame.marbleStateFlags.has(Jumped))
|
||||||
|
|
@ -2056,6 +2068,32 @@ class Marble extends GameObject {
|
||||||
playedSounds = [];
|
playedSounds = [];
|
||||||
advancePhysics(timeState, move, collisionWorld, pathedInteriors);
|
advancePhysics(timeState, move, collisionWorld, pathedInteriors);
|
||||||
|
|
||||||
|
// physicsAccumulator += timeState.dt;
|
||||||
|
|
||||||
|
// while (physicsAccumulator > 0.032) {
|
||||||
|
// var adt = timeState.clone();
|
||||||
|
// adt.dt = 0.032;
|
||||||
|
// advancePhysics(adt, move, collisionWorld, pathedInteriors);
|
||||||
|
// physicsAccumulator -= 0.032;
|
||||||
|
// }
|
||||||
|
// if (oldPos != null && newPos != null) {
|
||||||
|
// var deltaT = physicsAccumulator / 0.032;
|
||||||
|
// var renderPos = Util.lerpThreeVectors(this.oldPos, this.newPos, deltaT);
|
||||||
|
// this.setPosition(renderPos.x, renderPos.y, renderPos.z);
|
||||||
|
|
||||||
|
// var rot = this.getRotationQuat();
|
||||||
|
// var quat = new Quat();
|
||||||
|
// quat.initRotation(omega.x * timeState.dt, omega.y * timeState.dt, omega.z * timeState.dt);
|
||||||
|
// quat.multiply(quat, rot);
|
||||||
|
// this.setRotationQuat(quat);
|
||||||
|
|
||||||
|
// var adt = timeState.clone();
|
||||||
|
// adt.dt = physicsAccumulator;
|
||||||
|
// for (pi in pathedInteriors) {
|
||||||
|
// pi.update(adt);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (!this.level.isWatching) {
|
if (!this.level.isWatching) {
|
||||||
if (this.level.isRecording) {
|
if (this.level.isRecording) {
|
||||||
this.level.replay.recordMarbleState(this.getAbsPos().getPosition(), this.velocity, this.getRotationQuat(), this.omega);
|
this.level.replay.recordMarbleState(this.getAbsPos().getPosition(), this.velocity, this.getRotationQuat(), this.omega);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package src;
|
package src;
|
||||||
|
|
||||||
|
import rewind.InputRecorder;
|
||||||
import net.NetPacket.ScoreboardPacket;
|
import net.NetPacket.ScoreboardPacket;
|
||||||
import net.NetPacket.PowerupPickupPacket;
|
import net.NetPacket.PowerupPickupPacket;
|
||||||
import net.Move;
|
import net.Move;
|
||||||
|
|
@ -209,6 +210,10 @@ class MarbleWorld extends Scheduler {
|
||||||
public var rewindManager:RewindManager;
|
public var rewindManager:RewindManager;
|
||||||
public var rewinding:Bool = false;
|
public var rewinding:Bool = false;
|
||||||
|
|
||||||
|
public var inputRecorder:InputRecorder;
|
||||||
|
public var isReplayingMovement:Bool = false;
|
||||||
|
public var currentInputMoves:Array<InputRecorderFrame>;
|
||||||
|
|
||||||
// Multiplayer
|
// Multiplayer
|
||||||
public var isMultiplayer:Bool;
|
public var isMultiplayer:Bool;
|
||||||
|
|
||||||
|
|
@ -257,6 +262,7 @@ class MarbleWorld extends Scheduler {
|
||||||
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(cast this);
|
this.rewindManager = new RewindManager(cast this);
|
||||||
|
this.inputRecorder = new InputRecorder(cast this);
|
||||||
this.isMultiplayer = multiplayer;
|
this.isMultiplayer = multiplayer;
|
||||||
if (this.isMultiplayer) {
|
if (this.isMultiplayer) {
|
||||||
isRecording = false;
|
isRecording = false;
|
||||||
|
|
@ -761,7 +767,7 @@ class MarbleWorld extends Scheduler {
|
||||||
if (isMultiplayer) {
|
if (isMultiplayer) {
|
||||||
marble.megaMarbleUseTick = 0;
|
marble.megaMarbleUseTick = 0;
|
||||||
marble.helicopterUseTick = 0;
|
marble.helicopterUseTick = 0;
|
||||||
marble.collider.radius = marble._radius = 0.3;
|
// marble.collider.radius = marble._radius = 0.3;
|
||||||
@:privateAccess marble.netFlags |= MarbleNetFlags.DoHelicopter | MarbleNetFlags.DoMega | MarbleNetFlags.GravityChange;
|
@:privateAccess marble.netFlags |= MarbleNetFlags.DoHelicopter | MarbleNetFlags.DoMega | MarbleNetFlags.GravityChange;
|
||||||
} else {
|
} else {
|
||||||
@:privateAccess marble.helicopterEnableTime = -1e8;
|
@:privateAccess marble.helicopterEnableTime = -1e8;
|
||||||
|
|
@ -1496,11 +1502,44 @@ class MarbleWorld extends Scheduler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function rollback(t:Float) {
|
||||||
|
var newT = timeState.currentAttemptTime - t;
|
||||||
|
var rewindFrame = rewindManager.getNextRewindFrame(timeState.currentAttemptTime - t);
|
||||||
|
rewindManager.applyFrame(rewindFrame);
|
||||||
|
this.isReplayingMovement = true;
|
||||||
|
this.currentInputMoves = this.inputRecorder.getMovesFrom(timeState.currentAttemptTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function advanceWorld(dt:Float) {
|
||||||
|
ProfilerUI.measure("updateTimer");
|
||||||
|
this.updateTimer(dt);
|
||||||
|
this.tickSchedule(timeState.currentAttemptTime);
|
||||||
|
|
||||||
|
this.updateGameState();
|
||||||
|
ProfilerUI.measure("updateDTS");
|
||||||
|
for (obj in dtsObjects) {
|
||||||
|
obj.update(timeState);
|
||||||
|
}
|
||||||
|
for (obj in triggers) {
|
||||||
|
obj.update(timeState);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfilerUI.measure("updateMarbles");
|
||||||
|
marble.update(timeState, collisionWorld, this.pathedInteriors);
|
||||||
|
for (client => marble in clientMarbles) {
|
||||||
|
marble.update(timeState, collisionWorld, this.pathedInteriors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function update(dt:Float) {
|
public function update(dt:Float) {
|
||||||
if (!_ready) {
|
if (!_ready) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Key.isPressed(Key.T)) {
|
||||||
|
rollback(0.4);
|
||||||
|
}
|
||||||
|
|
||||||
var realDt = dt;
|
var realDt = dt;
|
||||||
|
|
||||||
if ((Key.isDown(Settings.controlsSettings.rewind)
|
if ((Key.isDown(Settings.controlsSettings.rewind)
|
||||||
|
|
@ -1558,6 +1597,31 @@ class MarbleWorld extends Scheduler {
|
||||||
if (dt < 0)
|
if (dt < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (this.isReplayingMovement) {
|
||||||
|
trace('Rollback start');
|
||||||
|
while (this.currentInputMoves.length > 1) {
|
||||||
|
while (this.currentInputMoves[1].time <= timeState.currentAttemptTime) {
|
||||||
|
this.currentInputMoves = this.currentInputMoves.slice(1);
|
||||||
|
if (this.currentInputMoves.length == 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.currentInputMoves.length > 1) {
|
||||||
|
dt = this.currentInputMoves[1].time - this.currentInputMoves[0].time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isReplayingMovement) {
|
||||||
|
if (this.timeState.currentAttemptTime != this.currentInputMoves[0].time)
|
||||||
|
trace("fucked");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentInputMoves.length > 1) {
|
||||||
|
advanceWorld(dt);
|
||||||
|
trace('Position: ${@:privateAccess marble.newPos.sub(currentInputMoves[1].pos).length()}. Vel: ${marble.velocity.sub(currentInputMoves[1].velocity).length()}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.isReplayingMovement = false;
|
||||||
|
}
|
||||||
|
|
||||||
ProfilerUI.measure("updateTimer");
|
ProfilerUI.measure("updateTimer");
|
||||||
this.updateTimer(dt);
|
this.updateTimer(dt);
|
||||||
|
|
||||||
|
|
@ -1615,6 +1679,11 @@ class MarbleWorld extends Scheduler {
|
||||||
for (obj in triggers) {
|
for (obj in triggers) {
|
||||||
obj.update(timeState);
|
obj.update(timeState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (!isReplayingMovement) {
|
||||||
|
// inputRecorder.recordInput(timeState.currentAttemptTime);
|
||||||
|
// }
|
||||||
|
|
||||||
ProfilerUI.measure("updateMarbles");
|
ProfilerUI.measure("updateMarbles");
|
||||||
if (this.isMultiplayer) {
|
if (this.isMultiplayer) {
|
||||||
tickAccumulator += timeState.dt;
|
tickAccumulator += timeState.dt;
|
||||||
|
|
@ -1726,6 +1795,10 @@ class MarbleWorld extends Scheduler {
|
||||||
if (!this.rewinding && Settings.optionsSettings.rewindEnabled && !this.isMultiplayer)
|
if (!this.rewinding && Settings.optionsSettings.rewindEnabled && !this.isMultiplayer)
|
||||||
this.rewindManager.recordFrame();
|
this.rewindManager.recordFrame();
|
||||||
|
|
||||||
|
// if (!this.isReplayingMovement) {
|
||||||
|
// inputRecorder.recordMarble();
|
||||||
|
// }
|
||||||
|
|
||||||
_instancesNeedsUpdate = true;
|
_instancesNeedsUpdate = true;
|
||||||
|
|
||||||
this.updateTexts();
|
this.updateTexts();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package modes;
|
package modes;
|
||||||
|
|
||||||
|
import net.BitStream.OutputBitStream;
|
||||||
|
import net.NetPacket.GemPickupPacket;
|
||||||
|
import net.NetPacket.GemSpawnPacket;
|
||||||
import octree.IOctreeObject;
|
import octree.IOctreeObject;
|
||||||
import octree.IOctreeObject.RayIntersectionData;
|
import octree.IOctreeObject.RayIntersectionData;
|
||||||
import h3d.col.Bounds;
|
import h3d.col.Bounds;
|
||||||
|
|
@ -17,6 +20,7 @@ import src.Mission;
|
||||||
import src.Marble;
|
import src.Marble;
|
||||||
import src.AudioManager;
|
import src.AudioManager;
|
||||||
import src.ResourceLoader;
|
import src.ResourceLoader;
|
||||||
|
import net.Net;
|
||||||
|
|
||||||
@:structInit
|
@:structInit
|
||||||
@:publicFields
|
@:publicFields
|
||||||
|
|
@ -142,10 +146,7 @@ class HuntMode extends NullMode {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupGems() {
|
function prepareGems() {
|
||||||
hideExisting();
|
|
||||||
this.activeGems = [];
|
|
||||||
this.activeGemSpawnGroup = [];
|
|
||||||
if (this.gemSpawnPoints == null) {
|
if (this.gemSpawnPoints == null) {
|
||||||
this.gemOctree = new Octree();
|
this.gemOctree = new Octree();
|
||||||
this.gemSpawnPoints = [];
|
this.gemSpawnPoints = [];
|
||||||
|
|
@ -158,6 +159,13 @@ class HuntMode extends NullMode {
|
||||||
gem.setHide(true);
|
gem.setHide(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupGems() {
|
||||||
|
hideExisting();
|
||||||
|
this.activeGems = [];
|
||||||
|
this.activeGemSpawnGroup = [];
|
||||||
|
prepareGems();
|
||||||
spawnHuntGems();
|
spawnHuntGems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,6 +235,15 @@ class HuntMode extends NullMode {
|
||||||
}
|
}
|
||||||
activeGemSpawnGroup = spawnSet;
|
activeGemSpawnGroup = spawnSet;
|
||||||
|
|
||||||
|
if (level.isMultiplayer && Net.isHost) {
|
||||||
|
var bs = new OutputBitStream();
|
||||||
|
bs.writeByte(GemSpawn);
|
||||||
|
var packet = new GemSpawnPacket();
|
||||||
|
packet.gemIds = spawnSet;
|
||||||
|
packet.serialize(bs);
|
||||||
|
Net.sendPacketToIngame(bs);
|
||||||
|
}
|
||||||
|
|
||||||
lastSpawn = furthest;
|
lastSpawn = furthest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -309,21 +326,25 @@ class HuntMode extends NullMode {
|
||||||
points = 0;
|
points = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override function onClientRestart() {
|
||||||
|
prepareGems();
|
||||||
|
}
|
||||||
|
|
||||||
override function onGemPickup(marble:Marble, gem:Gem) {
|
override function onGemPickup(marble:Marble, gem:Gem) {
|
||||||
// if ((@:privateAccess !marble.isNetUpdate && Net.isHost) || !Net.isMP) {
|
if ((@:privateAccess !marble.isNetUpdate && Net.isHost) || !Net.isMP) {
|
||||||
if (marble == level.marble)
|
if (marble == level.marble)
|
||||||
AudioManager.playSound(ResourceLoader.getResource('data/sound/gotgem.wav', ResourceLoader.getAudio, @:privateAccess this.level.soundResources));
|
AudioManager.playSound(ResourceLoader.getResource('data/sound/gotgem.wav', ResourceLoader.getAudio, @:privateAccess this.level.soundResources));
|
||||||
else
|
else
|
||||||
AudioManager.playSound(ResourceLoader.getResource('data/sound/opponent_gem_collect.wav', ResourceLoader.getAudio,
|
AudioManager.playSound(ResourceLoader.getResource('data/sound/opponentdiamond.wav', ResourceLoader.getAudio,
|
||||||
@:privateAccess this.level.soundResources));
|
@:privateAccess this.level.soundResources));
|
||||||
// }
|
}
|
||||||
activeGems.remove(gem);
|
activeGems.remove(gem);
|
||||||
var beam = gemToBeamMap.get(gem);
|
var beam = gemToBeamMap.get(gem);
|
||||||
beam.setHide(true);
|
beam.setHide(true);
|
||||||
|
|
||||||
// if (!this.level.isMultiplayer || Net.isHost) {
|
if (!this.level.isMultiplayer || Net.isHost) {
|
||||||
spawnHuntGems();
|
spawnHuntGems();
|
||||||
// }
|
}
|
||||||
|
|
||||||
var incr = 0;
|
var incr = 0;
|
||||||
switch (gem.gemColor) {
|
switch (gem.gemColor) {
|
||||||
|
|
@ -352,24 +373,24 @@ class HuntMode extends NullMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (this.level.isMultiplayer && Net.isHost) {
|
if (this.level.isMultiplayer && Net.isHost) {
|
||||||
// var packet = new GemPickupPacket();
|
var packet = new GemPickupPacket();
|
||||||
// packet.clientId = @:privateAccess marble.connection == null ? 0 : @:privateAccess marble.connection.id;
|
packet.clientId = @:privateAccess marble.connection == null ? 0 : @:privateAccess marble.connection.id;
|
||||||
// packet.gemId = gem.netIndex;
|
packet.gemId = gem.netIndex;
|
||||||
// packet.serverTicks = level.timeState.ticks;
|
packet.serverTicks = level.timeState.ticks;
|
||||||
// packet.scoreIncr = incr;
|
packet.scoreIncr = incr;
|
||||||
// var os = new OutputBitStream();
|
var os = new OutputBitStream();
|
||||||
// os.writeByte(GemPickup);
|
os.writeByte(GemPickup);
|
||||||
// packet.serialize(os);
|
packet.serialize(os);
|
||||||
// Net.sendPacketToIngame(os);
|
Net.sendPacketToIngame(os);
|
||||||
|
|
||||||
// Settings.playStatistics.totalMPScore += incr;
|
// Settings.playStatistics.totalMPScore += incr;
|
||||||
|
|
||||||
// @:privateAccess level.playGui.incrementPlayerScore(packet.clientId, packet.scoreIncr);
|
// @:privateAccess level.playGui.incrementPlayerScore(packet.clientId, packet.scoreIncr);
|
||||||
// }
|
}
|
||||||
// if (this.level.isMultiplayer && Net.isClient) {
|
if (this.level.isMultiplayer && Net.isClient) {
|
||||||
// gem.pickUpClient = @:privateAccess marble.connection == null ? Net.clientId : @:privateAccess marble.connection.id;
|
gem.pickUpClient = @:privateAccess marble.connection == null ? Net.clientId : @:privateAccess marble.connection.id;
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function timeMultiplier() {
|
override public function timeMultiplier() {
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,12 @@ class InputBitStream {
|
||||||
return FPHelper.i32ToFloat(readInt32());
|
return FPHelper.i32ToFloat(readInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function readDouble() {
|
||||||
|
var lo = readInt32();
|
||||||
|
var hi = readInt32();
|
||||||
|
return FPHelper.i64ToDouble(lo, hi);
|
||||||
|
}
|
||||||
|
|
||||||
public function readString() {
|
public function readString() {
|
||||||
var length = readUInt16();
|
var length = readUInt16();
|
||||||
var str = "";
|
var str = "";
|
||||||
|
|
@ -151,4 +157,10 @@ class OutputBitStream {
|
||||||
writeByte(StringTools.fastCodeAt(value, i));
|
writeByte(StringTools.fastCodeAt(value, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function writeDouble(value:Float) {
|
||||||
|
var i64 = FPHelper.doubleToI64(value);
|
||||||
|
writeInt32(i64.low);
|
||||||
|
writeInt32(i64.high);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ class MarblePrediction {
|
||||||
var subs = position.sub(p.position).lengthSq(); // + velocity.sub(p.velocity).lengthSq() + omega.sub(p.omega).lengthSq();
|
var subs = position.sub(p.position).lengthSq(); // + velocity.sub(p.velocity).lengthSq() + omega.sub(p.omega).lengthSq();
|
||||||
if (p.netFlags != 0)
|
if (p.netFlags != 0)
|
||||||
subs += 1;
|
subs += 1;
|
||||||
|
if (subs > 0.01) {
|
||||||
|
trace('Desync: ${position.x} ${position.y} ${position.z} != ${p.position.x} ${p.position.y} ${p.position.z}');
|
||||||
|
}
|
||||||
// if (p.powerUpId != powerupItemId)
|
// if (p.powerUpId != powerupItemId)
|
||||||
// if (tick % 10 == 0)
|
// if (tick % 10 == 0)
|
||||||
// subs += 1; // temp
|
// subs += 1; // temp
|
||||||
|
|
|
||||||
62
src/rewind/InputRecorder.hx
Normal file
62
src/rewind/InputRecorder.hx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
package rewind;
|
||||||
|
|
||||||
|
import src.MarbleWorld;
|
||||||
|
import h3d.Vector;
|
||||||
|
import net.Move;
|
||||||
|
|
||||||
|
@:publicFields
|
||||||
|
class InputRecorderFrame {
|
||||||
|
var time:Float;
|
||||||
|
var move:Move;
|
||||||
|
var marbleAxes:Array<Vector>;
|
||||||
|
var pos:Vector;
|
||||||
|
var velocity:Vector;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InputRecorder {
|
||||||
|
var frames:Array<InputRecorderFrame>;
|
||||||
|
var level:MarbleWorld;
|
||||||
|
|
||||||
|
public function new(level:MarbleWorld) {
|
||||||
|
frames = [];
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function recordInput(t:Float) {
|
||||||
|
var frame = new InputRecorderFrame();
|
||||||
|
frame.time = t;
|
||||||
|
frame.move = level.marble.recordMove();
|
||||||
|
frames.push(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function recordMarble() {
|
||||||
|
frames[frames.length - 1].pos = @:privateAccess level.marble.newPos?.clone();
|
||||||
|
frames[frames.length - 1].velocity = level.marble.velocity.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function recordAxis(axis:Array<Vector>) {
|
||||||
|
frames[frames.length - 1].marbleAxes = axis.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMovesFrom(t:Float) {
|
||||||
|
if (frames.length == 0)
|
||||||
|
return [];
|
||||||
|
var start = 0;
|
||||||
|
var end = frames.length - 1;
|
||||||
|
var mid = Std.int(frames.length / 2);
|
||||||
|
while (end - start > 1) {
|
||||||
|
mid = Std.int((start / 2) + (end / 2));
|
||||||
|
if (frames[mid].time < t) {
|
||||||
|
start = mid + 1;
|
||||||
|
} else if (frames[mid].time > t) {
|
||||||
|
end = mid - 1;
|
||||||
|
} else {
|
||||||
|
start = end = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames.slice(start - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue