import { Container, Cursor, ItemData, ItemStack } from "$/common/inventory.ts"; import { PlayerInfo, ScreenLayout } from "$/common/protocol.ts"; import { Tile } from "./world.ts"; export const INVENTORY_SIZE = 9 * 4; export const CRAFTING_SIZE = 10; // a screen the server opened for this player, showing a tile's container export interface OpenScreen { tile: Tile; container: Container; layout: ScreenLayout; properties(): Record; } // what's saved about a player between sessions, by name export interface SavedPlayer { x: number; y: number; z: number; yaw: number; pitch: number; selected_slot: number; inventory: (ItemData | null)[]; } export class ServerPlayer { readonly conn: number; readonly id = crypto.randomUUID(); readonly name: string; x = 0; y = 100; z = 0; yaw = 0; pitch = 0; inventory = new Container(INVENTORY_SIZE); crafting = new Container(CRAFTING_SIZE); cursor: Cursor = { item: undefined }; selected_slot = 0; screen: OpenScreen | undefined; // last json sent for each synced thing, so only changes get sent sent = new Map(); constructor(conn: number, name: string) { this.conn = conn; this.name = name; } get held_item(): ItemStack | undefined { return this.inventory.get_item(this.selected_slot); } info(): PlayerInfo { return { id: this.id, name: this.name, x: this.x, y: this.y, z: this.z, yaw: this.yaw, pitch: this.pitch }; } save(): SavedPlayer { return { x: this.x, y: this.y, z: this.z, yaw: this.yaw, pitch: this.pitch, selected_slot: this.selected_slot, inventory: this.inventory.to_data(), }; } load(saved: SavedPlayer) { this.x = saved.x; this.y = saved.y; this.z = saved.z; this.yaw = saved.yaw; this.pitch = saved.pitch; this.selected_slot = saved.selected_slot; this.inventory.load(saved.inventory); } }