mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
207 lines
5.3 KiB
Haxe
207 lines
5.3 KiB
Haxe
package net;
|
|
|
|
import net.BitStream.OutputBitStream;
|
|
import net.BitStream.InputBitStream;
|
|
import net.NetPacket.MarbleUpdatePacket;
|
|
import shapes.PowerUp;
|
|
import net.NetPacket.MarbleMovePacket;
|
|
import src.TimeState;
|
|
import src.Console;
|
|
import net.ClientConnection;
|
|
import net.Net.NetPacketType;
|
|
import src.MarbleWorld;
|
|
import net.Move;
|
|
import h3d.Vector;
|
|
import src.Gamepad;
|
|
import src.Settings;
|
|
import hxd.Key;
|
|
import src.MarbleGame;
|
|
import src.Util;
|
|
import src.Marble;
|
|
|
|
@:publicFields
|
|
class NetMove {
|
|
var motionDir:Vector;
|
|
var move:Move;
|
|
var id:Int;
|
|
var timeState:TimeState;
|
|
|
|
public function new(move:Move, motionDir:Vector, timeState:TimeState, id:Int) {
|
|
this.move = move;
|
|
this.motionDir = motionDir;
|
|
this.id = id;
|
|
this.timeState = timeState;
|
|
}
|
|
}
|
|
|
|
class MoveManager {
|
|
var connection:GameConnection;
|
|
var queuedMoves:Array<NetMove>;
|
|
var nextMoveId:Int;
|
|
var lastMove:NetMove;
|
|
var lastAckMoveId:Int = -1;
|
|
var ackRTT:Int = -1;
|
|
|
|
var maxMoves = 45;
|
|
|
|
public var stall = false;
|
|
|
|
public function new(connection:GameConnection) {
|
|
queuedMoves = [];
|
|
nextMoveId = 0;
|
|
this.connection = connection;
|
|
var mv = new Move();
|
|
mv.d = new Vector(0, 0);
|
|
}
|
|
|
|
public function recordMove(marble:Marble, motionDir:Vector, timeState:TimeState) {
|
|
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);
|
|
move.d.y = -Gamepad.getAxis(Settings.gamepadSettings.moveXAxis);
|
|
if (Key.isDown(Settings.controlsSettings.forward)) {
|
|
move.d.x -= 1;
|
|
}
|
|
if (Key.isDown(Settings.controlsSettings.backward)) {
|
|
move.d.x += 1;
|
|
}
|
|
if (Key.isDown(Settings.controlsSettings.left)) {
|
|
move.d.y += 1;
|
|
}
|
|
if (Key.isDown(Settings.controlsSettings.right)) {
|
|
move.d.y -= 1;
|
|
}
|
|
if (Key.isDown(Settings.controlsSettings.jump)
|
|
|| MarbleGame.instance.touchInput.jumpButton.pressed
|
|
|| Gamepad.isDown(Settings.gamepadSettings.jump)) {
|
|
move.jump = true;
|
|
}
|
|
if ((!Util.isTouchDevice() && Key.isDown(Settings.controlsSettings.powerup))
|
|
|| (Util.isTouchDevice() && MarbleGame.instance.touchInput.powerupButton.pressed)
|
|
|| Gamepad.isDown(Settings.gamepadSettings.powerup)) {
|
|
move.powerup = true;
|
|
}
|
|
|
|
if (Key.isDown(Settings.controlsSettings.blast)
|
|
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|
|
|| Gamepad.isDown(Settings.gamepadSettings.blast))
|
|
move.blast = true;
|
|
|
|
if (MarbleGame.instance.touchInput.movementInput.pressed) {
|
|
move.d.y = -MarbleGame.instance.touchInput.movementInput.value.x;
|
|
move.d.x = MarbleGame.instance.touchInput.movementInput.value.y;
|
|
}
|
|
|
|
var netMove = new NetMove(move, motionDir, timeState.clone(), nextMoveId++);
|
|
queuedMoves.push(netMove);
|
|
|
|
if (nextMoveId >= 65535) // 65535 is reserved for null move
|
|
nextMoveId = 0;
|
|
|
|
var b = new OutputBitStream();
|
|
var movePacket = new MarbleMovePacket();
|
|
movePacket.clientId = Net.clientId;
|
|
movePacket.move = netMove;
|
|
movePacket.clientTicks = timeState.ticks;
|
|
b.writeByte(NetPacketType.MarbleMove);
|
|
movePacket.serialize(b);
|
|
|
|
Net.sendPacketToHost(b);
|
|
|
|
return netMove;
|
|
}
|
|
|
|
public static inline function packMove(m:NetMove, b:OutputBitStream) {
|
|
b.writeUInt16(m.id);
|
|
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;
|
|
if (m.move.powerup)
|
|
flags |= 2;
|
|
if (m.move.blast)
|
|
flags |= 4;
|
|
b.writeByte(flags);
|
|
b.writeFloat(m.motionDir.x);
|
|
b.writeFloat(m.motionDir.y);
|
|
b.writeFloat(m.motionDir.z);
|
|
return b;
|
|
}
|
|
|
|
public static inline function unpackMove(b:InputBitStream) {
|
|
var moveId = b.readUInt16();
|
|
var move = new Move();
|
|
move.d = new Vector();
|
|
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;
|
|
move.blast = (flags & 4) != 0;
|
|
var motionDir = new Vector();
|
|
motionDir.x = b.readFloat();
|
|
motionDir.y = b.readFloat();
|
|
motionDir.z = b.readFloat();
|
|
var netMove = new NetMove(move, motionDir, MarbleGame.instance.world.timeState.clone(), moveId);
|
|
return netMove;
|
|
}
|
|
|
|
public inline function queueMove(m:NetMove) {
|
|
queuedMoves.push(m);
|
|
}
|
|
|
|
public function getNextMove() {
|
|
if (queuedMoves.length == 0)
|
|
return lastMove;
|
|
else {
|
|
lastMove = queuedMoves[0];
|
|
queuedMoves.shift();
|
|
return lastMove;
|
|
}
|
|
}
|
|
|
|
public inline function getQueueSize() {
|
|
return queuedMoves.length;
|
|
}
|
|
|
|
public function acknowledgeMove(m:Int, timeState:TimeState) {
|
|
if (m == 65535 || m == -1)
|
|
return null;
|
|
if (m <= lastAckMoveId)
|
|
return null; // Already acked
|
|
if (queuedMoves.length == 0)
|
|
return null;
|
|
while (m != queuedMoves[0].id) {
|
|
queuedMoves.shift();
|
|
}
|
|
var delta = -1;
|
|
var mv = null;
|
|
if (m == queuedMoves[0].id) {
|
|
delta = queuedMoves[0].id - lastAckMoveId;
|
|
mv = queuedMoves.shift();
|
|
ackRTT = timeState.ticks - mv.timeState.ticks;
|
|
maxMoves = ackRTT + 2;
|
|
}
|
|
lastAckMoveId = m;
|
|
return mv;
|
|
}
|
|
|
|
public function getMoveForTick(m:Int) {
|
|
if (m <= lastAckMoveId)
|
|
return null;
|
|
if (m == 65535 || m == -1)
|
|
return null;
|
|
if (queuedMoves.length == 0)
|
|
return null;
|
|
for (i in 0...queuedMoves.length) {
|
|
if (queuedMoves[i].id == m)
|
|
return queuedMoves[i];
|
|
if (queuedMoves[i].id > m)
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
}
|