This commit is contained in:
2025-12-13 00:02:38 +01:00
parent 93757fc8c4
commit 0b65d86e65
34 changed files with 13572 additions and 1210 deletions

View File

@@ -0,0 +1,591 @@
/**
* 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');
}
}