mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-12-31 20:32:21 +00:00
more net ui and netcode
This commit is contained in:
parent
cabc437ca0
commit
038e0ed16e
12 changed files with 144 additions and 58 deletions
|
|
@ -258,6 +258,8 @@ class Marble extends GameObject {
|
|||
var oldPos:Vector;
|
||||
var newPos:Vector;
|
||||
var prevRot:Quat;
|
||||
var posStore:Vector;
|
||||
var netCorrected:Bool;
|
||||
|
||||
public var contacts:Array<CollisionInfo> = [];
|
||||
public var bestContact:CollisionInfo;
|
||||
|
|
@ -324,6 +326,7 @@ class Marble extends GameObject {
|
|||
var isNetUpdate:Bool = false;
|
||||
var netFlags:Int = 0;
|
||||
var serverTicks:Int;
|
||||
var recvServerTick:Int;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
|
|
@ -368,6 +371,9 @@ class Marble extends GameObject {
|
|||
|
||||
var isUltra = true;
|
||||
|
||||
this.posStore = new Vector();
|
||||
this.netCorrected = false;
|
||||
|
||||
var marbleDts = new DtsObject();
|
||||
Console.log("Marble: " + Settings.optionsSettings.marbleModel + " (" + Settings.optionsSettings.marbleSkin + ")");
|
||||
marbleDts.dtsPath = Settings.optionsSettings.marbleModel;
|
||||
|
|
@ -1748,8 +1754,9 @@ class Marble extends GameObject {
|
|||
// }
|
||||
// }
|
||||
this.serverTicks = p.serverTicks;
|
||||
this.oldPos = this.newPos;
|
||||
this.newPos = p.position;
|
||||
this.recvServerTick = p.serverTicks;
|
||||
// this.oldPos = this.newPos;
|
||||
// this.newPos = p.position;
|
||||
this.collider.transform.setPosition(p.position);
|
||||
this.velocity = p.velocity;
|
||||
this.omega = p.omega;
|
||||
|
|
@ -1767,29 +1774,36 @@ class Marble extends GameObject {
|
|||
this.level.pickUpPowerUp(cast this, this.level.powerUps[p.powerUpId]);
|
||||
}
|
||||
|
||||
if (this.controllable && Net.isClient) {
|
||||
// We are client, need to do something about the queue
|
||||
var mm = Net.clientConnection.moveManager;
|
||||
// trace('Queue size: ${mm.getQueueSize()}, server: ${p.moveQueueSize}');
|
||||
if (mm.getQueueSize() / p.moveQueueSize < 2) {
|
||||
mm.stall = true;
|
||||
} else {
|
||||
mm.stall = false;
|
||||
}
|
||||
}
|
||||
// if (this.controllable && Net.isClient) {
|
||||
// // We are client, need to do something about the queue
|
||||
// var mm = Net.clientConnection.moveManager;
|
||||
// // trace('Queue size: ${mm.getQueueSize()}, server: ${p.moveQueueSize}');
|
||||
// if (mm.getQueueSize() / p.moveQueueSize < 2) {
|
||||
// mm.stall = true;
|
||||
// } else {
|
||||
// mm.stall = false;
|
||||
// }
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
function calculateNetSmooth() {
|
||||
if (this.netCorrected) {
|
||||
this.netCorrected = false;
|
||||
this.oldPos.load(this.posStore);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateServer(timeState:TimeState, collisionWorld:CollisionWorld, pathedInteriors:Array<PathedInterior>) {
|
||||
var move:NetMove = null;
|
||||
if (this.controllable && this.mode != Finish && !MarbleGame.instance.paused && !this.level.isWatching && !this.level.isReplayingMovement) {
|
||||
if (Net.isClient) {
|
||||
var axis = getMarbleAxis()[1];
|
||||
move = Net.clientConnection.recordMove(cast this, axis, timeState);
|
||||
move = Net.clientConnection.recordMove(cast this, axis, timeState, recvServerTick);
|
||||
} else if (Net.isHost) {
|
||||
var axis = getMarbleAxis()[1];
|
||||
var innerMove = recordMove();
|
||||
move = new NetMove(innerMove, axis, timeState, 65535);
|
||||
move = new NetMove(innerMove, axis, timeState, recvServerTick, 65535);
|
||||
}
|
||||
}
|
||||
var moveId = 65535;
|
||||
|
|
@ -1800,30 +1814,35 @@ class Marble extends GameObject {
|
|||
var axis = getMarbleAxis()[1];
|
||||
var innerMove = new Move();
|
||||
innerMove.d = new Vector(0, 0);
|
||||
move = new NetMove(innerMove, axis, timeState, 65535);
|
||||
move = new NetMove(innerMove, axis, timeState, recvServerTick, 65535);
|
||||
} else {
|
||||
move = nextMove;
|
||||
moveMotionDir = nextMove.motionDir;
|
||||
moveId = nextMove.id;
|
||||
}
|
||||
}
|
||||
if (move == null) {
|
||||
if (move == null && !this.controllable) {
|
||||
var axis = moveMotionDir != null ? moveMotionDir : new Vector(0, -1, 0);
|
||||
var innerMove = lastMove;
|
||||
if (innerMove == null) {
|
||||
innerMove = new Move();
|
||||
innerMove.d = new Vector(0, 0);
|
||||
}
|
||||
move = new NetMove(innerMove, axis, timeState, 65535);
|
||||
move = new NetMove(innerMove, axis, timeState, recvServerTick, 65535);
|
||||
}
|
||||
|
||||
playedSounds = [];
|
||||
advancePhysics(timeState, move.move, collisionWorld, pathedInteriors);
|
||||
physicsAccumulator = 0;
|
||||
if (move != null) {
|
||||
playedSounds = [];
|
||||
advancePhysics(timeState, move.move, collisionWorld, pathedInteriors);
|
||||
physicsAccumulator = 0;
|
||||
|
||||
if (move.move.jump && this.outOfBounds) {
|
||||
this.level.cancel(this.oobSchedule);
|
||||
this.level.restart(cast this);
|
||||
if (move.move.jump && this.outOfBounds) {
|
||||
this.level.cancel(this.oobSchedule);
|
||||
this.level.restart(cast this);
|
||||
}
|
||||
} else {
|
||||
physicsAccumulator = 0;
|
||||
newPos.load(oldPos);
|
||||
}
|
||||
|
||||
return move;
|
||||
|
|
@ -1833,6 +1852,7 @@ class Marble extends GameObject {
|
|||
}
|
||||
|
||||
public function updateClient(timeState:TimeState, pathedInteriors:Array<PathedInterior>) {
|
||||
calculateNetSmooth();
|
||||
this.level.updateBlast(cast this, timeState);
|
||||
if (oldPos != null && newPos != null) {
|
||||
var deltaT = physicsAccumulator / 0.032;
|
||||
|
|
@ -2318,6 +2338,8 @@ class Marble extends GameObject {
|
|||
this.prevRot = this.getRotationQuat().clone();
|
||||
this.oldPos = this.getAbsPos().getPosition();
|
||||
this.newPos = this.getAbsPos().getPosition();
|
||||
this.posStore = new Vector();
|
||||
this.netCorrected = false;
|
||||
if (this._radius != this._prevRadius) {
|
||||
this._radius = this._prevRadius;
|
||||
this._marbleScale = this._renderScale = this._defaultScale;
|
||||
|
|
|
|||
|
|
@ -1077,7 +1077,7 @@ class MarbleWorld extends Scheduler {
|
|||
if (!lastMoves.ourMoveApplied) {
|
||||
var ourMove = lastMoves.myMarbleUpdate;
|
||||
if (ourMove != null) {
|
||||
var ourMoveStruct = Net.clientConnection.acknowledgeMove(ourMove.move.id, timeState);
|
||||
var ourMoveStruct = Net.clientConnection.acknowledgeMove(ourMove.move, timeState);
|
||||
lastMoves.ourMoveApplied = true;
|
||||
for (client => arr in lastMoves.otherMarbleUpdates) {
|
||||
var lastMove = null;
|
||||
|
|
@ -1203,9 +1203,11 @@ class MarbleWorld extends Scheduler {
|
|||
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
|
||||
// Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
|
||||
|
||||
var distFromUs = @:privateAccess marbleToUpdate.newPos.distance(this.marble.newPos);
|
||||
// var distFromUs = @:privateAccess marbleToUpdate.newPos.distance(this.marble.newPos);
|
||||
// if (distFromUs < 5) // {
|
||||
m.calculationTicks = ourQueuedMoves.length;
|
||||
@:privateAccess marbleToUpdate.posStore.load(marbleToUpdate.newPos);
|
||||
@:privateAccess marbleToUpdate.netCorrected = true;
|
||||
// } else {
|
||||
// m.calculationTicks = Std.int(Math.max(1, ourQueuedMoves.length - (distFromUs - 5) / 3));
|
||||
// }
|
||||
|
|
@ -1220,6 +1222,9 @@ class MarbleWorld extends Scheduler {
|
|||
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
|
||||
// var syncTickStates = new Map();
|
||||
|
||||
@:privateAccess this.marble.posStore.load(this.marble.newPos);
|
||||
@:privateAccess this.marble.netCorrected = true;
|
||||
|
||||
for (move in ourQueuedMoves) {
|
||||
var m = move.move;
|
||||
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
|
||||
|
|
@ -1479,9 +1484,11 @@ class MarbleWorld extends Scheduler {
|
|||
for (client => marble in clientMarbles) {
|
||||
otherMoves.push(marble.updateServer(fixedDt, collisionWorld, pathedInteriors));
|
||||
}
|
||||
this.predictions.storeState(marble, myMove.timeState.ticks);
|
||||
for (client => marble in clientMarbles) {
|
||||
if (myMove != null) {
|
||||
this.predictions.storeState(marble, myMove.timeState.ticks);
|
||||
for (client => marble in clientMarbles) {
|
||||
this.predictions.storeState(marble, myMove.timeState.ticks);
|
||||
}
|
||||
}
|
||||
if (Net.isHost) {
|
||||
for (client => othermarble in clientMarbles) { // Oh no!
|
||||
|
|
|
|||
|
|
@ -114,8 +114,9 @@ class CreateMatchGui extends GuiImage {
|
|||
nextButton.gamepadAccelerator = ["A"];
|
||||
nextButton.accelerators = [hxd.Key.ENTER];
|
||||
nextButton.pressedAction = (e) -> {
|
||||
Net.hostServer('${Settings.highscoreName}\'s Server', maxPlayers, privateSlots, privateGame);
|
||||
MarbleGame.canvas.setContent(new MultiplayerLevelSelectGui(true));
|
||||
Net.hostServer('${Settings.highscoreName}\'s Server', maxPlayers, privateSlots, privateGame, () -> {
|
||||
MarbleGame.canvas.setContent(new MultiplayerLevelSelectGui(true));
|
||||
});
|
||||
};
|
||||
bottomBar.addChild(nextButton);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class EnterNameDlg extends GuiImage {
|
|||
textInput.text.selectionTile = h2d.Tile.fromColor(0x88BCEE, 0, hxd.Math.ceil(textInput.text.font.lineHeight));
|
||||
textFrame.addChild(textInput);
|
||||
|
||||
textInput.text.text = Settings.highscoreName;
|
||||
textInput.text.text = Settings.highscoreName == "" ? "Player Name" : Settings.highscoreName;
|
||||
|
||||
var okButton = new GuiXboxButton("Ok", 120);
|
||||
okButton.position = new Vector(211, 248);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package gui;
|
||||
|
||||
import net.Net;
|
||||
import gui.GuiControl.MouseState;
|
||||
import src.AudioManager;
|
||||
import src.MarbleGame;
|
||||
|
|
@ -82,7 +83,8 @@ class ExitGameDlg extends GuiImage {
|
|||
innerCtrl.addChild(btnList);
|
||||
|
||||
btnList.addButton(0, "Resume", (evt) -> noFunc(btnList));
|
||||
btnList.addButton(0, "Restart", (evt) -> restartFunc(btnList));
|
||||
if (!Net.isMP)
|
||||
btnList.addButton(0, "Restart", (evt) -> restartFunc(btnList));
|
||||
btnList.addButton(4, "Exit Level", (evt) -> {
|
||||
MarbleGame.canvas.pushDialog(new MessageBoxYesNoDlg("Are you sure you want to exit this level? You will lose your current level progress.",
|
||||
() -> yesFunc(btnList), () -> {}));
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class MultiplayerLevelSelectGui extends GuiImage {
|
|||
static var currentSelectionStatic:Int = 0;
|
||||
|
||||
static var setLevelFn:Int->Void;
|
||||
static var playSelectedLevel:Void->Void;
|
||||
static var playSelectedLevel:Int->Void;
|
||||
|
||||
var playerList:GuiMLTextListCtrl;
|
||||
var updatePlayerCountFn:(Int, Int, Int, Int) -> Void;
|
||||
|
|
@ -200,7 +200,8 @@ class MultiplayerLevelSelectGui extends GuiImage {
|
|||
};
|
||||
bottomBar.addChild(nextButton);
|
||||
|
||||
playSelectedLevel = () -> {
|
||||
playSelectedLevel = (index:Int) -> {
|
||||
curMission = difficultyMissions[index];
|
||||
MarbleGame.instance.playMission(curMission, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ abstract class GameConnection {
|
|||
moveManager.queueMove(m);
|
||||
}
|
||||
|
||||
public inline function acknowledgeMove(m:Int, timeState:TimeState) {
|
||||
public inline function acknowledgeMove(m:NetMove, timeState:TimeState) {
|
||||
return moveManager.acknowledgeMove(m, timeState);
|
||||
}
|
||||
|
||||
|
|
@ -81,8 +81,8 @@ abstract class GameConnection {
|
|||
return moveManager.getQueueSize();
|
||||
}
|
||||
|
||||
public function recordMove(marble:src.Marble, motionDir:h3d.Vector, timeState:TimeState) {
|
||||
return moveManager.recordMove(marble, motionDir, timeState);
|
||||
public function recordMove(marble:src.Marble, motionDir:h3d.Vector, timeState:TimeState, serverTicks:Int) {
|
||||
return moveManager.recordMove(marble, motionDir, timeState, serverTicks);
|
||||
}
|
||||
|
||||
public function getNextMove() {
|
||||
|
|
|
|||
|
|
@ -26,10 +26,18 @@ class MasterServerClient {
|
|||
var open = false;
|
||||
|
||||
public function new(onOpenFunc:() -> Void) {
|
||||
#if sys
|
||||
var senderThread = sys.thread.Thread.current();
|
||||
#end
|
||||
ws = new WebSocket(serverIp);
|
||||
ws.onopen = () -> {
|
||||
open = true;
|
||||
#if sys
|
||||
senderThread.events.run(onOpenFunc);
|
||||
#end
|
||||
#if js
|
||||
onOpenFunc();
|
||||
#end
|
||||
}
|
||||
ws.onmessage = (m) -> {
|
||||
switch (m) {
|
||||
|
|
@ -44,8 +52,15 @@ class MasterServerClient {
|
|||
public static function connectToMasterServer(onConnect:() -> Void) {
|
||||
if (instance == null)
|
||||
instance = new MasterServerClient(onConnect);
|
||||
else
|
||||
onConnect();
|
||||
else {
|
||||
if (instance.open)
|
||||
onConnect();
|
||||
else {
|
||||
instance.ws.close();
|
||||
instance = null;
|
||||
instance = new MasterServerClient(onConnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function disconnectFromMasterServer() {
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@ class NetMove {
|
|||
var move:Move;
|
||||
var id:Int;
|
||||
var timeState:TimeState;
|
||||
var serverTicks:Int;
|
||||
|
||||
public function new(move:Move, motionDir:Vector, timeState:TimeState, id:Int) {
|
||||
public function new(move:Move, motionDir:Vector, timeState:TimeState, serverTicks:Int, id:Int) {
|
||||
this.move = move;
|
||||
this.motionDir = motionDir;
|
||||
this.id = id;
|
||||
this.serverTicks = serverTicks;
|
||||
this.timeState = timeState;
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +46,12 @@ class MoveManager {
|
|||
|
||||
var maxMoves = 45;
|
||||
|
||||
var serverTargetMoveListSize = 3;
|
||||
var serverMaxMoveListSize = 5;
|
||||
var serverAvgMoveListSize = 3.0;
|
||||
var serverSmoothMoveAvg = 0.15;
|
||||
var serverMoveListSizeSlack = 1.0;
|
||||
|
||||
public var stall = false;
|
||||
|
||||
public function new(connection:GameConnection) {
|
||||
|
|
@ -54,9 +62,10 @@ class MoveManager {
|
|||
mv.d = new Vector(0, 0);
|
||||
}
|
||||
|
||||
public function recordMove(marble:Marble, motionDir:Vector, timeState:TimeState) {
|
||||
if (queuedMoves.length >= maxMoves || stall)
|
||||
public function recordMove(marble:Marble, motionDir:Vector, timeState:TimeState, serverTicks:Int) {
|
||||
if (queuedMoves.length >= maxMoves || stall) {
|
||||
return queuedMoves[queuedMoves.length - 1];
|
||||
}
|
||||
var move = new Move();
|
||||
move.d = new Vector();
|
||||
move.d.x = Gamepad.getAxis(Settings.gamepadSettings.moveYAxis);
|
||||
|
|
@ -94,7 +103,7 @@ class MoveManager {
|
|||
move.d.x = MarbleGame.instance.touchInput.movementInput.value.y;
|
||||
}
|
||||
|
||||
var netMove = new NetMove(move, motionDir, timeState.clone(), nextMoveId++);
|
||||
var netMove = new NetMove(move, motionDir, timeState.clone(), serverTicks, nextMoveId++);
|
||||
queuedMoves.push(netMove);
|
||||
|
||||
if (nextMoveId >= 65535) // 65535 is reserved for null move
|
||||
|
|
@ -113,6 +122,11 @@ class MoveManager {
|
|||
return netMove;
|
||||
}
|
||||
|
||||
function copyMove(to:Int, from:Int) {
|
||||
queuedMoves[to].move = queuedMoves[from].move;
|
||||
queuedMoves[to].motionDir.load(queuedMoves[from].motionDir);
|
||||
}
|
||||
|
||||
public static inline function packMove(m:NetMove, b:OutputBitStream) {
|
||||
b.writeUInt16(m.id);
|
||||
b.writeByte(Std.int((m.move.d.x * 16) + 16));
|
||||
|
|
@ -139,7 +153,7 @@ class MoveManager {
|
|||
motionDir.x = b.readFloat();
|
||||
motionDir.y = b.readFloat();
|
||||
motionDir.z = b.readFloat();
|
||||
var netMove = new NetMove(move, motionDir, MarbleGame.instance.world.timeState.clone(), moveId);
|
||||
var netMove = new NetMove(move, motionDir, MarbleGame.instance.world.timeState.clone(), 0, moveId);
|
||||
return netMove;
|
||||
}
|
||||
|
||||
|
|
@ -148,9 +162,31 @@ class MoveManager {
|
|||
}
|
||||
|
||||
public function getNextMove() {
|
||||
if (queuedMoves.length == 0)
|
||||
if (Net.isHost) {
|
||||
serverAvgMoveListSize *= (1 - serverSmoothMoveAvg);
|
||||
serverAvgMoveListSize += serverSmoothMoveAvg * queuedMoves.length;
|
||||
if (serverAvgMoveListSize < serverTargetMoveListSize - serverMoveListSizeSlack
|
||||
&& queuedMoves.length < serverTargetMoveListSize
|
||||
&& queuedMoves.length != 0) {
|
||||
// Send null move
|
||||
return null;
|
||||
}
|
||||
if (queuedMoves.length > serverMaxMoveListSize
|
||||
|| (serverAvgMoveListSize > serverTargetMoveListSize + serverMoveListSizeSlack
|
||||
&& queuedMoves.length > serverTargetMoveListSize)) {
|
||||
var dropAmt = queuedMoves.length - serverTargetMoveListSize;
|
||||
while (dropAmt-- > 0) {
|
||||
queuedMoves.pop();
|
||||
}
|
||||
serverAvgMoveListSize = serverTargetMoveListSize;
|
||||
}
|
||||
}
|
||||
if (queuedMoves.length == 0) {
|
||||
// if (lastMove != null) {
|
||||
// lastMove.id++; // So that we force client's move to be overriden by this one
|
||||
// }
|
||||
return lastMove;
|
||||
else {
|
||||
} else {
|
||||
lastMove = queuedMoves[0];
|
||||
queuedMoves.shift();
|
||||
return lastMove;
|
||||
|
|
@ -161,25 +197,29 @@ class MoveManager {
|
|||
return queuedMoves.length;
|
||||
}
|
||||
|
||||
public function acknowledgeMove(m:Int, timeState:TimeState) {
|
||||
if (m == 65535 || m == -1)
|
||||
public function acknowledgeMove(m:NetMove, timeState:TimeState) {
|
||||
if (m.id == 65535 || m.id == -1) {
|
||||
return null;
|
||||
if (m <= lastAckMoveId)
|
||||
}
|
||||
if (m.id <= lastAckMoveId)
|
||||
return null; // Already acked
|
||||
if (queuedMoves.length == 0)
|
||||
return null;
|
||||
while (m != queuedMoves[0].id) {
|
||||
if (m.id >= nextMoveId) {
|
||||
return queuedMoves[0]; // Input lag
|
||||
}
|
||||
while (m.id != queuedMoves[0].id) {
|
||||
queuedMoves.shift();
|
||||
}
|
||||
var delta = -1;
|
||||
var mv = null;
|
||||
if (m == queuedMoves[0].id) {
|
||||
if (m.id == queuedMoves[0].id) {
|
||||
delta = queuedMoves[0].id - lastAckMoveId;
|
||||
mv = queuedMoves.shift();
|
||||
ackRTT = timeState.ticks - mv.timeState.ticks;
|
||||
maxMoves = ackRTT + 2;
|
||||
}
|
||||
lastAckMoveId = m;
|
||||
lastAckMoveId = m.id;
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class Net {
|
|||
public static var serverInfo:ServerInfo;
|
||||
public static var remoteServerInfo:RemoteServerInfo;
|
||||
|
||||
public static function hostServer(name:String, maxPlayers:Int, privateSlots:Int, privateServer:Bool) {
|
||||
public static function hostServer(name:String, maxPlayers:Int, privateSlots:Int, privateServer:Bool, onHosted:() -> Void) {
|
||||
serverInfo = new ServerInfo(name, 1, maxPlayers, privateSlots, privateServer, Std.int(999999 * Math.random()), "Lobby", getPlatform());
|
||||
MasterServerClient.connectToMasterServer(() -> {
|
||||
isHost = true;
|
||||
|
|
@ -87,6 +87,7 @@ class Net {
|
|||
clientId = 0;
|
||||
isMP = true;
|
||||
MasterServerClient.instance.sendServerInfo(serverInfo);
|
||||
onHosted();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ class NetCommands {
|
|||
MultiplayerLevelSelectGui.setLevelFn(i);
|
||||
}
|
||||
|
||||
@:rpc(server) public static function playLevel() {
|
||||
MultiplayerLevelSelectGui.playSelectedLevel();
|
||||
@:rpc(server) public static function playLevel(levelIndex:Int) {
|
||||
MultiplayerLevelSelectGui.playSelectedLevel(levelIndex);
|
||||
}
|
||||
|
||||
@:rpc(server) public static function setNetworkRNG(rng:Float) {
|
||||
|
|
@ -43,7 +43,7 @@ class NetCommands {
|
|||
}
|
||||
}
|
||||
if (allReady && Net.lobbyHostReady) {
|
||||
NetCommands.playLevel();
|
||||
NetCommands.playLevel(MultiplayerLevelSelectGui.currentSelectionStatic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@ class NoiseTileMaterial extends hxsl.Shader {
|
|||
};
|
||||
var calculatedUV:Vec2;
|
||||
var pixelColor:Vec4;
|
||||
var specColor:Vec3;
|
||||
var specPower:Float;
|
||||
var noiseUV:Vec2;
|
||||
@const var useAccurateNoise:Bool;
|
||||
@var var outLightVec:Vec4;
|
||||
@var var outPos:Vec3;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue