813 lines
32 KiB
JavaScript
813 lines
32 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);
|
|
|
|
// Inicializiraj terrain sistem - 100x100 mapa
|
|
console.log('🌍 Initializing terrain...');
|
|
try {
|
|
this.terrainSystem = new TerrainSystem(this, 100, 100);
|
|
this.terrainSystem.generate();
|
|
|
|
// 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();
|
|
|
|
// 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++) {
|
|
this.terrainSystem.tiles[22][x].type = 'pavement';
|
|
this.terrainSystem.tiles[22][x].sprite.setTexture('dirt'); // Uporablj dirt kot "cesto"
|
|
this.terrainSystem.tiles[22][x].sprite.setTint(0x808080); // Siva barva
|
|
}
|
|
// Vertikalna cesta do mesta
|
|
for (let y = 22; y <= 65; y++) {
|
|
this.terrainSystem.tiles[y][45].type = 'pavement';
|
|
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++) {
|
|
this.terrainSystem.tiles[65][x].type = 'pavement';
|
|
this.terrainSystem.tiles[65][x].sprite.setTexture('dirt');
|
|
this.terrainSystem.tiles[65][x].sprite.setTint(0x808080);
|
|
}
|
|
|
|
// SIGNPOSTS - navigacijske table
|
|
console.log('🪧 Placing Signposts...');
|
|
this.terrainSystem.placeStructure(23, 22, 'signpost_city'); // Pri farmi "→ City"
|
|
this.terrainSystem.placeStructure(65, 64, 'signpost_farm'); // Pri mestu "← Farm"
|
|
this.terrainSystem.placeStructure(45, 40, 'signpost_both'); // Na križišču
|
|
|
|
// DAMAGED CITY WALLS - vizualni markerji mesta (porušeni zidovi)
|
|
console.log('🏚️ Placing Damaged City Walls...');
|
|
// Delno porušeni zidovi okoli city perimetra
|
|
const wallPositions = [
|
|
[65, 65], [70, 65], [75, 65], // Top wall
|
|
[65, 79], [70, 79], [75, 79], // Bottom wall
|
|
[65, 70], [65, 75], // Left wall
|
|
[79, 70], [79, 75] // Right wall
|
|
];
|
|
wallPositions.forEach(([wx, wy]) => {
|
|
if (Math.random() < 0.7) { // 70% chance per segment (gaps for realism)
|
|
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);
|
|
|
|
// Dodaj 3 NPCje (Mixed)
|
|
// Dodaj 3 NPCje (Mixed) - Removed zombie
|
|
console.log('🧟 Initializing NPCs...');
|
|
const npcTypes = ['villager', 'merchant'];
|
|
for (let i = 0; i < npcTypes.length; i++) {
|
|
const randomX = Phaser.Math.Between(40, 60); // Closer to center
|
|
const randomY = Phaser.Math.Between(40, 60);
|
|
console.log(`👤 Spawning NPC type: ${npcTypes[i]} at (${randomX}, ${randomY})`);
|
|
const npc = new NPC(this, randomX, randomY, this.terrainOffsetX, this.terrainOffsetY, npcTypes[i]);
|
|
this.npcs.push(npc);
|
|
}
|
|
|
|
// Dodaj 10 dodatnih Zombijev! - REMOVED BY REQUEST
|
|
/*
|
|
for (let i = 0; i < 10; i++) {
|
|
const randomX = Phaser.Math.Between(10, 90);
|
|
const randomY = Phaser.Math.Between(10, 90);
|
|
const zombie = new NPC(this, randomX, randomY, this.terrainOffsetX, this.terrainOffsetY, 'zombie');
|
|
this.npcs.push(zombie);
|
|
}
|
|
*/
|
|
|
|
// ZOMBIE WORKER SYSTEM
|
|
console.log('🧟⚒️ Initializing Zombie Worker System...');
|
|
this.zombieWorkerSystem = new ZombieWorkerSystem(this);
|
|
|
|
// GRAVE SYSTEM
|
|
console.log('🪦 Initializing Grave System...');
|
|
this.graveSystem = new GraveSystem(this);
|
|
|
|
// SCOOTER REPAIR SYSTEM
|
|
console.log('🛵 Initializing Scooter Repair System...');
|
|
this.scooterRepairSystem = new ScooterRepairSystem(this);
|
|
|
|
// EXPANSION SYSTEM
|
|
console.log('🗺️ Initializing Expansion System...');
|
|
this.expansionSystem = new ExpansionSystem(this);
|
|
|
|
// BLUEPRINT SYSTEM
|
|
console.log('📜 Initializing Blueprint System...');
|
|
this.blueprintSystem = new BlueprintSystem(this);
|
|
|
|
// WORKSTATION SYSTEM
|
|
console.log('🏭 Initializing Workstation System...');
|
|
this.workstationSystem = new WorkstationSystem(this);
|
|
|
|
// ELITE ZOMBIE v City območju (1x za testiranje)
|
|
console.log('👹 Spawning ELITE ZOMBIE in City...');
|
|
const eliteX = Phaser.Math.Between(50, 80); // City area
|
|
const eliteY = Phaser.Math.Between(50, 80);
|
|
const elite = new NPC(this, eliteX, eliteY, this.terrainOffsetX, this.terrainOffsetY, 'elite_zombie');
|
|
this.npcs.push(elite);
|
|
|
|
// MUTANTS (Troll & Elf)
|
|
console.log('👹 Spawning MUTANTS...');
|
|
this.npcs.push(new NPC(this, 60, 20, this.terrainOffsetX, this.terrainOffsetY, 'troll')); // Forest
|
|
this.npcs.push(new NPC(this, 70, 70, this.terrainOffsetX, this.terrainOffsetY, 'elf')); // City
|
|
|
|
// ANIMALS (Peaceful + Mutated)
|
|
console.log('🐄 Spawning ANIMALS...');
|
|
this.npcs.push(new NPC(this, 22, 22, this.terrainOffsetX, this.terrainOffsetY, 'cow'));
|
|
this.npcs.push(new NPC(this, 24, 20, this.terrainOffsetX, this.terrainOffsetY, 'chicken'));
|
|
this.npcs.push(new NPC(this, 25, 23, this.terrainOffsetX, this.terrainOffsetY, 'chicken'));
|
|
this.npcs.push(new NPC(this, 62, 22, this.terrainOffsetX, this.terrainOffsetY, 'cow_mutant')); // Aggressive mutant
|
|
|
|
// 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)
|
|
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 });
|
|
}
|
|
|
|
// 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);
|
|
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();
|
|
|
|
// 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
|
|
this.saveSystem.loadGame();
|
|
|
|
// 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}`);
|
|
}
|
|
};
|
|
|
|
// 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.buildingSystem) this.buildingSystem.toggleBuildMode();
|
|
});
|
|
|
|
this.input.keyboard.on('keydown-ONE', () => {
|
|
if (this.buildingSystem && this.buildingSystem.isBuildMode) this.buildingSystem.selectBuilding('fence');
|
|
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(0);
|
|
});
|
|
|
|
this.input.keyboard.on('keydown-TWO', () => {
|
|
if (this.buildingSystem && this.buildingSystem.isBuildMode) this.buildingSystem.selectBuilding('wall');
|
|
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(1);
|
|
});
|
|
|
|
this.input.keyboard.on('keydown-THREE', () => {
|
|
if (this.buildingSystem && this.buildingSystem.isBuildMode) this.buildingSystem.selectBuilding('house');
|
|
else if (this.scene.get('UIScene')) this.scene.get('UIScene').selectSlot(2);
|
|
});
|
|
|
|
// 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.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.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
|
|
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);
|
|
|
|
// 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() {
|
|
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() {
|
|
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 grass or dirt - USE CORRECT TERRAIN TYPE OBJECT
|
|
this.terrainSystem.tiles[y][x].type = this.terrainSystem.terrainTypes.GRASS_FULL;
|
|
if (this.terrainSystem.tiles[y][x].sprite) {
|
|
this.terrainSystem.tiles[y][x].sprite.setTexture('grass');
|
|
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);
|
|
}
|
|
|
|
// 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!');
|
|
}
|
|
}
|
|
}
|