'use client' import { create } from 'zustand' import type { Player, PlayerInventory } from '@/types' import { CREATIVE_BLOCKS } from '@/engine/constants' interface PlayerStore { player: Player | null initPlayer: (spawnY?: number) => void updatePosition: (pos: [number, number, number]) => void updateRotation: (rot: [number, number]) => void updateVelocity: (vel: [number, number, number]) => void setHealth: (hp: number) => void setFood: (food: number) => void setGamemode: (mode: Player['gamemode']) => void setSelectedSlot: (slot: number) => void setSneaking: (v: boolean) => void setSprinting: (v: boolean) => void setFlying: (v: boolean) => void damage: (amount: number) => void heal: (amount: number) => void feed: (amount: number) => void starve: (amount: number) => void } export const usePlayerStore = create((set, get) => ({ player: null, initPlayer: (spawnY = 100) => { const inventory: PlayerInventory = { hotbar: Array(9).fill(null), main: Array(27).fill(null), armor: Array(4).fill(null), offhand: null, } // Fill hotbar with a diverse selection of creative blocks const starterBlocks = [ CREATIVE_BLOCKS[0], // stone CREATIVE_BLOCKS[1], // granite CREATIVE_BLOCKS[3], // dirt CREATIVE_BLOCKS[4], // grass CREATIVE_BLOCKS[7], // sand CREATIVE_BLOCKS[10], // oak planks CREATIVE_BLOCKS[8], // cobblestone CREATIVE_BLOCKS[12], // oak log CREATIVE_BLOCKS[5], // bedrock ] starterBlocks.forEach((blockId, i) => { if (blockId !== undefined) { inventory.hotbar[i] = { id: blockId, count: 64, damage: 0 } } }) set({ player: { id: 'player', uuid: crypto.randomUUID(), position: [8, spawnY, 8], velocity: [0, 0, 0], rotation: [0, 0], health: 20, maxHealth: 20, onGround: false, gamemode: 'creative', inventory, selectedSlot: 0, foodLevel: 20, saturation: 5, experience: 0, experienceLevel: 0, flying: true, sneaking: false, sprinting: false, } }) }, updatePosition: (pos) => set(s => s.player ? { player: { ...s.player, position: pos } } : s), updateRotation: (rot) => set(s => s.player ? { player: { ...s.player, rotation: rot } } : s), updateVelocity: (vel) => set(s => s.player ? { player: { ...s.player, velocity: vel } } : s), setHealth: (hp) => set(s => s.player ? { player: { ...s.player, health: Math.max(0, Math.min(s.player.maxHealth, hp)) } } : s), setFood: (food) => set(s => s.player ? { player: { ...s.player, foodLevel: Math.max(0, Math.min(20, food)) } } : s), setGamemode: (mode) => set(s => s.player ? { player: { ...s.player, gamemode: mode, flying: mode === 'creative' ? true : s.player.flying, } } : s), setSelectedSlot: (slot) => set(s => s.player ? { player: { ...s.player, selectedSlot: slot } } : s), setSneaking: (v) => set(s => s.player ? { player: { ...s.player, sneaking: v } } : s), setSprinting: (v) => set(s => s.player ? { player: { ...s.player, sprinting: v } } : s), setFlying: (v) => set(s => s.player ? { player: { ...s.player, flying: v } } : s), damage: (amount) => set(s => { if (!s.player) return s const newHealth = Math.max(0, s.player.health - amount) return { player: { ...s.player, health: newHealth } } }), heal: (amount) => set(s => { if (!s.player) return s return { player: { ...s.player, health: Math.min(s.player.maxHealth, s.player.health + amount) } } }), feed: (amount) => set(s => { if (!s.player) return s return { player: { ...s.player, foodLevel: Math.min(20, s.player.foodLevel + amount) } } }), starve: (amount) => set(s => { if (!s.player) return s return { player: { ...s.player, foodLevel: Math.max(0, s.player.foodLevel - amount) } } }), }))