mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-01-02 05:12:21 +00:00
network the MPs finally, this removes traplaunches though
This commit is contained in:
parent
37e0b74347
commit
b4d7d5633b
7 changed files with 213 additions and 28 deletions
|
|
@ -7,6 +7,7 @@ import mis.MisParser;
|
|||
import src.Settings;
|
||||
import src.Debug;
|
||||
import src.MarbleGame;
|
||||
import src.ProfilerUI;
|
||||
|
||||
@:publicFields
|
||||
class ConsoleEntry {
|
||||
|
|
@ -122,6 +123,7 @@ class Console {
|
|||
log("rewindTimeScale <scale>");
|
||||
log("drawBounds <true/false>");
|
||||
log("wireframe <true/false>");
|
||||
log("fps <true/false>");
|
||||
} else if (cmdType == "timeScale") {
|
||||
if (cmdSplit.length == 2) {
|
||||
var scale = Std.parseFloat(cmdSplit[1]);
|
||||
|
|
@ -163,6 +165,14 @@ class Console {
|
|||
} else {
|
||||
error("Expected one argument, got " + (cmdSplit.length - 1));
|
||||
}
|
||||
} else if (cmdType == "fps") {
|
||||
if (cmdSplit.length == 2) {
|
||||
var scale = MisParser.parseBoolean(cmdSplit[1]);
|
||||
ProfilerUI.setEnabled(scale);
|
||||
log("FPS Display set to " + scale);
|
||||
} else {
|
||||
error("Expected one argument, got " + (cmdSplit.length - 1));
|
||||
}
|
||||
} else if (cmdType == 'rollback') {
|
||||
var t = Std.parseFloat(cmdSplit[1]);
|
||||
MarbleGame.instance.world.rollback(t);
|
||||
|
|
|
|||
|
|
@ -1637,12 +1637,13 @@ class Marble extends GameObject {
|
|||
oldPos = this.collider.transform.getPosition();
|
||||
prevRot = this.getRotationQuat().clone();
|
||||
|
||||
if (this.controllable) {
|
||||
for (interior in pathedInteriors) {
|
||||
// interior.pushTickState();
|
||||
interior.computeNextPathStep(timeRemaining);
|
||||
}
|
||||
// if (this.controllable) {
|
||||
for (interior in pathedInteriors) {
|
||||
if (Net.isMP)
|
||||
interior.pushTickState();
|
||||
interior.computeNextPathStep(timeRemaining);
|
||||
}
|
||||
// }
|
||||
|
||||
// Blast
|
||||
if (m != null && m.blast) {
|
||||
|
|
@ -1795,11 +1796,11 @@ class Marble extends GameObject {
|
|||
|
||||
timeRemaining -= timeStep;
|
||||
|
||||
if (this.controllable) {
|
||||
for (interior in pathedInteriors) {
|
||||
interior.advance(timeStep);
|
||||
}
|
||||
// if (this.controllable) {
|
||||
for (interior in pathedInteriors) {
|
||||
interior.advance(timeStep);
|
||||
}
|
||||
// }
|
||||
|
||||
piTime += timeStep;
|
||||
|
||||
|
|
@ -1808,11 +1809,11 @@ class Marble extends GameObject {
|
|||
} while (true);
|
||||
if (timeRemaining > 0) {
|
||||
// Advance pls
|
||||
if (this.controllable) {
|
||||
for (interior in pathedInteriors) {
|
||||
interior.advance(timeRemaining);
|
||||
}
|
||||
// if (this.controllable) {
|
||||
for (interior in pathedInteriors) {
|
||||
interior.advance(timeRemaining);
|
||||
}
|
||||
// }
|
||||
}
|
||||
this.queuedContacts = [];
|
||||
|
||||
|
|
@ -1856,6 +1857,10 @@ class Marble extends GameObject {
|
|||
this.level.cancel(this.oobSchedule);
|
||||
this.level.restart(cast this);
|
||||
}
|
||||
|
||||
for (interior in pathedInteriors) {
|
||||
interior.popTickState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1899,6 +1904,7 @@ class Marble extends GameObject {
|
|||
// return false;
|
||||
// }
|
||||
// }
|
||||
// trace('Tick RTT: ', this.serverTicks - p.serverTicks);
|
||||
this.serverTicks = p.serverTicks;
|
||||
this.recvServerTick = p.serverTicks;
|
||||
// this.oldPos = this.newPos;
|
||||
|
|
@ -2034,13 +2040,13 @@ class Marble extends GameObject {
|
|||
var smooth = 1.0 / (newDt * (newDt * 0.235 * newDt) + newDt + 1.0 + 0.48 * newDt * newDt);
|
||||
this.netSmoothOffset.scale(smooth);
|
||||
var smoothScale = this.netSmoothOffset.lengthSq();
|
||||
if (smoothScale < 0.1 || smoothScale > 10.0)
|
||||
if (smoothScale < 0.01 || smoothScale > 10.0)
|
||||
this.netSmoothOffset.set(0, 0, 0);
|
||||
|
||||
if (oldPos != null && newPos != null) {
|
||||
var deltaT = physicsAccumulator / 0.032;
|
||||
if (Net.isClient && !this.controllable)
|
||||
deltaT *= 0.75; // Don't overshoot
|
||||
// if (Net.isClient && !this.controllable)
|
||||
// deltaT *= 0.75; // Don't overshoot
|
||||
var renderPos = Util.lerpThreeVectors(this.oldPos, this.newPos, deltaT);
|
||||
if (Net.isClient) {
|
||||
renderPos.load(renderPos.add(this.netSmoothOffset));
|
||||
|
|
|
|||
|
|
@ -1547,6 +1547,12 @@ class MarbleWorld extends Scheduler {
|
|||
@:privateAccess this.marble.posStore.load(this.marble.newPos);
|
||||
@:privateAccess this.marble.netCorrected = true;
|
||||
|
||||
// if ((marbleNeedsPrediction & (1 << Net.clientId) > 0)) {
|
||||
for (pi in this.pathedInteriors) {
|
||||
pi.rollbackToTick(currentTick);
|
||||
}
|
||||
// }
|
||||
|
||||
for (move in ourQueuedMoves) {
|
||||
var m = move.move;
|
||||
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
|
||||
|
|
@ -1574,6 +1580,13 @@ class MarbleWorld extends Scheduler {
|
|||
advanceTimeState.currentAttemptTime += 0.032;
|
||||
advanceTimeState.ticks++;
|
||||
currentTick++;
|
||||
|
||||
// if ((marbleNeedsPrediction & (1 << Net.clientId) > 0)) {
|
||||
for (pi in this.pathedInteriors) {
|
||||
pi.computeNextPathStep(0.032);
|
||||
pi.advance(0.032);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
lastMoves.ourMoveApplied = true;
|
||||
|
|
@ -1858,6 +1871,10 @@ class MarbleWorld extends Scheduler {
|
|||
this.marble.clearNetFlags();
|
||||
}
|
||||
}
|
||||
for (pi in this.pathedInteriors) {
|
||||
pi.computeNextPathStep(0.032);
|
||||
pi.advance(0.032);
|
||||
}
|
||||
timeState.ticks++;
|
||||
}
|
||||
timeState.subframe = tickAccumulator / 0.032;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ class PathedInterior extends InteriorObject {
|
|||
public var currentTime:Float;
|
||||
public var targetTime:Float;
|
||||
|
||||
var initialPosition:Float;
|
||||
var initialTargetPosition:Float;
|
||||
|
||||
var basePosition:Vector;
|
||||
var baseOrientation:Quat;
|
||||
var baseScale:Vector;
|
||||
|
|
@ -52,6 +55,12 @@ class PathedInterior extends InteriorObject {
|
|||
var stopped:Bool = false;
|
||||
var stoppedPosition:Vector;
|
||||
|
||||
var savedPosition:Vector;
|
||||
var savedVelocity:Vector;
|
||||
var savedStopped:Bool;
|
||||
var savedStoppedPosition:Vector;
|
||||
var savedTime:Float;
|
||||
|
||||
var soundChannel:Channel;
|
||||
|
||||
public static function createFromSimGroup(simGroup:MissionElementSimGroup, level:MarbleWorld, onFinish:PathedInterior->Void) {
|
||||
|
|
@ -173,6 +182,33 @@ class PathedInterior extends InteriorObject {
|
|||
}
|
||||
}
|
||||
|
||||
public function getInternalTime(externalTime:Float) {
|
||||
if (this.targetTime < 0) {
|
||||
var direction = (this.targetTime == -1) ? 1 : (this.targetTime == -2) ? -1 : 0;
|
||||
return Util.adjustedMod(this.currentTime + externalTime * direction, this.duration);
|
||||
} else {
|
||||
var dur = Math.abs(this.currentTime - this.targetTime);
|
||||
|
||||
var compvarion = Util.clamp(dur != 0 ? externalTime / dur : 1, 0, 1);
|
||||
return Util.clamp(Util.lerp(this.currentTime, this.targetTime, compvarion), 0, this.duration);
|
||||
}
|
||||
}
|
||||
|
||||
public function rollbackToTick(tick:Int) {
|
||||
// this.reset();
|
||||
// Reset
|
||||
this.currentTime = initialPosition;
|
||||
this.targetTime = initialTargetPosition;
|
||||
if (this.targetTime < 0) {
|
||||
var direction = (this.targetTime == -1) ? 1 : (this.targetTime == -2) ? -1 : 0;
|
||||
this.currentTime = Util.adjustedMod(this.currentTime + (tick * 0.032) * direction, duration);
|
||||
} else {
|
||||
this.currentTime = Util.clamp(this.currentTime + (tick * 0.032), 0, duration);
|
||||
}
|
||||
this.computeNextPathStep(0.032);
|
||||
this.advance(0.032);
|
||||
}
|
||||
|
||||
public function advance(timeDelta:Float) {
|
||||
if (stopped)
|
||||
return;
|
||||
|
|
@ -213,6 +249,25 @@ class PathedInterior extends InteriorObject {
|
|||
this.stoppedPosition = this.position.clone();
|
||||
}
|
||||
|
||||
public function pushTickState() {
|
||||
savedPosition = this.position.clone();
|
||||
savedVelocity = this.velocity.clone();
|
||||
savedStopped = this.stopped;
|
||||
savedStoppedPosition = this.stoppedPosition != null ? this.stoppedPosition.clone() : null;
|
||||
savedTime = this.currentTime;
|
||||
}
|
||||
|
||||
public function popTickState() {
|
||||
this.position.load(savedPosition);
|
||||
this.velocity.load(savedVelocity);
|
||||
this.stopped = savedStopped;
|
||||
this.stoppedPosition = savedStoppedPosition;
|
||||
this.collider.transform.setPosition(savedPosition);
|
||||
collisionWorld.updateTransform(this.collider);
|
||||
|
||||
this.currentTime = savedTime;
|
||||
}
|
||||
|
||||
function computeDuration() {
|
||||
var total = 0.0;
|
||||
for (i in 0...(markerData.length - 1)) {
|
||||
|
|
@ -311,9 +366,12 @@ class PathedInterior extends InteriorObject {
|
|||
override function reset() {
|
||||
this.currentTime = 0;
|
||||
this.targetTime = 0;
|
||||
this.initialPosition = 0;
|
||||
this.initialTargetPosition = 0;
|
||||
|
||||
if (this.element.initialposition != "") {
|
||||
this.currentTime = MisParser.parseNumber(this.element.initialposition) / 1000;
|
||||
initialPosition = this.currentTime;
|
||||
}
|
||||
|
||||
if (this.element.initialtargetposition != "") {
|
||||
|
|
@ -323,6 +381,8 @@ class PathedInterior extends InteriorObject {
|
|||
// Alright this is strange. In Torque, there are some FPS-dependent client/server desync issues that cause the interior to start at the end position whenever the initialTargetPosition is somewhere greater than 1 and, like, approximately below 50.
|
||||
if (this.targetTime > 0 && this.targetTime < 0.05)
|
||||
this.currentTime = this.duration;
|
||||
|
||||
initialTargetPosition = this.targetTime;
|
||||
}
|
||||
|
||||
this.stopped = false;
|
||||
|
|
|
|||
|
|
@ -1,44 +1,136 @@
|
|||
package src;
|
||||
|
||||
import net.Net;
|
||||
import src.MarbleGame;
|
||||
import h3d.Vector;
|
||||
import hxd.res.DefaultFont;
|
||||
import h2d.Text;
|
||||
|
||||
class ProfilerUI {
|
||||
var fpsCounter:Text;
|
||||
var networkStats:Text;
|
||||
var debugProfiler:h3d.impl.Benchmark;
|
||||
var s2d:h2d.Scene;
|
||||
|
||||
public var fps:Float;
|
||||
|
||||
public static var instance:ProfilerUI;
|
||||
|
||||
static var enabled:Bool = false;
|
||||
static var mode:Int = 0;
|
||||
|
||||
public function new(s2d:h2d.Scene) {
|
||||
if (instance != null)
|
||||
return;
|
||||
|
||||
instance = this;
|
||||
// debugProfiler = new h3d.impl.Benchmark(s2d);
|
||||
// debugProfiler.y = 40;
|
||||
|
||||
// fpsCounter = new Text(DefaultFont.get(), s2d);
|
||||
// fpsCounter.y = 80;
|
||||
// fpsCounter.color = new Vector(1, 1, 1, 1);
|
||||
this.s2d = s2d;
|
||||
}
|
||||
|
||||
public static function begin() {
|
||||
// instance.debugProfiler.begin();
|
||||
if (!enabled)
|
||||
return;
|
||||
// if (type == mode)
|
||||
instance.debugProfiler.begin();
|
||||
}
|
||||
|
||||
public static function measure(name:String) {
|
||||
// instance.debugProfiler.measure(name);
|
||||
if (!enabled)
|
||||
return;
|
||||
// if (type == mode)
|
||||
instance.debugProfiler.measure(name);
|
||||
}
|
||||
|
||||
public static function end() {
|
||||
// instance.debugProfiler.end();
|
||||
if (!enabled)
|
||||
return;
|
||||
// if (type == mode)
|
||||
instance.debugProfiler.end();
|
||||
}
|
||||
|
||||
public static function update(fps:Float) {
|
||||
instance.fps = fps;
|
||||
// instance.fpsCounter.text = "FPS: " + fps;
|
||||
if (!enabled)
|
||||
return;
|
||||
instance.fpsCounter.text = "FPS: " + fps;
|
||||
updateNetworkStats();
|
||||
}
|
||||
|
||||
public static function setEnabled(val:Bool) {
|
||||
enabled = val;
|
||||
if (enabled) {
|
||||
if (instance.debugProfiler != null) {
|
||||
instance.debugProfiler.remove();
|
||||
instance.debugProfiler = null;
|
||||
}
|
||||
if (instance.fpsCounter != null) {
|
||||
instance.fpsCounter.remove();
|
||||
instance.fpsCounter = null;
|
||||
}
|
||||
if (instance.networkStats != null) {
|
||||
instance.networkStats.remove();
|
||||
instance.networkStats = null;
|
||||
}
|
||||
instance.debugProfiler = new h3d.impl.Benchmark(instance.s2d);
|
||||
instance.debugProfiler.y = 40;
|
||||
|
||||
instance.fpsCounter = new Text(DefaultFont.get(), instance.s2d);
|
||||
instance.fpsCounter.y = 80;
|
||||
instance.fpsCounter.color = new Vector(1, 1, 1, 1);
|
||||
|
||||
instance.networkStats = new Text(DefaultFont.get(), instance.s2d);
|
||||
instance.networkStats.y = 150;
|
||||
instance.networkStats.color = new Vector(1, 1, 1, 1);
|
||||
|
||||
instance.debugProfiler.end(); // End current frame
|
||||
} else {
|
||||
instance.debugProfiler.remove();
|
||||
instance.fpsCounter.remove();
|
||||
instance.networkStats.remove();
|
||||
instance.debugProfiler = null;
|
||||
instance.fpsCounter = null;
|
||||
instance.networkStats = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function setDisplayMode(m:Int) {
|
||||
mode = m;
|
||||
if (instance.debugProfiler != null) {
|
||||
instance.debugProfiler.end(); // End
|
||||
}
|
||||
}
|
||||
|
||||
static function updateNetworkStats() {
|
||||
if (MarbleGame.instance.world != null && MarbleGame.instance.world.isMultiplayer) {
|
||||
static var lastSentMove = 0;
|
||||
if (Net.isClient && Net.clientConnection.getQueuedMovesLength() > 0) {
|
||||
lastSentMove = @:privateAccess Net.clientConnection.moveManager.queuedMoves[Net.clientConnection.moveManager.queuedMoves.length - 1].id;
|
||||
}
|
||||
|
||||
if (Net.isClient
|
||||
&& lastSentMove != 0
|
||||
&& @:privateAccess MarbleGame.instance.world.lastMoves != null
|
||||
&& @:privateAccess MarbleGame.instance.world.lastMoves.myMarbleUpdate != null) {
|
||||
instance.networkStats.text = 'Client World Ticks: ${MarbleGame.instance.world.timeState.ticks}\n'
|
||||
+ 'Client Marble Ticks: ${@:privateAccess MarbleGame.instance.world.marble.serverTicks}\n'
|
||||
+ 'Server Ticks: ${@:privateAccess MarbleGame.instance.world.lastMoves.myMarbleUpdate.serverTicks}\n'
|
||||
+ 'Client Move Queue Size: ${Net.isClient ? Net.clientConnection.getQueuedMovesLength() : 0}\n'
|
||||
+ 'Server Move Queue Size: ${Net.isClient ? @:privateAccess MarbleGame.instance.world.lastMoves.myMarbleUpdate.moveQueueSize : 0}\n'
|
||||
+ 'Last Sent Move: ${Net.isClient ? lastSentMove : 0}\n'
|
||||
+ 'Last Ack Move: ${Net.isClient ? @:privateAccess Net.clientConnection.moveManager.lastAckMoveId : 0}\n'
|
||||
+ 'Move Ack RTT: ${Net.isClient ? @:privateAccess Net.clientConnection.moveManager.ackRTT : 0}';
|
||||
}
|
||||
if (Net.isHost) {
|
||||
var strs = [];
|
||||
strs.push('World Ticks: ${MarbleGame.instance.world.timeState.ticks}');
|
||||
for (dc => cc in Net.clients) {
|
||||
strs.push('${cc.id} move: sz ${@:privateAccess cc.moveManager.getQueueSize()} avg ${@:privateAccess cc.moveManager.serverAvgMoveListSize}');
|
||||
}
|
||||
|
||||
instance.networkStats.text = strs.join('\n');
|
||||
}
|
||||
} else {
|
||||
instance.networkStats.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ class MPPlayMissionGui extends GuiImage {
|
|||
searchBtn.position = new Vector(255, 514);
|
||||
searchBtn.extent = new Vector(44, 44);
|
||||
searchBtn.pressedAction = (e) -> {
|
||||
MarbleGame.canvas.pushDialog(new MPSearchGui(false));
|
||||
MarbleGame.canvas.pushDialog(new MPSearchGui(currentCategory == "custom"));
|
||||
}
|
||||
if (Net.isHost)
|
||||
window.addChild(searchBtn);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class MPSearchGui extends GuiImage {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
var customsList = MissionList.customMissions;
|
||||
var customsList = Marbleland.multiplayerMissions;
|
||||
for (mis in customsList) {
|
||||
missionList.push({
|
||||
mis: mis,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue