/** * ANIMAL BREEDING & GENETICS SYSTEM * Complete breeding system with normal animals, genetics, mutants, and baby care */ class AnimalBreedingSystem { constructor(scene) { this.scene = scene; this.enabled = true; // Animals this.animals = new Map(); this.babies = []; this.breedingPairs = []; // Genetics this.geneticTraits = new Map(); this.mutations = new Map(); // Breeding stations this.breedingStations = new Map(); // Settings this.settings = { autoBreeding: true, proximityRange: 2, // tiles mutationChance: 0.05, // 5% gestationSpeed: 1.0 // 1.0 = normal }; // Gestation periods (in game days) this.gestationPeriods = { sheep: 7, cow: 14, chicken: 3, pig: 10, horse: 21, mutant_cow: 30, mutant_chicken: 15, mutant_pig: 20, mutant_horse: 40, fire_sheep: 14 }; this.loadProgress(); this.init(); console.log('✅ Animal Breeding System initialized'); } init() { this.defineGeneticTraits(); this.defineMutations(); console.log('🐑 Animal breeding ready'); } // ========== GENETIC TRAITS ========== defineGeneticTraits() { // Colors (Mendelian genetics) this.geneticTraits.set('color', { dominant: ['brown', 'black'], recessive: ['white', 'golden'], rare: ['rainbow', 'crystal'] }); // Size this.geneticTraits.set('size', { values: ['small', 'medium', 'large'], modifiers: { small: 0.8, medium: 1.0, large: 1.2 } }); // Speed this.geneticTraits.set('speed', { values: ['slow', 'normal', 'fast'], modifiers: { slow: 0.8, normal: 1.0, fast: 1.3 } }); // Production this.geneticTraits.set('production', { values: ['low', 'normal', 'high'], modifiers: { low: 0.7, normal: 1.0, high: 1.5 } }); } defineMutations() { this.mutations.set('golden_fleece', { chance: 0.05, species: 'sheep', effects: { production: 2.0, value: 5.0 }, rarity: 'legendary' }); this.mutations.set('three_heads', { chance: 0.03, species: 'chicken', effects: { production: 3.0, eggs: 3 }, rarity: 'epic' }); this.mutations.set('giant', { chance: 0.04, species: 'pig', effects: { size: 2.0, rideable: true }, rarity: 'epic' }); this.mutations.set('undead', { chance: 0.02, species: 'horse', effects: { stamina: Infinity, speed: 1.5 }, rarity: 'legendary' }); this.mutations.set('fire_wool', { chance: 0.01, species: 'sheep', effects: { fire_resistance: true, production: 1.5 }, rarity: 'mythic' }); } // ========== ANIMAL MANAGEMENT ========== addAnimal(species, gender, x, y) { const animal = { id: `animal_${Date.now()}_${Math.random()}`, species, gender, // 'male' or 'female' x, y, age: 0, stage: 'adult', // baby, teen, adult genetics: this.generateGenetics(species), pregnant: false, gestationProgress: 0, offspring: null, lastBreed: 0, sprite: null }; this.animals.set(animal.id, animal); return animal; } generateGenetics(species) { return { color: this.randomTrait('color'), size: this.randomTrait('size'), speed: this.randomTrait('speed'), production: this.randomTrait('production'), mutation: this.checkMutation(species) }; } randomTrait(traitType) { const trait = this.geneticTraits.get(traitType); const allValues = [...trait.dominant, ...trait.recessive]; return allValues[Math.floor(Math.random() * allValues.length)]; } checkMutation(species) { for (const [mutationId, mutation] of this.mutations.entries()) { if (mutation.species === species && Math.random() < mutation.chance) { return mutationId; } } return null; } // ========== BREEDING ========== attemptBreeding(animal1, animal2) { // Check compatibility if (!this.canBreed(animal1, animal2)) { return false; } // Check proximity const distance = Math.sqrt( Math.pow(animal1.x - animal2.x, 2) + Math.pow(animal1.y - animal2.y, 2) ); if (distance > this.settings.proximityRange) { return false; } // Breed! return this.breed(animal1, animal2); } canBreed(animal1, animal2) { // Same species if (animal1.species !== animal2.species) return false; // Different genders if (animal1.gender === animal2.gender) return false; // Both adults if (animal1.stage !== 'adult' || animal2.stage !== 'adult') return false; // Not pregnant if (animal1.pregnant || animal2.pregnant) return false; // Cooldown (1 day) const now = Date.now(); if (now - animal1.lastBreed < 86400000) return false; if (now - animal2.lastBreed < 86400000) return false; return true; } breed(male, female) { // Determine which is female const mother = female.gender === 'female' ? female : male; const father = female.gender === 'male' ? female : male; // Create offspring genetics const offspring = { species: mother.species, genetics: this.inheritGenetics(father, mother), birthTime: null, gestationStart: Date.now() }; // Set mother as pregnant mother.pregnant = true; mother.gestationProgress = 0; mother.offspring = offspring; mother.lastBreed = Date.now(); father.lastBreed = Date.now(); // Visual effect if (this.scene.visualEnhancements) { this.scene.visualEnhancements.createHeartParticles(mother.x, mother.y); } console.log(`💕 ${mother.species} breeding started!`); return true; } inheritGenetics(father, mother) { const genetics = { color: this.inheritColor(father.genetics.color, mother.genetics.color), size: this.inheritTrait(father.genetics.size, mother.genetics.size), speed: this.inheritTrait(father.genetics.speed, mother.genetics.speed), production: this.inheritTrait(father.genetics.production, mother.genetics.production), mutation: this.inheritMutation(father, mother) }; return genetics; } inheritColor(color1, color2) { const colorTrait = this.geneticTraits.get('color'); // Dominant genes if (colorTrait.dominant.includes(color1)) return color1; if (colorTrait.dominant.includes(color2)) return color2; // 50/50 for recessive return Math.random() < 0.5 ? color1 : color2; } inheritTrait(trait1, trait2) { // 50% from each parent return Math.random() < 0.5 ? trait1 : trait2; } inheritMutation(father, mother) { // Both parents have mutation = 100% chance if (father.genetics.mutation && mother.genetics.mutation) { return father.genetics.mutation; } // One parent has mutation = 50% chance if (father.genetics.mutation) { return Math.random() < 0.5 ? father.genetics.mutation : null; } if (mother.genetics.mutation) { return Math.random() < 0.5 ? mother.genetics.mutation : null; } // New mutation check return this.checkMutation(father.species); } // ========== GESTATION & BIRTH ========== updateGestation(delta) { const dayInMs = 86400000 / this.settings.gestationSpeed; for (const animal of this.animals.values()) { if (!animal.pregnant) continue; // Update gestation progress const elapsed = Date.now() - animal.offspring.gestationStart; const gestationDays = this.gestationPeriods[animal.species]; animal.gestationProgress = (elapsed / dayInMs) / gestationDays; // Birth! if (animal.gestationProgress >= 1.0) { this.giveBirth(animal); } } } giveBirth(mother) { const baby = { id: `baby_${Date.now()}_${Math.random()}`, species: mother.offspring.species, gender: Math.random() < 0.5 ? 'male' : 'female', x: mother.x, y: mother.y, age: 0, stage: 'baby', genetics: mother.offspring.genetics, pregnant: false, hunger: 100, bonding: 0, growthProgress: 0, sprite: null }; // Add to babies list this.babies.push(baby); // Add to animals (will become adult later) this.animals.set(baby.id, baby); // Reset mother mother.pregnant = false; mother.offspring = null; mother.gestationProgress = 0; // Visual effect if (this.scene.visualEnhancements) { this.scene.visualEnhancements.createSparkleEffect(baby.x, baby.y); } // Achievement if (this.scene.uiGraphics) { this.scene.uiGraphics.unlockAchievement('first_birth'); } console.log(`🐣 Baby ${baby.species} born! (${baby.genetics.mutation || 'normal'})`); return baby; } // ========== BABY CARE ========== updateBabies(delta) { const dayInMs = 86400000; for (let i = this.babies.length - 1; i >= 0; i--) { const baby = this.babies[i]; // Hunger baby.hunger -= (delta / 60000) * 1; // 1% per minute baby.hunger = Math.max(0, baby.hunger); // Growth (only if fed) if (baby.hunger > 30) { baby.age += delta / dayInMs; baby.growthProgress = baby.age / 14; // 14 days to adult // Stage progression if (baby.age > 3 && baby.stage === 'baby') { baby.stage = 'teen'; console.log(`🐑 ${baby.species} is now a teen!`); } if (baby.age > 14 && baby.stage === 'teen') { baby.stage = 'adult'; this.babies.splice(i, 1); // Remove from babies console.log(`🐑 ${baby.species} is now an adult!`); } } // Bonding (if player nearby) if (this.isPlayerNearby(baby)) { baby.bonding += (delta / 120000) * 1; // 1% per 2 minutes baby.bonding = Math.min(100, baby.bonding); } // Starving if (baby.hunger === 0) { console.log(`💀 Baby ${baby.species} starved!`); this.animals.delete(baby.id); this.babies.splice(i, 1); } } } feedBaby(baby, food) { if (!baby || baby.stage === 'adult') return false; baby.hunger = Math.min(100, baby.hunger + 30); baby.bonding += 5; console.log(`🍼 Fed baby ${baby.species}`); return true; } isPlayerNearby(animal) { if (!this.scene.player) return false; const playerPos = this.scene.player.getPosition(); const distance = Math.sqrt( Math.pow(animal.x - playerPos.x, 2) + Math.pow(animal.y - playerPos.y, 2) ); return distance < 3; } // ========== BREEDING STATIONS ========== buildBreedingStation(type, x, y) { const stations = { love_pen: { name: 'Love Pen', capacity: 10, autoBreed: true, cost: { wood: 20, fence: 10 } }, incubation_chamber: { name: 'Incubation Chamber', capacity: 5, temperature: 37, cost: { iron: 15, glass: 10 } }, mutation_lab: { name: 'Mutation Lab', capacity: 2, mutantOnly: true, cost: { steel: 30, circuit: 20 } }, cloning_vat: { name: 'Cloning Vat', capacity: 1, cloning: true, cost: { energy_crystal: 10, bio_gel: 50 } } }; const stationData = stations[type]; if (!stationData) return null; const station = { id: `${type}_${x}_${y}`, type, x, y, ...stationData, animals: [], active: true }; this.breedingStations.set(station.id, station); console.log(`🏠 Built ${stationData.name} at (${x}, ${y})`); return station; } addAnimalToStation(stationId, animalId) { const station = this.breedingStations.get(stationId); const animal = this.animals.get(animalId); if (!station || !animal) return false; if (station.animals.length >= station.capacity) { console.log('❌ Station is full'); return false; } station.animals.push(animalId); animal.x = station.x; animal.y = station.y; console.log(`🐑 Added ${animal.species} to ${station.name}`); return true; } updateBreedingStations() { for (const station of this.breedingStations.values()) { if (!station.active || !station.autoBreed) continue; // Try to breed animals in station const stationAnimals = station.animals .map(id => this.animals.get(id)) .filter(a => a); for (let i = 0; i < stationAnimals.length; i++) { for (let j = i + 1; j < stationAnimals.length; j++) { this.attemptBreeding(stationAnimals[i], stationAnimals[j]); } } } } // ========== MUTANT BREEDING ========== breedMutants(mutant1, mutant2, mutationSerum = false) { if (!mutationSerum) { console.log('❌ Requires Mutation Serum!'); return { result: 'no_serum' }; } // Failure chances const roll = Math.random(); if (roll < 0.5) { console.log('💀 Breeding failed - creature died'); return { result: 'death' }; } if (roll < 0.8) { console.log('🚫 Offspring is sterile'); return { result: 'sterile' }; } // Success! const offspring = this.breed(mutant1, mutant2); return { result: 'success', offspring, loot: ['mutant_hide', 'mutant_horn', 'mutant_blood'] }; } // ========== AUTO-BREEDING ========== updateAutoBreeding() { if (!this.settings.autoBreeding) return; const animals = Array.from(this.animals.values()); for (let i = 0; i < animals.length; i++) { for (let j = i + 1; j < animals.length; j++) { this.attemptBreeding(animals[i], animals[j]); } } } // ========== UPDATE ========== update(delta) { this.updateGestation(delta); this.updateBabies(delta); this.updateBreedingStations(); this.updateAutoBreeding(); } // ========== PERSISTENCE ========== saveProgress() { const data = { animals: Array.from(this.animals.values()).map(a => ({ id: a.id, species: a.species, gender: a.gender, genetics: a.genetics, age: a.age, stage: a.stage })), stations: Array.from(this.breedingStations.values()).map(s => ({ id: s.id, type: s.type, x: s.x, y: s.y })) }; localStorage.setItem('novafarma_animal_breeding', JSON.stringify(data)); } loadProgress() { const saved = localStorage.getItem('novafarma_animal_breeding'); if (saved) { try { const data = JSON.parse(saved); console.log('✅ Animal breeding progress loaded'); } catch (error) { console.error('Failed to load breeding progress:', error); } } } destroy() { this.saveProgress(); console.log('🐑 Animal Breeding System destroyed'); } }