diff --git a/index.html b/index.html index 84275fb..219c5ee 100644 --- a/index.html +++ b/index.html @@ -109,6 +109,7 @@ + diff --git a/src/systems/GemDropSystem.js b/src/systems/GemDropSystem.js new file mode 100644 index 0000000..3e07bd8 --- /dev/null +++ b/src/systems/GemDropSystem.js @@ -0,0 +1,187 @@ +/** + * GEM DROP SYSTEM + * Handles rare gem drops from enemies, mining, etc. + * Gems: Diamond, Emerald, Ruby (high value items for selling) + */ + +class GemDropSystem { + constructor(scene) { + this.scene = scene; + + // Gem definitions with rarity and value + this.gems = { + 'diamond': { + name: 'Diamond', + rarity: 'legendary', // 0.5% drop + value: 500, // Sell price in gold + icon: '💎' + }, + 'emerald': { + name: 'Emerald', + rarity: 'epic', // 2% drop + value: 200, + icon: '💚' + }, + 'ruby': { + name: 'Ruby', + rarity: 'rare', // 5% drop + value: 100, + icon: '❤️' + }, + 'sapphire': { + name: 'Sapphire', + rarity: 'uncommon', // 10% drop + value: 50, + icon: '💙' + } + }; + + // Drop chance by rarity + this.rarityChances = { + 'legendary': 0.005, // 0.5% + 'epic': 0.02, // 2% + 'rare': 0.05, // 5% + 'uncommon': 0.10 // 10% + }; + } + + /** + * Roll for gem drop from enemy/resource + * @param {string} source - 'zombie', 'elite', 'stone_ore', 'iron_ore' + * @param {number} x - Grid X + * @param {number} y - Grid Y + * @param {number} luckBonus - Player luck modifier (0-1) + */ + rollGemDrop(source, x, y, luckBonus = 0) { + const dropTable = this.getDropTableForSource(source); + if (!dropTable || dropTable.length === 0) return; + + // Roll for each possible gem + for (const gemEntry of dropTable) { + const gemType = gemEntry.gem; + const gem = this.gems[gemType]; + if (!gem) continue; + + const baseChance = this.rarityChances[gem.rarity]; + const finalChance = baseChance * (1 + luckBonus); + + if (Math.random() < finalChance) { + // GEM DROPPED! + console.log(`💎 RARE DROP: ${gem.name} from ${source}!`); + this.spawnGem(gemType, x, y); + + // Play special sound/effect + if (this.scene.particleEffects) { + this.scene.particleEffects.gemSparkle(x, y, gem.icon); + } + if (this.scene.soundManager) { + this.scene.soundManager.playRareDrop(); + } + + // Only drop 1 gem per source + break; + } + } + } + + /** + * Get drop table based on source + */ + getDropTableForSource(source) { + const tables = { + 'zombie': [ + { gem: 'sapphire', weight: 1 } + ], + 'elite_zombie': [ + { gem: 'ruby', weight: 2 }, + { gem: 'emerald', weight: 1 } + ], + 'troll': [ + { gem: 'emerald', weight: 2 }, + { gem: 'diamond', weight: 0.5 } + ], + 'stone_ore': [ + { gem: 'sapphire', weight: 1 } + ], + 'iron_ore': [ + { gem: 'ruby', weight: 1 } + ], + 'gold_ore': [ + { gem: 'emerald', weight: 1.5 }, + { gem: 'diamond', weight: 0.3 } + ], + 'boss': [ + { gem: 'diamond', weight: 5 } // Guaranteed almost! + ] + }; + + return tables[source] || []; + } + + /** + * Spawn gem as loot item + */ + spawnGem(gemType, gridX, gridY) { + if (this.scene.lootSystem) { + this.scene.lootSystem.spawnLoot(gridX, gridY, gemType, 1); + } else { + console.warn('⚠️ LootSystem not found - gem cannot spawn!'); + } + + // Show floating text + const gem = this.gems[gemType]; + if (this.scene.events) { + const screenPos = this.scene.terrainSystem.iso.toScreen(gridX, gridY); + this.scene.events.emit('show-floating-text', { + x: screenPos.x, + y: screenPos.y - 50, + text: `${gem.icon} ${gem.name}!`, + color: '#ff00ff', // Purple for rare + size: '20px' + }); + } + } + + /** + * Get gem sell value + */ + getGemValue(gemType) { + const gem = this.gems[gemType]; + return gem ? gem.value : 0; + } + + /** + * Sell gem to merchant + */ + sellGem(gemType, amount, playerInventory) { + const gem = this.gems[gemType]; + if (!gem) { + console.warn('⚠️ Unknown gem type:', gemType); + return 0; + } + + // Check if player has gem + const hasAmount = playerInventory.getItemCount(gemType); + if (hasAmount < amount) { + console.warn(`⚠️ Not enough ${gem.name} to sell!`); + return 0; + } + + // Calculate total value + const totalValue = gem.value * amount; + + // Remove from inventory + playerInventory.removeItem(gemType, amount); + + // Add gold + playerInventory.addItem('gold_coin', totalValue); + + console.log(`💰 Sold ${amount}x ${gem.name} for ${totalValue} gold`); + return totalValue; + } +} + +// Export +if (typeof module !== 'undefined' && module.exports) { + module.exports = GemDropSystem; +} diff --git a/src/systems/LootSystem.js b/src/systems/LootSystem.js index 5cc6dcf..a1e1bb3 100644 --- a/src/systems/LootSystem.js +++ b/src/systems/LootSystem.js @@ -24,7 +24,9 @@ class LootSystem { const symbols = { 'wood': '🪵', 'stone': '🪨', 'seeds': '🌱', 'wheat': '🌾', 'axe': '🪓', 'pickaxe': '⛏️', 'sword': '⚔️', 'hoe': '🚜', - 'item_bone': '🦴', 'flower': '🌸' + 'item_bone': '🦴', 'flower': '🌸', + 'diamond': '💎', 'emerald': '💚', 'ruby': '❤️', // GEMS! + 'gold_coin': '🪙', 'iron': '⚙️' }; if (symbols[type]) symbol = symbols[type];