Files
novafarma/src/scenes/GameScene.js
2025-12-12 13:55:54 +01:00

1118 lines
43 KiB
JavaScript

// Game Scene - Glavna igralna scena
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
this.terrainSystem = null;
this.terrainContainer = null;
this.player = null;
this.npcs = []; // Array za NPCje
// Settings
this.settings = {
viewDistance: 'HIGH', // LOW, MEDIUM, HIGH
particles: 'HIGH', // NONE, LOW, HIGH
shadows: true
};
}
create() {
console.log('🎮 GameScene: Initialized!');
// Generate procedural textures
new TextureGenerator(this).generateAll();
InventoryIcons.create(this); // Override with flat 2D inventory icons
window.gameState.currentScene = 'GameScene';
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Setup kamere - SVETLO SIVO OZADJE!
this.cameras.main.setBackgroundColor('#c8c8c8');
// Initialize Isometric Utils
this.iso = new IsometricUtils();
// Initialize Spatial Grid
this.spatialGrid = new SpatialGrid(10);
// Initialize Concept Systems (Zombie Roots)
this.zombieSystem = new ZombieWorkerSystem(this);
this.legacySystem = new LegacySystem(this);
this.expansionSystem = new ExpansionSystem(this);
this.blueprintSystem = new BlueprintSystem(this);
// Farm Stats Tracking for UI
this.farmStats = {
cropsPlanted: 0,
totalHarvested: 0,
goldEarned: 0,
daysFarmed: 0
};
// PARALLAX BACKGROUND - Clouds & Birds
this.createParallaxBackground();
// Inicializiraj terrain sistem - 100x100 mapa
console.log('🌍 Initializing terrain...');
try {
this.terrainSystem = new TerrainSystem(this, 100, 100);
this.terrainSystem.generate();
// Initialize Farming System
this.farmingSystem = new FarmingSystem(this);
console.log('🌾 Farming system initialized!');
// Initialize Build System
this.buildSystem = new BuildSystem(this);
console.log('🏗️ Build system initialized!');
// ========================================================
// 🏗️ TESTNI PRIMERI - Postavitev Ograj (ONEMOGOČENO)
// ========================================================
// Odstrani // pred vrsticami, če želiš videti testne ograje!
// ALI pritisni B v igri za Build Mode in postavljaj ročno!
// PRIMER 1: Ena sama ograja
// this.buildSystem.placeSingleFence(50, 50, 'fence_post', false);
// PRIMER 2: Vodoravna linija ograj (10 ograj)
// for (let i = 0; i < 10; i++) {
// this.buildSystem.placeSingleFence(45 + i, 52, 'fence_horizontal', false);
// }
// PRIMER 3: Navpična linija ograj (10 ograj)
// for (let i = 0; i < 10; i++) {
// this.buildSystem.placeSingleFence(43, 48 + i, 'fence_vertical', false);
// }
// PRIMER 4: Majhen pravokotnik (8x6)
// this.buildSystem.placeFenceRectangle(60, 45, 8, 6, 'fence_post', false);
// PRIMER 5: Diagonalna linija (Bresenham)
// this.buildSystem.placeFenceLine(30, 30, 40, 40, 'fence_corner', false);
// PRIMER 6: Večji pravokotnik (20x15)
// this.buildSystem.placeFenceRectangle(20, 60, 20, 15, 'fence_horizontal', false);
// PRIMER 7: Različni tipi ograj v vrsti
// this.buildSystem.placeSingleFence(70, 50, 'fence', false);
// this.buildSystem.placeSingleFence(71, 50, 'fence_post', false);
// this.buildSystem.placeSingleFence(72, 50, 'fence_horizontal', false);
// this.buildSystem.placeSingleFence(73, 50, 'fence_vertical', false);
// this.buildSystem.placeSingleFence(74, 50, 'fence_corner', false);
// console.log('✅ Testne ograje postavljene! Preveri mapo.');
// ========================================================
// Terrain offset
this.terrainOffsetX = width / 2;
this.terrainOffsetY = 100;
// Initialization for culling
this.terrainSystem.init(this.terrainOffsetX, this.terrainOffsetY);
// Initial force update to render active tiles before first frame
this.terrainSystem.updateCulling(this.cameras.main);
// INITIALIZE FARM AREA (Starter Zone @ 20,20)
this.initializeFarmWorld();
// 🍎 SADOVNJAK - Sadna Drevesa (ONEMOGOČENO)
// ========================================================
// Odstrani // če želiš sadovnjak
/*
console.log('🍎 Ustvarjam sadovnjak...');
const orchardX = 35; // Lokacija sadovnjaka
const orchardY = 60;
const orchardSize = 10; // 10x10 območje
// 1. Očisti območje (odstrani obstoječe drevese)
for (let x = orchardX; x < orchardX + orchardSize; x++) {
for (let y = orchardY; y < orchardY + orchardSize; y++) {
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
const key = `${x},${y}`;
if (this.terrainSystem.decorationsMap.has(key)) {
this.terrainSystem.removeDecoration(x, y);
}
// Spremeni teren v travo
if (this.terrainSystem.tiles[y] && this.terrainSystem.tiles[y][x]) {
this.terrainSystem.tiles[y][x].type = 'grass';
if (this.terrainSystem.tiles[y][x].sprite) {
this.terrainSystem.tiles[y][x].sprite.setTexture('grass');
this.terrainSystem.tiles[y][x].sprite.clearTint();
}
}
}
}
}
// 2. Dodaj SADIKE (tree_sapling) - bodo rasle v sadna drevesa!
const fruitTreeTypes = ['tree_apple', 'tree_orange', 'tree_cherry'];
let treeCount = 0;
const saplingPositions = []; // Shrani pozicije za ograje
for (let x = orchardX + 1; x < orchardX + orchardSize - 1; x += 2) {
for (let y = orchardY + 1; y < orchardY + orchardSize - 1; y += 2) {
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
// Dodaj SADIKO (bo rasla v sadno drevo)
this.terrainSystem.addDecoration(x, y, 'tree_sapling');
saplingPositions.push({ x, y, type: fruitTreeTypes[treeCount % fruitTreeTypes.length] });
treeCount++;
}
}
}
// 3. Dodaj LESENO OGRAJO okoli vsakega drevesa (3x3 kvadrat)
saplingPositions.forEach(pos => {
// Ograja okoli drevesa (3x3)
const fencePositions = [
// Zgornja vrstica
{ x: pos.x - 1, y: pos.y - 1 },
{ x: pos.x, y: pos.y - 1 },
{ x: pos.x + 1, y: pos.y - 1 },
// Spodnja vrstica
{ x: pos.x - 1, y: pos.y + 1 },
{ x: pos.x, y: pos.y + 1 },
{ x: pos.x + 1, y: pos.y + 1 },
// Leva stran
{ x: pos.x - 1, y: pos.y },
// Desna stran
{ x: pos.x + 1, y: pos.y }
];
fencePositions.forEach(fPos => {
if (fPos.x >= 0 && fPos.x < 100 && fPos.y >= 0 && fPos.y < 100) {
this.buildSystem.placeSingleFence(fPos.x, fPos.y, 'fence_horizontal', false);
}
});
});
// 4. Dodaj ZUNANJO OGRAJO okoli celega sadovnjaka
this.buildSystem.placeFenceRectangle(
orchardX - 1,
orchardY - 1,
orchardSize + 2,
orchardSize + 2,
'fence_post',
false
);
// 5. Dodaj cvetje med ograjami
for (let x = orchardX; x < orchardX + orchardSize; x++) {
for (let y = orchardY; y < orchardY + orchardSize; y++) {
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
const key = `${x},${y}`;
if (!this.terrainSystem.decorationsMap.has(key) && Math.random() > 0.85) {
this.terrainSystem.addDecoration(x, y, 'flowers_new');
}
}
}
}
// 6. RAST DREVES - Sadike bodo rasle v sadna drevesa!
// Nastavi timer za rast (vsako drevo raste po 30 sekundah)
saplingPositions.forEach((pos, index) => {
this.time.delayedCall(30000 + (index * 2000), () => {
const key = `${pos.x},${pos.y}`;
// Odstrani sadiko
if (this.terrainSystem.decorationsMap.has(key)) {
this.terrainSystem.removeDecoration(pos.x, pos.y);
}
// Dodaj SADNO DREVO
this.terrainSystem.addDecoration(pos.x, pos.y, pos.type);
// Animacija rasti
if (this.terrainSystem.visibleDecorations.has(key)) {
const sprite = this.terrainSystem.visibleDecorations.get(key);
sprite.setScale(0.01);
this.tweens.add({
targets: sprite,
scaleX: 0.04,
scaleY: 0.04,
duration: 2000,
ease: 'Bounce.out'
});
}
console.log(`🌳 Drevo zraslo: ${pos.type} na (${pos.x}, ${pos.y})`);
});
});
console.log(`✅ Sadovnjak ustvarjen na (${orchardX}, ${orchardY}) - ${treeCount} sadik (bodo rasle v 30s)`);
*/
// ========================================================
// CITY CONTENT: Ruins, Chests, Spawners
console.log('🏚️ Generating City Content...');
// DISABLED - City structures removed for cleaner gameplay
// Main Ruins
// this.terrainSystem.placeStructure(55, 55, 'ruin');
// this.terrainSystem.placeStructure(65, 65, 'ruin');
// this.terrainSystem.placeStructure(75, 75, 'ruin');
// this.terrainSystem.placeStructure(60, 70, 'ruin');
// this.terrainSystem.placeStructure(70, 60, 'ruin');
// Arena (Boss battle area)
// this.terrainSystem.placeStructure(75, 55, 'arena');
// Treasure Chests (scattered in ruins)
// this.terrainSystem.placeStructure(56, 56, 'chest');
// this.terrainSystem.placeStructure(66, 66, 'chest');
// this.terrainSystem.placeStructure(76, 76, 'chest');
// Zombie Spawners (in city)
// this.terrainSystem.placeStructure(58, 68, 'spawner');
// this.terrainSystem.placeStructure(72, 62, 'spawner');
// CESTE (ROADS) - povezava med farmo (20,20) in mestom (65,65)
console.log('🛣️ Building Roads...');
// Horizontalna cesta od farme
for (let x = 20; x <= 45; x++) {
if (this.terrainSystem.tiles[22] && this.terrainSystem.tiles[22][x]) {
this.terrainSystem.tiles[22][x].type = 'pavement';
if (this.terrainSystem.tiles[22][x].sprite) {
this.terrainSystem.tiles[22][x].sprite.setTexture('dirt');
this.terrainSystem.tiles[22][x].sprite.setTint(0x808080);
}
}
}
// Vertikalna cesta do mesta
for (let y = 22; y <= 65; y++) {
if (this.terrainSystem.tiles[y] && this.terrainSystem.tiles[y][45]) {
this.terrainSystem.tiles[y][45].type = 'pavement';
if (this.terrainSystem.tiles[y][45].sprite) {
this.terrainSystem.tiles[y][45].sprite.setTexture('dirt');
this.terrainSystem.tiles[y][45].sprite.setTint(0x808080);
}
}
}
// Horizontalna cesta do mesta
for (let x = 45; x <= 65; x++) {
if (this.terrainSystem.tiles[65] && this.terrainSystem.tiles[65][x]) {
this.terrainSystem.tiles[65][x].type = 'pavement';
if (this.terrainSystem.tiles[65][x].sprite) {
this.terrainSystem.tiles[65][x].sprite.setTexture('dirt');
this.terrainSystem.tiles[65][x].sprite.setTint(0x808080);
}
}
}
// SIGNPOSTS - navigacijske table
// SIGNPOSTS - DISABLED (User request: clean world)
// console.log('🪧 Placing Signposts...');
// this.terrainSystem.placeStructure(23, 22, 'signpost_city');
// this.terrainSystem.placeStructure(65, 64, 'signpost_farm');
// this.terrainSystem.placeStructure(45, 40, 'signpost_both');
// DAMAGED CITY WALLS - DISABLED (User request: clean world)
// console.log('🏚️ Placing Damaged City Walls...');
// const wallPositions = [
// [65, 65], [70, 65], [75, 65],
// [65, 79], [70, 79], [75, 79],
// [65, 70], [65, 75],
// [79, 70], [79, 75]
// ];
// wallPositions.forEach(([wx, wy]) => {
// if (Math.random() < 0.7) {
// this.terrainSystem.placeStructure(wx, wy, 'wall_damaged');
// }
// });
// Initialize Pathfinding (Worker)
console.log('🗺️ Initializing Pathfinding...');
this.pathfinding = new PathfindingSystem(this);
this.pathfinding.updateGrid();
} catch (e) {
console.error("Terrain system failed:", e);
}
// Dodaj igralca
console.log('👤 Initializing player...');
this.player = new Player(this, 50, 50, this.terrainOffsetX, this.terrainOffsetY);
// ALL NPCs REMOVED - Solo farming mode
console.log('🌾 Solo farming mode - no NPCs');
// FPS Monitor (Performance)
console.log('📊 Initializing FPS Monitor...');
this.fpsMonitor = new FPSMonitor(this);
// Performance Monitor (Advanced)
console.log('⚡ Initializing Performance Monitor...');
this.performanceMonitor = new PerformanceMonitor(this);
// NPC Spawner
console.log('🧟 Initializing NPC Spawner...');
this.npcSpawner = new NPCSpawner(this);
this.npcSpawner.spawnInitialNPCs();
// Easter Egg: Broken Scooter
console.log('🛵 Spawning Scooter Easter Egg...');
this.vehicles = [];
// const scooter = new Scooter(this, 25, 25);
// this.vehicles.push(scooter);
// ZOMBIE SPAWNERS (City area)
console.log('👹 Creating Zombie Spawners...');
this.spawners = [];
// DISABLED - Too many zombies for testing
// this.spawners.push(new ZombieSpawner(this, 55, 55, 5, 2, 25000)); // NW
// this.spawners.push(new ZombieSpawner(this, 75, 55, 5, 2, 25000)); // NE
// this.spawners.push(new ZombieSpawner(this, 65, 75, 5, 3, 20000)); // South
// LOOT CHESTS
console.log('📦 Placing Loot Chests...');
this.chests = [];
// Farm Starter Chest ONLY (near spawn)
this.chests.push(new LootChest(this, 28, 28, 'farm_starter'));
// DISABLED - City chests removed for cleaner gameplay
// this.chests.push(new LootChest(this, 60, 60, 'city'));
// this.chests.push(new LootChest(this, 70, 60, 'city'));
// this.chests.push(new LootChest(this, 65, 70, 'elite'));
// SIGNPOSTS/NAVIGATION
console.log('🪧 Adding Signposts...');
this.signposts = [];
// Path markers (using fence sprites as signposts)
// ONLY if terrainSystem was successfully initialized
if (this.terrainSystem) {
const pathMarkers = [
{ x: 35, y: 35, label: '→ City' },
{ x: 50, y: 50, label: '← Farm' },
];
for (const marker of pathMarkers) {
this.terrainSystem.addDecoration(marker.x, marker.y, 'fence');
this.signposts.push({ gridX: marker.x, gridY: marker.y, label: marker.label });
}
} else {
console.warn('⚠️ TerrainSystem not initialized - skipping signposts');
}
// Kamera sledi igralcu z gladko interpolacijo (lerp 0.1)
this.cameras.main.startFollow(this.player.sprite, true, 0.1, 0.1);
// Nastavi deadzone (100px border)
this.cameras.main.setDeadzone(100, 100);
// Round pixels za crisp pixel art
this.cameras.main.roundPixels = true;
// Zoom out za boljši pogled (85% zoom)
this.cameras.main.setZoom(0.85);
// Parallax oblaki
this.createClouds();
// Kamera kontrole
this.setupCamera();
// Initialize Systems
console.log('🌦️ Initializing Unified Weather System...');
this.weatherSystem = new WeatherSystem(this);
this.timeSystem = this.weatherSystem; // Alias
this.statsSystem = new StatsSystem(this);
this.inventorySystem = new InventorySystem(this);
// ========================================================
// 💎 NEOMEJENI VIRI - Les in Kamen
// ========================================================
console.log('💎 Dodajam neomejene vire...');
this.inventorySystem.addItem('wood', 999999);
this.inventorySystem.addItem('stone', 999999);
this.inventorySystem.gold = 999999;
console.log('✅ Neomejeni viri dodani: 999,999 lesa, kamna in zlata!');
// ========================================================
this.lootSystem = new LootSystem(this);
this.interactionSystem = new InteractionSystem(this);
this.farmingSystem = new FarmingSystem(this);
this.buildingSystem = new BuildingSystem(this);
// this.pathfinding = new Pathfinding(this); // REMOVED: Using PathfindingSystem (Worker) instead
this.questSystem = new QuestSystem(this);
this.collectionSystem = new CollectionSystem(this);
this.multiplayerSystem = new MultiplayerSystem(this);
this.worldEventSystem = new WorldEventSystem(this);
this.hybridSkillSystem = new HybridSkillSystem(this);
this.oceanSystem = new OceanSystem(this);
this.legacySystem = new LegacySystem(this);
// Initialize Sound Manager
console.log('🎵 Initializing Sound Manager...');
this.soundManager = new SoundManager(this);
this.soundManager.startMusic();
// Initialize Parallax System
console.log('🌄 Initializing Parallax System...');
this.parallaxSystem = new ParallaxSystem(this);
// Initialize Particle Effects
console.log('✨ Initializing Particle Effects...');
this.particleEffects = new ParticleEffects(this);
this.particleEffects.createFallingLeaves();
// Initialize Accessibility System
console.log('♿ Initializing Accessibility System...');
this.accessibilitySystem = new AccessibilitySystem(this);
// Initialize Visual Sound Cue System (for deaf/hard-of-hearing players)
console.log('👁️ Initializing Visual Sound Cue System...');
this.visualSoundCueSystem = new VisualSoundCueSystem(this);
// Show epilepsy warning on first launch
const hasSeenWarning = localStorage.getItem('novafarma_epilepsy_warning');
if (!hasSeenWarning) {
this.time.delayedCall(2000, () => {
this.accessibilitySystem.showEpilepsyWarning(() => {
localStorage.setItem('novafarma_epilepsy_warning', 'true');
});
});
}
// Generate Item Sprites for UI
TextureGenerator.createItemSprites(this);
// Launch UI Scene
console.log('🖥️ Launching UI Scene...');
this.scene.launch('UIScene');
// Initialize Save System
this.saveSystem = new SaveSystem(this);
// Auto-load if available (DISABLED in SaveSystem!)
this.saveSystem.loadGame(); // Vrne false - ne naloži save-a!
// Debug Text
this.add.text(10, 10, 'NovaFarma Alpha v0.6', { font: '16px monospace', fill: '#ffffff' })
.setScrollFactor(0).setDepth(10000);
console.log('✅ GameScene ready - FAZA 20 (Full Features)!');
// Global command: giveSeeds(amount) - daj seeds najbližjemu tamed zombiju
window.giveSeeds = (amount = 10) => {
if (!this.zombieWorkerSystem || !this.player) {
console.log('🚫 System not ready!');
return;
}
const workers = this.zombieWorkerSystem.workers;
if (workers.length === 0) {
console.log('🚫 No tamed zombies found!');
return;
}
// Find closest worker
const playerPos = this.player.getPosition();
let closest = null;
let minDist = 999;
for (const worker of workers) {
const dist = Phaser.Math.Distance.Between(playerPos.x, playerPos.y, worker.gridX, worker.gridY);
if (dist < minDist) {
minDist = dist;
closest = worker;
}
}
if (closest && closest.workerData) {
closest.workerData.inventory.seeds += amount;
closest.showEmote(`📦+${amount}`);
console.log(`🧟📦 Gave ${amount} seeds to worker! (Total: ${closest.workerData.inventory.seeds})`);
}
};
console.log('💡 TIP: Use giveSeeds(20) to give 20 seeds to nearest zombie');
// Global command: placeGrave() - postavi grob pri playerju
window.placeGrave = () => {
if (!this.graveSystem || !this.player) {
console.log('🚫 System not ready!');
return;
}
const playerPos = this.player.getPosition();
const result = this.graveSystem.placeGrave(
Math.floor(playerPos.x),
Math.floor(playerPos.y)
);
if (result) {
console.log('🪦 Grave placed successfully!');
}
};
console.log('💡 TIP: Use placeGrave() to place grave at your location');
// Global command: giveAllParts() - daj vse scooter parts
window.giveAllParts = () => {
if (!this.scooterRepairSystem || !this.inventorySystem) {
console.log('🚫 System not ready!');
return;
}
const parts = this.scooterRepairSystem.requiredParts;
const tools = this.scooterRepairSystem.requiredTools;
for (const [part, count] of Object.entries(parts)) {
this.inventorySystem.addItem(part, count);
}
for (const [tool, count] of Object.entries(tools)) {
this.inventorySystem.addItem(tool, count);
}
console.log('✅ All scooter parts and tools added!');
this.scooterRepairSystem.listMissingParts();
};
// Global command: checkScooter() - preveri kaj manjka
window.checkScooter = () => {
if (!this.scooterRepairSystem) {
console.log('🚫 System not ready!');
return;
}
this.scooterRepairSystem.listMissingParts();
};
console.log('💡 TIP: Use checkScooter() to see repair requirements');
console.log('💡 TIP: Use giveAllParts() to get all scooter parts (testing)');
// Global command: unlockZone(id)
window.unlockZone = (id) => {
if (this.expansionSystem) {
this.expansionSystem.unlockZone(id);
}
};
// Global command: dropBlueprint()
window.dropBlueprint = () => {
if (this.blueprintSystem && this.player) {
const pos = this.player.getPosition();
this.blueprintSystem.tryDropBlueprint(pos.x, pos.y, 'boss'); // 100% chance
}
};
// Global command: placeFurnace()
window.placeFurnace = () => {
if (this.terrainSystem && this.player) {
const pos = this.player.getPosition();
const x = Math.floor(pos.x);
const y = Math.floor(pos.y);
this.terrainSystem.placeStructure(x, y, 'furnace');
if (this.inventorySystem) {
this.inventorySystem.addItem('coal', 10);
this.inventorySystem.addItem('ore_iron', 10);
}
console.log(`🏭 Furnace placed at ${x},${y}`);
}
};
// Global command: placeMint()
window.placeMint = () => {
if (this.terrainSystem && this.player) {
const pos = this.player.getPosition();
const x = Math.floor(pos.x);
const y = Math.floor(pos.y);
this.terrainSystem.placeStructure(x, y, 'mint');
if (this.inventorySystem) {
this.inventorySystem.addItem('iron_bar', 10);
this.inventorySystem.addItem('coal', 10);
}
console.log(`💰 Mint placed at ${x},${y}`);
}
};
// TESTNA DREVESA IN KAMNI - Za testiranje
console.log('🌳 Adding test trees and rocks near player...');
this.terrainSystem.addDecoration(52, 50, 'tree_green');
this.terrainSystem.addDecoration(48, 50, 'rock');
this.terrainSystem.addDecoration(50, 52, 'tree_oak');
this.terrainSystem.addDecoration(50, 48, 'rock_large');
console.log('✅ Test decorations added at (50±2, 50±2)');
// Start Engine
this.Antigravity_Start();
}
setupCamera() {
const cam = this.cameras.main;
// Zoom kontrole (Mouse Wheel)
this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => {
const zoomSpeed = 0.001;
const newZoom = Phaser.Math.Clamp(
cam.zoom - deltaY * zoomSpeed,
0.3,
2.0
);
cam.setZoom(newZoom);
});
// Q/E za zoom
this.zoomKeys = this.input.keyboard.addKeys({
zoomIn: Phaser.Input.Keyboard.KeyCodes.Q,
zoomOut: Phaser.Input.Keyboard.KeyCodes.E
});
// Save/Load Keys
this.input.keyboard.on('keydown-F8', () => this.saveGame());
this.input.keyboard.on('keydown-F9', () => this.loadGame());
// Spawn Boss (Debug)
this.input.keyboard.on('keydown-K', () => this.spawnBoss());
// Build Mode Keys
this.input.keyboard.on('keydown-B', () => {
if (this.buildSystem) this.buildSystem.toggleBuildMode();
});
this.input.keyboard.on('keydown-ONE', () => {
if (this.buildSystem && this.buildSystem.buildMode) this.buildSystem.selectBuilding('fence_post');
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(0);
});
this.input.keyboard.on('keydown-TWO', () => {
if (this.buildSystem && this.buildSystem.buildMode) this.buildSystem.selectBuilding('fence_horizontal');
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(1);
});
this.input.keyboard.on('keydown-THREE', () => {
if (this.buildSystem && this.buildSystem.buildMode) this.buildSystem.selectBuilding('fence_vertical');
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(2);
});
this.input.keyboard.on('keydown-FOUR', () => {
if (this.buildSystem && this.buildSystem.buildMode) this.buildSystem.selectBuilding('fence_corner');
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(3);
});
this.input.keyboard.on('keydown-FIVE', () => {
if (this.buildSystem && this.buildSystem.buildMode) this.buildSystem.selectBuilding('barn');
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(4);
});
// Soft Reset (F4)
this.input.keyboard.on('keydown-F4', () => window.location.reload());
// Mute Toggle (M key)
this.input.keyboard.on('keydown-M', () => {
if (this.soundManager) this.soundManager.toggleMute();
});
}
update(time, delta) {
if (this.player) this.player.update(delta);
// Update Systems
if (this.terrainSystem) this.terrainSystem.update(time, delta); // Water animation!
if (this.statsSystem) this.statsSystem.update(delta);
if (this.lootSystem) this.lootSystem.update(delta);
if (this.interactionSystem) this.interactionSystem.update(delta);
if (this.farmingSystem) this.farmingSystem.update(delta);
if (this.buildSystem) this.buildSystem.update(delta);
if (this.questSystem) this.questSystem.update(delta);
if (this.multiplayerSystem) this.multiplayerSystem.update(delta);
if (this.weatherSystem) {
this.weatherSystem.update(delta);
// Concept Systems Updates
if (this.zombieSystem) this.zombieSystem.update(this.time.now, delta);
// Night Logic
if (this.weatherSystem.isNight()) {
const isHorde = this.weatherSystem.isHordeNight();
const spawnInterval = isHorde ? 2000 : 10000;
// Check for Horde Start Warning
if (isHorde && !this.hordeWarningShown) {
this.showHordeWarning();
this.hordeWarningShown = true;
}
if (!this.nightSpawnTimer) this.nightSpawnTimer = 0;
this.nightSpawnTimer += delta;
if (this.nightSpawnTimer > spawnInterval) {
this.nightSpawnTimer = 0;
this.spawnNightZombie();
if (isHorde) {
this.spawnNightZombie();
this.spawnNightZombie();
}
}
} else {
this.hordeWarningShown = false;
}
}
// NPC Update - DISABLED (no NPCs)
/*
for (const npc of this.npcs) {
npc.update(delta);
}
*/
// Vehicles Update
if (this.vehicles) {
for (const vehicle of this.vehicles) {
if (vehicle.update) vehicle.update(delta);
}
}
// Spawners Update
if (this.spawners) {
for (const spawner of this.spawners) {
if (spawner.update) spawner.update(delta);
}
}
// Zombie Worker System
if (this.zombieWorkerSystem) this.zombieWorkerSystem.update(delta);
// Workstation System
if (this.workstationSystem) this.workstationSystem.update(delta);
// Grave System Update (regeneration)
if (this.graveSystem) {
this.graveSystem.update(delta);
// Auto-rest check every 5 seconds
if (!this.graveAutoRestTimer) this.graveAutoRestTimer = 0;
this.graveAutoRestTimer += delta;
if (this.graveAutoRestTimer >= 5000) {
this.graveSystem.autoRest();
this.graveAutoRestTimer = 0;
}
}
// Parallax Logic
if (this.parallaxSystem && this.player) {
const playerPos = this.player.getPosition();
const screenPos = this.iso.toScreen(playerPos.x, playerPos.y);
this.parallaxSystem.update(
screenPos.x + this.terrainOffsetX,
screenPos.y + this.terrainOffsetY
);
}
// Terrain Culling & Update
if (this.terrainSystem) {
this.terrainSystem.updateCulling(this.cameras.main);
this.terrainSystem.update(delta);
}
// Clouds
if (this.clouds) {
for (const cloud of this.clouds) {
cloud.sprite.x += cloud.speed * (delta / 1000);
if (cloud.sprite.x > this.terrainOffsetX + 2000) {
cloud.sprite.x = this.terrainOffsetX - 2000;
cloud.sprite.y = Phaser.Math.Between(0, 1000);
}
}
}
if (this.worldEventSystem) this.worldEventSystem.update(delta);
// FPS Monitor Update
if (this.fpsMonitor) this.fpsMonitor.update();
// Performance Monitor Update
if (this.performanceMonitor) this.performanceMonitor.update(delta);
// NPC Spawner Update
if (this.npcSpawner) this.npcSpawner.update(delta);
// Visual Sound Cue System Update
if (this.visualSoundCueSystem) this.visualSoundCueSystem.update();
// Update NPCs
for (const npc of this.npcs) {
if (npc.update) npc.update(delta);
}
// Debug Info
if (this.player) {
const playerPos = this.player.getPosition();
const uiScene = this.scene.get('UIScene');
if (uiScene && uiScene.debugText) {
const activeCrops = this.terrainSystem && this.terrainSystem.cropsMap ? this.terrainSystem.cropsMap.size : 0;
const dropsCount = this.lootSystem ? this.lootSystem.drops.length : 0;
const conn = this.multiplayerSystem && this.multiplayerSystem.isConnected ? '🟢 Online' : '🔴 Offline';
uiScene.debugText.setText(
`NovaFarma v0.6 [${conn}]\n` +
`[F5] Save | [F9] Load | [K] Boss\n` +
`Time: ${this.timeSystem ? this.timeSystem.gameTime.toFixed(1) : '?'}h\n` +
`Active Crops: ${activeCrops}\n` +
`Loot Drops: ${dropsCount}\n` +
`Player: (${playerPos.x}, ${playerPos.y})`
);
}
}
// Run Antigravity Engine Update
this.Antigravity_Update(delta);
}
spawnNightZombie() {
// DISABLED - No NPCs allowed
return;
/*
if (!this.player || this.npcs.length > 50) return;
const playerPos = this.player.getPosition();
const angle = Math.random() * Math.PI * 2;
const distance = Phaser.Math.Between(15, 25);
const spawnX = Math.floor(playerPos.x + Math.cos(angle) * distance);
const spawnY = Math.floor(playerPos.y + Math.sin(angle) * distance);
if (spawnX < 0 || spawnX >= 100 || spawnY < 0 || spawnY >= 100) return;
if (Phaser.Math.Distance.Between(spawnX, spawnY, 20, 20) < 15) return;
const tile = this.terrainSystem.getTile(spawnX, spawnY);
if (tile && tile.type !== 'water') {
console.log(`🌑 Night Spawn: Zombie at ${spawnX},${spawnY}`);
const zombie = new NPC(this, spawnX, spawnY, this.terrainOffsetX, this.terrainOffsetY, 'zombie');
zombie.state = 'CHASE';
this.npcs.push(zombie);
}
*/
}
showHordeWarning() {
console.log('🩸 BLOOD MOON RISING!');
if (this.soundManager) this.soundManager.playDeath();
const width = this.cameras.main.width;
const height = this.cameras.main.height;
const text = this.add.text(width / 2, height / 3, 'THE HORDE IS APPROACHING...', {
fontSize: '40px', fontFamily: 'Courier New', fill: '#ff0000', fontStyle: 'bold', stroke: '#000000', strokeThickness: 6
}).setOrigin(0.5).setScrollFactor(0).setDepth(10000);
this.tweens.add({
targets: text, scale: 1.2, duration: 500, yoyo: true, repeat: 5,
onComplete: () => {
this.tweens.add({
targets: text, alpha: 0, duration: 2000,
onComplete: () => text.destroy()
});
}
});
}
createClouds() {
if (!this.textures.exists('cloud')) TextureGenerator.createCloudSprite(this, 'cloud');
this.clouds = [];
console.log('☁️ Creating parallax clouds...');
for (let i = 0; i < 8; i++) {
const x = Phaser.Math.Between(-1000, 3000);
const y = Phaser.Math.Between(-500, 1500);
const cloud = this.add.sprite(x, y, 'cloud');
cloud.setAlpha(0.4).setScrollFactor(0.2).setDepth(2000).setScale(Phaser.Math.FloatBetween(2, 4));
this.clouds.push({ sprite: cloud, speed: Phaser.Math.FloatBetween(10, 30) });
}
}
spawnBoss() {
// DISABLED - No NPCs allowed
return;
/*
if (!this.player) return;
console.log('👑 SPANWING ZOMBIE KING!');
const playerPos = this.player.getPosition();
const spawnX = Math.floor(playerPos.x + 8);
const spawnY = Math.floor(playerPos.y + 8);
const boss = new Boss(this, spawnX, spawnY);
boss.state = 'CHASE';
this.npcs.push(boss);
this.showHordeWarning();
this.events.emit('show-floating-text', { x: this.player.x, y: this.player.y - 100, text: "THE KING HAS ARRIVED!", color: '#AA00FF' });
*/
}
saveGame() {
if (this.saveSystem) this.saveSystem.saveGame();
}
loadGame() {
if (this.saveSystem) this.saveSystem.loadGame();
}
initializeFarmWorld() {
console.log('🌾 Initializing Farm Area (Starter Zone)...');
const farmX = 20; // Farm center
const farmY = 20;
const farmRadius = 8;
// 1. Clear farm area (odstrani drevesa in kamne)
for (let x = farmX - farmRadius; x <= farmX + farmRadius; x++) {
for (let y = farmY - farmRadius; y <= farmY + farmRadius; y++) {
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
const key = `${x},${y}`;
// Remove trees and rocks in farm area
if (this.terrainSystem.decorationsMap.has(key)) {
this.terrainSystem.removeDecoration(x, y);
}
// Make it DIRT for farming
if (this.terrainSystem.tiles[y] && this.terrainSystem.tiles[y][x]) {
this.terrainSystem.tiles[y][x].type = 'dirt';
if (this.terrainSystem.tiles[y][x].sprite) {
this.terrainSystem.tiles[y][x].sprite.setTexture('dirt');
this.terrainSystem.tiles[y][x].sprite.setTint(0xffffff); // Clear tint
}
}
}
}
}
// 2. Place starter resources (chest s semeni) - REMOVED PER USER REQUEST (Floating chest bug)
// this.terrainSystem.placeStructure(farmX + 3, farmY + 3, 'chest');
// 3. Place FULL FENCE around farm
// console.log('🚧 Building Farm Fence...');
// const minX = farmX - farmRadius;
// const maxX = farmX + farmRadius;
// const minY = farmY - farmRadius;
// const maxY = farmY + farmRadius;
// // Top and bottom horizontal fences
// for (let x = minX; x <= maxX; x++) {
// if (x >= 0 && x < 100) {
// this.terrainSystem.placeStructure(x, minY, 'fence_full'); // Top
// this.terrainSystem.placeStructure(x, maxY, 'fence_full'); // Bottom
// }
// }
// // Left and right vertical fences
// for (let y = minY; y <= maxY; y++) {
// if (y >= 0 && y < 100) {
// this.terrainSystem.placeStructure(minX, y, 'fence_full'); // Left
// this.terrainSystem.placeStructure(maxX, y, 'fence_full'); // Right
// }
// }
console.log('✅ Farm Area Initialized at (20,20)');
}
// ========================================================
// ANTIGRAVITY ENGINE UPDATE
// ========================================================
Antigravity_Start() {
console.log('🚀 Starting Antigravity Engine...');
if (window.Antigravity) {
// Camera Setup
if (this.player && this.player.sprite) {
window.Antigravity.Camera.follow(this, this.player.sprite);
}
// ZOOM SETUP - 0.75 za "Open World" pregled
window.Antigravity.Camera.setZoom(this, 0.75);
}
}
Antigravity_Update(delta) {
// Globalni update klic
if (window.Antigravity) {
window.Antigravity.Update(this, delta);
}
// Parallax background update
this.updateParallax(delta);
// Terrain system update (za water animacijo)
if (this.terrainSystem && this.terrainSystem.update) {
this.terrainSystem.update(Date.now(), delta);
} else {
console.warn('⚠️ TerrainSystem.update not available!');
}
}
createParallaxBackground() {
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Parallax container
this.parallaxContainer = this.add.container(0, 0);
this.parallaxContainer.setDepth(-1000); // Always behind everything
this.clouds = [];
this.birds = [];
// Create 5 clouds
for (let i = 0; i < 5; i++) {
const cloud = this.add.text(
Math.random() * width * 2,
Math.random() * height * 0.5,
'☁️',
{ fontSize: `${30 + Math.random() * 20}px` }
);
cloud.speed = 0.3 + Math.random() * 0.2; // 0.3-0.5x speed
this.parallaxContainer.add(cloud);
this.clouds.push(cloud);
}
// Create 3 birds
for (let i = 0; i < 3; i++) {
const bird = this.add.text(
Math.random() * width * 2,
100 + Math.random() * 200,
'🐦',
{ fontSize: '20px' }
);
bird.speed = 0.5 + Math.random() * 0.3; // 0.5-0.8x speed
this.parallaxContainer.add(bird);
this.birds.push(bird);
}
console.log('☁️ Parallax background created!');
}
updateParallax(delta) {
if (!this.parallaxContainer) return;
const width = this.cameras.main.width;
// Update clouds
this.clouds.forEach(cloud => {
cloud.x -= cloud.speed * (delta / 16);
if (cloud.x < -100) {
cloud.x = width + 100;
cloud.y = Math.random() * this.cameras.main.height * 0.5;
}
});
// Update birds
this.birds.forEach(bird => {
bird.x -= bird.speed * (delta / 16);
bird.y += Math.sin(Date.now() / 1000 + bird.x) * 0.5; // Flutter effect
if (bird.x < -100) {
bird.x = width + 100;
bird.y = 100 + Math.random() * 200;
}
});
}
}