get powerups sorta working in net

This commit is contained in:
RandomityGuy 2024-01-31 23:50:00 +05:30
parent ca852396e5
commit 4484a67057
8 changed files with 135 additions and 125 deletions

View file

@ -294,6 +294,7 @@ class Marble extends GameObject {
var connection:net.Net.ClientConnection; var connection:net.Net.ClientConnection;
var moveMotionDir:Vector; var moveMotionDir:Vector;
var lastMove:Move;
var isNetUpdate:Bool = false; var isNetUpdate:Bool = false;
public function new() { public function new() {
@ -1140,16 +1141,17 @@ class Marble extends GameObject {
// var v0 = surface.points[surface.indices[i]].transformed(tform); // var v0 = surface.points[surface.indices[i]].transformed(tform);
// var v = surface.points[surface.indices[i + 1]].transformed(tform); // var v = surface.points[surface.indices[i + 1]].transformed(tform);
// var v2 = surface.points[surface.indices[i + 2]].transformed(tform); // var v2 = surface.points[surface.indices[i + 2]].transformed(tform);
var v0 = verts.v1; var v0 = new Vector(verts.v1x, verts.v1y, verts.v1z);
var v = verts.v2; var v = new Vector(verts.v2x, verts.v2y, verts.v2z);
var v2 = verts.v3; var v2 = new Vector(verts.v3x, verts.v3y, verts.v3z);
// var v0 = surface.points[surface.indices[i]].transformed(obj.transform); // var v0 = surface.points[surface.indices[i]].transformed(obj.transform);
// var v = surface.points[surface.indices[i + 1]].transformed(obj.transform); // var v = surface.points[surface.indices[i + 1]].transformed(obj.transform);
// var v2 = surface.points[surface.indices[i + 2]].transformed(obj.transform); // var v2 = surface.points[surface.indices[i + 2]].transformed(obj.transform);
var triangleVerts = [v0, v, v2]; var triangleVerts = [v0, v, v2];
var surfaceNormal = verts.n; // surface.normals[surface.indices[i]].transformed3x3(obj.transform).normalized(); var surfaceNormal = new Vector(verts.nx, verts.ny,
verts.nz); // surface.normals[surface.indices[i]].transformed3x3(obj.transform).normalized();
if (obj is DtsObject) if (obj is DtsObject)
surfaceNormal.multiply(-1); surfaceNormal.multiply(-1);
var surfaceD = -surfaceNormal.dot(v0); var surfaceD = -surfaceNormal.dot(v0);
@ -1160,10 +1162,6 @@ class Marble extends GameObject {
continue; continue;
} }
// var v0T = v0.transformed(obj.transform);
// var vT = v.transformed(obj.transform);
// var v2T = v2.transformed(obj.transform);
// var vN = surfaceNormal.transformed3x3(obj.transform);
testTriangles.push({ testTriangles.push({
v: [v0, v, v2], v: [v0, v, v2],
n: surfaceNormal, n: surfaceNormal,
@ -1175,22 +1173,6 @@ class Marble extends GameObject {
// Are we going to touch the plane during this time step? // Are we going to touch the plane during this time step?
if (collisionTime >= 0.000001 && finalT >= collisionTime) { if (collisionTime >= 0.000001 && finalT >= collisionTime) {
var collisionPoint = position.add(relVel.multiply(collisionTime)); var collisionPoint = position.add(relVel.multiply(collisionTime));
// var lastPoint = v2;
// var j = 0;
// while (j < 3) {
// var testPoint = surface.points[surface.indices[i + j]];
// if (testPoint != lastPoint) {
// var a = surfaceNormal;
// var b = lastPoint.sub(testPoint);
// var planeNorm = b.cross(a);
// var planeD = -planeNorm.dot(testPoint);
// lastPoint = testPoint;
// // if we are on the far side of the edge
// if (planeNorm.dot(collisionPoint) + planeD >= 0.0)
// break;
// }
// j++;
// }
// If we're inside the poly, just get the position // If we're inside the poly, just get the position
if (Collision.PointInTriangle(collisionPoint, v0, v, v2)) { if (Collision.PointInTriangle(collisionPoint, v0, v, v2)) {
finalT = collisionTime; finalT = collisionTime;
@ -1252,14 +1234,6 @@ class Marble extends GameObject {
// Check if the collision hasn't already happened // Check if the collision hasn't already happened
if (edgeCollisionTime >= 0.000001) { if (edgeCollisionTime >= 0.000001) {
// if (edgeCollisionTime < 0.000001) {
// edgeCollisionTime = edgeCollisionTime2;
// }
// if (edgeCollisionTime < 0.00001)
// continue;
// if (edgeCollisionTime > finalT)
// continue;
var edgeLen = vertDiff.length(); var edgeLen = vertDiff.length();
var relativeCollisionPos = position.add(relVel.multiply(edgeCollisionTime)).sub(thisVert); var relativeCollisionPos = position.add(relVel.multiply(edgeCollisionTime)).sub(thisVert);
@ -1391,18 +1365,6 @@ class Marble extends GameObject {
var finalPosition = position.add(deltaPosition); var finalPosition = position.add(deltaPosition);
position = finalPosition; position = finalPosition;
// for (testTri in testTriangles) {
// var tsi = Collision.TriangleSphereIntersection(testTri.v[0], testTri.v[1], testTri.v[2], testTri.n, finalPosition, radius, testTri.edge,
// testTri.concavity);
// if (tsi.result) {
// var contact = new CollisionInfo();
// contact.point = tsi.point;
// contact.normal = tsi.normal;
// contact.contactDistance = tsi.point.distance(position);
// finalContacts.push(contact);
// }
// }
return { return {
position: position, position: position,
t: finalT, t: finalT,
@ -1494,6 +1456,10 @@ class Marble extends GameObject {
var piTime = timeRemaining; var piTime = timeRemaining;
if (this.isNetUpdate) {
lastMove = m;
}
_bounceYet = false; _bounceYet = false;
var contactTime = 0.0; var contactTime = 0.0;
@ -1661,7 +1627,7 @@ class Marble extends GameObject {
newPos = this.collider.transform.getPosition(); newPos = this.collider.transform.getPosition();
if (this.prevPos != null && !this.isNetUpdate) { if (this.prevPos != null) {
var tempTimeState = timeState.clone(); var tempTimeState = timeState.clone();
tempTimeState.currentAttemptTime = passedTime; tempTimeState.currentAttemptTime = passedTime;
this.level.callCollisionHandlers(cast this, tempTimeState, oldPos, newPos); this.level.callCollisionHandlers(cast this, tempTimeState, oldPos, newPos);
@ -1719,7 +1685,7 @@ class Marble extends GameObject {
if (this.controllable && this.mode != Finish && !MarbleGame.instance.paused && !this.level.isWatching && !this.level.isReplayingMovement) { if (this.controllable && this.mode != Finish && !MarbleGame.instance.paused && !this.level.isWatching && !this.level.isReplayingMovement) {
if (Net.isClient) { if (Net.isClient) {
var axis = getMarbleAxis()[1]; var axis = getMarbleAxis()[1];
move = Net.clientConnection.moveManager.recordMove(axis, timeState); move = Net.clientConnection.moveManager.recordMove(this, axis, timeState);
} else if (Net.isHost) { } else if (Net.isHost) {
var axis = getMarbleAxis()[1]; var axis = getMarbleAxis()[1];
var innerMove = recordMove(); var innerMove = recordMove();
@ -1742,9 +1708,12 @@ class Marble extends GameObject {
} }
} }
if (move == null) { if (move == null) {
var axis = getMarbleAxis()[1]; var axis = moveMotionDir != null ? moveMotionDir : new Vector(0, -1, 0);
var innerMove = new Move(); var innerMove = lastMove;
if (innerMove == null) {
innerMove = new Move();
innerMove.d = new Vector(0, 0); innerMove.d = new Vector(0, 0);
}
move = new NetMove(innerMove, axis, timeState, 65535); move = new NetMove(innerMove, axis, timeState, 65535);
} }
playedSounds = []; playedSounds = [];

View file

@ -116,6 +116,7 @@ class MarbleWorld extends Scheduler {
public var interiors:Array<InteriorObject> = []; public var interiors:Array<InteriorObject> = [];
public var pathedInteriors:Array<PathedInterior> = []; public var pathedInteriors:Array<PathedInterior> = [];
public var dtsObjects:Array<DtsObject> = []; public var dtsObjects:Array<DtsObject> = [];
public var powerUps:Array<PowerUp> = [];
public var forceObjects:Array<ForceObject> = []; public var forceObjects:Array<ForceObject> = [];
public var triggers:Array<Trigger> = []; public var triggers:Array<Trigger> = [];
public var gems:Array<Gem> = []; public var gems:Array<Gem> = [];
@ -938,6 +939,8 @@ class MarbleWorld extends Scheduler {
var worker = new ResourceLoaderWorker(() -> { var worker = new ResourceLoaderWorker(() -> {
obj.idInLevel = this.dtsObjects.length; // Set the id of the thing obj.idInLevel = this.dtsObjects.length; // Set the id of the thing
this.dtsObjects.push(obj); this.dtsObjects.push(obj);
if (obj is PowerUp)
this.powerUps.push(cast obj);
if (obj is ForceObject) { if (obj is ForceObject) {
this.forceObjects.push(cast obj); this.forceObjects.push(cast obj);
} }
@ -1066,14 +1069,21 @@ class MarbleWorld extends Scheduler {
var ourQueuedMoves = @:privateAccess Net.clientConnection.moveManager.queuedMoves.copy(); var ourQueuedMoves = @:privateAccess Net.clientConnection.moveManager.queuedMoves.copy();
var advanceTimeState = timeState.clone(); var qm = ourQueuedMoves[0];
var advanceTimeState = qm != null ? qm.timeState.clone() : timeState.clone();
advanceTimeState.dt = 0.032; advanceTimeState.dt = 0.032;
ackLag = ourQueuedMoves.length; if (qm != null) {
var mvs = qm.powerupStates.copy();
if (mvStored != null) { for (pw in marble.level.powerUps) {
// trace('ACK Lag: ${timeState.ticks - mvStored.timeState.ticks} ${ourQueuedMoves.length}'); pw.lastPickUpTime = mvs.shift();
} }
@:privateAccess marble.helicopterEnableTime = qm.helicopterState;
@:privateAccess marble.megaMarbleEnableTime = qm.megaState;
marble.blastAmount = qm.blastAmt;
}
ackLag = ourQueuedMoves.length;
// Tick the remaining moves (ours) // Tick the remaining moves (ours)
if (!lastMoves.ourMoveApplied) { if (!lastMoves.ourMoveApplied) {
@ -1081,16 +1091,19 @@ class MarbleWorld extends Scheduler {
var totalTicksToDo = ourQueuedMoves.length; var totalTicksToDo = ourQueuedMoves.length;
var endTick = ourLastMoveTime + totalTicksToDo; var endTick = ourLastMoveTime + totalTicksToDo;
var currentTick = ourLastMoveTime; var currentTick = ourLastMoveTime;
//- Std.int(ourLastMove.moveQueueSize - @:privateAccess Net.clientConnection.moveManager.ackRTT); // - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT)) - offset;
var marblesToTick = new Map(); var marblesToTick = new Map();
for (client => arr in lastMoves.otherMarbleUpdates) { for (client => arr in lastMoves.otherMarbleUpdates) {
if (arr.length > 0) { if (arr.length > 0) {
var m = arr[0]; var m = arr[0];
if (m.serverTicks <= ourLastMoveTime) { if (m.serverTicks == ourLastMoveTime) {
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]]; var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius); Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
m.calculationTicks = Std.int(ackLag); m.calculationTicks = ourQueuedMoves.length; // ourQueuedMoves.length;
// - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT - ourLastMove.moveQueueSize) / 2);
marblesToTick.set(client, m); marblesToTick.set(client, m);
arr.shift(); arr.shift();
} }
@ -1098,17 +1111,20 @@ class MarbleWorld extends Scheduler {
} }
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius); Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
// var syncTickStates = new Map();
for (move in ourQueuedMoves) { for (move in ourQueuedMoves) {
var m = move.move; var m = move.move;
// Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius); // Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
this.marble.heldPowerup = move.powerup;
@:privateAccess this.marble.moveMotionDir = move.motionDir; @:privateAccess this.marble.moveMotionDir = move.motionDir;
@:privateAccess this.marble.advancePhysics(advanceTimeState, m, this.collisionWorld, this.pathedInteriors); @:privateAccess this.marble.advancePhysics(advanceTimeState, m, this.collisionWorld, this.pathedInteriors);
// var collidings = @:privateAccess this.marble.contactEntities.filter(x -> x is SphereCollisionEntity);
advanceTimeState.currentAttemptTime += 0.032;
for (client => m in marblesToTick) { for (client => m in marblesToTick) {
if (m.calculationTicks > 0) { if (m.calculationTicks > 0) {
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]]; var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
// Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius); // Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
var beforePos = @:privateAccess marbleToUpdate.newPos.clone(); var beforePos = @:privateAccess marbleToUpdate.newPos.clone();
@ -1125,20 +1141,24 @@ class MarbleWorld extends Scheduler {
currentTick++; currentTick++;
} }
for (client => m in marblesToTick) { // for (marble => state in syncTickStates) {
if (m.calculationTicks >= 0) { // marble.restoreState(state);
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]]; // }
while (m.calculationTicks > 0) { // for (client => m in marblesToTick) {
var mv = m.move.move; // if (m.calculationTicks >= 0) {
@:privateAccess marbleToUpdate.isNetUpdate = true; // var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
@:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
@:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors); // while (m.calculationTicks > 0) {
@:privateAccess marbleToUpdate.isNetUpdate = false; // var mv = m.move.move;
m.calculationTicks--; // @:privateAccess marbleToUpdate.isNetUpdate = true;
} // @:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
} // @:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
} // @:privateAccess marbleToUpdate.isNetUpdate = false;
// m.calculationTicks--;
// }
// }
// }
lastMoves.ourMoveApplied = true; lastMoves.ourMoveApplied = true;
@:privateAccess this.marble.isNetUpdate = false; @:privateAccess this.marble.isNetUpdate = false;
@ -2166,6 +2186,7 @@ class MarbleWorld extends Scheduler {
dtsObject.dispose(); dtsObject.dispose();
} }
dtsObjects = null; dtsObjects = null;
powerUps = [];
for (trigger in this.triggers) { for (trigger in this.triggers) {
trigger.dispose(); trigger.dispose();
} }

View file

@ -1,5 +1,6 @@
package net; package net;
import shapes.PowerUp;
import net.NetPacket.MarbleMovePacket; import net.NetPacket.MarbleMovePacket;
import src.TimeState; import src.TimeState;
import src.Console; import src.Console;
@ -13,6 +14,7 @@ import src.Settings;
import hxd.Key; import hxd.Key;
import src.MarbleGame; import src.MarbleGame;
import src.Util; import src.Util;
import src.Marble;
@:publicFields @:publicFields
class NetMove { class NetMove {
@ -20,6 +22,12 @@ class NetMove {
var move:Move; var move:Move;
var id:Int; var id:Int;
var timeState:TimeState; var timeState:TimeState;
// For rewind purposes
var powerup:PowerUp;
var powerupStates:Array<Float>;
var helicopterState:Float;
var megaState:Float;
var blastAmt:Float;
public function new(move:Move, motionDir:Vector, timeState:TimeState, id:Int) { public function new(move:Move, motionDir:Vector, timeState:TimeState, id:Int) {
this.move = move; this.move = move;
@ -47,7 +55,7 @@ class MoveManager {
this.connection = connection; this.connection = connection;
} }
public function recordMove(motionDir:Vector, timeState:TimeState) { public function recordMove(marble:Marble, motionDir:Vector, timeState:TimeState) {
if (queuedMoves.length >= maxMoves || stall) if (queuedMoves.length >= maxMoves || stall)
return queuedMoves[queuedMoves.length - 1]; return queuedMoves[queuedMoves.length - 1];
var move = new Move(); var move = new Move();
@ -88,6 +96,14 @@ class MoveManager {
} }
var netMove = new NetMove(move, motionDir, timeState.clone(), nextMoveId++); var netMove = new NetMove(move, motionDir, timeState.clone(), nextMoveId++);
netMove.powerup = marble.heldPowerup;
netMove.powerupStates = [];
netMove.helicopterState = @:privateAccess marble.helicopterEnableTime;
netMove.megaState = @:privateAccess marble.megaMarbleEnableTime;
netMove.blastAmt = marble.blastAmount;
for (pw in marble.level.powerUps) {
netMove.powerupStates.push(pw.lastPickUpTime);
}
queuedMoves.push(netMove); queuedMoves.push(netMove);
if (nextMoveId >= 65535) // 65535 is reserved for null move if (nextMoveId >= 65535) // 65535 is reserved for null move
@ -108,8 +124,8 @@ class MoveManager {
public static inline function packMove(m:NetMove, b:haxe.io.BytesOutput) { public static inline function packMove(m:NetMove, b:haxe.io.BytesOutput) {
b.writeUInt16(m.id); b.writeUInt16(m.id);
b.writeFloat(m.move.d.x); b.writeByte(Std.int((m.move.d.x * 16) + 16));
b.writeFloat(m.move.d.y); b.writeByte(Std.int((m.move.d.y * 16) + 16));
var flags = 0; var flags = 0;
if (m.move.jump) if (m.move.jump)
flags |= 1; flags |= 1;
@ -128,8 +144,8 @@ class MoveManager {
var moveId = b.readUInt16(); var moveId = b.readUInt16();
var move = new Move(); var move = new Move();
move.d = new Vector(); move.d = new Vector();
move.d.x = b.readFloat(); move.d.x = (b.readByte() - 16) / 16.0;
move.d.y = b.readFloat(); move.d.y = (b.readByte() - 16) / 16.0;
var flags = b.readByte(); var flags = b.readByte();
move.jump = (flags & 1) != 0; move.jump = (flags & 1) != 0;
move.powerup = (flags & 2) != 0; move.powerup = (flags & 2) != 0;

View file

@ -122,7 +122,7 @@ class Net {
public static function joinServer(connectedCb:() -> Void) { public static function joinServer(connectedCb:() -> Void) {
masterWs = new WebSocket("ws://localhost:8080"); masterWs = new WebSocket("ws://localhost:8080");
masterWs.onopen = () -> {
client = new RTCPeerConnection(["stun:stun.l.google.com:19302"], "0.0.0.0"); client = new RTCPeerConnection(["stun:stun.l.google.com:19302"], "0.0.0.0");
var candidates = []; var candidates = [];
@ -172,6 +172,7 @@ class Net {
isHost = false; isHost = false;
isClient = true; isClient = true;
} }
}
static function onClientConnect(c:RTCPeerConnection, dc:RTCDataChannel) { static function onClientConnect(c:RTCPeerConnection, dc:RTCDataChannel) {
clientId += 1; clientId += 1;

View file

@ -43,6 +43,7 @@ class MegaMarble extends PowerUp {
public function use(marble:Marble, timeState:TimeState) { public function use(marble:Marble, timeState:TimeState) {
marble.enableMegaMarble(timeState.currentAttemptTime); marble.enableMegaMarble(timeState.currentAttemptTime);
this.level.deselectPowerUp(marble); this.level.deselectPowerUp(marble);
if (this.level.marble == marble && @:privateAccess !marble.isNetUpdate)
AudioManager.playSound(ResourceLoader.getResource('data/sound/use_mega.wav', ResourceLoader.getAudio, this.soundResources)); AudioManager.playSound(ResourceLoader.getResource('data/sound/use_mega.wav', ResourceLoader.getAudio, this.soundResources));
} }

View file

@ -39,7 +39,7 @@ abstract class PowerUp extends DtsObject {
if (this.autoUse) if (this.autoUse)
this.use(marble, timeState); this.use(marble, timeState);
if (level.marble == marble) { if (level.marble == marble && @:privateAccess !marble.isNetUpdate) {
if (customPickupMessage != null) if (customPickupMessage != null)
this.level.displayAlert(customPickupMessage); this.level.displayAlert(customPickupMessage);
else else

View file

@ -71,10 +71,11 @@ class SuperJump extends PowerUp {
var masslessFactor = marble.getMass() * 0.7 + 1 - 0.7; var masslessFactor = marble.getMass() * 0.7 + 1 - 0.7;
var boost = marble.currentUp.multiply(20 * masslessFactor / marble.getMass()); var boost = marble.currentUp.multiply(20 * masslessFactor / marble.getMass());
marble.velocity = marble.velocity.add(boost); marble.velocity = marble.velocity.add(boost);
if (@:privateAccess !marble.isNetUpdate)
this.level.particleManager.createEmitter(superJumpParticleOptions, this.sjEmitterParticleData, null, () -> marble.getAbsPos().getPosition()); this.level.particleManager.createEmitter(superJumpParticleOptions, this.sjEmitterParticleData, null, () -> marble.getAbsPos().getPosition());
// marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity // marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity
// if (!this.level.rewinding) // if (!this.level.rewinding)
if (level.marble == marble) if (level.marble == marble && @:privateAccess !marble.isNetUpdate)
AudioManager.playSound(ResourceLoader.getResource("data/sound/use_superjump.wav", ResourceLoader.getAudio, this.soundResources)); AudioManager.playSound(ResourceLoader.getResource("data/sound/use_superjump.wav", ResourceLoader.getAudio, this.soundResources));
// this.level.particles.createEmitter(superJumpParticleOptions, null, () => Util.vecOimoToThree(marble.body.getPosition())); // this.level.particles.createEmitter(superJumpParticleOptions, null, () => Util.vecOimoToThree(marble.body.getPosition()));
this.level.deselectPowerUp(marble); this.level.deselectPowerUp(marble);

View file

@ -86,8 +86,9 @@ class SuperSpeed extends PowerUp {
// marble.body.addLinearVelocity(Util.vecThreeToOimo(movementVector).scale(24.7)); // Whirligig's determined value // marble.body.addLinearVelocity(Util.vecThreeToOimo(movementVector).scale(24.7)); // Whirligig's determined value
// marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity // marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity
// if (!this.level.rewinding) // if (!this.level.rewinding)
if (level.marble == marble) if (level.marble == marble && @:privateAccess !marble.isNetUpdate)
AudioManager.playSound(ResourceLoader.getResource("data/sound/use_speed.wav", ResourceLoader.getAudio, this.soundResources)); AudioManager.playSound(ResourceLoader.getResource("data/sound/use_speed.wav", ResourceLoader.getAudio, this.soundResources));
if (@:privateAccess !marble.isNetUpdate)
this.level.particleManager.createEmitter(superSpeedParticleOptions, this.ssEmitterParticleData, null, () -> marble.getAbsPos().getPosition()); this.level.particleManager.createEmitter(superSpeedParticleOptions, this.ssEmitterParticleData, null, () -> marble.getAbsPos().getPosition());
this.level.deselectPowerUp(marble); this.level.deselectPowerUp(marble);
} }