Files
nissefolk/src/systems/ResourceSystem.ts
2026-03-20 08:11:31 +00:00

91 lines
2.6 KiB
TypeScript

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<string, ResourceSprite>()
// 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)
}
}