- NEW: Flat2DTerrainSystem.js (375 lines) - NEW: map2d_data.js procedural map (221 lines) - MODIFIED: GameScene async create, 2D terrain integration - MODIFIED: Player.js flat 2D positioning - MODIFIED: game.js disabled pixelArt for smooth rendering - FIXED: 15+ bugs (updateCulling, isometric conversions, grid lines) - ADDED: Phase 28 to TASKS.md - DOCS: DNEVNIK.md session summary Result: Working flat 2D game with Stardew Valley style! Time: 5.5 hours
1969 lines
72 KiB
JavaScript
1969 lines
72 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
|
||
};
|
||
}
|
||
|
||
async 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';
|
||
window.gameState.gameScene = this; // Reference for global inventory helper
|
||
|
||
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 {
|
||
// 🎲 SEED-BASED GENERATION - Vsak krat ista mapa!
|
||
// Preveri če že imaš shranjeno spawn točko
|
||
let spawnPoint = localStorage.getItem('novafarma_spawn_point');
|
||
let terrainSeed = localStorage.getItem('novafarma_terrain_seed');
|
||
|
||
if (!terrainSeed) {
|
||
// PRVI LOGIN - generiraj nov seed
|
||
terrainSeed = Math.random().toString(36).substring(7);
|
||
localStorage.setItem('novafarma_terrain_seed', terrainSeed);
|
||
console.log('🆕 New world seed:', terrainSeed);
|
||
} else {
|
||
console.log('♻️ Loading existing world with seed:', terrainSeed);
|
||
}
|
||
|
||
// 🎨 2D FLAT TERRAIN SYSTEM (NEW!)
|
||
console.log('🎨 Initializing Flat 2D Terrain...');
|
||
this.terrainSystem = new Flat2DTerrainSystem(this);
|
||
await this.terrainSystem.generate();
|
||
console.log('✅ Flat 2D terrain ready!');
|
||
|
||
// 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);
|
||
|
||
// 🎲 RANDOM SPAWN POINT + 8x8 FARM (Prvi login)
|
||
if (!spawnPoint) {
|
||
// PRVI LOGIN - Random spawn točka
|
||
const spawnX = Math.floor(Math.random() * 80) + 10; // 10-90
|
||
const spawnY = Math.floor(Math.random() * 80) + 10; // 10-90
|
||
|
||
spawnPoint = `${spawnX},${spawnY}`;
|
||
localStorage.setItem('novafarma_spawn_point', spawnPoint);
|
||
|
||
console.log(`🎲 First login - Random spawn at (${spawnX}, ${spawnY})`);
|
||
console.log(`🏡 Creating 8x8 starter farm at spawn location...`);
|
||
|
||
// Ustvari 8x8 farmo na spawn točki
|
||
this.initializeFarmWorld(spawnX, spawnY);
|
||
} else {
|
||
// NI PRVI LOGIN - Naloži obstoječo spawn točko
|
||
const [spawnX, spawnY] = spawnPoint.split(',').map(Number);
|
||
console.log(`♻️ Returning player - spawn at (${spawnX}, ${spawnY})`);
|
||
|
||
// Obnovi farmo (če je shranjena)
|
||
this.initializeFarmWorld(spawnX, spawnY);
|
||
}
|
||
|
||
// 🍎 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 NA SPAWN TOČKI
|
||
console.log('👤 Initializing player...');
|
||
const savedSpawn = localStorage.getItem('novafarma_spawn_point');
|
||
let playerSpawnX = 50, playerSpawnY = 50;
|
||
|
||
if (savedSpawn) {
|
||
[playerSpawnX, playerSpawnY] = savedSpawn.split(',').map(Number);
|
||
console.log(`👤 Spawning player at saved location: (${playerSpawnX}, ${playerSpawnY})`);
|
||
}
|
||
|
||
this.player = new Player(this, playerSpawnX, playerSpawnY, this.terrainOffsetX, this.terrainOffsetY);
|
||
|
||
// 🎯 SORTABLE OBJECTS GROUP - Za 2.5D Z-Sorting
|
||
console.log('🎯 Creating sortableObjects group for Z-sorting...');
|
||
this.sortableObjects = this.add.group();
|
||
|
||
// Dodaj player sprite v sortableObjects
|
||
if (this.player && this.player.sprite) {
|
||
this.sortableObjects.add(this.player.sprite);
|
||
console.log('✅ Player added to sortableObjects');
|
||
}
|
||
|
||
// ALL NPCs REMOVED - Solo farming mode
|
||
console.log('🌾 Solo farming mode - no NPCs');
|
||
|
||
// FPS Monitor (Performance)
|
||
// FPS Monitor - DISABLED (Using UnifiedStatsPanel instead)
|
||
// console.log('📊 Initializing FPS Monitor...');
|
||
// this.fpsMonitor = new FPSMonitor(this);
|
||
|
||
// Unified Stats Panel (Performance + Debug in one)
|
||
console.log('📊 Initializing Unified Stats Panel...');
|
||
this.unifiedStatsPanel = new UnifiedStatsPanel(this);
|
||
|
||
// NPC Spawner - DISABLED (NPCs look like player duplicates)
|
||
console.log('🧟 NPC Spawner - DISABLED');
|
||
this.npcSpawner = null; // 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);
|
||
|
||
// 🛠️ CRAFTING SYSTEM
|
||
this.craftingSystem = new CraftingSystem(this);
|
||
this.craftingSystem.loadRecipes().then(() => {
|
||
console.log('🛠️ Crafting system ready!');
|
||
|
||
// Create UI after recipes loaded
|
||
this.craftingUI = new CraftingUI(this);
|
||
|
||
// Add C key to toggle crafting UI
|
||
this.input.keyboard.on('keydown-C', () => {
|
||
if (this.craftingUI) {
|
||
this.craftingUI.toggle();
|
||
}
|
||
});
|
||
});
|
||
|
||
// ========================================================
|
||
// 💎 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);
|
||
|
||
// Central Popup System (for quests, dialogs, etc.)
|
||
this.centralPopup = new CentralPopupSystem(this);
|
||
|
||
// Tutorial System (shows keyboard shortcuts)
|
||
this.tutorialSystem = new TutorialSystem(this);
|
||
|
||
// Full Inventory UI (24 slots, I key to open)
|
||
this.fullInventoryUI = new FullInventoryUI(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);
|
||
|
||
// Initialize Input Remapping System (for custom controls)
|
||
console.log('🎮 Initializing Input Remapping System...');
|
||
this.inputRemapping = new InputRemappingSystem(this);
|
||
|
||
// Initialize Screen Reader System (for blind/visually impaired players)
|
||
console.log('🔊 Initializing Screen Reader System...');
|
||
this.screenReader = new ScreenReaderSystem(this);
|
||
|
||
// Initialize Dyslexia Support System
|
||
console.log('📖 Initializing Dyslexia Support System...');
|
||
this.dyslexiaSupport = new DyslexiaSupportSystem(this);
|
||
|
||
// Initialize ADHD/Autism Support System
|
||
console.log('🧠 Initializing ADHD/Autism Support System...');
|
||
this.adhdAutismSupport = new ADHDAutismSupportSystem(this);
|
||
|
||
// Initialize Motor Accessibility System
|
||
console.log('🦾 Initializing Motor Accessibility System...');
|
||
this.motorAccessibility = new MotorAccessibilitySystem(this);
|
||
|
||
// Initialize Visual Enhancement System
|
||
console.log('✨ Initializing Visual Enhancement System...');
|
||
this.visualEnhancements = new VisualEnhancementSystem(this);
|
||
|
||
// Initialize Fog of War System
|
||
console.log('🌫️ Initializing Fog of War System...');
|
||
this.fogOfWar = new FogOfWarSystem(this);
|
||
|
||
// Initialize UI Graphics System
|
||
console.log('🎨 Initializing UI Graphics System...');
|
||
this.uiGraphics = new UIGraphicsSystem(this);
|
||
|
||
// Initialize Building Visuals System
|
||
console.log('🏭 Initializing Building Visuals System...');
|
||
this.buildingVisuals = new BuildingVisualsSystem(this);
|
||
|
||
// Initialize Skill Tree System
|
||
console.log('🌳 Initializing Skill Tree System...');
|
||
this.skillTree = new SkillTreeSystem(this);
|
||
|
||
// Initialize Crafting Tiers System
|
||
console.log('⚒️ Initializing Crafting Tiers System...');
|
||
this.craftingTiers = new CraftingTiersSystem(this);
|
||
|
||
// Initialize Farm Automation System
|
||
console.log('🤖 Initializing Farm Automation System...');
|
||
this.farmAutomation = new FarmAutomationSystem(this);
|
||
|
||
// Initialize Animal Breeding System
|
||
console.log('🐑 Initializing Animal Breeding System...');
|
||
this.animalBreeding = new AnimalBreedingSystem(this);
|
||
|
||
// Initialize Automation Tier System
|
||
console.log('🤖 Initializing Automation Tier System...');
|
||
this.automationTiers = new AutomationTierSystem(this);
|
||
|
||
// Initialize Breeding UI System
|
||
console.log('🌳 Initializing Breeding UI System...');
|
||
this.breedingUI = new BreedingUISystem(this);
|
||
|
||
// Initialize Cooking System
|
||
console.log('🍳 Initializing Cooking System...');
|
||
this.cooking = new CookingSystem(this);
|
||
|
||
// Initialize Fishing System
|
||
console.log('🎣 Initializing Fishing System...');
|
||
this.fishing = new FishingSystem(this);
|
||
|
||
// Initialize Worker Creatures System
|
||
console.log('🦌 Initializing Worker Creatures System...');
|
||
this.workerCreatures = new WorkerCreaturesSystem(this);
|
||
|
||
// Initialize Mining & Dungeons System
|
||
console.log('⛏️ Initializing Mining & Dungeons System...');
|
||
this.miningDungeons = new MiningDungeonsSystem(this);
|
||
|
||
// Initialize Boss Battles System
|
||
console.log('👹 Initializing Boss Battles System...');
|
||
this.bossBattles = new BossBattlesSystem(this);
|
||
|
||
// Initialize Story & Quest System
|
||
console.log('📖 Initializing Story & Quest System...');
|
||
this.storyQuest = new StoryQuestSystem(this);
|
||
|
||
// Initialize Multiplayer & Social System
|
||
console.log('🌐 Initializing Multiplayer & Social System...');
|
||
this.multiplayerSocial = new MultiplayerSocialSystem(this);
|
||
|
||
// Initialize Technical & Performance System
|
||
console.log('⚡ Initializing Technical & Performance System...');
|
||
this.technicalPerformance = new TechnicalPerformanceSystem(this);
|
||
|
||
// Initialize Platform Support System
|
||
console.log('🎮 Initializing Platform Support System...');
|
||
this.platformSupport = new PlatformSupportSystem(this);
|
||
|
||
// Initialize Save System Expansion
|
||
console.log('💾 Initializing Save System Expansion...');
|
||
this.saveSystemExpansion = new SaveSystemExpansion(this);
|
||
|
||
console.log('🎉🎉🎉 ALL 27 SYSTEMS INITIALIZED! 🎉🎉🎉');
|
||
console.log('💀 MRTVA DOLINA - DEATH VALLEY 💀');
|
||
|
||
// 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 - REMOVED (Version shown in UnifiedStatsPanel)
|
||
// 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;
|
||
|
||
// 🎨 FLAT 2D CAMERA SETUP (NEW!)
|
||
const worldSize = 100 * 48; // 100 tiles × 48px = 4800px
|
||
cam.setBounds(0, 0, worldSize, worldSize);
|
||
cam.setZoom(1.0); // Default zoom for 2D
|
||
|
||
// Follow player
|
||
if (this.player && this.player.sprite) {
|
||
cam.startFollow(this.player.sprite, true, 0.1, 0.1);
|
||
}
|
||
|
||
console.log('📹 2D Camera setup:', worldSize, 'x', worldSize);
|
||
|
||
// 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());
|
||
|
||
// Help / Tutorial (H key)
|
||
this.input.keyboard.on('keydown-H', () => {
|
||
if (this.tutorialSystem) {
|
||
this.tutorialSystem.showHelp();
|
||
}
|
||
});
|
||
|
||
// Mute Toggle (M key)
|
||
this.input.keyboard.on('keydown-M', () => {
|
||
if (this.soundManager) this.soundManager.toggleMute();
|
||
});
|
||
|
||
// 🌧️ WEATHER SYSTEM KEYS
|
||
this.input.keyboard.on('keydown-R', () => this.setWeather('rain'));
|
||
this.input.keyboard.on('keydown-SHIFT-S', () => this.setWeather('snow'));
|
||
this.input.keyboard.on('keydown-T', () => this.setWeather('storm'));
|
||
this.input.keyboard.on('keydown-F', () => this.setWeather('fog'));
|
||
this.input.keyboard.on('keydown-SHIFT-C', () => this.setWeather('clear'));
|
||
|
||
// Initialize weather system
|
||
this.initializeWeatherSystem();
|
||
|
||
// Initialize Weather UI Panel
|
||
this.weatherUI = new WeatherUI(this);
|
||
console.log('📊 Weather UI Panel created (press W to toggle)');
|
||
}
|
||
|
||
// 🌦️ COMPLETE WEATHER SYSTEM
|
||
initializeWeatherSystem() {
|
||
this.currentWeather = 'clear';
|
||
this.weatherIntensity = 1.0;
|
||
this.puddles = [];
|
||
this.splashes = [];
|
||
this.autoWeatherEnabled = false;
|
||
this.weatherCycleTimer = null;
|
||
|
||
// Load saved weather state
|
||
this.loadWeatherState();
|
||
|
||
console.log('🌦️ Weather system initialized');
|
||
console.log('💡 R = Rain | Shift+S = Snow | T = Storm | F = Fog | Shift+C = Clear');
|
||
console.log('💡 Shift+A = Toggle Auto Weather Cycle');
|
||
|
||
// Auto weather cycle toggle
|
||
this.input.keyboard.on('keydown-SHIFT-A', () => {
|
||
this.toggleAutoWeather();
|
||
});
|
||
|
||
// Intensity controls (+/-)
|
||
this.input.keyboard.on('keydown-PLUS', () => this.adjustIntensity(0.2));
|
||
this.input.keyboard.on('keydown-MINUS', () => this.adjustIntensity(-0.2));
|
||
}
|
||
|
||
toggleAutoWeather() {
|
||
this.autoWeatherEnabled = !this.autoWeatherEnabled;
|
||
|
||
if (this.autoWeatherEnabled) {
|
||
console.log('🔄 Auto weather cycle ENABLED');
|
||
this.startWeatherCycle();
|
||
} else {
|
||
console.log('⏸️ Auto weather cycle DISABLED');
|
||
if (this.weatherCycleTimer) {
|
||
this.weatherCycleTimer.destroy();
|
||
this.weatherCycleTimer = null;
|
||
}
|
||
}
|
||
this.saveWeatherState();
|
||
}
|
||
|
||
startWeatherCycle() {
|
||
// Weather cycle: Clear → Rain → Storm → Clear → Snow → Fog → Clear
|
||
const weatherSequence = ['clear', 'rain', 'storm', 'clear', 'snow', 'fog'];
|
||
const weatherDurations = {
|
||
clear: 120000, // 2 minutes
|
||
rain: 90000, // 1.5 minutes
|
||
storm: 60000, // 1 minute
|
||
snow: 90000, // 1.5 minutes
|
||
fog: 60000 // 1 minute
|
||
};
|
||
|
||
let currentIndex = 0;
|
||
|
||
const cycleWeather = () => {
|
||
const nextWeather = weatherSequence[currentIndex];
|
||
this.setWeather(nextWeather);
|
||
|
||
currentIndex = (currentIndex + 1) % weatherSequence.length;
|
||
|
||
const duration = weatherDurations[nextWeather] || 120000;
|
||
|
||
this.weatherCycleTimer = this.time.delayedCall(duration, () => {
|
||
if (this.autoWeatherEnabled) {
|
||
cycleWeather();
|
||
}
|
||
});
|
||
|
||
console.log(`🌦️ Auto weather: ${nextWeather} (${duration / 1000}s)`);
|
||
};
|
||
|
||
cycleWeather();
|
||
}
|
||
|
||
adjustIntensity(delta) {
|
||
this.weatherIntensity = Phaser.Math.Clamp(this.weatherIntensity + delta, 0.2, 2.0);
|
||
|
||
// Update current weather with new intensity
|
||
if (this.currentWeather !== 'clear' && this.currentWeather !== 'fog') {
|
||
this.setWeather(this.currentWeather); // Restart with new intensity
|
||
}
|
||
|
||
console.log(`🎚️ Weather intensity: ${(this.weatherIntensity * 100).toFixed(0)}%`);
|
||
this.saveWeatherState();
|
||
}
|
||
|
||
saveWeatherState() {
|
||
const state = {
|
||
currentWeather: this.currentWeather,
|
||
intensity: this.weatherIntensity,
|
||
autoEnabled: this.autoWeatherEnabled
|
||
};
|
||
localStorage.setItem('novafarma_weather_state', JSON.stringify(state));
|
||
}
|
||
|
||
loadWeatherState() {
|
||
const saved = localStorage.getItem('novafarma_weather_state');
|
||
if (saved) {
|
||
try {
|
||
const state = JSON.parse(saved);
|
||
this.currentWeather = state.currentWeather || 'clear';
|
||
this.weatherIntensity = state.intensity || 1.0;
|
||
this.autoWeatherEnabled = state.autoEnabled || false;
|
||
|
||
console.log('📂 Weather state loaded:', state);
|
||
|
||
// Restore weather (delayed to avoid initialization issues)
|
||
this.time.delayedCall(1000, () => {
|
||
if (this.currentWeather !== 'clear') {
|
||
this.setWeather(this.currentWeather);
|
||
}
|
||
if (this.autoWeatherEnabled) {
|
||
this.startWeatherCycle();
|
||
}
|
||
});
|
||
} catch (e) {
|
||
console.warn('⚠️ Failed to load weather state:', e);
|
||
}
|
||
}
|
||
}
|
||
|
||
setWeather(type) {
|
||
// Stop current weather
|
||
this.stopAllWeather();
|
||
|
||
this.currentWeather = type;
|
||
|
||
switch (type) {
|
||
case 'rain':
|
||
this.startRain();
|
||
break;
|
||
case 'snow':
|
||
this.startSnow();
|
||
break;
|
||
case 'storm':
|
||
this.startStorm();
|
||
break;
|
||
case 'fog':
|
||
this.startFog();
|
||
break;
|
||
case 'clear':
|
||
console.log('☀️ Clear weather');
|
||
break;
|
||
}
|
||
|
||
this.saveWeatherState();
|
||
}
|
||
|
||
stopAllWeather() {
|
||
// Stop all particle emitters
|
||
if (this.rainEmitter) this.rainEmitter.stop();
|
||
if (this.snowEmitter) this.snowEmitter.stop();
|
||
if (this.stormEmitter) this.stormEmitter.stop();
|
||
|
||
// Stop lightning
|
||
if (this.lightningTimer) {
|
||
this.lightningTimer.destroy();
|
||
this.lightningTimer = null;
|
||
}
|
||
|
||
// Stop puddle spawning
|
||
if (this.puddleTimer) {
|
||
this.puddleTimer.destroy();
|
||
this.puddleTimer = null;
|
||
}
|
||
|
||
// Fade out fog
|
||
if (this.fogOverlay) {
|
||
this.tweens.add({
|
||
targets: this.fogOverlay,
|
||
alpha: 0,
|
||
duration: 2000,
|
||
onComplete: () => {
|
||
if (this.fogOverlay) this.fogOverlay.destroy();
|
||
this.fogOverlay = null;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Cleanup puddles
|
||
this.puddles.forEach(puddle => {
|
||
this.tweens.add({
|
||
targets: puddle,
|
||
alpha: 0,
|
||
duration: 3000,
|
||
onComplete: () => puddle.destroy()
|
||
});
|
||
});
|
||
this.puddles = [];
|
||
}
|
||
|
||
// ☔ RAIN SYSTEM
|
||
startRain() {
|
||
if (!this.rainEmitter) {
|
||
this.createRainParticles();
|
||
}
|
||
|
||
// Apply intensity
|
||
this.rainEmitter.setQuantity(Math.floor(3 * this.weatherIntensity));
|
||
this.rainEmitter.setFrequency(30 / this.weatherIntensity);
|
||
|
||
this.rainEmitter.start();
|
||
console.log('🌧️ Rain started!');
|
||
|
||
// Start puddle spawning
|
||
this.puddleTimer = this.time.addEvent({
|
||
delay: 3000 / this.weatherIntensity,
|
||
callback: () => this.spawnPuddle(),
|
||
loop: true
|
||
});
|
||
|
||
// Play rain sound
|
||
if (this.soundManager && this.soundManager.playRainSound) {
|
||
this.soundManager.playRainSound();
|
||
}
|
||
}
|
||
|
||
createRainParticles() {
|
||
if (!this.textures.exists('raindrop')) {
|
||
const graphics = this.make.graphics({ x: 0, y: 0, add: false });
|
||
graphics.fillStyle(0x88ccff, 1);
|
||
graphics.fillCircle(1, 2, 1);
|
||
graphics.generateTexture('raindrop', 2, 4);
|
||
graphics.destroy();
|
||
}
|
||
|
||
const cam = this.cameras.main;
|
||
this.rainEmitter = this.add.particles(0, 0, 'raindrop', {
|
||
x: { min: 0, max: cam.width },
|
||
y: -50,
|
||
lifespan: 3000,
|
||
speedY: { min: 400, max: 600 },
|
||
scale: { start: 1, end: 0.5 },
|
||
alpha: { start: 0.6, end: 0.2 },
|
||
quantity: 3,
|
||
frequency: 30,
|
||
blendMode: 'ADD',
|
||
|
||
// 🌊 DETECT WHEN RAINDROP HITS GROUND
|
||
deathCallback: (particle) => {
|
||
// Convert camera-relative position to world position
|
||
const worldX = particle.x + cam.scrollX;
|
||
const worldY = particle.y + cam.scrollY;
|
||
|
||
// Check if hit water tile
|
||
this.checkRainImpactOnWater(worldX, worldY);
|
||
}
|
||
});
|
||
|
||
this.rainEmitter.setScrollFactor(0);
|
||
this.rainEmitter.setDepth(999999);
|
||
this.rainEmitter.stop();
|
||
}
|
||
|
||
// ❄️ SNOW SYSTEM
|
||
startSnow() {
|
||
if (!this.snowEmitter) {
|
||
this.createSnowParticles();
|
||
}
|
||
|
||
this.snowEmitter.start();
|
||
console.log('❄️ Snow started!');
|
||
}
|
||
|
||
createSnowParticles() {
|
||
if (!this.textures.exists('snowflake')) {
|
||
const graphics = this.make.graphics({ x: 0, y: 0, add: false });
|
||
graphics.fillStyle(0xffffff, 1);
|
||
graphics.fillCircle(2, 2, 2);
|
||
graphics.generateTexture('snowflake', 4, 4);
|
||
graphics.destroy();
|
||
}
|
||
|
||
const cam = this.cameras.main;
|
||
this.snowEmitter = this.add.particles(0, 0, 'snowflake', {
|
||
x: { min: 0, max: cam.width },
|
||
y: -50,
|
||
lifespan: 8000,
|
||
speedY: { min: 50, max: 150 },
|
||
speedX: { min: -30, max: 30 },
|
||
scale: { start: 0.5, end: 1.5 },
|
||
alpha: { start: 0.8, end: 0.3 },
|
||
quantity: 2,
|
||
frequency: 80,
|
||
blendMode: 'ADD'
|
||
});
|
||
|
||
this.snowEmitter.setScrollFactor(0);
|
||
this.snowEmitter.setDepth(999999);
|
||
this.snowEmitter.stop();
|
||
}
|
||
|
||
// ⚡ STORM SYSTEM
|
||
startStorm() {
|
||
if (!this.stormEmitter) {
|
||
this.createStormParticles();
|
||
}
|
||
|
||
this.stormEmitter.start();
|
||
console.log('⛈️ Storm started!');
|
||
|
||
// Lightning flashes
|
||
this.lightningTimer = this.time.addEvent({
|
||
delay: Phaser.Math.Between(3000, 8000),
|
||
callback: () => this.triggerLightning(),
|
||
loop: true
|
||
});
|
||
|
||
// Puddles (faster spawn)
|
||
this.puddleTimer = this.time.addEvent({
|
||
delay: 2000,
|
||
callback: () => this.spawnPuddle(),
|
||
loop: true
|
||
});
|
||
}
|
||
|
||
createStormParticles() {
|
||
if (!this.textures.exists('raindrop')) {
|
||
this.createRainParticles();
|
||
}
|
||
|
||
const cam = this.cameras.main;
|
||
this.stormEmitter = this.add.particles(0, 0, 'raindrop', {
|
||
x: { min: 0, max: cam.width },
|
||
y: -50,
|
||
lifespan: 2000,
|
||
speedY: { min: 600, max: 900 },
|
||
speedX: { min: 50, max: 150 },
|
||
scale: { start: 1.5, end: 0.5 },
|
||
alpha: { start: 0.8, end: 0.3 },
|
||
quantity: 5,
|
||
frequency: 20,
|
||
blendMode: 'ADD'
|
||
});
|
||
|
||
this.stormEmitter.setScrollFactor(0);
|
||
this.stormEmitter.setDepth(999999);
|
||
this.stormEmitter.stop();
|
||
}
|
||
|
||
triggerLightning() {
|
||
// White flash overlay
|
||
const flash = this.add.rectangle(
|
||
this.cameras.main.scrollX,
|
||
this.cameras.main.scrollY,
|
||
this.cameras.main.width,
|
||
this.cameras.main.height,
|
||
0xffffff,
|
||
0.8
|
||
);
|
||
flash.setOrigin(0, 0);
|
||
flash.setScrollFactor(0);
|
||
flash.setDepth(1000000);
|
||
|
||
// Fade out
|
||
this.tweens.add({
|
||
targets: flash,
|
||
alpha: 0,
|
||
duration: 200,
|
||
onComplete: () => flash.destroy()
|
||
});
|
||
|
||
// Screen shake
|
||
this.cameras.main.shake(200, 0.005);
|
||
|
||
// Thunder sound (if available)
|
||
if (this.soundManager && this.soundManager.playThunderSound) {
|
||
this.time.delayedCall(300, () => {
|
||
this.soundManager.playThunderSound();
|
||
});
|
||
}
|
||
|
||
console.log('⚡ Lightning strike!');
|
||
}
|
||
|
||
// 🌫️ FOG SYSTEM
|
||
startFog() {
|
||
if (!this.fogOverlay) {
|
||
this.fogOverlay = this.add.rectangle(
|
||
0, 0,
|
||
this.cameras.main.width * 2,
|
||
this.cameras.main.height * 2,
|
||
0xcccccc,
|
||
0
|
||
);
|
||
this.fogOverlay.setOrigin(0, 0);
|
||
this.fogOverlay.setScrollFactor(0);
|
||
this.fogOverlay.setDepth(500000);
|
||
}
|
||
|
||
this.tweens.add({
|
||
targets: this.fogOverlay,
|
||
alpha: 0.4,
|
||
duration: 3000
|
||
});
|
||
|
||
console.log('🌫️ Fog started!');
|
||
}
|
||
|
||
|
||
// 💧 PUDDLES SYSTEM (Spawn on grass/dirt where rain lands!)
|
||
spawnPuddle() {
|
||
if (!this.terrainSystem) return;
|
||
|
||
const cam = this.cameras.main;
|
||
const worldX = cam.scrollX + Phaser.Math.Between(100, cam.width - 100);
|
||
const worldY = cam.scrollY + Phaser.Math.Between(100, cam.height - 100);
|
||
|
||
// 🎨 FLAT 2D CONVERSION (NEW!)
|
||
const tileSize = 48;
|
||
const x = Math.floor(worldX / tileSize);
|
||
const y = Math.floor(worldY / tileSize);
|
||
|
||
// Get tile type
|
||
const tile = this.terrainSystem.getTile(x, y);
|
||
|
||
// ONLY spawn puddles on grass or dirt!
|
||
if (!tile || (tile.type !== 'grass' && tile.type !== 'dirt' && tile.type !== 'farmland')) {
|
||
return; // Skip - not valid surface
|
||
}
|
||
|
||
// Limit max puddles
|
||
if (this.puddles.length >= 15) {
|
||
const oldest = this.puddles.shift();
|
||
if (oldest && oldest.active) oldest.destroy();
|
||
}
|
||
|
||
// Create puddle SPRITE (realistic!)
|
||
const puddle = this.add.image(worldX, worldY, 'luza_sprite');
|
||
puddle.setOrigin(0.5, 0.5);
|
||
puddle.setScale(1.5); // BIGGER - more visible!
|
||
puddle.setDepth(10); // ABOVE terrain
|
||
puddle.setScrollFactor(1);
|
||
puddle.setAlpha(0); // Start invisible
|
||
|
||
// Fade in
|
||
this.tweens.add({
|
||
targets: puddle,
|
||
alpha: 0.35,
|
||
duration: 2000
|
||
});
|
||
|
||
this.puddles.push(puddle);
|
||
|
||
// Auto cleanup after 30 seconds
|
||
this.time.delayedCall(30000, () => {
|
||
if (puddle && puddle.active) {
|
||
this.tweens.add({
|
||
targets: puddle,
|
||
alpha: 0,
|
||
duration: 3000,
|
||
onComplete: () => {
|
||
puddle.destroy();
|
||
const index = this.puddles.indexOf(puddle);
|
||
if (index > -1) this.puddles.splice(index, 1);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
// Random splash effects
|
||
this.time.addEvent({
|
||
delay: Phaser.Math.Between(1000, 3000),
|
||
callback: () => {
|
||
if (puddle && puddle.active && (this.currentWeather === 'rain' || this.currentWeather === 'storm')) {
|
||
this.createSplash(puddle.x, puddle.y);
|
||
}
|
||
},
|
||
loop: true,
|
||
repeat: 5
|
||
});
|
||
}
|
||
|
||
// 🌊 CHECK IF RAIN HIT WATER TILE
|
||
checkRainImpactOnWater(worldX, worldY) {
|
||
if (!this.terrainSystem) return;
|
||
|
||
// 🎨 FLAT 2D CONVERSION (NEW!)
|
||
const tileSize = 48;
|
||
const x = Math.floor(worldX / tileSize);
|
||
const y = Math.floor(worldY / tileSize);
|
||
|
||
// Get tile at position
|
||
const tile = this.terrainSystem.getTile(x, y);
|
||
|
||
// If water tile, create ripple!
|
||
if (tile && tile.type === 'water') {
|
||
this.createWaterRipple(worldX, worldY);
|
||
}
|
||
// If grass/dirt, 3% chance to spawn puddle
|
||
else if (tile && (tile.type === 'grass' || tile.type === 'dirt' || tile.type === 'farmland')) {
|
||
if (Math.random() < 0.03) {
|
||
this.spawnPuddleAtLocation(worldX, worldY);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 💧 CREATE WATER RIPPLE EFFECT
|
||
createWaterRipple(x, y) {
|
||
// Small expanding circle on water surface
|
||
const ripple = this.add.circle(x, y, 2, 0xffffff, 0.5);
|
||
ripple.setDepth(500); // Above water tiles
|
||
ripple.setScrollFactor(1); // World-bound
|
||
|
||
this.tweens.add({
|
||
targets: ripple,
|
||
radius: 10,
|
||
alpha: 0,
|
||
duration: 400,
|
||
ease: 'Quad.easeOut',
|
||
onComplete: () => ripple.destroy()
|
||
});
|
||
}
|
||
|
||
// 💧 SPAWN PUDDLE AT EXACT LOCATION (from rain impact)
|
||
spawnPuddleAtLocation(worldX, worldY) {
|
||
// Limit max puddles
|
||
if (this.puddles.length >= 15) {
|
||
// Remove oldest puddle
|
||
const oldest = this.puddles.shift();
|
||
if (oldest && oldest.active) oldest.destroy();
|
||
}
|
||
|
||
// Create puddle SPRITE (realistic!)
|
||
const puddle = this.add.image(worldX, worldY, 'luza_sprite');
|
||
puddle.setOrigin(0.5, 0.5);
|
||
puddle.setScale(1.5); // BIGGER - more visible!
|
||
puddle.setDepth(10); // ABOVE terrain
|
||
puddle.setScrollFactor(1);
|
||
puddle.setAlpha(0); // Start invisible
|
||
|
||
// Fade in
|
||
this.tweens.add({
|
||
targets: puddle,
|
||
alpha: 0.35,
|
||
duration: 2000
|
||
});
|
||
|
||
this.puddles.push(puddle);
|
||
|
||
// Auto cleanup after 30 seconds
|
||
this.time.delayedCall(30000, () => {
|
||
if (puddle && puddle.active) {
|
||
this.tweens.add({
|
||
targets: puddle,
|
||
alpha: 0,
|
||
duration: 3000,
|
||
onComplete: () => {
|
||
puddle.destroy();
|
||
const index = this.puddles.indexOf(puddle);
|
||
if (index > -1) this.puddles.splice(index, 1);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
// 💦 SPLASH EFFECT (Ripples)
|
||
createSplash(x, y) {
|
||
// Concentric circles
|
||
for (let i = 0; i < 3; i++) {
|
||
this.time.delayedCall(i * 100, () => {
|
||
const circle = this.add.circle(x, y, 3, 0xffffff, 0.5);
|
||
circle.setDepth(2);
|
||
|
||
this.tweens.add({
|
||
targets: circle,
|
||
radius: 20 + (i * 5),
|
||
alpha: 0,
|
||
duration: 600,
|
||
onComplete: () => circle.destroy()
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
update(time, delta) {
|
||
if (this.player) this.player.update(delta);
|
||
|
||
// 🎯 Z-SORTING: SortableObjects based on Y position
|
||
if (this.sortableObjects) {
|
||
const children = this.sortableObjects.getChildren();
|
||
|
||
// Sortiranje po Y koordinati (nižji Y = nižji depth)
|
||
children.sort((a, b) => a.y - b.y);
|
||
|
||
// Nastavi depth glede na vrstni red (index)
|
||
children.forEach((obj, index) => {
|
||
// Use LAYER_OBJECTS base + index for depth
|
||
obj.setDepth(200000 + index);
|
||
});
|
||
}
|
||
|
||
// Weather UI Update
|
||
if (this.weatherUI) this.weatherUI.update();
|
||
|
||
// Update Systems
|
||
if (this.terrainSystem) this.terrainSystem.update(time, delta); // Water animation!
|
||
if (this.statsSystem) this.statsSystem.update(delta);
|
||
if (this.craftingSystem) this.craftingSystem.update(delta); // 🛠️ Crafting progress
|
||
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();
|
||
// 🎨 FLAT 2D (NEW!) - Direct position, no conversion
|
||
const tileSize = 48;
|
||
const screenX = playerPos.x * tileSize + tileSize / 2;
|
||
const screenY = playerPos.y * tileSize + tileSize / 2;
|
||
this.parallaxSystem.update(screenX, screenY);
|
||
}
|
||
|
||
// Terrain Update
|
||
if (this.terrainSystem) {
|
||
// Note: Flat2D doesn't need culling (already optimized)
|
||
// this.terrainSystem.updateCulling(this.cameras.main);
|
||
this.terrainSystem.update(delta);
|
||
}
|
||
|
||
|
||
// Clouds
|
||
if (this.clouds) {
|
||
for (const cloud of this.clouds) {
|
||
if (cloud && cloud.sprite) {
|
||
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();
|
||
|
||
// Screen Reader System Update
|
||
if (this.screenReader) this.screenReader.update();
|
||
|
||
// Motor Accessibility System Update
|
||
if (this.motorAccessibility) this.motorAccessibility.update();
|
||
|
||
// Visual Enhancement System Update
|
||
if (this.visualEnhancements) this.visualEnhancements.update(delta);
|
||
|
||
// Fog of War System Update
|
||
if (this.fogOfWar) this.fogOfWar.update();
|
||
|
||
// Farm Automation System Update
|
||
if (this.farmAutomation) this.farmAutomation.update(delta);
|
||
|
||
// Animal Breeding System Update
|
||
if (this.animalBreeding) this.animalBreeding.update(delta);
|
||
|
||
// Automation Tier System Update
|
||
if (this.automationTiers) this.automationTiers.update(delta);
|
||
|
||
// Cooking System Update
|
||
if (this.cooking) this.cooking.update(delta);
|
||
|
||
// Fishing System Update
|
||
if (this.fishing) this.fishing.update(delta);
|
||
|
||
// Worker Creatures System Update
|
||
if (this.workerCreatures) this.workerCreatures.update(delta);
|
||
|
||
// Boss Battles System Update
|
||
if (this.bossBattles) this.bossBattles.update(delta);
|
||
|
||
// Multiplayer & Social System Update
|
||
if (this.multiplayerSocial) this.multiplayerSocial.update(delta);
|
||
|
||
// Technical & Performance System Update
|
||
if (this.technicalPerformance) this.technicalPerformance.update(delta);
|
||
|
||
// Platform Support System Update
|
||
if (this.platformSupport) this.platformSupport.update(delta);
|
||
|
||
// Save System Expansion Update
|
||
if (this.saveSystemExpansion) this.saveSystemExpansion.update(delta);
|
||
|
||
// Update NPCs
|
||
for (const npc of this.npcs) {
|
||
if (npc.update) npc.update(delta);
|
||
}
|
||
|
||
// Update Unified Stats Panel
|
||
if (this.unifiedStatsPanel) {
|
||
this.unifiedStatsPanel.update(delta);
|
||
}
|
||
|
||
// Update Full Inventory UI
|
||
if (this.fullInventoryUI) {
|
||
this.fullInventoryUI.update();
|
||
}
|
||
|
||
// 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(spawnX = 20, spawnY = 20) {
|
||
console.log(`🌾 Initializing 8x8 Farm Area at (${spawnX}, ${spawnY})...`);
|
||
|
||
const farmX = spawnX; // Farm center (custom spawn)
|
||
const farmY = spawnY;
|
||
const farmRadius = 4; // 8x8 = radius 4 (4 tiles in each direction)
|
||
|
||
// 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);
|
||
}
|
||
|
||
// Change terrain to grass
|
||
if (this.terrainSystem.tiles[y] && this.terrainSystem.tiles[y][x]) {
|
||
this.terrainSystem.tiles[y][x].type = 'grass';
|
||
this.terrainSystem.tiles[y][x].solid = false;
|
||
if (this.terrainSystem.tiles[y][x].sprite) {
|
||
this.terrainSystem.tiles[y][x].sprite.setTexture('grass');
|
||
this.terrainSystem.tiles[y][x].sprite.clearTint();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 2. Optional: Add fence around farm (commented out)
|
||
// const minX = farmX - farmRadius - 1;
|
||
// const maxX = farmX + farmRadius + 1;
|
||
// const minY = farmY - farmRadius - 1;
|
||
// const maxY = farmY + farmRadius + 1;
|
||
|
||
// // 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(`✅ 8x8 Farm Area Initialized at (${spawnX},${spawnY})`);
|
||
}
|
||
|
||
// ========================================================
|
||
// 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;
|
||
}
|
||
});
|
||
}
|
||
}
|