Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/MicroFarmExpansionSystem.js
2026-01-16 02:43:46 +01:00

499 lines
14 KiB
JavaScript

/**
* MicroFarmExpansionSystem.js
* ============================
* KRVAVA ŽETEV - Micro Farm & Expansion System (Phase 37)
*
* Features:
* - 8x8 starting micro farm
* - Expansion system (2x2 tiles at a time)
* - Land type mechanics (Grass, Forest, Rocky, Swamp)
* - Zombie clearing crews
* - Resource costs
* - Tutorial integration
*
* @author NovaFarma Team
* @date 2025-12-23
*/
export default class MicroFarmExpansionSystem {
constructor(scene) {
this.scene = scene;
// Farm grid (tile-based)
this.farmSize = { width: 8, height: 8 }; // Starting size
this.maxSize = { width: 64, height: 64 }; // Maximum farm size
this.tileSize = 48; // Pixels per tile
// Expansion state
this.unlockedTiles = new Set();
this.expansionQueue = [];
// Land types
this.landTypes = new Map();
// Tutorial state
this.tutorialComplete = false;
this.tutorialStep = 0;
console.log('🌾 MicroFarmExpansionSystem initialized');
// Initialize starting farm
this.initializeStartingFarm();
// Register land types
this.registerLandTypes();
}
/**
* Initialize 8x8 starting micro farm
*/
initializeStartingFarm() {
const centerX = Math.floor(this.maxSize.width / 2);
const centerY = Math.floor(this.maxSize.height / 2);
// Unlock center 8x8 area
for (let x = centerX - 4; x < centerX + 4; x++) {
for (let y = centerY - 4; y < centerY + 4; y++) {
const tileKey = `${x},${y}`;
this.unlockedTiles.add(tileKey);
// Mark as grass (cleared)
this.landTypes.set(tileKey, {
type: 'grass',
cleared: true,
fertility: 100
});
}
}
console.log(`✅ Micro farm initialized: 8x8 tiles (64 tiles total)`);
console.log(` Center: (${centerX}, ${centerY})`);
// Show starting area
this.visualizeFarm();
// Start tutorial
this.startTutorial();
}
/**
* Register land types
*/
registerLandTypes() {
// Land type definitions
const types = {
grass: {
name: 'Grass',
icon: '🌿',
clearingRequired: false,
clearingCost: { zlatniki: 0 },
fertility: 100
},
forest: {
name: 'Forest',
icon: '🌲',
clearingRequired: true,
clearingCost: { zlatniki: 50, wood: 0 }, // Get wood from clearing
clearingTask: 'chop_trees',
clearingTime: 60, // seconds
fertility: 80
},
rocky: {
name: 'Rocky',
icon: '⛰️',
clearingRequired: true,
clearingCost: { zlatniki: 100, stone: 0 }, // Get stone from clearing
clearingTask: 'mine_rocks',
clearingTime: 90,
fertility: 50
},
swamp: {
name: 'Swamp',
icon: '💧',
clearingRequired: true,
clearingCost: { zlatniki: 150 },
clearingTask: 'drain_water',
clearingTime: 120,
fertility: 90 // High fertility after drainage!
}
};
console.log(`✅ Registered ${Object.keys(types).length} land types`);
}
/**
* Expand farm by 2x2 area
*/
expandFarm(direction) {
const expansionSize = 2; // Expand by 2x2 tiles
const cost = this.calculateExpansionCost(direction);
// Check if player can afford
if (!this.canAffordExpansion(cost)) {
this.showNotification({
title: 'Cannot Expand',
text: `Need ${cost.zlatniki}Ž, ${cost.wood || 0} Wood, ${cost.stone || 0} Stone`,
icon: '💰'
});
return false;
}
// Get expansion tiles
const newTiles = this.getExpansionTiles(direction, expansionSize);
if (newTiles.length === 0) {
this.showNotification({
title: 'Cannot Expand',
text: 'Maximum farm size reached or invalid direction!',
icon: '🚫'
});
return false;
}
// Pay cost
this.payExpansionCost(cost);
// Add to expansion queue
this.queueExpansion(newTiles);
console.log(`🌾 Expanding farm ${direction}: +${newTiles.length} tiles`);
this.showNotification({
title: 'Expansion Started!',
text: `🌾 Expanding ${direction}! Send zombies to clear the land!`,
icon: '🚜'
});
return true;
}
/**
* Get tiles for expansion
*/
getExpansionTiles(direction, size) {
const tiles = [];
const bounds = this.getCurrentBounds();
switch (direction) {
case 'north':
for (let x = bounds.minX; x <= bounds.maxX; x++) {
for (let y = bounds.minY - size; y < bounds.minY; y++) {
tiles.push({ x, y });
}
}
break;
case 'south':
for (let x = bounds.minX; x <= bounds.maxX; x++) {
for (let y = bounds.maxY + 1; y <= bounds.maxY + size; y++) {
tiles.push({ x, y });
}
}
break;
case 'east':
for (let x = bounds.maxX + 1; x <= bounds.maxX + size; x++) {
for (let y = bounds.minY; y <= bounds.maxY; y++) {
tiles.push({ x, y });
}
}
break;
case 'west':
for (let x = bounds.minX - size; x < bounds.minX; x++) {
for (let y = bounds.minY; y <= bounds.maxY; y++) {
tiles.push({ x, y });
}
}
break;
}
// Filter out already unlocked tiles
return tiles.filter(tile => !this.unlockedTiles.has(`${tile.x},${tile.y}`));
}
/**
* Get current farm bounds
*/
getCurrentBounds() {
let minX = Infinity, minY = Infinity;
let maxX = -Infinity, maxY = -Infinity;
this.unlockedTiles.forEach(tileKey => {
const [x, y] = tileKey.split(',').map(Number);
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
});
return { minX, minY, maxX, maxY };
}
/**
* Calculate expansion cost
*/
calculateExpansionCost(direction) {
const baseZlatniki = 100;
const currentSize = this.unlockedTiles.size;
// Cost increases with farm size
const zlatniki = baseZlatniki + Math.floor(currentSize / 10) * 50;
return {
zlatniki: zlatniki,
wood: 10,
stone: 5
};
}
/**
* Check if player can afford expansion
*/
canAffordExpansion(cost) {
// TODO: Check actual player resources
// For now, return true
return true;
}
/**
* Pay expansion cost
*/
payExpansionCost(cost) {
console.log(`💰 Paid: ${cost.zlatniki}Ž, ${cost.wood} Wood, ${cost.stone} Stone`);
// TODO: Actually deduct from player inventory
}
/**
* Queue expansion for zombie clearing
*/
queueExpansion(tiles) {
tiles.forEach(tile => {
const tileKey = `${tile.x},${tile.y}`;
// Randomly assign land type
const landType = this.getRandomLandType();
this.landTypes.set(tileKey, {
type: landType,
cleared: landType === 'grass', // Grass is pre-cleared
fertility: this.getLandTypeFertility(landType),
clearingProgress: 0
});
this.expansionQueue.push({
tileKey: tileKey,
tile: tile,
landType: landType,
status: 'queued'
});
});
console.log(`📋 Queued ${tiles.length} tiles for expansion`);
}
/**
* Get random land type
*/
getRandomLandType() {
const types = ['grass', 'forest', 'rocky', 'swamp'];
const weights = [40, 30, 20, 10]; // Grass more common
const total = weights.reduce((a, b) => a + b, 0);
let random = Math.random() * total;
for (let i = 0; i < types.length; i++) {
random -= weights[i];
if (random <= 0) return types[i];
}
return 'grass';
}
/**
* Get land type fertility
*/
getLandTypeFertility(type) {
const fertility = {
grass: 100,
forest: 80,
rocky: 50,
swamp: 90
};
return fertility[type] || 100;
}
/**
* Send zombies to clear land
*/
sendZombiesToClear(tileKey, zombieIds) {
const land = this.landTypes.get(tileKey);
if (!land) {
console.error(`Tile ${tileKey} not found!`);
return false;
}
if (land.cleared) {
console.log(`Tile ${tileKey} already cleared!`);
return false;
}
console.log(`🧟 Sending ${zombieIds.length} zombies to clear ${land.type} at ${tileKey}`);
// Set zombies to clearing task
// TODO: Integrate with ZombieSystem
// Start clearing progress
land.clearingProgress = 0;
land.clearingZombies = zombieIds;
land.clearingStartTime = Date.now();
return true;
}
/**
* Update clearing progress
*/
updateClearingProgress(delta) {
this.landTypes.forEach((land, tileKey) => {
if (!land.cleared && land.clearingZombies) {
// Progress based on number of zombies
const zombieCount = land.clearingZombies.length;
const progressRate = zombieCount * 0.01; // 1% per zombie per second
land.clearingProgress += progressRate * (delta / 1000);
// Check if complete
if (land.clearingProgress >= 100) {
this.completeLandClearing(tileKey);
}
}
});
}
/**
* Complete land clearing
*/
completeLandClearing(tileKey) {
const land = this.landTypes.get(tileKey);
if (!land) return;
land.cleared = true;
land.clearingProgress = 100;
land.clearingZombies = null;
// Add tile to unlocked
this.unlockedTiles.add(tileKey);
// Grant clearing rewards
this.grantClearingRewards(land.type);
console.log(`✅ Land cleared: ${tileKey} (${land.type})`);
this.showNotification({
title: 'Land Cleared!',
text: `${this.getLandTypeIcon(land.type)} ${land.type} tile ready for farming!`,
icon: '🎉'
});
}
/**
* Grant clearing rewards
*/
grantClearingRewards(landType) {
const rewards = {
forest: { wood: 10 },
rocky: { stone: 15 },
swamp: { clay: 5 }
};
const reward = rewards[landType];
if (reward) {
console.log(`🎁 Clearing rewards:`, reward);
// TODO: Add to inventory
}
}
/**
* Get land type icon
*/
getLandTypeIcon(type) {
const icons = {
grass: '🌿',
forest: '🌲',
rocky: '⛰️',
swamp: '💧'
};
return icons[type] || '❓';
}
/**
* Tutorial system
*/
startTutorial() {
this.tutorialStep = 1;
this.showNotification({
title: 'Welcome to Your Micro Farm!',
text: '🌾 You start with an 8x8 plot. Expand by clearing surrounding land!',
icon: '📚'
});
// TODO: Show tutorial UI with steps
}
/**
* Visualize farm (console)
*/
visualizeFarm() {
const bounds = this.getCurrentBounds();
console.log('🌾 FARM MAP:');
for (let y = bounds.minY; y <= bounds.maxY; y++) {
let row = '';
for (let x = bounds.minX; x <= bounds.maxX; x++) {
const tileKey = `${x},${y}`;
if (this.unlockedTiles.has(tileKey)) {
const land = this.landTypes.get(tileKey);
row += land.cleared ? '✅' : '⏳';
} else {
row += '🔒';
}
}
console.log(row);
}
}
/**
* Get farm info
*/
getFarmInfo() {
return {
unlockedTiles: this.unlockedTiles.size,
bounds: this.getCurrentBounds(),
expansionQueue: this.expansionQueue.length,
tutorialComplete: this.tutorialComplete
};
}
/**
* Helper: Show notification
*/
showNotification(notification) {
console.log(`📢 ${notification.icon} ${notification.title}: ${notification.text}`);
const ui = this.scene.scene.get('UIScene');
if (ui && ui.showNotification) {
ui.showNotification(notification);
}
}
/**
* Update system
*/
update(delta) {
// Update clearing progress
this.updateClearingProgress(delta);
}
}