diff --git a/index.html b/index.html
index dac4b69..458a403 100644
--- a/index.html
+++ b/index.html
@@ -166,6 +166,7 @@
+
diff --git a/src/scenes/GameScene.js b/src/scenes/GameScene.js
index 9e45719..aa659a3 100644
--- a/src/scenes/GameScene.js
+++ b/src/scenes/GameScene.js
@@ -84,6 +84,11 @@ class GameScene extends Phaser.Scene {
this.buildSystem = new BuildSystem(this);
console.log('🏗️ Build system initialized!');
+ // 🌱 Initialize Micro Farm System (PHASE 37!)
+ this.microFarmSystem = new MicroFarmSystem(this);
+ console.log('🌱 Micro Farm system initialized!');
+
+
// ========================================================
// 🏗️ TESTNI PRIMERI - Postavitev Ograj (ONEMOGOČENO)
// ========================================================
diff --git a/src/scenes/UIScene.js b/src/scenes/UIScene.js
index 1b7df29..e08e05c 100644
--- a/src/scenes/UIScene.js
+++ b/src/scenes/UIScene.js
@@ -2689,7 +2689,7 @@ class UIScene extends Phaser.Scene {
*/
updateMinimapContent() {
if (!this.minimapExpanded) return;
- if (!this.gameScene || !this.gameScene.terrain) return;
+ if (!this.gameScene) return;
this.minimapGraphics.clear();
@@ -2698,38 +2698,60 @@ class UIScene extends Phaser.Scene {
const scale = (mapSize * 2) / worldSize;
// Get player position
- const playerPos = this.gameScene.player.getPosition();
- const centerX = playerPos.x;
- const centerY = playerPos.y;
+ const player = this.gameScene.player;
+ if (!player) return;
+
+ const centerX = Math.floor(player.gridX || 0);
+ const centerY = Math.floor(player.gridY || 0);
// View radius around player
const viewRadius = 25;
// Draw terrain tiles
- for (let y = Math.max(0, centerY - viewRadius); y < Math.min(worldSize, centerY + viewRadius); y++) {
- for (let x = Math.max(0, centerX - viewRadius); x < Math.min(worldSize, centerX + viewRadius); x++) {
- const tile = this.gameScene.terrain[y] && this.gameScene.terrain[y][x];
- if (!tile) continue;
+ if (this.gameScene.terrainSystem && this.gameScene.terrainSystem.tiles) {
+ for (let y = Math.max(0, centerY - viewRadius); y < Math.min(worldSize, centerY + viewRadius); y++) {
+ for (let x = Math.max(0, centerX - viewRadius); x < Math.min(worldSize, centerX + viewRadius); x++) {
+ const tile = this.gameScene.terrainSystem.getTile(x, y);
+ if (!tile) continue;
- // Calculate position relative to player
- const relX = (x - centerX) * scale;
- const relY = (y - centerY) * scale;
+ // Calculate position relative to player
+ const relX = (x - centerX) * scale;
+ const relY = (y - centerY) * scale;
- // Only draw if within circle
- const dist = Math.sqrt(relX * relX + relY * relY);
- if (dist > mapSize) continue;
+ // Only draw if within circle
+ const dist = Math.sqrt(relX * relX + relY * relY);
+ if (dist > mapSize) continue;
- // Color based on tile type
- let color = 0x228B22; // Default green
- if (tile.type === 'water') color = 0x4488ff;
- else if (tile.type === 'sand') color = 0xf4a460;
- else if (tile.type === 'stone') color = 0x808080;
- else if (tile.type === 'grass') color = 0x228B22;
+ // Color based on tile type
+ let color = 0x228B22; // Default green
+ if (tile.type === 'water') color = 0x4488ff;
+ else if (tile.type === 'sand') color = 0xf4a460;
+ else if (tile.type === 'stone') color = 0x808080;
+ else if (tile.type === 'grass') color = 0x228B22;
- this.minimapGraphics.fillStyle(color, 0.8);
- this.minimapGraphics.fillRect(relX - scale / 2, relY - scale / 2, scale, scale);
+ this.minimapGraphics.fillStyle(color, 0.8);
+ this.minimapGraphics.fillRect(relX - scale / 2, relY - scale / 2, scale, scale);
+ }
}
}
+
+ // 🌱 DRAW MICRO FARM BOUNDARY!
+ if (this.gameScene.microFarmSystem) {
+ const farmCenterX = this.gameScene.microFarmSystem.farmCenterX;
+ const farmCenterY = this.gameScene.microFarmSystem.farmCenterY;
+ const farmSize = this.gameScene.microFarmSystem.farmSize;
+ const halfSize = Math.floor(farmSize / 2);
+
+ // Farm boundary in minimap coords
+ const farmX1 = (farmCenterX - halfSize - centerX) * scale;
+ const farmY1 = (farmCenterY - halfSize - centerY) * scale;
+ const farmW = farmSize * scale;
+ const farmH = farmSize * scale;
+
+ // Draw white farm boundary
+ this.minimapGraphics.lineStyle(2, 0xFFFFFF, 0.9);
+ this.minimapGraphics.strokeRect(farmX1, farmY1, farmW, farmH);
+ }
}
/**
diff --git a/src/systems/FarmingSystem.js b/src/systems/FarmingSystem.js
index 8972fa5..7583856 100644
--- a/src/systems/FarmingSystem.js
+++ b/src/systems/FarmingSystem.js
@@ -26,6 +26,22 @@ class FarmingSystem {
tillSoil(gridX, gridY) {
if (!this.scene.terrainSystem) return false;
+ // 🌱 CHECK MICRO FARM BOUNDARY!
+ if (this.scene.microFarmSystem && !this.scene.microFarmSystem.isTileUnlocked(gridX, gridY)) {
+ console.log('❌ Cannot till outside farm boundary!');
+
+ // Show error message
+ if (this.scene.events) {
+ this.scene.events.emit('show-floating-text', {
+ x: gridX * 48,
+ y: gridY * 48,
+ text: '🚫 Unlock farm first!',
+ color: '#ff0000'
+ });
+ }
+ return false;
+ }
+
// Check if already tilled
const key = `${gridX},${gridY}`;
if (this.isTilled(gridX, gridY)) {
diff --git a/src/systems/Flat2DTerrainSystem.js b/src/systems/Flat2DTerrainSystem.js
index 8cbee1c..85a575d 100644
--- a/src/systems/Flat2DTerrainSystem.js
+++ b/src/systems/Flat2DTerrainSystem.js
@@ -16,6 +16,9 @@ class Flat2DTerrainSystem {
this.pathsLayer = null;
this.decorLayer = null;
+ // Decoration tracking (for interaction system)
+ this.decorationsMap = new Map();
+
// Textures ready flag
this.texturesReady = false;
diff --git a/src/systems/MicroFarmSystem.js b/src/systems/MicroFarmSystem.js
new file mode 100644
index 0000000..ff3d4db
--- /dev/null
+++ b/src/systems/MicroFarmSystem.js
@@ -0,0 +1,331 @@
+// 🌱 MICRO FARM SYSTEM - Phase 37
+// Začetna 8x8 parcela z postopno širitvijo
+
+class MicroFarmSystem {
+ constructor(scene) {
+ this.scene = scene;
+
+ // MICRO FARM CONFIG
+ this.farmCenterX = 50; // Center of 100x100 map
+ this.farmCenterY = 50;
+ this.farmSize = 8; // 8x8 tiles (initial)
+
+ // EXPANSION SYSTEM
+ this.unlockedTiles = new Set(); // Tracks unlocked tiles
+ this.expansionCost = 50; // Gold per 2x2 expansion
+
+ // LAND TYPES
+ this.landTypes = {
+ GRASS: 'grass', // Free to use
+ FOREST: 'forest', // Needs clearing (trees)
+ ROCKY: 'rocky', // Needs mining (rocks)
+ SWAMP: 'swamp' // Needs drainage (water)
+ };
+
+ this.init();
+ }
+
+ init() {
+ console.log('🌱 MicroFarmSystem initialized');
+
+ // Unlock initial 8x8 farm
+ this.unlockInitialFarm();
+
+ // Create visual boundaries
+ this.createFarmBoundaries();
+
+ // Render locked tile overlay
+ this.renderLockedTileOverlay();
+
+ // Create expansion UI buttons
+ this.createExpansionUI();
+ }
+
+ createExpansionUI() {
+ // Create UI buttons for farm expansion
+ const uiScene = this.scene.scene.get('UIScene');
+ if (!uiScene) {
+ console.warn('⚠️ UIScene not found - cannot create expansion UI');
+ return;
+ }
+
+ // Store reference
+ this.uiScene = uiScene;
+ this.expansionButtons = [];
+
+ const buttonSize = 40;
+ const buttonColor = 0x8B4513; // Brown
+ const buttonHoverColor = 0xD2691E;
+ const expandCost = this.expansionCost;
+
+ // Button positions relative to farm center
+ const farmWorldX = this.farmCenterX * 48;
+ const farmWorldY = this.farmCenterY * 48;
+ const farmPixelSize = this.farmSize * 48;
+ const halfSize = farmPixelSize / 2;
+
+ const buttons = [
+ { dir: 'north', x: farmWorldX, y: farmWorldY - halfSize - 60, icon: '⬆️' },
+ { dir: 'south', x: farmWorldX, y: farmWorldY + halfSize + 60, icon: '⬇️' },
+ { dir: 'east', x: farmWorldX + halfSize + 60, y: farmWorldY, icon: '➡️' },
+ { dir: 'west', x: farmWorldX - halfSize - 60, y: farmWorldY, icon: '⬅️' }
+ ];
+
+ buttons.forEach(btn => {
+ // Button background
+ const bg = this.scene.add.rectangle(btn.x, btn.y, buttonSize, buttonSize, buttonColor);
+ bg.setStrokeStyle(2, 0xFFFFFF);
+ bg.setDepth(10);
+ bg.setInteractive({ useHandCursor: true });
+
+ // Button text
+ const text = this.scene.add.text(btn.x, btn.y, btn.icon, {
+ fontSize: '20px',
+ color: '#ffffff'
+ }).setOrigin(0.5);
+ text.setDepth(11);
+
+ // Cost label
+ const costLabel = this.scene.add.text(btn.x, btn.y + 30, `${expandCost}g`, {
+ fontSize: '12px',
+ color: '#FFD700',
+ fontStyle: 'bold'
+ }).setOrigin(0.5);
+ costLabel.setDepth(11);
+
+ // Hover effects
+ bg.on('pointerover', () => {
+ bg.setFillStyle(buttonHoverColor);
+ bg.setScale(1.1);
+ });
+
+ bg.on('pointerout', () => {
+ bg.setFillStyle(buttonColor);
+ bg.setScale(1.0);
+ });
+
+ // Click handler
+ bg.on('pointerdown', () => {
+ this.tryExpandFarm(btn.dir);
+ });
+
+ this.expansionButtons.push({ bg, text, costLabel, dir: btn.dir });
+ });
+
+ console.log('✅ Expansion UI created!');
+ }
+
+ tryExpandFarm(direction) {
+ // Check if player has enough gold
+ const inv = this.scene.inventorySystem;
+ if (!inv || inv.gold < this.expansionCost) {
+ console.log(`❌ Not enough gold! Need ${this.expansionCost}g`);
+
+ if (this.scene.events) {
+ this.scene.events.emit('show-floating-text', {
+ x: this.scene.cameras.main.width / 2,
+ y: 100,
+ text: `Need ${this.expansionCost} gold!`,
+ color: '#ff0000'
+ });
+ }
+ return;
+ }
+
+ // Deduct gold
+ inv.gold -= this.expansionCost;
+
+ // Expand farm
+ this.expandFarm(direction);
+
+ // Success feedback
+ if (this.scene.events) {
+ this.scene.events.emit('show-floating-text', {
+ x: this.scene.cameras.main.width / 2,
+ y: 100,
+ text: `✅ Farm expanded ${direction.toUpperCase()}!`,
+ color: '#00ff00'
+ });
+ }
+
+ console.log(`✅ Farm expanded ${direction}! (-${this.expansionCost}g)`);
+ }
+
+ unlockInitialFarm() {
+ // Unlock central 8x8 tiles
+ const halfSize = Math.floor(this.farmSize / 2);
+
+ for (let y = this.farmCenterY - halfSize; y < this.farmCenterY + halfSize; y++) {
+ for (let x = this.farmCenterX - halfSize; x < this.farmCenterX + halfSize; x++) {
+ const tileKey = `${x},${y}`;
+ this.unlockedTiles.add(tileKey);
+ }
+ }
+
+ console.log(`✅ Unlocked ${this.unlockedTiles.size} tiles (8x8 micro farm)`);
+ }
+
+ createFarmBoundaries() {
+ // Visual indicator of farm boundaries
+ const graphics = this.scene.add.graphics();
+ const halfSize = Math.floor(this.farmSize / 2);
+
+ const startX = (this.farmCenterX - halfSize) * 48;
+ const startY = (this.farmCenterY - halfSize) * 48;
+ const width = this.farmSize * 48;
+ const height = this.farmSize * 48;
+
+ // Farm border (white dashed line)
+ graphics.lineStyle(3, 0xFFFFFF, 0.8);
+ graphics.strokeRect(startX, startY, width, height);
+
+ // Corner markers
+ graphics.fillStyle(0xFFFFFF, 0.9);
+ const markerSize = 8;
+ graphics.fillRect(startX - markerSize / 2, startY - markerSize / 2, markerSize, markerSize);
+ graphics.fillRect(startX + width - markerSize / 2, startY - markerSize / 2, markerSize, markerSize);
+ graphics.fillRect(startX - markerSize / 2, startY + height - markerSize / 2, markerSize, markerSize);
+ graphics.fillRect(startX + width - markerSize / 2, startY + height - markerSize / 2, markerSize, markerSize);
+
+ graphics.setDepth(5); // Above ground, below player
+
+ // Store graphics for later updates
+ this.boundaryGraphics = graphics;
+ }
+
+ renderLockedTileOverlay() {
+ // Render dark overlay on locked tiles
+ if (!this.scene || !this.lockedOverlayGraphics) {
+ // Create overlay graphics if not exists
+ this.lockedOverlayGraphics = this.scene.add.graphics();
+ this.lockedOverlayGraphics.setDepth(4); // Above ground, below boundaries
+ }
+
+ this.lockedOverlayGraphics.clear();
+
+ // Darken all tiles that are NOT unlocked
+ const halfSize = Math.floor(this.farmSize / 2);
+ const farmStartX = this.farmCenterX - halfSize;
+ const farmEndX = this.farmCenterX + halfSize;
+ const farmStartY = this.farmCenterY - halfSize;
+ const farmEndY = this.farmCenterY + halfSize;
+
+ // Render grid of locked tiles
+ const viewRange = 15; // Show some area around farm
+ for (let y = this.farmCenterY - viewRange; y < this.farmCenterY + viewRange; y++) {
+ for (let x = this.farmCenterX - viewRange; x < this.farmCenterX + viewRange; x++) {
+ // Skip if within farm boundaries
+ if (x >= farmStartX && x < farmEndX && y >= farmStartY && y < farmEndY) {
+ continue;
+ }
+
+ // Draw dark overlay (lighter)
+ const worldX = x * 48;
+ const worldY = y * 48;
+ this.lockedOverlayGraphics.fillStyle(0x000000, 0.3); // 0.5 -> 0.3
+ this.lockedOverlayGraphics.fillRect(worldX, worldY, 48, 48);
+ }
+ }
+
+ console.log('🔒 Locked tile overlay rendered!');
+ }
+
+ isTileUnlocked(tileX, tileY) {
+ const tileKey = `${tileX},${tileY}`;
+ return this.unlockedTiles.has(tileKey);
+ }
+
+ canExpand(direction) {
+ // Check if expansion in direction is possible
+ // direction: 'north', 'south', 'east', 'west'
+ // TODO: Implement expansion logic
+ return true;
+ }
+
+ expandFarm(direction) {
+ // Unlock 2x2 tiles in specified direction
+ const halfSize = Math.floor(this.farmSize / 2);
+ const expansionSize = 2; // Unlock 2x2 tiles at a time
+
+ let newTiles = [];
+
+ switch (direction) {
+ case 'north':
+ for (let y = this.farmCenterY - halfSize - expansionSize; y < this.farmCenterY - halfSize; y++) {
+ for (let x = this.farmCenterX - halfSize; x < this.farmCenterX + halfSize; x++) {
+ newTiles.push({ x, y });
+ }
+ }
+ break;
+
+ case 'south':
+ for (let y = this.farmCenterY + halfSize; y < this.farmCenterY + halfSize + expansionSize; y++) {
+ for (let x = this.farmCenterX - halfSize; x < this.farmCenterX + halfSize; x++) {
+ newTiles.push({ x, y });
+ }
+ }
+ break;
+
+ case 'east':
+ for (let y = this.farmCenterY - halfSize; y < this.farmCenterY + halfSize; y++) {
+ for (let x = this.farmCenterX + halfSize; x < this.farmCenterX + halfSize + expansionSize; x++) {
+ newTiles.push({ x, y });
+ }
+ }
+ break;
+
+ case 'west':
+ for (let y = this.farmCenterY - halfSize; y < this.farmCenterY + halfSize; y++) {
+ for (let x = this.farmCenterX - halfSize - expansionSize; x < this.farmCenterX - halfSize; x++) {
+ newTiles.push({ x, y });
+ }
+ }
+ break;
+ }
+
+ // Unlock the tiles
+ newTiles.forEach(tile => {
+ const tileKey = `${tile.x},${tile.y}`;
+ this.unlockedTiles.add(tileKey);
+ });
+
+ // Update farm size
+ if (direction === 'north' || direction === 'south') {
+ this.farmSize += expansionSize;
+ } else {
+ this.farmSize += expansionSize;
+ }
+
+ // Update visuals
+ this.createFarmBoundaries(); // Redraw boundaries
+ this.renderLockedTileOverlay(); // Update overlay
+
+ console.log(`🔓 Expanded farm ${direction}! +${newTiles.length} tiles. Total: ${this.unlockedTiles.size}`);
+ }
+
+ getLandType(tileX, tileY) {
+ // Determine land type based on tile position
+ // TODO: Use terrain system data
+
+ // For now, return grass for unlocked tiles
+ if (this.isTileUnlocked(tileX, tileY)) {
+ return this.landTypes.GRASS;
+ }
+
+ // Surrounding areas have different types
+ const distFromCenter = Math.sqrt(
+ Math.pow(tileX - this.farmCenterX, 2) +
+ Math.pow(tileY - this.farmCenterY, 2)
+ );
+
+ if (distFromCenter < 10) return this.landTypes.GRASS;
+ if (distFromCenter < 15) return this.landTypes.FOREST;
+ if (distFromCenter < 20) return this.landTypes.ROCKY;
+ return this.landTypes.SWAMP;
+ }
+
+ destroy() {
+ // Cleanup
+ this.unlockedTiles.clear();
+ }
+}