✨ implement unified tile system (Issue #14)
- Tree seedlings: plant tree_seed on grass via farming tool; two-stage growth (sprout → sapling → young tree, ~1 min/stage); matures into a harvestable FOREST resource tile - Tile recovery: Nisse chops start a 5-min DARK_GRASS→GRASS timer; terrain canvas updated live via WorldSystem.refreshTerrainTile() - New TreeSeedlingSystem manages sprites, growth ticking, maturation - BootScene generates seedling_0/1/2 textures procedurally - FarmingSystem adds tree_seed to tool cycle (F key) - Stockpile panel shows tree_seed (default: 5); panel height adjusted - StateManager v5: treeSeedlings + tileRecovery in WorldState - WorldSystem uses CanvasTexture for live single-pixel updates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,15 +5,16 @@ import type { CropKind, CropState, ItemId } from '../types'
|
||||
import { stateManager } from '../StateManager'
|
||||
import type { LocalAdapter } from '../NetworkAdapter'
|
||||
|
||||
export type FarmingTool = 'none' | 'hoe' | 'wheat_seed' | 'carrot_seed' | 'water'
|
||||
export type FarmingTool = 'none' | 'hoe' | 'wheat_seed' | 'carrot_seed' | 'tree_seed' | 'water'
|
||||
|
||||
const TOOL_CYCLE: FarmingTool[] = ['none', 'hoe', 'wheat_seed', 'carrot_seed', 'water']
|
||||
const TOOL_CYCLE: FarmingTool[] = ['none', 'hoe', 'wheat_seed', 'carrot_seed', 'tree_seed', 'water']
|
||||
|
||||
const TOOL_LABELS: Record<FarmingTool, string> = {
|
||||
none: '— None',
|
||||
hoe: '⛏ Hoe (till grass)',
|
||||
wheat_seed: '🌾 Wheat Seeds',
|
||||
carrot_seed: '🥕 Carrot Seeds',
|
||||
tree_seed: '🌲 Tree Seeds (plant on grass)',
|
||||
water: '💧 Watering Can',
|
||||
}
|
||||
|
||||
@@ -30,6 +31,14 @@ export class FarmingSystem {
|
||||
onToolChange?: (tool: FarmingTool, label: string) => void
|
||||
/** Emitted for toast notifications */
|
||||
onMessage?: (msg: string) => void
|
||||
/**
|
||||
* Called when the player uses the tree_seed tool on a tile.
|
||||
* @param tileX - Target tile column
|
||||
* @param tileY - Target tile row
|
||||
* @param underlyingTile - The tile type at that position
|
||||
* @returns true if planting succeeded, false if validation failed
|
||||
*/
|
||||
onPlantTreeSeed?: (tileX: number, tileY: number, underlyingTile: TileType) => boolean
|
||||
|
||||
constructor(scene: Phaser.Scene, adapter: LocalAdapter) {
|
||||
this.scene = scene
|
||||
@@ -87,9 +96,27 @@ export class FarmingSystem {
|
||||
const state = stateManager.getState()
|
||||
const tile = state.world.tiles[tileY * 512 + tileX] as TileType
|
||||
|
||||
if (this.currentTool === 'hoe') this.tillSoil(tileX, tileY, tile)
|
||||
else if (this.currentTool === 'water') this.waterTile(tileX, tileY, tile)
|
||||
else this.plantCrop(tileX, tileY, tile, this.currentTool.replace('_seed', '') as CropKind)
|
||||
if (this.currentTool === 'hoe') this.tillSoil(tileX, tileY, tile)
|
||||
else if (this.currentTool === 'water') this.waterTile(tileX, tileY, tile)
|
||||
else if (this.currentTool === 'tree_seed') this.plantTreeSeed(tileX, tileY, tile)
|
||||
else this.plantCrop(tileX, tileY, tile, this.currentTool.replace('_seed', '') as CropKind)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates tree-seedling planting to the registered callback (TreeSeedlingSystem).
|
||||
* Only works on GRASS or DARK_GRASS tiles. Shows a toast on success or failure.
|
||||
* @param tileX - Target tile column
|
||||
* @param tileY - Target tile row
|
||||
* @param tile - Current tile type at that position
|
||||
*/
|
||||
private plantTreeSeed(tileX: number, tileY: number, tile: TileType): void {
|
||||
if (tile !== TileType.GRASS && tile !== TileType.DARK_GRASS) {
|
||||
this.onMessage?.('Plant tree seeds on grass!')
|
||||
return
|
||||
}
|
||||
const ok = this.onPlantTreeSeed?.(tileX, tileY, tile)
|
||||
if (ok === false) this.onMessage?.('No tree seeds, or tile is occupied!')
|
||||
else if (ok) this.onMessage?.('Tree seed planted! 🌱 (~2 min to grow)')
|
||||
}
|
||||
|
||||
private tillSoil(tileX: number, tileY: number, tile: TileType): void {
|
||||
|
||||
Reference in New Issue
Block a user