mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-27 05:01:38 +00:00
spectator mode
This commit is contained in:
parent
fb9bdc65b1
commit
723c3f34f3
7 changed files with 301 additions and 4 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package src;
|
package src;
|
||||||
|
|
||||||
|
import net.Net;
|
||||||
import mis.MisParser;
|
import mis.MisParser;
|
||||||
import h3d.col.Bounds;
|
import h3d.col.Bounds;
|
||||||
import h3d.col.Plane;
|
import h3d.col.Plane;
|
||||||
|
|
@ -28,6 +29,7 @@ import h3d.Vector;
|
||||||
import hxsl.Types.Matrix;
|
import hxsl.Types.Matrix;
|
||||||
import h3d.scene.Scene;
|
import h3d.scene.Scene;
|
||||||
import src.Gamepad;
|
import src.Gamepad;
|
||||||
|
import src.MarbleGame;
|
||||||
|
|
||||||
enum CameraMode {
|
enum CameraMode {
|
||||||
FreeOrbit;
|
FreeOrbit;
|
||||||
|
|
@ -71,6 +73,9 @@ class CameraController extends Object {
|
||||||
public var finish:Bool = false;
|
public var finish:Bool = false;
|
||||||
public var overview:Bool = false;
|
public var overview:Bool = false;
|
||||||
|
|
||||||
|
var spectate:Bool = false;
|
||||||
|
var spectateMarbleIndex:Int = -1;
|
||||||
|
|
||||||
var overviewCenter:Vector;
|
var overviewCenter:Vector;
|
||||||
var overviewWidth:Vector;
|
var overviewWidth:Vector;
|
||||||
var overviewHeight:Float;
|
var overviewHeight:Float;
|
||||||
|
|
@ -124,6 +129,14 @@ class CameraController extends Object {
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function enableSpectate() {
|
||||||
|
spectate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function stopSpectate() {
|
||||||
|
spectate = false;
|
||||||
|
}
|
||||||
|
|
||||||
public function orbit(mouseX:Float, mouseY:Float, isTouch:Bool = false) {
|
public function orbit(mouseX:Float, mouseY:Float, isTouch:Bool = false) {
|
||||||
if (_ignoreCursor) {
|
if (_ignoreCursor) {
|
||||||
_ignoreCursor = false;
|
_ignoreCursor = false;
|
||||||
|
|
@ -226,6 +239,221 @@ class CameraController extends Object {
|
||||||
camera.up.z = 1;
|
camera.up.z = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doSpectateCamera(currentTime:Float, dt:Float) {
|
||||||
|
var camera = level.scene.camera;
|
||||||
|
|
||||||
|
var lerpt = Math.pow(0.5, dt / 0.032); // Math.min(1, 1 - Math.pow(0.6, dt / 0.032)); // hxd.Math.min(1, 1 - Math.pow(0.6, dt * 600));
|
||||||
|
|
||||||
|
var cameraPitchDelta = (Key.isDown(Settings.controlsSettings.camBackward) ? 1 : 0)
|
||||||
|
- (Key.isDown(Settings.controlsSettings.camForward) ? 1 : 0)
|
||||||
|
+ Gamepad.getAxis(Settings.gamepadSettings.cameraYAxis);
|
||||||
|
if (Settings.gamepadSettings.invertYAxis)
|
||||||
|
cameraPitchDelta = -cameraPitchDelta;
|
||||||
|
nextCameraPitch += 0.75 * 5 * cameraPitchDelta * dt * Settings.gamepadSettings.cameraSensitivity;
|
||||||
|
var cameraYawDelta = (Key.isDown(Settings.controlsSettings.camRight) ? 1 : 0) - (Key.isDown(Settings.controlsSettings.camLeft) ? 1 : 0)
|
||||||
|
+ Gamepad.getAxis(Settings.gamepadSettings.cameraXAxis);
|
||||||
|
if (Settings.gamepadSettings.invertXAxis)
|
||||||
|
cameraYawDelta = -cameraYawDelta;
|
||||||
|
nextCameraYaw += 0.75 * 5 * cameraYawDelta * dt * Settings.gamepadSettings.cameraSensitivity;
|
||||||
|
|
||||||
|
nextCameraPitch = Math.max(-Math.PI / 2 + Math.PI / 4, Math.min(Math.PI / 2 - 0.0001, nextCameraPitch));
|
||||||
|
|
||||||
|
CameraYaw = Util.lerp(CameraYaw, nextCameraYaw, lerpt);
|
||||||
|
CameraPitch = Util.lerp(CameraPitch, nextCameraPitch, lerpt);
|
||||||
|
|
||||||
|
CameraPitch = Math.max(-Math.PI / 2 + Math.PI / 4, Math.min(Math.PI / 2 - 0.0001, CameraPitch)); // Util.clamp(CameraPitch, -Math.PI / 12, Math.PI / 2);
|
||||||
|
|
||||||
|
function getRotQuat(v1:Vector, v2:Vector) {
|
||||||
|
function orthogonal(v:Vector) {
|
||||||
|
var x = Math.abs(v.x);
|
||||||
|
var y = Math.abs(v.y);
|
||||||
|
var z = Math.abs(v.z);
|
||||||
|
var other = x < y ? (x < z ? new Vector(1, 0, 0) : new Vector(0, 0, 1)) : (y < z ? new Vector(0, 1, 0) : new Vector(0, 0, 1));
|
||||||
|
return v.cross(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
var u = v1.normalized();
|
||||||
|
var v = v2.normalized();
|
||||||
|
if (u.multiply(-1).equals(v)) {
|
||||||
|
var q = new Quat();
|
||||||
|
var o = orthogonal(u).normalized();
|
||||||
|
q.x = o.x;
|
||||||
|
q.y = o.y;
|
||||||
|
q.z = o.z;
|
||||||
|
q.w = 0;
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
var half = u.add(v).normalized();
|
||||||
|
var q = new Quat();
|
||||||
|
q.w = u.dot(half);
|
||||||
|
var vr = u.cross(half);
|
||||||
|
q.x = vr.x;
|
||||||
|
q.y = vr.y;
|
||||||
|
q.z = vr.z;
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
var orientationQuat = level.getOrientationQuat(currentTime);
|
||||||
|
|
||||||
|
if (spectateMarbleIndex == -1) {
|
||||||
|
var up = new Vector(0, 0, 1);
|
||||||
|
up.transform(orientationQuat.toMatrix());
|
||||||
|
var directionVector = new Vector(1, 0, 0);
|
||||||
|
|
||||||
|
var q1 = new Quat();
|
||||||
|
q1.initRotateAxis(0, 1, 0, CameraPitch);
|
||||||
|
directionVector.transform(q1.toMatrix());
|
||||||
|
q1.initRotateAxis(0, 0, 1, CameraYaw);
|
||||||
|
directionVector.transform(q1.toMatrix());
|
||||||
|
directionVector.transform(orientationQuat.toMatrix());
|
||||||
|
|
||||||
|
var dy = Gamepad.getAxis(Settings.gamepadSettings.moveYAxis) * CameraSpeed * dt;
|
||||||
|
var dx = -Gamepad.getAxis(Settings.gamepadSettings.moveXAxis) * CameraSpeed * dt;
|
||||||
|
|
||||||
|
if (Key.isDown(Settings.controlsSettings.forward)) {
|
||||||
|
dy += CameraSpeed * dt;
|
||||||
|
}
|
||||||
|
if (Key.isDown(Settings.controlsSettings.backward)) {
|
||||||
|
dy -= CameraSpeed * dt;
|
||||||
|
}
|
||||||
|
if (Key.isDown(Settings.controlsSettings.left)) {
|
||||||
|
dx += CameraSpeed * dt;
|
||||||
|
}
|
||||||
|
if (Key.isDown(Settings.controlsSettings.right)) {
|
||||||
|
dx -= CameraSpeed * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MarbleGame.instance.touchInput.movementInput.pressed) {
|
||||||
|
dx = -MarbleGame.instance.touchInput.movementInput.value.x * CameraSpeed * dt;
|
||||||
|
dy = MarbleGame.instance.touchInput.movementInput.value.y * CameraSpeed * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!Util.isTouchDevice() && Key.isDown(Settings.controlsSettings.powerup))
|
||||||
|
|| (Util.isTouchDevice() && MarbleGame.instance.touchInput.powerupButton.pressed)
|
||||||
|
|| Gamepad.isDown(Settings.gamepadSettings.powerup)) {
|
||||||
|
dx *= 2;
|
||||||
|
dy *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Key.isPressed(Settings.controlsSettings.blast)
|
||||||
|
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|
||||||
|
|| Gamepad.isPressed(Settings.gamepadSettings.blast)) {
|
||||||
|
var freeMarbleIndex = -1;
|
||||||
|
|
||||||
|
for (i in 0...level.marbles.length) {
|
||||||
|
var marble = level.marbles[i];
|
||||||
|
@:privateAccess if ((marble.connection != null && !marble.connection.spectator)) {
|
||||||
|
freeMarbleIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spectateMarbleIndex = freeMarbleIndex;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sideDir = directionVector.cross(up);
|
||||||
|
|
||||||
|
var moveDir = directionVector.multiply(dy).add(sideDir.multiply(dx));
|
||||||
|
camera.pos.load(camera.pos.add(moveDir));
|
||||||
|
|
||||||
|
camera.up = up;
|
||||||
|
camera.target = camera.pos.add(directionVector);
|
||||||
|
} else {
|
||||||
|
if (Key.isPressed(Settings.controlsSettings.left)) {
|
||||||
|
spectateMarbleIndex = (spectateMarbleIndex - 1 + level.marbles.length) % level.marbles.length;
|
||||||
|
@:privateAccess while (level.marbles[spectateMarbleIndex].connection == null
|
||||||
|
|| level.marbles[spectateMarbleIndex].connection.spectator) {
|
||||||
|
spectateMarbleIndex = (spectateMarbleIndex - 1 + level.marbles.length) % level.marbles.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Key.isPressed(Settings.controlsSettings.right)) {
|
||||||
|
spectateMarbleIndex = (spectateMarbleIndex + 1 + level.marbles.length) % level.marbles.length;
|
||||||
|
@:privateAccess while (level.marbles[spectateMarbleIndex].connection == null
|
||||||
|
|| level.marbles[spectateMarbleIndex].connection.spectator) {
|
||||||
|
spectateMarbleIndex = (spectateMarbleIndex + 1 + level.marbles.length) % level.marbles.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Key.isPressed(Settings.controlsSettings.blast)
|
||||||
|
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|
||||||
|
|| Gamepad.isPressed(Settings.gamepadSettings.blast)) {
|
||||||
|
spectateMarbleIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var marblePosition = level.marbles[spectateMarbleIndex].getAbsPos().getPosition();
|
||||||
|
var up = new Vector(0, 0, 1);
|
||||||
|
up.transform(orientationQuat.toMatrix());
|
||||||
|
var directionVector = new Vector(1, 0, 0);
|
||||||
|
var cameraVerticalTranslation = new Vector(0, 0, 0.3);
|
||||||
|
|
||||||
|
var q1 = new Quat();
|
||||||
|
q1.initRotateAxis(0, 1, 0, CameraPitch);
|
||||||
|
directionVector.transform(q1.toMatrix());
|
||||||
|
cameraVerticalTranslation.transform(q1.toMatrix());
|
||||||
|
q1.initRotateAxis(0, 0, 1, CameraYaw);
|
||||||
|
directionVector.transform(q1.toMatrix());
|
||||||
|
cameraVerticalTranslation.transform(q1.toMatrix());
|
||||||
|
directionVector.transform(orientationQuat.toMatrix());
|
||||||
|
cameraVerticalTranslation.transform(orientationQuat.toMatrix());
|
||||||
|
camera.up = up;
|
||||||
|
camera.pos = marblePosition.sub(directionVector.multiply(CameraDistance));
|
||||||
|
camera.target = marblePosition.add(cameraVerticalTranslation);
|
||||||
|
|
||||||
|
var closeness = 0.1;
|
||||||
|
var rayCastOrigin = marblePosition.add(level.marbles[spectateMarbleIndex].currentUp.multiply(marble._radius));
|
||||||
|
|
||||||
|
var processedShapes = [];
|
||||||
|
for (i in 0...3) {
|
||||||
|
var rayCastDirection = camera.pos.sub(rayCastOrigin);
|
||||||
|
rayCastDirection = rayCastDirection.add(rayCastDirection.normalized().multiply(2));
|
||||||
|
|
||||||
|
var rayCastLen = rayCastDirection.length();
|
||||||
|
|
||||||
|
var results = level.collisionWorld.rayCast(rayCastOrigin, rayCastDirection.normalized(), rayCastLen);
|
||||||
|
|
||||||
|
var firstHit:octree.IOctreeObject.RayIntersectionData = null;
|
||||||
|
var firstHitDistance = 1e8;
|
||||||
|
for (result in results) {
|
||||||
|
if (!processedShapes.contains(result.object)
|
||||||
|
&& (firstHit == null || (rayCastOrigin.distance(result.point) < firstHitDistance))) {
|
||||||
|
firstHit = result;
|
||||||
|
firstHitDistance = rayCastOrigin.distance(result.point);
|
||||||
|
processedShapes.push(result.object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstHit != null) {
|
||||||
|
if (firstHitDistance < CameraDistance) {
|
||||||
|
// camera.pos = marblePosition.sub(directionVector.multiply(firstHit.distance * 0.7));
|
||||||
|
var plane = new Plane(firstHit.normal.x, firstHit.normal.y, firstHit.normal.z, firstHit.point.dot(firstHit.normal));
|
||||||
|
var normal = firstHit.normal.multiply(-1);
|
||||||
|
// var position = firstHit.point;
|
||||||
|
|
||||||
|
var projected = plane.project(camera.pos.toPoint());
|
||||||
|
var dist = plane.distance(camera.pos.toPoint());
|
||||||
|
|
||||||
|
if (dist >= closeness)
|
||||||
|
break;
|
||||||
|
|
||||||
|
camera.pos = projected.toVector().add(normal.multiply(-closeness));
|
||||||
|
|
||||||
|
var forwardVec = marblePosition.sub(camera.pos).normalized();
|
||||||
|
var rightVec = camera.up.cross(forwardVec).normalized();
|
||||||
|
var upVec = forwardVec.cross(rightVec);
|
||||||
|
|
||||||
|
camera.target = marblePosition.add(upVec.multiply(0.3));
|
||||||
|
camera.up = upVec;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setPosition(camera.pos.x, camera.pos.y, camera.pos.z);
|
||||||
|
}
|
||||||
|
|
||||||
public function update(currentTime:Float, dt:Float) {
|
public function update(currentTime:Float, dt:Float) {
|
||||||
// camera.position.set(marblePosition.x, marblePosition.y, marblePosition.z).sub(directionVector.clone().multiplyScalar(2.5));
|
// camera.position.set(marblePosition.x, marblePosition.y, marblePosition.z).sub(directionVector.clone().multiplyScalar(2.5));
|
||||||
// this.level.scene.camera.target = marblePosition.add(cameraVerticalTranslation);
|
// this.level.scene.camera.target = marblePosition.add(cameraVerticalTranslation);
|
||||||
|
|
@ -236,6 +464,11 @@ class CameraController extends Object {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (spectate) {
|
||||||
|
doSpectateCamera(currentTime, dt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var camera = level.scene.camera;
|
var camera = level.scene.camera;
|
||||||
|
|
||||||
var lerpt = hxd.Math.min(1, 1 - Math.pow(0.6, dt * 600));
|
var lerpt = hxd.Math.min(1, 1 - Math.pow(0.6, dt * 600));
|
||||||
|
|
|
||||||
|
|
@ -1641,6 +1641,16 @@ class Marble extends GameObject {
|
||||||
oldPos = this.collider.transform.getPosition();
|
oldPos = this.collider.transform.getPosition();
|
||||||
prevRot = this.getRotationQuat().clone();
|
prevRot = this.getRotationQuat().clone();
|
||||||
|
|
||||||
|
// Handle spectator hacky bullshit
|
||||||
|
if (Net.isMP) {
|
||||||
|
if ((connection != null && connection.spectator) || (connection == null && (Net.hostSpectate || Net.clientSpectate))) {
|
||||||
|
this.collider.transform.setPosition(new Vector(1e8, 1e8, 1e8));
|
||||||
|
this.collisionWorld.updateTransform(this.collider);
|
||||||
|
this.setPosition(1e8, 1e8, 1e8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if (this.controllable) {
|
// if (this.controllable) {
|
||||||
for (interior in pathedInteriors) {
|
for (interior in pathedInteriors) {
|
||||||
if (Net.isMP)
|
if (Net.isMP)
|
||||||
|
|
|
||||||
|
|
@ -540,6 +540,7 @@ class MarbleWorld extends Scheduler {
|
||||||
public function start() {
|
public function start() {
|
||||||
Console.log("LEVEL START");
|
Console.log("LEVEL START");
|
||||||
restart(this.marble, true);
|
restart(this.marble, true);
|
||||||
|
|
||||||
for (interior in this.interiors)
|
for (interior in this.interiors)
|
||||||
interior.onLevelStart();
|
interior.onLevelStart();
|
||||||
for (shape in this.dtsObjects)
|
for (shape in this.dtsObjects)
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,11 @@ class MPPreGameDlg extends GuiControl {
|
||||||
spectateBtn.vertSizing = Top;
|
spectateBtn.vertSizing = Top;
|
||||||
spectateBtn.position = new Vector(190, 394);
|
spectateBtn.position = new Vector(190, 394);
|
||||||
spectateBtn.extent = new Vector(127, 33);
|
spectateBtn.extent = new Vector(127, 33);
|
||||||
|
spectateBtn.buttonType = Toggle;
|
||||||
|
spectateBtn.pressedAction = (e) -> {
|
||||||
|
NetCommands.toggleSpectate(Net.isHost ? 0 : Net.clientId);
|
||||||
|
updatePlayerList();
|
||||||
|
}
|
||||||
dialogImg.addChild(spectateBtn);
|
dialogImg.addChild(spectateBtn);
|
||||||
|
|
||||||
var serverTitle = new GuiText(markerFelt24);
|
var serverTitle = new GuiText(markerFelt24);
|
||||||
|
|
@ -223,20 +228,23 @@ class MPPreGameDlg extends GuiControl {
|
||||||
if (Net.isHost) {
|
if (Net.isHost) {
|
||||||
playerListArr.push({
|
playerListArr.push({
|
||||||
name: Settings.highscoreName,
|
name: Settings.highscoreName,
|
||||||
ready: Net.lobbyHostReady
|
ready: Net.lobbyHostReady,
|
||||||
|
spectate: Net.hostSpectate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (Net.isClient) {
|
if (Net.isClient) {
|
||||||
playerListArr.push({
|
playerListArr.push({
|
||||||
name: Settings.highscoreName,
|
name: Settings.highscoreName,
|
||||||
ready: Net.lobbyClientReady
|
ready: Net.lobbyClientReady,
|
||||||
|
spectate: Net.clientSpectate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (Net.clientIdMap != null) {
|
if (Net.clientIdMap != null) {
|
||||||
for (c => v in Net.clientIdMap) {
|
for (c => v in Net.clientIdMap) {
|
||||||
playerListArr.push({
|
playerListArr.push({
|
||||||
name: v.name,
|
name: v.name,
|
||||||
ready: v.lobbyReady
|
ready: v.lobbyReady,
|
||||||
|
spectate: v.spectator
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +257,7 @@ class MPPreGameDlg extends GuiControl {
|
||||||
|
|
||||||
playBtn.disabled = !allReady;
|
playBtn.disabled = !allReady;
|
||||||
|
|
||||||
var playerListCompiled = playerListArr.map(player -> player.name);
|
var playerListCompiled = playerListArr.map(player -> player.spectate ? '[S] ${player.name}' : player.name);
|
||||||
var playerListStateCompiled = playerListArr.map(player -> player.ready ? "[Ready]" : "[Waiting]");
|
var playerListStateCompiled = playerListArr.map(player -> player.ready ? "[Ready]" : "[Waiting]");
|
||||||
playerListLeft.setTexts(playerListCompiled);
|
playerListLeft.setTexts(playerListCompiled);
|
||||||
playerListRight.setTexts(playerListStateCompiled);
|
playerListRight.setTexts(playerListStateCompiled);
|
||||||
|
|
@ -268,7 +276,9 @@ class MPPreGameDlg extends GuiControl {
|
||||||
// Make everyone un-lobby ready (again!)
|
// Make everyone un-lobby ready (again!)
|
||||||
for (c in Net.clients) {
|
for (c in Net.clients) {
|
||||||
c.lobbyReady = false;
|
c.lobbyReady = false;
|
||||||
|
c.spectator = false;
|
||||||
}
|
}
|
||||||
|
Net.hostSpectate = false;
|
||||||
Net.lobbyClientReady = false;
|
Net.lobbyClientReady = false;
|
||||||
Net.lobbyHostReady = false;
|
Net.lobbyHostReady = false;
|
||||||
if (Net.isHost) {
|
if (Net.isHost) {
|
||||||
|
|
|
||||||
|
|
@ -77,11 +77,13 @@ abstract class GameConnection {
|
||||||
var platform:NetPlatform;
|
var platform:NetPlatform;
|
||||||
var marbleId:Int;
|
var marbleId:Int;
|
||||||
var marbleCatId:Int;
|
var marbleCatId:Int;
|
||||||
|
var spectator:Bool;
|
||||||
|
|
||||||
function new(id:Int) {
|
function new(id:Int) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.moveManager = new MoveManager(this);
|
this.moveManager = new MoveManager(this);
|
||||||
this.lobbyReady = false;
|
this.lobbyReady = false;
|
||||||
|
this.spectator = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ready() {
|
public function ready() {
|
||||||
|
|
@ -92,6 +94,10 @@ abstract class GameConnection {
|
||||||
lobbyReady = !lobbyReady;
|
lobbyReady = !lobbyReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function toggleSpectate() {
|
||||||
|
spectator = !spectator;
|
||||||
|
}
|
||||||
|
|
||||||
public function queueMove(m:NetMove) {
|
public function queueMove(m:NetMove) {
|
||||||
moveManager.queueMove(m);
|
moveManager.queueMove(m);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,8 @@ class Net {
|
||||||
public static var lobbyHostReady:Bool;
|
public static var lobbyHostReady:Bool;
|
||||||
public static var lobbyClientReady:Bool;
|
public static var lobbyClientReady:Bool;
|
||||||
public static var hostReady:Bool;
|
public static var hostReady:Bool;
|
||||||
|
public static var hostSpectate:Bool;
|
||||||
|
public static var clientSpectate:Bool;
|
||||||
|
|
||||||
static var clientIdAllocs:Int = 1;
|
static var clientIdAllocs:Int = 1;
|
||||||
public static var clientId:Int;
|
public static var clientId:Int;
|
||||||
|
|
@ -373,6 +375,8 @@ class Net {
|
||||||
Net.lobbyHostReady = false;
|
Net.lobbyHostReady = false;
|
||||||
Net.lobbyClientReady = false;
|
Net.lobbyClientReady = false;
|
||||||
Net.hostReady = false;
|
Net.hostReady = false;
|
||||||
|
Net.hostSpectate = false;
|
||||||
|
Net.clientSpectate = false;
|
||||||
// MultiplayerLevelSelectGui.custSelected = false;
|
// MultiplayerLevelSelectGui.custSelected = false;
|
||||||
}
|
}
|
||||||
if (Net.isHost) {
|
if (Net.isHost) {
|
||||||
|
|
@ -394,6 +398,8 @@ class Net {
|
||||||
Net.lobbyHostReady = false;
|
Net.lobbyHostReady = false;
|
||||||
Net.lobbyClientReady = false;
|
Net.lobbyClientReady = false;
|
||||||
Net.hostReady = false;
|
Net.hostReady = false;
|
||||||
|
Net.hostSpectate = false;
|
||||||
|
Net.clientSpectate = false;
|
||||||
// MultiplayerLevelSelectGui.custSelected = false;
|
// MultiplayerLevelSelectGui.custSelected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -629,6 +635,7 @@ class Net {
|
||||||
b.writeByte(v.platform);
|
b.writeByte(v.platform);
|
||||||
b.writeByte(v.marbleId);
|
b.writeByte(v.marbleId);
|
||||||
b.writeByte(v.marbleCatId);
|
b.writeByte(v.marbleCatId);
|
||||||
|
b.writeByte(v.spectator ? 1 : 0);
|
||||||
var name = v.getName();
|
var name = v.getName();
|
||||||
b.writeByte(name.length);
|
b.writeByte(name.length);
|
||||||
for (i in 0...name.length) {
|
for (i in 0...name.length) {
|
||||||
|
|
@ -641,6 +648,7 @@ class Net {
|
||||||
b.writeByte(getPlatform());
|
b.writeByte(getPlatform());
|
||||||
b.writeByte(Settings.optionsSettings.marbleIndex);
|
b.writeByte(Settings.optionsSettings.marbleIndex);
|
||||||
b.writeByte(Settings.optionsSettings.marbleCategoryIndex);
|
b.writeByte(Settings.optionsSettings.marbleCategoryIndex);
|
||||||
|
b.writeByte(Net.hostSpectate ? 1 : 0);
|
||||||
var name = Settings.highscoreName;
|
var name = Settings.highscoreName;
|
||||||
b.writeByte(name.length);
|
b.writeByte(name.length);
|
||||||
for (i in 0...name.length) {
|
for (i in 0...name.length) {
|
||||||
|
|
@ -752,6 +760,7 @@ class Net {
|
||||||
var platform = input.readByte();
|
var platform = input.readByte();
|
||||||
var marble = input.readByte();
|
var marble = input.readByte();
|
||||||
var marbleCat = input.readByte();
|
var marbleCat = input.readByte();
|
||||||
|
var cspectator = input.readByte() == 1;
|
||||||
if (id != 0 && id != Net.clientId && !clientIdMap.exists(id)) {
|
if (id != 0 && id != Net.clientId && !clientIdMap.exists(id)) {
|
||||||
Console.log('Adding ghost connection ${id}');
|
Console.log('Adding ghost connection ${id}');
|
||||||
addGhost(id);
|
addGhost(id);
|
||||||
|
|
@ -767,9 +776,11 @@ class Net {
|
||||||
clientIdMap[id].setMarbleId(marble, marbleCat);
|
clientIdMap[id].setMarbleId(marble, marbleCat);
|
||||||
clientIdMap[id].lobbyReady = cready;
|
clientIdMap[id].lobbyReady = cready;
|
||||||
clientIdMap[id].platform = platform;
|
clientIdMap[id].platform = platform;
|
||||||
|
clientIdMap[id].spectator = cspectator;
|
||||||
}
|
}
|
||||||
if (Net.clientId == id) {
|
if (Net.clientId == id) {
|
||||||
Net.lobbyClientReady = cready;
|
Net.lobbyClientReady = cready;
|
||||||
|
Net.clientSpectate = cspectator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MarbleGame.canvas.content is MPPlayMissionGui) {
|
if (MarbleGame.canvas.content is MPPlayMissionGui) {
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,26 @@ class NetCommands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@:rpc(client) public static function toggleSpectate(clientId:Int) {
|
||||||
|
if (Net.isHost) {
|
||||||
|
if (clientId == 0)
|
||||||
|
Net.hostSpectate = !Net.hostSpectate;
|
||||||
|
else
|
||||||
|
Net.clientIdMap[clientId].toggleSpectate();
|
||||||
|
|
||||||
|
if (MarbleGame.canvas.content is MPPlayMissionGui) {
|
||||||
|
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
|
||||||
|
}
|
||||||
|
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
|
||||||
|
cast(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1], MPPreGameDlg).updatePlayerList();
|
||||||
|
}
|
||||||
|
var b = Net.sendPlayerInfosBytes();
|
||||||
|
for (cc in Net.clients) {
|
||||||
|
cc.sendBytes(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@:rpc(client) public static function clientIsReady(clientId:Int) {
|
@:rpc(client) public static function clientIsReady(clientId:Int) {
|
||||||
if (Net.isHost) {
|
if (Net.isHost) {
|
||||||
if (Net.serverInfo.state == "WAITING") {
|
if (Net.serverInfo.state == "WAITING") {
|
||||||
|
|
@ -214,6 +234,12 @@ class NetCommands {
|
||||||
MarbleGame.instance.world.setCursorLock(true);
|
MarbleGame.instance.world.setCursorLock(true);
|
||||||
MarbleGame.instance.world.marble.camera.stopOverview();
|
MarbleGame.instance.world.marble.camera.stopOverview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Net.clientSpectate || Net.hostSpectate) {
|
||||||
|
MarbleGame.instance.world.marble.camera.enableSpectate();
|
||||||
|
} else {
|
||||||
|
MarbleGame.instance.world.marble.camera.stopSpectate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue