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 moveMotionDir:Vector;
var lastMove:Move;
var isNetUpdate:Bool = false;
public function new() {
@ -1140,16 +1141,17 @@ class Marble extends GameObject {
// var v0 = surface.points[surface.indices[i]].transformed(tform);
// var v = surface.points[surface.indices[i + 1]].transformed(tform);
// var v2 = surface.points[surface.indices[i + 2]].transformed(tform);
var v0 = verts.v1;
var v = verts.v2;
var v2 = verts.v3;
var v0 = new Vector(verts.v1x, verts.v1y, verts.v1z);
var v = new Vector(verts.v2x, verts.v2y, verts.v2z);
var v2 = new Vector(verts.v3x, verts.v3y, verts.v3z);
// var v0 = surface.points[surface.indices[i]].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 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)
surfaceNormal.multiply(-1);
var surfaceD = -surfaceNormal.dot(v0);
@ -1160,10 +1162,6 @@ class Marble extends GameObject {
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({
v: [v0, v, v2],
n: surfaceNormal,
@ -1175,22 +1173,6 @@ class Marble extends GameObject {
// Are we going to touch the plane during this time step?
if (collisionTime >= 0.000001 && finalT >= 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 (Collision.PointInTriangle(collisionPoint, v0, v, v2)) {
finalT = collisionTime;
@ -1252,14 +1234,6 @@ class Marble extends GameObject {
// Check if the collision hasn't already happened
if (edgeCollisionTime >= 0.000001) {
// if (edgeCollisionTime < 0.000001) {
// edgeCollisionTime = edgeCollisionTime2;
// }
// if (edgeCollisionTime < 0.00001)
// continue;
// if (edgeCollisionTime > finalT)
// continue;
var edgeLen = vertDiff.length();
var relativeCollisionPos = position.add(relVel.multiply(edgeCollisionTime)).sub(thisVert);
@ -1391,18 +1365,6 @@ class Marble extends GameObject {
var finalPosition = position.add(deltaPosition);
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 {
position: position,
t: finalT,
@ -1494,6 +1456,10 @@ class Marble extends GameObject {
var piTime = timeRemaining;
if (this.isNetUpdate) {
lastMove = m;
}
_bounceYet = false;
var contactTime = 0.0;
@ -1661,7 +1627,7 @@ class Marble extends GameObject {
newPos = this.collider.transform.getPosition();
if (this.prevPos != null && !this.isNetUpdate) {
if (this.prevPos != null) {
var tempTimeState = timeState.clone();
tempTimeState.currentAttemptTime = passedTime;
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 (Net.isClient) {
var axis = getMarbleAxis()[1];
move = Net.clientConnection.moveManager.recordMove(axis, timeState);
move = Net.clientConnection.moveManager.recordMove(this, axis, timeState);
} else if (Net.isHost) {
var axis = getMarbleAxis()[1];
var innerMove = recordMove();
@ -1742,9 +1708,12 @@ class Marble extends GameObject {
}
}
if (move == null) {
var axis = getMarbleAxis()[1];
var innerMove = new Move();
innerMove.d = new Vector(0, 0);
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);
}
playedSounds = [];

View file

@ -116,6 +116,7 @@ class MarbleWorld extends Scheduler {
public var interiors:Array<InteriorObject> = [];
public var pathedInteriors:Array<PathedInterior> = [];
public var dtsObjects:Array<DtsObject> = [];
public var powerUps:Array<PowerUp> = [];
public var forceObjects:Array<ForceObject> = [];
public var triggers:Array<Trigger> = [];
public var gems:Array<Gem> = [];
@ -938,6 +939,8 @@ class MarbleWorld extends Scheduler {
var worker = new ResourceLoaderWorker(() -> {
obj.idInLevel = this.dtsObjects.length; // Set the id of the thing
this.dtsObjects.push(obj);
if (obj is PowerUp)
this.powerUps.push(cast obj);
if (obj is ForceObject) {
this.forceObjects.push(cast obj);
}
@ -1066,31 +1069,41 @@ class MarbleWorld extends Scheduler {
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;
ackLag = ourQueuedMoves.length;
if (mvStored != null) {
// trace('ACK Lag: ${timeState.ticks - mvStored.timeState.ticks} ${ourQueuedMoves.length}');
if (qm != null) {
var mvs = qm.powerupStates.copy();
for (pw in marble.level.powerUps) {
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)
if (!lastMoves.ourMoveApplied) {
@:privateAccess this.marble.isNetUpdate = true;
var totalTicksToDo = ourQueuedMoves.length;
var endTick = ourLastMoveTime + totalTicksToDo;
var currentTick = ourLastMoveTime;
//- Std.int(ourLastMove.moveQueueSize - @:privateAccess Net.clientConnection.moveManager.ackRTT); // - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT)) - offset;
var marblesToTick = new Map();
for (client => arr in lastMoves.otherMarbleUpdates) {
if (arr.length > 0) {
var m = arr[0];
if (m.serverTicks <= ourLastMoveTime) {
if (m.serverTicks == ourLastMoveTime) {
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
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);
arr.shift();
}
@ -1098,17 +1111,20 @@ class MarbleWorld extends Scheduler {
}
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
// var syncTickStates = new Map();
for (move in ourQueuedMoves) {
var m = move.move;
// Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
this.marble.heldPowerup = move.powerup;
@:privateAccess this.marble.moveMotionDir = move.motionDir;
@: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) {
if (m.calculationTicks > 0) {
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
// Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
var beforePos = @:privateAccess marbleToUpdate.newPos.clone();
@ -1125,20 +1141,24 @@ class MarbleWorld extends Scheduler {
currentTick++;
}
for (client => m in marblesToTick) {
if (m.calculationTicks >= 0) {
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
// for (marble => state in syncTickStates) {
// marble.restoreState(state);
// }
while (m.calculationTicks > 0) {
var mv = m.move.move;
@: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--;
}
}
}
// for (client => m in marblesToTick) {
// if (m.calculationTicks >= 0) {
// var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
// while (m.calculationTicks > 0) {
// var mv = m.move.move;
// @: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;
@:privateAccess this.marble.isNetUpdate = false;
@ -2166,6 +2186,7 @@ class MarbleWorld extends Scheduler {
dtsObject.dispose();
}
dtsObjects = null;
powerUps = [];
for (trigger in this.triggers) {
trigger.dispose();
}

View file

@ -1,5 +1,6 @@
package net;
import shapes.PowerUp;
import net.NetPacket.MarbleMovePacket;
import src.TimeState;
import src.Console;
@ -13,6 +14,7 @@ import src.Settings;
import hxd.Key;
import src.MarbleGame;
import src.Util;
import src.Marble;
@:publicFields
class NetMove {
@ -20,6 +22,12 @@ class NetMove {
var move:Move;
var id:Int;
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) {
this.move = move;
@ -47,7 +55,7 @@ class MoveManager {
this.connection = connection;
}
public function recordMove(motionDir:Vector, timeState:TimeState) {
public function recordMove(marble:Marble, motionDir:Vector, timeState:TimeState) {
if (queuedMoves.length >= maxMoves || stall)
return queuedMoves[queuedMoves.length - 1];
var move = new Move();
@ -88,6 +96,14 @@ class MoveManager {
}
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);
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) {
b.writeUInt16(m.id);
b.writeFloat(m.move.d.x);
b.writeFloat(m.move.d.y);
b.writeByte(Std.int((m.move.d.x * 16) + 16));
b.writeByte(Std.int((m.move.d.y * 16) + 16));
var flags = 0;
if (m.move.jump)
flags |= 1;
@ -128,8 +144,8 @@ class MoveManager {
var moveId = b.readUInt16();
var move = new Move();
move.d = new Vector();
move.d.x = b.readFloat();
move.d.y = b.readFloat();
move.d.x = (b.readByte() - 16) / 16.0;
move.d.y = (b.readByte() - 16) / 16.0;
var flags = b.readByte();
move.jump = (flags & 1) != 0;
move.powerup = (flags & 2) != 0;

View file

@ -122,55 +122,56 @@ class Net {
public static function joinServer(connectedCb:() -> Void) {
masterWs = new WebSocket("ws://localhost:8080");
masterWs.onopen = () -> {
client = new RTCPeerConnection(["stun:stun.l.google.com:19302"], "0.0.0.0");
var candidates = [];
client = new RTCPeerConnection(["stun:stun.l.google.com:19302"], "0.0.0.0");
var candidates = [];
client.onLocalCandidate = (c) -> {
if (c != "")
candidates.push('a=${c}');
}
client.onGatheringStateChange = (s) -> {
if (s == RTC_GATHERING_COMPLETE) {
Console.log("Local Description Set!");
var sdpObj = StringTools.trim(client.localDescription);
sdpObj = sdpObj + '\r\n' + candidates.join('\r\n');
masterWs.send(Json.stringify({
type: "connect",
sdpObj: {
sdp: sdpObj,
type: "offer"
}
}));
client.onLocalCandidate = (c) -> {
if (c != "")
candidates.push('a=${c}');
}
}
masterWs.onmessage = (m) -> {
switch (m) {
case StrMessage(content):
Console.log("Remote Description Received!");
var conts = Json.parse(content);
client.setRemoteDescription(conts.sdp, conts.type);
case _: {}
client.onGatheringStateChange = (s) -> {
if (s == RTC_GATHERING_COMPLETE) {
Console.log("Local Description Set!");
var sdpObj = StringTools.trim(client.localDescription);
sdpObj = sdpObj + '\r\n' + candidates.join('\r\n');
masterWs.send(Json.stringify({
type: "connect",
sdpObj: {
sdp: sdpObj,
type: "offer"
}
}));
}
}
}
clientDatachannel = client.createDatachannel("mp");
clientDatachannel.onOpen = (n) -> {
Console.log("Successfully connected!");
clients.set(client, new ClientConnection(0, client, clientDatachannel)); // host is always 0
clientIdMap[0] = clients[client];
clientConnection = clients[client];
onConnectedToServer();
haxe.Timer.delay(() -> connectedCb(), 1500); // 1.5 second delay to do the RTT calculation
}
clientDatachannel.onMessage = (b) -> {
onPacketReceived(client, clientDatachannel, new haxe.io.BytesInput(b));
}
masterWs.onmessage = (m) -> {
switch (m) {
case StrMessage(content):
Console.log("Remote Description Received!");
var conts = Json.parse(content);
client.setRemoteDescription(conts.sdp, conts.type);
case _: {}
}
}
isMP = true;
isHost = false;
isClient = true;
clientDatachannel = client.createDatachannel("mp");
clientDatachannel.onOpen = (n) -> {
Console.log("Successfully connected!");
clients.set(client, new ClientConnection(0, client, clientDatachannel)); // host is always 0
clientIdMap[0] = clients[client];
clientConnection = clients[client];
onConnectedToServer();
haxe.Timer.delay(() -> connectedCb(), 1500); // 1.5 second delay to do the RTT calculation
}
clientDatachannel.onMessage = (b) -> {
onPacketReceived(client, clientDatachannel, new haxe.io.BytesInput(b));
}
isMP = true;
isHost = false;
isClient = true;
}
}
static function onClientConnect(c:RTCPeerConnection, dc:RTCDataChannel) {

View file

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

View file

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

View file

@ -71,10 +71,11 @@ class SuperJump extends PowerUp {
var masslessFactor = marble.getMass() * 0.7 + 1 - 0.7;
var boost = marble.currentUp.multiply(20 * masslessFactor / marble.getMass());
marble.velocity = marble.velocity.add(boost);
this.level.particleManager.createEmitter(superJumpParticleOptions, this.sjEmitterParticleData, null, () -> marble.getAbsPos().getPosition());
if (@:privateAccess !marble.isNetUpdate)
this.level.particleManager.createEmitter(superJumpParticleOptions, this.sjEmitterParticleData, null, () -> marble.getAbsPos().getPosition());
// marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity
// 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));
// this.level.particles.createEmitter(superJumpParticleOptions, null, () => Util.vecOimoToThree(marble.body.getPosition()));
this.level.deselectPowerUp(marble);

View file

@ -86,9 +86,10 @@ class SuperSpeed extends PowerUp {
// 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
// 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));
this.level.particleManager.createEmitter(superSpeedParticleOptions, this.ssEmitterParticleData, null, () -> marble.getAbsPos().getPosition());
if (@:privateAccess !marble.isNetUpdate)
this.level.particleManager.createEmitter(superSpeedParticleOptions, this.ssEmitterParticleData, null, () -> marble.getAbsPos().getPosition());
this.level.deselectPowerUp(marble);
}