78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import { System } from "$/common/ecs/mod.ts";
|
|
import { Position } from "$/common/components/position.ts";
|
|
import { ClientWorld } from "../client_world.ts";
|
|
import { Camera } from "../components/camera.ts";
|
|
|
|
const MOVE_SEND_INTERVAL = 1 / 10;
|
|
const REMOTE_PLAYER_SMOOTHING = 12;
|
|
|
|
export class NetworkSystem extends System {
|
|
move_timer = 0;
|
|
|
|
update(world: ClientWorld, delta: number): void {
|
|
const connection = world.connection;
|
|
if (!connection) {
|
|
return;
|
|
}
|
|
|
|
for (const message of connection.incoming) {
|
|
switch (message.type) {
|
|
case "player_join":
|
|
connection.add_player(message.player);
|
|
break;
|
|
case "player_leave":
|
|
connection.players.delete(message.id);
|
|
break;
|
|
case "player_move": {
|
|
const player = connection.players.get(message.id);
|
|
if (player) {
|
|
player.x = message.x;
|
|
player.y = message.y;
|
|
player.z = message.z;
|
|
player.yaw = message.yaw;
|
|
player.pitch = message.pitch;
|
|
}
|
|
break;
|
|
}
|
|
case "set_block":
|
|
world.dimension.record_change(message.x, message.y, message.z, message.id);
|
|
world.dimension.apply_change(message.x, message.y, message.z, message.id);
|
|
break;
|
|
case "chat":
|
|
world.add_chat(message.from ? `<${message.from}> ${message.text}` : message.text);
|
|
break;
|
|
}
|
|
}
|
|
connection.incoming.length = 0;
|
|
|
|
if (connection.closed) {
|
|
world.add_chat("Lost connection to the server");
|
|
world.connection = undefined;
|
|
return;
|
|
}
|
|
|
|
const t = Math.min(1, delta * REMOTE_PLAYER_SMOOTHING);
|
|
for (const player of connection.players.values()) {
|
|
player.display_x += (player.x - player.display_x) * t;
|
|
player.display_y += (player.y - player.display_y) * t;
|
|
player.display_z += (player.z - player.display_z) * t;
|
|
}
|
|
|
|
this.move_timer += delta;
|
|
if (this.move_timer >= MOVE_SEND_INTERVAL) {
|
|
this.move_timer = 0;
|
|
const [player] = world.get_tag("player")!;
|
|
const position = player.get(Position)!;
|
|
const camera = player.get(Camera)!;
|
|
connection.send({
|
|
type: "move",
|
|
x: position.x,
|
|
y: position.y,
|
|
z: position.z,
|
|
yaw: camera.yaw,
|
|
pitch: camera.pitch,
|
|
});
|
|
}
|
|
}
|
|
}
|