diff --git a/src/Marble.hx b/src/Marble.hx index 3d9019be..f5982d4b 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -618,7 +618,7 @@ class Marble extends GameObject { } for (marble in level.marbles) { if (marble != cast this) { - var force = marble.getForce(this.collider.transform.getPosition(), timeState.ticks); + var force = marble.getForce(this.collider.transform.getPosition(), Net.isHost ? timeState.ticks : serverTicks); A = A.add(force.multiply(1 / mass)); } } @@ -2223,7 +2223,7 @@ class Marble extends GameObject { if (this.level.isMultiplayer) { if (this.blastTicks < (7500 >> 5)) return false; - this.blastUseTick = timeState.ticks; + this.blastUseTick = Net.isHost ? timeState.ticks : serverTicks; if (!this.isNetUpdate) this.netFlags |= MarbleNetFlags.DoBlast; var amount = this.blastTicks / (30000 >> 5); diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 52471ebd..b34bb6da 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -571,7 +571,7 @@ class MarbleWorld extends Scheduler { } if (!full) { - var respawnT = this.gameMode.getRespawnTransform(); + var respawnT = this.gameMode.getRespawnTransform(marble); if (respawnT != null) { respawn(marble, respawnT.position, respawnT.orientation, respawnT.up); return 0; @@ -1213,34 +1213,37 @@ class MarbleWorld extends Scheduler { // clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove); // needsPrediction |= 1 << client; // arr.insert(0, lastMove); - if (ourMove.serverTicks == lastMove.serverTicks) { - if (ourMoveStruct != null) { - var otherPred = predictions.retrieveState(clientMarbles[Net.clientIdMap[client]], ourMoveStruct.timeState.ticks); - if (otherPred != null) { - if (otherPred.getError(lastMove) > 0.1) { - Debug.drawSphere(@:privateAccess clientMarbles[Net.clientIdMap[client]].newPos, 0.2, 0.5); - // trace('Prediction error: ${otherPred.getError(lastMove)}'); + var clientMarble = clientMarbles[Net.clientIdMap[client]]; + if (clientMarble != null) { + if (ourMove.serverTicks == lastMove.serverTicks) { + if (ourMoveStruct != null) { + var otherPred = predictions.retrieveState(clientMarble, ourMoveStruct.timeState.ticks); + if (otherPred != null) { + if (otherPred.getError(lastMove) > 0.1) { + // Debug.drawSphere(@:privateAccess clientMarbles[Net.clientIdMap[client]].newPos, 0.2, 0.5); + // trace('Prediction error: ${otherPred.getError(lastMove)}'); + // trace('Desync for tick ${ourMoveStruct.timeState.ticks}'); + clientMarble.unpackUpdate(lastMove); + needsPrediction |= 1 << client; + arr.packets.insert(0, lastMove); + predictions.clearStatesAfterTick(clientMarbles[Net.clientIdMap[client]], ourMoveStruct.timeState.ticks); + } + } else { + // Debug.drawSphere(@:privateAccess clientMarbles[Net.clientIdMap[client]].newPos, 0.2, 0.5); // trace('Desync for tick ${ourMoveStruct.timeState.ticks}'); - clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove); + clientMarble.unpackUpdate(lastMove); needsPrediction |= 1 << client; arr.packets.insert(0, lastMove); - predictions.clearStatesAfterTick(clientMarbles[Net.clientIdMap[client]], ourMoveStruct.timeState.ticks); + predictions.clearStatesAfterTick(clientMarble, ourMoveStruct.timeState.ticks); } } else { - Debug.drawSphere(@:privateAccess clientMarbles[Net.clientIdMap[client]].newPos, 0.2, 0.5); - // trace('Desync for tick ${ourMoveStruct.timeState.ticks}'); - clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove); + // Debug.drawSphere(@:privateAccess clientMarbles[Net.clientIdMap[client]].newPos, 0.2, 0.5); + // trace('Desync in General'); + clientMarble.unpackUpdate(lastMove); needsPrediction |= 1 << client; arr.packets.insert(0, lastMove); - predictions.clearStatesAfterTick(clientMarbles[Net.clientIdMap[client]], ourMoveStruct.timeState.ticks); + // predictions.clearStatesAfterTick(clientMarbles[Net.clientIdMap[client]], ourMoveStruct.timeState.ticks); } - } else { - Debug.drawSphere(@:privateAccess clientMarbles[Net.clientIdMap[client]].newPos, 0.2, 0.5); - // trace('Desync in General'); - clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove); - needsPrediction |= 1 << client; - arr.packets.insert(0, lastMove); - // predictions.clearStatesAfterTick(clientMarbles[Net.clientIdMap[client]], ourMoveStruct.timeState.ticks); } } } diff --git a/src/modes/GameMode.hx b/src/modes/GameMode.hx index c1948055..c881c970 100644 --- a/src/modes/GameMode.hx +++ b/src/modes/GameMode.hx @@ -7,6 +7,7 @@ import h3d.Quat; import h3d.Vector; import src.MarbleWorld; import src.Mission; +import src.Marble; enum ScoreType { Time; @@ -15,7 +16,7 @@ enum ScoreType { interface GameMode { public function getSpawnTransform():{position:Vector, orientation:Quat, up:Vector}; - public function getRespawnTransform():{position:Vector, orientation:Quat, up:Vector}; + public function getRespawnTransform(marble:Marble):{position:Vector, orientation:Quat, up:Vector}; public function missionScan(mission:Mission):Void; public function getStartTime():Float; public function timeMultiplier():Float; diff --git a/src/modes/HuntMode.hx b/src/modes/HuntMode.hx index 8d7a039c..705d910d 100644 --- a/src/modes/HuntMode.hx +++ b/src/modes/HuntMode.hx @@ -221,8 +221,8 @@ class HuntMode extends NullMode { } } - override function getRespawnTransform() { - var lastContactPos = this.level.marble.lastContactPosition; + override function getRespawnTransform(marble:Marble) { + var lastContactPos = marble.lastContactPosition; if (lastContactPos == null) { return getSpawnTransform(); } diff --git a/src/modes/NullMode.hx b/src/modes/NullMode.hx index 3da19a76..69e1097d 100644 --- a/src/modes/NullMode.hx +++ b/src/modes/NullMode.hx @@ -39,7 +39,7 @@ class NullMode implements GameMode { }; } - public function getRespawnTransform():{up:Vector, position:Vector, orientation:Quat} { + public function getRespawnTransform(marble:Marble):{up:Vector, position:Vector, orientation:Quat} { return null; }