// BiomeSystem - Manages world biomes and generation class BiomeSystem { constructor(scene) { this.scene = scene; // World size this.worldWidth = 500; this.worldHeight = 500; // Biome map (500x500 grid of biome IDs) this.biomeMap = []; // Biome definitions this.biomes = { grassland: { id: 'grassland', name: 'Grassland', color: 0x4a9d5f, tileColor: '#4a9d5f', features: { trees: 0.05, rocks: 0.02, flowers: 0.15 }, weather: 'normal', temperature: 20 }, forest: { id: 'forest', name: 'Forest', color: 0x2d5016, tileColor: '#2d5016', features: { trees: 0.60, rocks: 0.05, bushes: 0.20, mushrooms: 0.10 }, weather: 'rainy', temperature: 15 }, desert: { id: 'desert', name: 'Desert', color: 0xd4c4a1, tileColor: '#d4c4a1', features: { cacti: 0.08, rocks: 0.15, deadTrees: 0.03 }, weather: 'hot', temperature: 35 }, mountain: { id: 'mountain', name: 'Mountain', color: 0x808080, tileColor: '#808080', features: { rocks: 0.40, largeRocks: 0.20, snow: 0.10 }, weather: 'cold', temperature: -5 }, swamp: { id: 'swamp', name: 'Swamp', color: 0x3d5a3d, tileColor: '#3d5a3d', features: { water: 0.30, deadTrees: 0.25, vines: 0.15, fog: true }, weather: 'foggy', temperature: 18 }, // ===== NEW BIOMES - NORMAL (4) ===== snow: { id: 'snow', name: 'Frozen Tundra', color: 0xE0F7FA, tileColor: '#E0F7FA', features: { ice: 0.40, frozenTrees: 0.15, snowDrifts: 0.25, icicles: 0.10 }, weather: 'blizzard', temperature: -20 }, wasteland: { id: 'wasteland', name: 'Wasteland', color: 0x4a4a4a, tileColor: '#4a4a4a', features: { ruins: 0.30, rubble: 0.40, scrapMetal: 0.20, brokenMachinery: 0.15 }, weather: 'dusty', temperature: 25 }, tropical: { id: 'tropical', name: 'Tropical Beach', color: 0xFFE082, tileColor: '#FFE082', features: { palmTrees: 0.25, coconuts: 0.15, shells: 0.20, water: 0.40 }, weather: 'sunny', temperature: 30 }, radioactive: { id: 'radioactive', name: 'Radioactive Zone', color: 0x39FF14, tileColor: '#39FF14', features: { glowingRocks: 0.30, mutantPlants: 0.25, radioactiveBarrels: 0.15, toxicPuddles: 0.20, glow: true }, weather: 'toxic', temperature: 28 }, // ===== NEW BIOMES - ANOMALOUS (9) ===== dino_valley: { id: 'dino_valley', name: 'Dino Valley', color: 0x6B8E23, tileColor: '#6B8E23', features: { prehistoricTrees: 0.45, largeFerns: 0.35, dinoFootprints: 0.20, fossils: 0.10, eggs: 0.05 }, weather: 'humid', temperature: 32, anomalous: true, unlockRequirement: 'portal_dino' }, mythical: { id: 'mythical', name: 'Mythical Highlands', color: 0xB39DDB, tileColor: '#B39DDB', features: { magicalTrees: 0.30, crystals: 0.25, floatingRocks: 0.20, rainbows: 0.10, magicAura: true }, weather: 'magical', temperature: 18, anomalous: true, unlockRequirement: 'portal_mythical' }, endless_forest: { id: 'endless_forest', name: 'Endless Forest', color: 0x1B5E20, tileColor: '#1B5E20', features: { ancientTrees: 0.80, mysteryFog: 0.30, strangeFootprints: 0.15, hiddenPaths: 0.20 }, weather: 'misty', temperature: 12, anomalous: true, unlockRequirement: 'portal_endless_forest' }, loch_ness: { id: 'loch_ness', name: 'Loch Ness', color: 0x546E7A, tileColor: '#546E7A', features: { scottishPines: 0.35, heather: 0.25, lochWater: 0.40, castleRuins: 0.10 }, weather: 'rainy', temperature: 10, anomalous: true, unlockRequirement: 'portal_scotland' }, catacombs: { id: 'catacombs', name: 'Catacombs', color: 0x3E2723, tileColor: '#3E2723', features: { bones: 0.50, tombs: 0.30, skulls: 0.25, ancientUrns: 0.15, darkness: true }, weather: 'underground', temperature: 15, anomalous: true, unlockRequirement: 'portal_catacombs' }, egyptian_desert: { id: 'egyptian_desert', name: 'Egyptian Desert', color: 0xFFD54F, tileColor: '#FFD54F', features: { pyramids: 0.05, sandDunes: 0.60, hieroglyphs: 0.15, scarabs: 0.20, sphinx: 0.01 }, weather: 'scorching', temperature: 45, anomalous: true, unlockRequirement: 'portal_egypt' }, amazon: { id: 'amazon', name: 'Amazon Rainforest', color: 0x1B5E20, tileColor: '#1B5E20', features: { jungleTrees: 0.75, vines: 0.40, exoticFlowers: 0.30, tribalTotems: 0.10, piranhaRivers: 0.15 }, weather: 'monsoon', temperature: 35, anomalous: true, unlockRequirement: 'portal_amazon' }, atlantis: { id: 'atlantis', name: 'Atlantis', color: 0x00BCD4, tileColor: '#00BCD4', features: { coralReefs: 0.40, underwaterRuins: 0.35, pearls: 0.15, seaweed: 0.30, bubbles: true, underwater: true }, weather: 'underwater', temperature: 20, anomalous: true, unlockRequirement: 'portal_atlantis' }, chernobyl: { id: 'chernobyl', name: 'Chernobyl', color: 0x757575, tileColor: '#757575', features: { reactorRuins: 0.20, abandonedBuildings: 0.40, radioactiveBarrels: 0.25, sovietRelics: 0.20, hazmatSigns: 0.15, radiation: true }, weather: 'nuclear', temperature: 22, anomalous: true, isFinalZone: true, unlockRequirement: 'train_to_chernobyl' } }; console.log('🌍 BiomeSystem initialized (500x500 world)'); } // Generate biome map using Perlin-like noise generateBiomeMap() { console.log('🌍 Generating biome map...'); this.biomeMap = []; // Initialize empty map for (let y = 0; y < this.worldHeight; y++) { this.biomeMap[y] = []; for (let x = 0; x < this.worldWidth; x++) { this.biomeMap[y][x] = null; } } // Center is always grassland (farm area) const centerX = Math.floor(this.worldWidth / 2); const centerY = Math.floor(this.worldHeight / 2); const farmRadius = 50; // 100x100 farm area // Define biome centers (for now, simple regions) const biomeRegions = [ { biome: 'grassland', centerX: 250, centerY: 250, radius: 80 }, // Center (FARM) { biome: 'forest', centerX: 150, centerY: 150, radius: 100 }, // Northwest { biome: 'forest', centerX: 350, centerY: 150, radius: 80 }, // Northeast { biome: 'desert', centerX: 400, centerY: 350, radius: 90 }, // Southeast { biome: 'mountain', centerX: 100, centerY: 100, radius: 70 }, // Far northwest { biome: 'swamp', centerX: 100, centerY: 400, radius: 80 } // Southwest ]; // Fill biomes based on distance to region centers for (let y = 0; y < this.worldHeight; y++) { for (let x = 0; x < this.worldWidth; x++) { // Find closest biome region let closestBiome = 'grassland'; // Default let minDistance = Infinity; for (const region of biomeRegions) { const dx = x - region.centerX; const dy = y - region.centerY; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < minDistance) { minDistance = distance; closestBiome = region.biome; } } this.biomeMap[y][x] = closestBiome; } } console.log('✅ Biome map generated!'); } // Get biome at specific coordinates getBiomeAt(x, y) { if (x < 0 || x >= this.worldWidth || y < 0 || y >= this.worldHeight) { return 'grassland'; // Default outside bounds } return this.biomeMap[y][x] || 'grassland'; } // Get biome data getBiomeData(biomeId) { return this.biomes[biomeId] || this.biomes.grassland; } // Check if feature should spawn at location shouldSpawnFeature(x, y, featureType) { const biomeId = this.getBiomeAt(x, y); const biomeData = this.getBiomeData(biomeId); if (!biomeData.features[featureType]) return false; const chance = biomeData.features[featureType]; return Math.random() < chance; } // Get tile color for biome getTileColor(x, y) { const biomeId = this.getBiomeAt(x, y); const biomeData = this.getBiomeData(biomeId); return biomeData.tileColor; } // Apply biome-specific features during world generation applyBiomeFeatures(x, y) { const biomeId = this.getBiomeAt(x, y); const biomeData = this.getBiomeData(biomeId); const features = []; // Trees if (this.shouldSpawnFeature(x, y, 'trees')) { features.push({ type: 'tree', variant: Math.floor(Math.random() * 3) }); } // Rocks if (this.shouldSpawnFeature(x, y, 'rocks')) { features.push({ type: 'rock', size: Math.random() > 0.7 ? 'large' : 'small' }); } // Biome-specific features if (biomeId === 'forest') { if (this.shouldSpawnFeature(x, y, 'bushes')) { features.push({ type: 'bush' }); } if (this.shouldSpawnFeature(x, y, 'mushrooms')) { features.push({ type: 'mushroom' }); } } else if (biomeId === 'desert') { if (this.shouldSpawnFeature(x, y, 'cacti')) { features.push({ type: 'cactus' }); } if (this.shouldSpawnFeature(x, y, 'deadTrees')) { features.push({ type: 'deadTree' }); } } else if (biomeId === 'mountain') { if (this.shouldSpawnFeature(x, y, 'largeRocks')) { features.push({ type: 'boulder' }); } } else if (biomeId === 'swamp') { if (this.shouldSpawnFeature(x, y, 'deadTrees')) { features.push({ type: 'deadTree' }); } if (this.shouldSpawnFeature(x, y, 'vines')) { features.push({ type: 'vine' }); } } return features; } // Get biome transitions (blend zones) getBiomeBlend(x, y, radius = 3) { // Check surrounding tiles for different biomes const centerBiome = this.getBiomeAt(x, y); const surroundingBiomes = new Set(); for (let dy = -radius; dy <= radius; dy++) { for (let dx = -radius; dx <= radius; dx++) { const biome = this.getBiomeAt(x + dx, y + dy); if (biome !== centerBiome) { surroundingBiomes.add(biome); } } } return { isTransition: surroundingBiomes.size > 0, mainBiome: centerBiome, nearbyBiomes: Array.from(surroundingBiomes) }; } // Get biome statistics (for debugging/UI) getBiomeStats() { const stats = {}; for (const biomeId in this.biomes) { stats[biomeId] = 0; } for (let y = 0; y < this.worldHeight; y++) { for (let x = 0; x < this.worldWidth; x++) { const biome = this.getBiomeAt(x, y); stats[biome] = (stats[biome] || 0) + 1; } } // Convert to percentages const total = this.worldWidth * this.worldHeight; for (const biomeId in stats) { stats[biomeId] = { tiles: stats[biomeId], percentage: ((stats[biomeId] / total) * 100).toFixed(1) }; } return stats; } // Export biome map for debugging/visualization exportBiomeMap() { return { width: this.worldWidth, height: this.worldHeight, biomes: this.biomes, map: this.biomeMap }; } // Destroy destroy() { this.biomeMap = []; console.log('🌍 BiomeSystem destroyed'); } }