import Phaser from 'phaser' import { TILE_SIZE } from '../config' import { TileType } from '../types' import { stateManager } from '../StateManager' import type { LocalAdapter } from '../NetworkAdapter' import type { ResourceNodeState } from '../types' interface ResourceSprite { sprite: Phaser.GameObjects.Image node: ResourceNodeState healthBar: Phaser.GameObjects.Graphics } export class ResourceSystem { private scene: Phaser.Scene private adapter: LocalAdapter private sprites = new Map() // Emits after each successful harvest: (message: string) onHarvest?: (message: string) => void constructor(scene: Phaser.Scene, adapter: LocalAdapter) { this.scene = scene this.adapter = adapter } create(): void { const state = stateManager.getState() // Spawn sprites for all resources in state for (const node of Object.values(state.world.resources)) { this.spawnSprite(node) } } private spawnSprite(node: ResourceNodeState): void { const x = (node.tileX + 0.5) * TILE_SIZE const y = (node.tileY + 0.5) * TILE_SIZE const key = node.kind === 'tree' ? 'tree' : 'rock' const sprite = this.scene.add.image(x, y, key) // Trees are taller; offset them upward so trunk sits on tile if (node.kind === 'tree') { sprite.setOrigin(0.5, 0.85) } else { sprite.setOrigin(0.5, 0.75) } sprite.setDepth(5) const healthBar = this.scene.add.graphics() healthBar.setDepth(6) healthBar.setVisible(false) this.sprites.set(node.id, { sprite, node, healthBar }) } update(delta: number): void { // Hide all health bars each frame (no player proximity detection) for (const entry of this.sprites.values()) { entry.healthBar.setVisible(false) } } private removeSprite(id: string): void { const entry = this.sprites.get(id) if (!entry) return entry.sprite.destroy() entry.healthBar.destroy() this.sprites.delete(id) } /** Called by VillagerSystem when a villager finishes chopping/mining */ public removeResource(id: string): void { this.removeSprite(id) } /** Called when WorldSystem changes a tile (e.g. after tree removed) */ syncTileChange(tileX: number, tileY: number, worldSystem: { setTile: (x: number, y: number, type: TileType) => void }): void { const state = stateManager.getState() const idx = tileY * 512 + tileX // WORLD_TILES = 512 const tile = state.world.tiles[idx] as TileType worldSystem.setTile(tileX, tileY, tile) } destroy(): void { for (const [id] of this.sprites) this.removeSprite(id) } }