class LootSystem { constructor(scene) { this.scene = scene; this.drops = []; // Active loot drops this.iso = scene.terrainSystem ? scene.terrainSystem.iso : null; // Reference to IsoUtils // Settings this.pickupRadius = 1.0; // Grid based this.magnetRadius = 3.0; // Optional: fly towards player } spawnLoot(gridX, gridY, type, count = 1) { if (!this.iso && this.scene.terrainSystem) this.iso = this.scene.terrainSystem.iso; if (!this.iso) return; // Safety check console.log(`🎁 Spawning ${count}x ${type} at ${gridX},${gridY}`); const screenPos = this.iso.toScreen(gridX, gridY); const x = screenPos.x + (this.scene.terrainOffsetX || 0); const y = screenPos.y + (this.scene.terrainOffsetY || 0); // Visual Symbol Mapping let symbol = '?'; const symbols = { 'wood': '🪵', 'stone': '🪨', 'seeds': '🌱', 'wheat': '🌾', 'axe': '🪓', 'pickaxe': '⛏️', 'sword': '⚔️', 'hoe': '🚜', 'item_bone': '🦴', 'flower': '🌸', 'diamond': '💎', 'emerald': '💚', 'ruby': '❤️', // GEMS! 'gold_coin': '🪙', 'iron': '⚙️' }; if (symbols[type]) symbol = symbols[type]; // Create Sprite/Text // Using Text for now as it supports emojis easily, but could be Sprite const drop = this.scene.add.text(x, y - 20, symbol, { fontSize: '20px' }); drop.setOrigin(0.5); drop.setDepth(this.iso.getDepth(gridX, gridY) + 500); // Animation (Bobbing) this.scene.tweens.add({ targets: drop, y: y - 40, duration: 600, yoyo: true, ease: 'Sine.easeInOut', repeat: -1 }); // Add to list this.drops.push({ gridX, gridY, x, y, sprite: drop, type: type, count: count, spawnTime: Date.now() }); } update() { if (!this.scene.player) return; const playerPos = this.scene.player.getPosition(); // Loop backwards to allow removal for (let i = this.drops.length - 1; i >= 0; i--) { const drop = this.drops[i]; // Distance Check const dist = Math.abs(drop.gridX - playerPos.x) + Math.abs(drop.gridY - playerPos.y); // Manhattan-ish // Pickup Logic if (dist < 0.8) { this.collectLoot(drop, i); } // Magnet Logic (Visual fly to player) - Optional else if (dist < 3.0) { // Move visual slightly towards player? // Implementing full physics/velocity might be overkill for now. } } } collectLoot(drop, index) { if (this.scene.inventorySystem) { const leftover = this.scene.inventorySystem.addItem(drop.type, drop.count); if (leftover === 0) { // Success - Play Sound if (this.scene.soundManager) { this.scene.soundManager.playPickup(); } // Sparkle Effect if (this.scene.particleEffects) { this.scene.particleEffects.sparkle(drop.x, drop.y); } // Float text effect this.showFloatingText(`+${drop.count} ${drop.type}`, drop.x, drop.y); // Remove drop.sprite.destroy(); this.drops.splice(index, 1); } else { // Config full? Update count? drop.count = leftover; } } } showFloatingText(text, x, y) { const txt = this.scene.add.text(x, y - 50, text, { fontSize: '14px', fill: '#ffff00', stroke: '#000', strokeThickness: 2 }).setOrigin(0.5).setDepth(20000); this.scene.tweens.add({ targets: txt, y: y - 100, alpha: 0, duration: 800, onComplete: () => txt.destroy() }); } }