diff --git a/src/Marble.hx b/src/Marble.hx index 477ab6d0..3d9019be 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -1728,7 +1728,7 @@ class Marble extends GameObject { // MP Only Functions - public function clearNetFlags() { + public inline function clearNetFlags() { this.netFlags = 0; } diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 8755383d..5dfd3e18 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1,5 +1,7 @@ package src; +import net.NetPacket.PowerupPickupPacket; +import net.Move; import net.NetPacket.GemSpawnPacket; import net.BitStream.OutputBitStream; import net.MasterServerClient; @@ -1137,7 +1139,43 @@ class MarbleWorld extends Scheduler { packet.serialize(bs); packets.push(bs.getBytes()); + // Marble states + for (marb in this.marbles) { + var oldFlags = @:privateAccess marb.netFlags; + @:privateAccess marb.netFlags = MarbleNetFlags.DoBlast | MarbleNetFlags.DoMega | MarbleNetFlags.DoHelicopter | MarbleNetFlags.PickupPowerup | MarbleNetFlags.GravityChange; + + var innerMove = @:privateAccess marb.lastMove; + if (innerMove == null) { + innerMove = new Move(); + innerMove.d = new Vector(0, 0); + } + var motionDir = @:privateAccess marb.moveMotionDir; + if (motionDir == null) { + motionDir = marb.getMarbleAxis()[1]; + } + + var move = new NetMove(innerMove, motionDir, timeState, timeState.ticks, 65535); + + packets.push(@:privateAccess marb.packUpdate(move, timeState)); + + @:privateAccess marb.netFlags = oldFlags; + } + // Powerup states + for (powerup in this.powerUps) { + if (powerup.currentOpacity != 1.0) { // it must be picked up or something + if (@:privateAccess powerup.pickupClient != -1) { + var b = new OutputBitStream(); + b.writeByte(NetPacketType.PowerupPickup); + var pickupPacket = new PowerupPickupPacket(); + pickupPacket.clientId = @:privateAccess powerup.pickupClient; + pickupPacket.serverTicks = @:privateAccess powerup.pickupTicks; + pickupPacket.powerupItemId = powerup.netIndex; + pickupPacket.serialize(b); + packets.push(b.getBytes()); + } + } + } return packets; } @@ -1570,18 +1608,23 @@ class MarbleWorld extends Scheduler { packets.push(marble.packUpdate(myMove, fixedDt)); packets.push(othermarble.packUpdate(mv, fixedDt)); } + var allRecv = true; for (client => marble in clientMarbles) { // Oh no! // var pktClone = packets.copy(); // pktClone.sort((a, b) -> { // return (a.c == client.id) ? 1 : (b.c == client.id) ? -1 : 0; // }); - if (client.state != GAME) + if (client.state != GAME) { + allRecv = false; continue; // Only send if in game + } marble.clearNetFlags(); for (packet in packets) { client.sendBytes(packet); } } + if (allRecv) + this.marble.clearNetFlags(); } timeState.ticks++; } diff --git a/src/modes/HuntMode.hx b/src/modes/HuntMode.hx index 9c73ef4f..8d7a039c 100644 --- a/src/modes/HuntMode.hx +++ b/src/modes/HuntMode.hx @@ -223,6 +223,9 @@ class HuntMode extends NullMode { override function getRespawnTransform() { var lastContactPos = this.level.marble.lastContactPosition; + if (lastContactPos == null) { + return getSpawnTransform(); + } // Pick closest spawn point var closestSpawn:MissionElementSpawnSphere = null; var closestDistance = 1e10; diff --git a/src/shapes/PowerUp.hx b/src/shapes/PowerUp.hx index 9530f222..ecc059d9 100644 --- a/src/shapes/PowerUp.hx +++ b/src/shapes/PowerUp.hx @@ -21,6 +21,10 @@ abstract class PowerUp extends DtsObject { public var pickupSound:Sound; public var netIndex:Int; + // Net + var pickupClient:Int = -1; + var pickupTicks:Int = -1; + var customPickupMessage:String = null; public function new(element:MissionElementItem) { @@ -48,6 +52,8 @@ abstract class PowerUp extends DtsObject { pickupPacket.powerupItemId = this.netIndex; pickupPacket.serialize(b); Net.sendPacketToIngame(b); + pickupClient = pickupPacket.clientId; + pickupTicks = pickupPacket.serverTicks; } this.lastPickUpTime = timeState.currentAttemptTime; @@ -86,5 +92,7 @@ abstract class PowerUp extends DtsObject { public override function reset() { this.lastPickUpTime = Math.NEGATIVE_INFINITY; + this.pickupClient = -1; + this.pickupTicks = -1; } }