559 lines
17 KiB
JavaScript
559 lines
17 KiB
JavaScript
/**
|
||
* AUTOMATION SYSTEM
|
||
* Manages sprinkler system, minting building, auto-harvest, and complete farm automation.
|
||
*
|
||
* Features:
|
||
* - Sprinkler System: 4 tiers (Basic → Automatic entire farm), Water Tower + Pipes
|
||
* - Minting Building: Gold → Zlatniki conversion, passive income
|
||
* - Auto-Harvest: Zombie workers, automated collection, processing
|
||
* - Complete Automation: Fully hands-off farm operation
|
||
*/
|
||
class AutomationSystem {
|
||
constructor(scene) {
|
||
this.scene = scene;
|
||
|
||
// Sprinkler tiers
|
||
this.sprinklerTiers = {
|
||
basic: {
|
||
name: 'Basic Sprinkler',
|
||
range: 1, // Waters 3x3 (1 tile radius)
|
||
cost: { iron: 5, copper: 2 },
|
||
waterUsage: 10
|
||
},
|
||
quality: {
|
||
name: 'Quality Sprinkler',
|
||
range: 2, // Waters 5x5 (2 tile radius)
|
||
cost: { iron: 10, copper: 5, gold: 1 },
|
||
waterUsage: 20
|
||
},
|
||
iridium: {
|
||
name: 'Iridium Sprinkler',
|
||
range: 3, // Waters 7x7 (3 tile radius)
|
||
cost: { iridium: 5, gold: 2, copper: 10 },
|
||
waterUsage: 30
|
||
},
|
||
automatic: {
|
||
name: 'Automatic Sprinkler System',
|
||
range: Infinity, // Waters entire farm!
|
||
cost: { iridium: 50, gold: 100, copper: 200, atlantean_crystal: 10 },
|
||
waterUsage: 0, // Self-sustaining
|
||
legendary: true
|
||
}
|
||
};
|
||
|
||
// Water towers
|
||
this.waterTowers = new Map(); // towerId -> tower data
|
||
|
||
// Sprinklers
|
||
this.sprinklers = new Map(); // sprinklerId -> sprinkler data
|
||
|
||
// Pipe network
|
||
this.pipes = [];
|
||
|
||
// Minting buildings
|
||
this.mintingBuildings = [];
|
||
|
||
// Auto-harvest workers
|
||
this.autoHarvestWorkers = [];
|
||
|
||
// Automation status
|
||
this.fullyAutomated = false;
|
||
|
||
console.log('💦💰 Automation System initialized!');
|
||
}
|
||
|
||
/**
|
||
* Build water tower
|
||
*/
|
||
buildWaterTower(position) {
|
||
const towerId = `tower_${Date.now()}`;
|
||
|
||
const tower = {
|
||
id: towerId,
|
||
position: position,
|
||
capacity: 1000,
|
||
currentWater: 1000,
|
||
refillRate: 10, // Per hour
|
||
connectedSprinklers: []
|
||
};
|
||
|
||
this.waterTowers.set(towerId, tower);
|
||
|
||
console.log('💧 Water Tower built! Capacity: 1000 units.');
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Water Tower Built!',
|
||
message: 'Connect sprinklers with pipes!',
|
||
icon: '💧'
|
||
});
|
||
|
||
return towerId;
|
||
}
|
||
|
||
/**
|
||
* Place sprinkler
|
||
*/
|
||
placeSprinkler(tier, position, connectedTowerId = null) {
|
||
const sprinklerData = this.sprinklerTiers[tier];
|
||
if (!sprinklerData) {
|
||
console.log(`❌ Unknown sprinkler tier: ${tier}`);
|
||
return null;
|
||
}
|
||
|
||
// Check resources
|
||
if (!this.checkResources(sprinklerData.cost)) {
|
||
return { success: false, message: 'Not enough resources!' };
|
||
}
|
||
|
||
// Consume resources
|
||
this.consumeResources(sprinklerData.cost);
|
||
|
||
const sprinklerId = `sprinkler_${tier}_${Date.now()}`;
|
||
|
||
const sprinkler = {
|
||
id: sprinklerId,
|
||
tier: tier,
|
||
name: sprinklerData.name,
|
||
position: position,
|
||
range: sprinklerData.range,
|
||
waterUsage: sprinklerData.waterUsage,
|
||
connectedTower: connectedTowerId,
|
||
active: connectedTowerId !== null || tier === 'automatic',
|
||
coverage: this.calculateCoverage(position, sprinklerData.range)
|
||
};
|
||
|
||
this.sprinklers.set(sprinklerId, sprinkler);
|
||
|
||
// Connect to tower
|
||
if (connectedTowerId) {
|
||
const tower = this.waterTowers.get(connectedTowerId);
|
||
if (tower) {
|
||
tower.connectedSprinklers.push(sprinklerId);
|
||
}
|
||
}
|
||
|
||
console.log(`💦 Placed ${sprinklerData.name}! Watering ${sprinkler.coverage.length} tiles.`);
|
||
|
||
return { success: true, sprinklerId: sprinklerId };
|
||
}
|
||
|
||
/**
|
||
* Calculate coverage area
|
||
*/
|
||
calculateCoverage(position, range) {
|
||
if (range === Infinity) {
|
||
return ['entire_farm']; // Special case for automatic
|
||
}
|
||
|
||
const coverage = [];
|
||
|
||
for (let dx = -range; dx <= range; dx++) {
|
||
for (let dy = -range; dy <= range; dy++) {
|
||
// Check if within circular range
|
||
if (Math.sqrt(dx * dx + dy * dy) <= range) {
|
||
coverage.push({
|
||
x: position.x + dx,
|
||
y: position.y + dy
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
return coverage;
|
||
}
|
||
|
||
/**
|
||
* Lay pipe between tower and sprinkler
|
||
*/
|
||
layPipe(fromPosition, toPosition) {
|
||
const distance = Phaser.Math.Distance.Between(
|
||
fromPosition.x, fromPosition.y,
|
||
toPosition.x, toPosition.y
|
||
);
|
||
|
||
const pipeCost = Math.ceil(distance / 10); // 1 pipe per 10 tiles
|
||
|
||
const pipe = {
|
||
id: `pipe_${Date.now()}`,
|
||
from: fromPosition,
|
||
to: toPosition,
|
||
length: distance,
|
||
cost: { copper: pipeCost }
|
||
};
|
||
|
||
// Check and consume resources
|
||
if (!this.checkResources(pipe.cost)) {
|
||
return { success: false, message: 'Not enough copper!' };
|
||
}
|
||
|
||
this.consumeResources(pipe.cost);
|
||
this.pipes.push(pipe);
|
||
|
||
console.log(`🔧 Laid ${Math.ceil(distance)} tiles of pipe. Cost: ${pipeCost} copper.`);
|
||
|
||
return { success: true, pipeId: pipe.id };
|
||
}
|
||
|
||
/**
|
||
* Water crops (called daily)
|
||
*/
|
||
waterCrops() {
|
||
let totalWatered = 0;
|
||
|
||
this.sprinklers.forEach((sprinkler, id) => {
|
||
if (!sprinkler.active) return;
|
||
|
||
// Check water tower
|
||
if (sprinkler.connectedTower && sprinkler.tier !== 'automatic') {
|
||
const tower = this.waterTowers.get(sprinkler.connectedTower);
|
||
if (!tower || tower.currentWater < sprinkler.waterUsage) {
|
||
console.log(`⚠️ ${sprinkler.name} out of water!`);
|
||
return;
|
||
}
|
||
|
||
// Use water
|
||
tower.currentWater -= sprinkler.waterUsage;
|
||
}
|
||
|
||
// Water covered tiles
|
||
sprinkler.coverage.forEach(tile => {
|
||
// In real game, would actually water crop at this position
|
||
totalWatered++;
|
||
});
|
||
});
|
||
|
||
if (totalWatered > 0) {
|
||
console.log(`💦 Sprinklers watered ${totalWatered} tiles!`);
|
||
}
|
||
|
||
// Refill water towers
|
||
this.refillWaterTowers();
|
||
}
|
||
|
||
/**
|
||
* Refill water towers
|
||
*/
|
||
refillWaterTowers() {
|
||
this.waterTowers.forEach((tower, id) => {
|
||
tower.currentWater = Math.min(tower.capacity, tower.currentWater + tower.refillRate);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Build minting building
|
||
*/
|
||
buildMintingBuilding(position) {
|
||
const mintId = `mint_${Date.now()}`;
|
||
|
||
const mint = {
|
||
id: mintId,
|
||
position: position,
|
||
goldInput: 0,
|
||
goldCapacity: 1000,
|
||
conversionRate: 10, // 10 gold = 1 Zł (Złotnik/Zlatnik)
|
||
dailyOutput: 0,
|
||
active: true
|
||
};
|
||
|
||
this.mintingBuildings.push(mint);
|
||
|
||
console.log('💰 Minting Building constructed!');
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Minting Building!',
|
||
message: 'Convert gold to Zlatniki!',
|
||
icon: '💰'
|
||
});
|
||
|
||
return mintId;
|
||
}
|
||
|
||
/**
|
||
* Deposit gold into mint
|
||
*/
|
||
depositGoldToMint(mintId, amount) {
|
||
const mint = this.mintingBuildings.find(m => m.id === mintId);
|
||
if (!mint) {
|
||
return { success: false, message: 'Mint not found' };
|
||
}
|
||
|
||
if (mint.goldInput + amount > mint.goldCapacity) {
|
||
return { success: false, message: 'Mint capacity exceeded!' };
|
||
}
|
||
|
||
// Check if player has gold
|
||
if (this.scene.player && this.scene.player.gold < amount) {
|
||
return { success: false, message: 'Not enough gold!' };
|
||
}
|
||
|
||
// Deduct gold from player
|
||
if (this.scene.player) {
|
||
this.scene.player.gold -= amount;
|
||
}
|
||
|
||
mint.goldInput += amount;
|
||
|
||
console.log(`💰 Deposited ${amount} gold to mint. Total: ${mint.goldInput}/${mint.goldCapacity}`);
|
||
|
||
return { success: true, total: mint.goldInput };
|
||
}
|
||
|
||
/**
|
||
* Process minting (called daily)
|
||
*/
|
||
processMinting() {
|
||
this.mintingBuildings.forEach(mint => {
|
||
if (!mint.active || mint.goldInput < mint.conversionRate) return;
|
||
|
||
// Convert gold to Zlatniki
|
||
const conversions = Math.floor(mint.goldInput / mint.conversionRate);
|
||
const goldUsed = conversions * mint.conversionRate;
|
||
|
||
mint.goldInput -= goldUsed;
|
||
mint.dailyOutput = conversions;
|
||
|
||
// Add currency to player
|
||
if (this.scene.player) {
|
||
this.scene.player.currency = (this.scene.player.currency || 0) + conversions;
|
||
}
|
||
|
||
console.log(`💰 Mint produced ${conversions} Zlatniki! (Used ${goldUsed} gold)`);
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Minting Complete!',
|
||
message: `+${conversions} Zlatniki minted!`,
|
||
icon: '💰'
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Assign zombie to auto-harvest
|
||
*/
|
||
assignAutoHarvest(zombieId) {
|
||
if (this.autoHarvestWorkers.includes(zombieId)) {
|
||
console.log('ℹ️ Zombie already assigned to auto-harvest!');
|
||
return false;
|
||
}
|
||
|
||
// Check if zombie is Lv5+
|
||
if (this.scene.smartZombieSystem) {
|
||
const zombie = this.scene.smartZombieSystem.zombies.get(zombieId);
|
||
if (!zombie || zombie.level < 5) {
|
||
console.log('❌ Zombie must be Lv5+ for auto-harvest!');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
this.autoHarvestWorkers.push(zombieId);
|
||
|
||
console.log(`🧟 Zombie assigned to auto-harvest! Total workers: ${this.autoHarvestWorkers.length}`);
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Auto-Harvest Active!',
|
||
message: 'Zombie will harvest crops automatically!',
|
||
icon: '🧟'
|
||
});
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Auto-harvest crops (called daily)
|
||
*/
|
||
autoHarvestCrops() {
|
||
if (this.autoHarvestWorkers.length === 0) return;
|
||
|
||
let totalHarvested = 0;
|
||
|
||
this.autoHarvestWorkers.forEach(zombieId => {
|
||
// Simulate harvesting (in real game, would check for mature crops)
|
||
const harvestedCrops = Math.floor(Math.random() * 20) + 10; // 10-30 crops
|
||
totalHarvested += harvestedCrops;
|
||
});
|
||
|
||
console.log(`🌾 Auto-harvest: ${totalHarvested} crops collected by ${this.autoHarvestWorkers.length} zombies!`);
|
||
|
||
if (totalHarvested > 0) {
|
||
this.scene.events.emit('notification', {
|
||
title: 'Auto-Harvest Complete!',
|
||
message: `${totalHarvested} crops automatically collected!`,
|
||
icon: '🌾'
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Enable full automation (requires all systems)
|
||
*/
|
||
enableFullAutomation() {
|
||
// Check requirements
|
||
const hasAutomaticSprinkler = Array.from(this.sprinklers.values()).some(s => s.tier === 'automatic');
|
||
const hasMint = this.mintingBuildings.length > 0;
|
||
const hasAutoHarvest = this.autoHarvestWorkers.length >= 3;
|
||
const hasZombieWorkers = this.scene.smartZombieSystem?.independentWorkers.length >= 5;
|
||
|
||
if (!hasAutomaticSprinkler) {
|
||
return { success: false, message: 'Need Automatic Sprinkler System!' };
|
||
}
|
||
|
||
if (!hasMint) {
|
||
return { success: false, message: 'Need Minting Building!' };
|
||
}
|
||
|
||
if (!hasAutoHarvest) {
|
||
return { success: false, message: 'Need at least 3 auto-harvest zombies!' };
|
||
}
|
||
|
||
if (!hasZombieWorkers) {
|
||
return { success: false, message: 'Need at least 5 Lv8+ independent zombies!' };
|
||
}
|
||
|
||
this.fullyAutomated = true;
|
||
|
||
console.log('🏆 FULL AUTOMATION ACHIEVED!');
|
||
console.log('Your farm now runs completely hands-off!');
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'FULL AUTOMATION!',
|
||
message: 'Your farm is now fully autonomous!',
|
||
icon: '🏆'
|
||
});
|
||
|
||
this.scene.events.emit('achievement-unlocked', {
|
||
id: 'full_automation',
|
||
title: 'The Ultimate Farmer',
|
||
description: 'Achieve complete farm automation',
|
||
reward: 'Legendary Farmer Title'
|
||
});
|
||
|
||
return { success: true };
|
||
}
|
||
|
||
/**
|
||
* Run all automation tasks (called daily)
|
||
*/
|
||
runDailyAutomation() {
|
||
console.log('⚙️ Running daily automation...');
|
||
|
||
this.waterCrops();
|
||
this.autoHarvestCrops();
|
||
this.processMinting();
|
||
|
||
if (this.fullyAutomated) {
|
||
// Additional benefits for full automation
|
||
const passiveGold = 500;
|
||
if (this.scene.player) {
|
||
this.scene.player.gold = (this.scene.player.gold || 0) + passiveGold;
|
||
}
|
||
|
||
console.log(`💰 Full automation bonus: +${passiveGold} gold!`);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check resources
|
||
*/
|
||
checkResources(cost) {
|
||
// Placeholder - in real game would check inventory
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Consume resources
|
||
*/
|
||
consumeResources(cost) {
|
||
// Placeholder - in real game would remove from inventory
|
||
Object.keys(cost).forEach(resource => {
|
||
console.log(`Consumed ${cost[resource]} ${resource}`);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Get automation stats
|
||
*/
|
||
getAutomationStats() {
|
||
return {
|
||
waterTowers: this.waterTowers.size,
|
||
sprinklers: this.sprinklers.size,
|
||
automaticSprinkler: Array.from(this.sprinklers.values()).some(s => s.tier === 'automatic'),
|
||
pipes: this.pipes.length,
|
||
mintingBuildings: this.mintingBuildings.length,
|
||
autoHarvestWorkers: this.autoHarvestWorkers.length,
|
||
fullyAutomated: this.fullyAutomated,
|
||
dailyGoldProduction: this.mintingBuildings.reduce((sum, m) => sum + m.dailyOutput, 0),
|
||
wateredTiles: Array.from(this.sprinklers.values()).reduce((sum, s) => {
|
||
return sum + (s.coverage.length || 0);
|
||
}, 0)
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Upgrade sprinkler
|
||
*/
|
||
upgradeSprinkler(sprinklerId, newTier) {
|
||
const sprinkler = this.sprinklers.get(sprinklerId);
|
||
if (!sprinkler) {
|
||
return { success: false, message: 'Sprinkler not found!' };
|
||
}
|
||
|
||
const newData = this.sprinklerTiers[newTier];
|
||
if (!newData) {
|
||
return { success: false, message: 'Invalid tier!' };
|
||
}
|
||
|
||
// Check if upgrade is valid (can't downgrade)
|
||
const tierOrder = ['basic', 'quality', 'iridium', 'automatic'];
|
||
const currentIndex = tierOrder.indexOf(sprinkler.tier);
|
||
const newIndex = tierOrder.indexOf(newTier);
|
||
|
||
if (newIndex <= currentIndex) {
|
||
return { success: false, message: 'Must upgrade to higher tier!' };
|
||
}
|
||
|
||
// Check and consume resources
|
||
if (!this.checkResources(newData.cost)) {
|
||
return { success: false, message: 'Not enough resources!' };
|
||
}
|
||
|
||
this.consumeResources(newData.cost);
|
||
|
||
// Upgrade
|
||
sprinkler.tier = newTier;
|
||
sprinkler.name = newData.name;
|
||
sprinkler.range = newData.range;
|
||
sprinkler.waterUsage = newData.waterUsage;
|
||
sprinkler.coverage = this.calculateCoverage(sprinkler.position, newData.range);
|
||
|
||
console.log(`⬆️ Upgraded to ${newData.name}!`);
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Sprinkler Upgraded!',
|
||
message: `Now ${newData.name}!`,
|
||
icon: '⬆️'
|
||
});
|
||
|
||
return { success: true };
|
||
}
|
||
|
||
/**
|
||
* Get sprinkler info
|
||
*/
|
||
getSprinklerInfo(sprinklerId) {
|
||
const sprinkler = this.sprinklers.get(sprinklerId);
|
||
if (!sprinkler) return null;
|
||
|
||
return {
|
||
name: sprinkler.name,
|
||
tier: sprinkler.tier,
|
||
range: sprinkler.range === Infinity ? 'Entire Farm' : `${sprinkler.range} tiles`,
|
||
coverage: sprinkler.coverage.length === 1 && sprinkler.coverage[0] === 'entire_farm'
|
||
? 'Entire Farm'
|
||
: `${sprinkler.coverage.length} tiles`,
|
||
waterUsage: sprinkler.tier === 'automatic' ? 'Self-Sustaining' : `${sprinkler.waterUsage} units/day`,
|
||
active: sprinkler.active,
|
||
connected: sprinkler.connectedTower !== null || sprinkler.tier === 'automatic'
|
||
};
|
||
}
|
||
}
|