import type { PlayerInfo } from "$/common/protocol.ts"; import { TICK_DELTA } from "$/common/constants.ts"; import type { ClientLevel } from "../level/client_level.ts"; import { Player } from "./player.ts"; const SMOOTHING = 12; // another player on the server, it moves where the server says instead of simulating anything export class RemotePlayer extends Player { color: [number, number, number]; // where the server last said it is, the drawn position eases towards it so movement isn't choppy target_x: number; target_y: number; target_z: number; constructor(level: ClientLevel, info: PlayerInfo) { super(level, info.id, info.name); this.set_position(info.x, info.y, info.z); this.target_x = info.x; this.target_y = info.y; this.target_z = info.z; this.yaw = info.yaw; this.pitch = info.pitch; this.color = color_from_name(info.name); } lerp_to(x: number, y: number, z: number, yaw: number, pitch: number) { this.target_x = x; this.target_y = y; this.target_z = z; this.yaw = yaw; this.pitch = pitch; } tick() { const t = Math.min(1, TICK_DELTA * SMOOTHING); this.x += (this.target_x - this.x) * t; this.y += (this.target_y - this.y) * t; this.z += (this.target_z - this.z) * t; } } function color_from_name(name: string): [number, number, number] { let hash = 0; for (const ch of name) { hash = (hash * 31 + ch.charCodeAt(0)) | 0; } const hue = ((hash % 360) + 360) % 360; // hsl with s=0.6 l=0.6 to rgb const c = 0.48; const x = c * (1 - Math.abs(((hue / 60) % 2) - 1)); const m = 0.36; const [r, g, b] = hue < 60 ? [c, x, 0] : hue < 120 ? [x, c, 0] : hue < 180 ? [0, c, x] : hue < 240 ? [0, x, c] : hue < 300 ? [x, 0, c] : [c, 0, x]; return [r + m, g + m, b + m]; }