narejeno
This commit is contained in:
563
src/systems/FarmAutomationSystem.js
Normal file
563
src/systems/FarmAutomationSystem.js
Normal file
@@ -0,0 +1,563 @@
|
||||
/**
|
||||
* FARM AUTOMATION SYSTEM
|
||||
* Complete automation with zombie workers, creature helpers, buildings, and power grid
|
||||
*/
|
||||
class FarmAutomationSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.enabled = true;
|
||||
|
||||
// Workers
|
||||
this.zombieWorkers = [];
|
||||
this.creatureWorkers = [];
|
||||
this.taskQueue = [];
|
||||
|
||||
// Buildings
|
||||
this.automationBuildings = new Map();
|
||||
this.powerGrid = new Map();
|
||||
|
||||
// Power system
|
||||
this.totalPower = 0;
|
||||
this.powerConsumption = 0;
|
||||
|
||||
// Settings
|
||||
this.settings = {
|
||||
maxZombieWorkers: 10,
|
||||
maxCreatureWorkers: 5,
|
||||
zombieEfficiency: 0.7, // 70% of player speed
|
||||
powerUpdateInterval: 1000 // ms
|
||||
};
|
||||
|
||||
this.loadProgress();
|
||||
this.init();
|
||||
|
||||
console.log('✅ Farm Automation System initialized');
|
||||
}
|
||||
|
||||
init() {
|
||||
// Start power update loop
|
||||
this.startPowerUpdate();
|
||||
console.log('🤖 Farm automation ready');
|
||||
}
|
||||
|
||||
// ========== ZOMBIE WORKER SYSTEM ==========
|
||||
|
||||
hireZombieWorker(name = 'Zombie') {
|
||||
if (this.zombieWorkers.length >= this.settings.maxZombieWorkers) {
|
||||
console.log('❌ Max zombie workers reached');
|
||||
return null;
|
||||
}
|
||||
|
||||
const worker = {
|
||||
id: `zombie_${Date.now()}`,
|
||||
name,
|
||||
type: 'zombie',
|
||||
level: 1,
|
||||
xp: 0,
|
||||
efficiency: this.settings.zombieEfficiency,
|
||||
currentTask: null,
|
||||
position: { x: 0, y: 0 },
|
||||
hunger: 100,
|
||||
fatigue: 0,
|
||||
sprite: null
|
||||
};
|
||||
|
||||
this.zombieWorkers.push(worker);
|
||||
this.saveProgress();
|
||||
console.log(`🧟 Hired zombie worker: ${name}`);
|
||||
return worker;
|
||||
}
|
||||
|
||||
assignTask(worker, task) {
|
||||
if (!worker) return false;
|
||||
|
||||
worker.currentTask = {
|
||||
type: task.type, // 'plant', 'harvest', 'water'
|
||||
target: task.target,
|
||||
priority: task.priority || 1,
|
||||
startTime: Date.now()
|
||||
};
|
||||
|
||||
console.log(`📋 ${worker.name} assigned to ${task.type}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
addToTaskQueue(task) {
|
||||
this.taskQueue.push({
|
||||
...task,
|
||||
id: `task_${Date.now()}`,
|
||||
status: 'pending'
|
||||
});
|
||||
|
||||
// Assign to available worker
|
||||
this.assignNextTask();
|
||||
}
|
||||
|
||||
assignNextTask() {
|
||||
// Find idle worker
|
||||
const idleWorker = [...this.zombieWorkers, ...this.creatureWorkers]
|
||||
.find(w => !w.currentTask);
|
||||
|
||||
if (!idleWorker || this.taskQueue.length === 0) return;
|
||||
|
||||
// Get highest priority task
|
||||
this.taskQueue.sort((a, b) => b.priority - a.priority);
|
||||
const task = this.taskQueue.shift();
|
||||
|
||||
this.assignTask(idleWorker, task);
|
||||
}
|
||||
|
||||
completeTask(worker) {
|
||||
if (!worker || !worker.currentTask) return;
|
||||
|
||||
const task = worker.currentTask;
|
||||
|
||||
// Give XP
|
||||
this.addWorkerXP(worker, 10);
|
||||
|
||||
// Increase fatigue
|
||||
worker.fatigue += 10;
|
||||
|
||||
// Clear task
|
||||
worker.currentTask = null;
|
||||
|
||||
// Assign next task
|
||||
this.assignNextTask();
|
||||
|
||||
console.log(`✅ ${worker.name} completed ${task.type}`);
|
||||
}
|
||||
|
||||
addWorkerXP(worker, amount) {
|
||||
worker.xp += amount;
|
||||
|
||||
// Level up check
|
||||
const xpNeeded = worker.level * 100;
|
||||
if (worker.xp >= xpNeeded) {
|
||||
worker.level++;
|
||||
worker.xp = 0;
|
||||
worker.efficiency += 0.05; // 5% faster per level
|
||||
console.log(`⬆️ ${worker.name} leveled up to ${worker.level}!`);
|
||||
}
|
||||
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
// ========== CREATURE WORKER SYSTEM ==========
|
||||
|
||||
tameCreature(creatureType, name) {
|
||||
if (this.creatureWorkers.length >= this.settings.maxCreatureWorkers) {
|
||||
console.log('❌ Max creature workers reached');
|
||||
return null;
|
||||
}
|
||||
|
||||
const specialties = {
|
||||
donkey: { specialty: 'transport', efficiency: 1.0 },
|
||||
bigfoot: { specialty: 'gathering', efficiency: 1.2 },
|
||||
yeti: { specialty: 'snow_tasks', efficiency: 1.1 },
|
||||
elf: { specialty: 'crafting', efficiency: 1.3 }
|
||||
};
|
||||
|
||||
const data = specialties[creatureType] || { specialty: 'general', efficiency: 0.8 };
|
||||
|
||||
const worker = {
|
||||
id: `creature_${Date.now()}`,
|
||||
name,
|
||||
type: creatureType,
|
||||
specialty: data.specialty,
|
||||
level: 1,
|
||||
xp: 0,
|
||||
efficiency: data.efficiency,
|
||||
currentTask: null,
|
||||
position: { x: 0, y: 0 },
|
||||
hunger: 100,
|
||||
fatigue: 0,
|
||||
sprite: null
|
||||
};
|
||||
|
||||
this.creatureWorkers.push(worker);
|
||||
this.saveProgress();
|
||||
console.log(`🦌 Tamed ${creatureType}: ${name} (${data.specialty})`);
|
||||
return worker;
|
||||
}
|
||||
|
||||
// ========== AUTOMATION BUILDINGS ==========
|
||||
|
||||
buildAutomation(type, x, y) {
|
||||
const buildings = {
|
||||
'auto_planter': {
|
||||
name: 'Auto-Planter',
|
||||
powerCost: 10,
|
||||
range: 3,
|
||||
speed: 2000 // ms per action
|
||||
},
|
||||
'auto_harvester': {
|
||||
name: 'Auto-Harvester',
|
||||
powerCost: 15,
|
||||
range: 5,
|
||||
speed: 1500
|
||||
},
|
||||
'irrigation': {
|
||||
name: 'Irrigation System',
|
||||
powerCost: 5,
|
||||
range: 10,
|
||||
speed: 3000
|
||||
},
|
||||
'conveyor': {
|
||||
name: 'Conveyor Belt',
|
||||
powerCost: 3,
|
||||
range: 1,
|
||||
speed: 500
|
||||
},
|
||||
'silo': {
|
||||
name: 'Storage Silo',
|
||||
powerCost: 2,
|
||||
capacity: 1000
|
||||
},
|
||||
'sorter': {
|
||||
name: 'Sorting Machine',
|
||||
powerCost: 8,
|
||||
speed: 1000
|
||||
}
|
||||
};
|
||||
|
||||
const buildingData = buildings[type];
|
||||
if (!buildingData) return null;
|
||||
|
||||
const building = {
|
||||
id: `${type}_${x}_${y}`,
|
||||
type,
|
||||
x, y,
|
||||
...buildingData,
|
||||
active: false,
|
||||
lastAction: 0
|
||||
};
|
||||
|
||||
this.automationBuildings.set(building.id, building);
|
||||
this.updatePowerConsumption();
|
||||
this.saveProgress();
|
||||
|
||||
console.log(`🏭 Built ${buildingData.name} at (${x}, ${y})`);
|
||||
return building;
|
||||
}
|
||||
|
||||
activateBuilding(buildingId) {
|
||||
const building = this.automationBuildings.get(buildingId);
|
||||
if (!building) return false;
|
||||
|
||||
// Check power
|
||||
if (this.totalPower < this.powerConsumption + building.powerCost) {
|
||||
console.log('❌ Not enough power!');
|
||||
return false;
|
||||
}
|
||||
|
||||
building.active = true;
|
||||
this.updatePowerConsumption();
|
||||
console.log(`⚡ Activated ${building.name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
deactivateBuilding(buildingId) {
|
||||
const building = this.automationBuildings.get(buildingId);
|
||||
if (!building) return false;
|
||||
|
||||
building.active = false;
|
||||
this.updatePowerConsumption();
|
||||
console.log(`🔌 Deactivated ${building.name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ========== POWER SYSTEM ==========
|
||||
|
||||
buildPowerSource(type, x, y) {
|
||||
const sources = {
|
||||
'windmill': { name: 'Windmill', power: 20, cost: { wood: 10, iron: 5 } },
|
||||
'water_wheel': { name: 'Water Wheel', power: 15, cost: { wood: 8, iron: 3 } },
|
||||
'solar_panel': { name: 'Solar Panel', power: 25, cost: { iron: 10, glass: 5 } },
|
||||
'zombie_treadmill': { name: 'Zombie Treadmill', power: 10, cost: { wood: 5 } }
|
||||
};
|
||||
|
||||
const sourceData = sources[type];
|
||||
if (!sourceData) return null;
|
||||
|
||||
const source = {
|
||||
id: `${type}_${x}_${y}`,
|
||||
type,
|
||||
x, y,
|
||||
...sourceData,
|
||||
active: true,
|
||||
currentPower: sourceData.power
|
||||
};
|
||||
|
||||
this.powerGrid.set(source.id, source);
|
||||
this.updateTotalPower();
|
||||
this.saveProgress();
|
||||
|
||||
console.log(`⚡ Built ${sourceData.name} (+${sourceData.power} power)`);
|
||||
return source;
|
||||
}
|
||||
|
||||
updateTotalPower() {
|
||||
this.totalPower = 0;
|
||||
|
||||
for (const source of this.powerGrid.values()) {
|
||||
if (source.active) {
|
||||
// Solar panels only work during day
|
||||
if (source.type === 'solar_panel') {
|
||||
const time = this.scene.weatherSystem?.gameTime || 12;
|
||||
if (time >= 6 && time <= 18) {
|
||||
this.totalPower += source.currentPower;
|
||||
}
|
||||
} else {
|
||||
this.totalPower += source.currentPower;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updatePowerConsumption() {
|
||||
this.powerConsumption = 0;
|
||||
|
||||
for (const building of this.automationBuildings.values()) {
|
||||
if (building.active) {
|
||||
this.powerConsumption += building.powerCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startPowerUpdate() {
|
||||
setInterval(() => {
|
||||
this.updateTotalPower();
|
||||
this.updatePowerConsumption();
|
||||
|
||||
// Deactivate buildings if not enough power
|
||||
if (this.powerConsumption > this.totalPower) {
|
||||
this.handlePowerShortage();
|
||||
}
|
||||
}, this.settings.powerUpdateInterval);
|
||||
}
|
||||
|
||||
handlePowerShortage() {
|
||||
console.log('⚠️ Power shortage! Deactivating low-priority buildings...');
|
||||
|
||||
// Deactivate buildings until power is sufficient
|
||||
for (const building of this.automationBuildings.values()) {
|
||||
if (building.active && this.powerConsumption > this.totalPower) {
|
||||
this.deactivateBuilding(building.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getPowerStatus() {
|
||||
return {
|
||||
total: this.totalPower,
|
||||
consumption: this.powerConsumption,
|
||||
available: this.totalPower - this.powerConsumption,
|
||||
percentage: (this.powerConsumption / this.totalPower) * 100
|
||||
};
|
||||
}
|
||||
|
||||
// ========== WORKER MANAGEMENT ==========
|
||||
|
||||
updateWorkers(delta) {
|
||||
// Update zombie workers
|
||||
for (const worker of this.zombieWorkers) {
|
||||
this.updateWorker(worker, delta);
|
||||
}
|
||||
|
||||
// Update creature workers
|
||||
for (const worker of this.creatureWorkers) {
|
||||
this.updateWorker(worker, delta);
|
||||
}
|
||||
}
|
||||
|
||||
updateWorker(worker, delta) {
|
||||
// Decrease hunger over time
|
||||
worker.hunger -= delta / 60000; // 1% per minute
|
||||
|
||||
// Increase fatigue if working
|
||||
if (worker.currentTask) {
|
||||
worker.fatigue += delta / 30000; // 1% per 30 seconds
|
||||
|
||||
// Complete task if enough time passed
|
||||
const taskDuration = 5000 / worker.efficiency; // Base 5 seconds
|
||||
if (Date.now() - worker.currentTask.startTime > taskDuration) {
|
||||
this.completeTask(worker);
|
||||
}
|
||||
} else {
|
||||
// Recover fatigue when idle
|
||||
worker.fatigue -= delta / 60000;
|
||||
}
|
||||
|
||||
// Clamp values
|
||||
worker.hunger = Math.max(0, Math.min(100, worker.hunger));
|
||||
worker.fatigue = Math.max(0, Math.min(100, worker.fatigue));
|
||||
|
||||
// Worker needs rest
|
||||
if (worker.fatigue > 80) {
|
||||
worker.currentTask = null;
|
||||
console.log(`😴 ${worker.name} is too tired to work`);
|
||||
}
|
||||
|
||||
// Worker needs food
|
||||
if (worker.hunger < 20) {
|
||||
worker.efficiency *= 0.5; // 50% slower when hungry
|
||||
}
|
||||
}
|
||||
|
||||
feedWorker(worker, food) {
|
||||
if (!worker) return false;
|
||||
|
||||
worker.hunger = Math.min(100, worker.hunger + 30);
|
||||
console.log(`🍖 Fed ${worker.name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
restWorker(worker) {
|
||||
if (!worker) return false;
|
||||
|
||||
worker.currentTask = null;
|
||||
worker.fatigue = Math.max(0, worker.fatigue - 50);
|
||||
console.log(`😴 ${worker.name} is resting`);
|
||||
return true;
|
||||
}
|
||||
|
||||
upgradeWorkerTools(worker, toolTier) {
|
||||
if (!worker) return false;
|
||||
|
||||
const tierBonus = {
|
||||
'bronze': 0.1,
|
||||
'iron': 0.2,
|
||||
'steel': 0.3,
|
||||
'enchanted': 0.5
|
||||
};
|
||||
|
||||
const bonus = tierBonus[toolTier] || 0;
|
||||
worker.efficiency += bonus;
|
||||
|
||||
console.log(`⚒️ ${worker.name} upgraded to ${toolTier} tools (+${bonus * 100}% efficiency)`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ========== AUTOMATION UPDATE ==========
|
||||
|
||||
updateAutomation(delta) {
|
||||
const now = Date.now();
|
||||
|
||||
for (const building of this.automationBuildings.values()) {
|
||||
if (!building.active) continue;
|
||||
|
||||
// Check if enough time passed
|
||||
if (now - building.lastAction < building.speed) continue;
|
||||
|
||||
// Perform building action
|
||||
switch (building.type) {
|
||||
case 'auto_planter':
|
||||
this.autoPlant(building);
|
||||
break;
|
||||
case 'auto_harvester':
|
||||
this.autoHarvest(building);
|
||||
break;
|
||||
case 'irrigation':
|
||||
this.autoWater(building);
|
||||
break;
|
||||
case 'conveyor':
|
||||
this.moveItems(building);
|
||||
break;
|
||||
case 'sorter':
|
||||
this.sortItems(building);
|
||||
break;
|
||||
}
|
||||
|
||||
building.lastAction = now;
|
||||
}
|
||||
}
|
||||
|
||||
autoPlant(building) {
|
||||
// Plant crops in range
|
||||
console.log(`🌱 Auto-planter working at (${building.x}, ${building.y})`);
|
||||
}
|
||||
|
||||
autoHarvest(building) {
|
||||
// Harvest crops in range
|
||||
console.log(`🌾 Auto-harvester working at (${building.x}, ${building.y})`);
|
||||
}
|
||||
|
||||
autoWater(building) {
|
||||
// Water crops in range
|
||||
console.log(`💧 Irrigation system working at (${building.x}, ${building.y})`);
|
||||
}
|
||||
|
||||
moveItems(building) {
|
||||
// Move items along conveyor
|
||||
console.log(`📦 Conveyor moving items at (${building.x}, ${building.y})`);
|
||||
}
|
||||
|
||||
sortItems(building) {
|
||||
// Sort items in storage
|
||||
console.log(`🔀 Sorter organizing items at (${building.x}, ${building.y})`);
|
||||
}
|
||||
|
||||
// ========== UPDATE ==========
|
||||
|
||||
update(delta) {
|
||||
this.updateWorkers(delta);
|
||||
this.updateAutomation(delta);
|
||||
}
|
||||
|
||||
// ========== PERSISTENCE ==========
|
||||
|
||||
saveProgress() {
|
||||
const data = {
|
||||
zombieWorkers: this.zombieWorkers.map(w => ({
|
||||
id: w.id,
|
||||
name: w.name,
|
||||
level: w.level,
|
||||
xp: w.xp,
|
||||
efficiency: w.efficiency
|
||||
})),
|
||||
creatureWorkers: this.creatureWorkers.map(w => ({
|
||||
id: w.id,
|
||||
name: w.name,
|
||||
type: w.type,
|
||||
level: w.level,
|
||||
xp: w.xp
|
||||
})),
|
||||
buildings: Array.from(this.automationBuildings.values()).map(b => ({
|
||||
id: b.id,
|
||||
type: b.type,
|
||||
x: b.x,
|
||||
y: b.y,
|
||||
active: b.active
|
||||
})),
|
||||
powerSources: Array.from(this.powerGrid.values()).map(p => ({
|
||||
id: p.id,
|
||||
type: p.type,
|
||||
x: p.x,
|
||||
y: p.y
|
||||
}))
|
||||
};
|
||||
|
||||
localStorage.setItem('novafarma_farm_automation', JSON.stringify(data));
|
||||
}
|
||||
|
||||
loadProgress() {
|
||||
const saved = localStorage.getItem('novafarma_farm_automation');
|
||||
if (saved) {
|
||||
try {
|
||||
const data = JSON.parse(saved);
|
||||
|
||||
// Restore workers (basic data only, full restoration in init)
|
||||
this.savedData = data;
|
||||
|
||||
console.log('✅ Farm automation progress loaded');
|
||||
} catch (error) {
|
||||
console.error('Failed to load farm automation:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.saveProgress();
|
||||
console.log('🤖 Farm Automation System destroyed');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user