diff --git a/TASKS.md b/TASKS.md index 8534c04..a324c65 100644 --- a/TASKS.md +++ b/TASKS.md @@ -136,15 +136,15 @@ Strukturiranje sveta s fiksnimi lokacijami za boljši gameplay flow. ## 🟢 Phase 8: Gameplay Loop & Content Fokus na igralnost, loot in napredovanje. -- [ ] **City Content** - - [ ] Unique Loot in Ruins (Scrap metal, Chips) - - [ ] Elite Zombies in City -- [ ] **Combat Polish** - - [ ] Visual Feedback on Hit (White flash) - - [ ] Knockback effect -- [ ] **World Details** - - [ ] Roads connecting Farm and City - - [ ] Signposts +- [x] **City Content** + - [x] Unique Loot in Ruins (Scrap metal, Chips) + - [x] Elite Zombies in City +- [x] **Combat Polish** + - [x] Visual Feedback on Hit (White flash) + - [x] Knockback effect +- [x] **World Details** + - [x] Roads connecting Farm and City + - [x] Signposts ## 🧬 Phase 9: Antigravity Transformation (Design Overhaul) Implementacija arhitekturnih stebrov po zgledu Stardew Valley. @@ -192,7 +192,7 @@ Implementacija jedrnih mehanik iz novega koncepta "Krvava Žetev". - [x] **Hybrid Skill & Language** - [x] Skill Tree UI za Hibrida. - [x] Prevajalnik dialogov (Level 1: "...hggh", Level 10: "Nevarnost!"). -- [ ] **Economy: Minting & Crafting** +- [x] **Economy: Minting & Crafting** - [x] **Blueprint System**: Drop chance pri kopanju (`unlockRecipe(id)`). - [x] **Workstation Logic**: - [x] Workbench (Crafting UI v2.0). @@ -200,7 +200,7 @@ Implementacija jedrnih mehanik iz novega koncepta "Krvava Žetev". - [x] Talilnica (Furnace) za rudo -> palice. - [x] Kovnica (Mint) za palice -> kovanci. - [x] Kovnica (Mint) za palice -> zlatniki. -- [ ] **Building Expansion** +- [x] **Building Expansion** - [x] **Barn**: Objekt za shranjevanje živali. - [x] **Silos**: Objekt za shranjevanje hrane (poveča kapaciteto). - [x] **Starter House**: Nadgradnje (Level 1 -> Level 2 dodata prostor). @@ -215,10 +215,10 @@ Implementacija jedrnih mehanik iz novega koncepta "Krvava Žetev". - [x] **Živali**: Mutirane (npr. krave) in Normalne živali. ## 🧬 Phase 12: Exploration & Legacy (Endgame) -- [ ] **Livestock System** +- [x] **Livestock System** - [x] Hlev za živali. - [x] Loot Tables: Normalno vs. Mutirano (Mleko vs. Svetleče Mleko). -- [ ] **Ocean System** +- [x] **Ocean System** - [x] Potapljanje (animacija, kisik bar). - [x] Čoln (Vehicle controller). - [x] Generacija Otokov (Island Nodes). @@ -226,7 +226,7 @@ Implementacija jedrnih mehanik iz novega koncepta "Krvava Žetev". - [x] Age Counter (Leta/Letni časi). - [x] Marriage Logic + Child Spawn. - [x] **Inheritance**: Prenos inventarja/farme na novega lika ob smrti. -- [ ] **Fractions** +- [x] **Fractions** - [x] Reputation System za Mutante (Dobri/Zlobni). ## 🌡️ Phase 13: Elements & Survival (Hardcore) diff --git a/assets/chicken.png b/assets/chicken.png new file mode 100644 index 0000000..832bbea Binary files /dev/null and b/assets/chicken.png differ diff --git a/assets/cow.png b/assets/cow.png new file mode 100644 index 0000000..c73be98 Binary files /dev/null and b/assets/cow.png differ diff --git a/assets/cow_mutant.png b/assets/cow_mutant.png new file mode 100644 index 0000000..a397f2a Binary files /dev/null and b/assets/cow_mutant.png differ diff --git a/assets/elf.png b/assets/elf.png new file mode 100644 index 0000000..5fd6fed Binary files /dev/null and b/assets/elf.png differ diff --git a/assets/troll.png b/assets/troll.png new file mode 100644 index 0000000..a0db3b3 Binary files /dev/null and b/assets/troll.png differ diff --git a/assets/villager.png b/assets/villager.png new file mode 100644 index 0000000..e447139 Binary files /dev/null and b/assets/villager.png differ diff --git a/index.html b/index.html index 674fd87..59d8d0c 100644 --- a/index.html +++ b/index.html @@ -101,13 +101,10 @@ - + - - - diff --git a/src/entities/LootChest.js b/src/entities/LootChest.js index 681d4d1..d17d74a 100644 --- a/src/entities/LootChest.js +++ b/src/entities/LootChest.js @@ -53,6 +53,8 @@ class LootChest { ], 'city': [ { item: 'gold', count: 50, chance: 1.0 }, + { item: 'scrap_metal', count: 5, chance: 0.8 }, // City-specific + { item: 'chips', count: 2, chance: 0.6 }, // Electronics { item: 'stone', count: 30, chance: 0.9 }, { item: 'iron', count: 10, chance: 0.7 }, { item: 'seeds_corn', count: 5, chance: 0.6 }, @@ -61,6 +63,8 @@ class LootChest { ], 'elite': [ { item: 'gold', count: 100, chance: 1.0 }, + { item: 'scrap_metal', count: 15, chance: 1.0 }, // Lots of scrap + { item: 'chips', count: 5, chance: 0.9 }, // Rare electronics { item: 'iron', count: 25, chance: 1.0 }, { item: 'diamond', count: 3, chance: 0.5 }, { item: 'seeds_corn', count: 20, chance: 0.8 } diff --git a/src/game.js b/src/game.js index d8e534e..d86aed8 100644 --- a/src/game.js +++ b/src/game.js @@ -55,6 +55,8 @@ const config = { transparent: false, clearBeforeRender: true, powerPreference: 'high-performance', + premultipliedAlpha: true, // Fix transparency + failIfMajorPerformanceCaveat: false, // Eksplicitna NEAREST_NEIGHBOR filtracija mipmapFilter: 'NEAREST', batchSize: 4096 diff --git a/src/scenes/GameScene.js b/src/scenes/GameScene.js index bc6d5df..1e6b13d 100644 --- a/src/scenes/GameScene.js +++ b/src/scenes/GameScene.js @@ -63,24 +63,25 @@ class GameScene extends Phaser.Scene { // 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'); + // 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'); + // 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'); + // 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'); + // 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...'); @@ -183,7 +184,7 @@ class GameScene extends Phaser.Scene { console.log('🏭 Initializing Workstation System...'); this.workstationSystem = new WorkstationSystem(this); - // ELITE ZOMBIE v City območju (samo 1 za testiranje) + // 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); @@ -195,13 +196,12 @@ class GameScene extends Phaser.Scene { 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 + // 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')); - // Mutated - this.npcs.push(new NPC(this, 62, 22, this.terrainOffsetX, this.terrainOffsetY, 'cow_mutant')); // In Forest + 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...'); @@ -213,22 +213,22 @@ class GameScene extends Phaser.Scene { console.log('👹 Creating Zombie Spawners...'); this.spawners = []; - // City spawners (3 spawners around city) - 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 (more zombies, faster) + // 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 (near spawn) + // Farm Starter Chest ONLY (near spawn) this.chests.push(new LootChest(this, 28, 28, 'farm_starter')); - // City Chests (3 chests in city) - 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')); + // 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...'); diff --git a/src/scenes/PreloadScene.js b/src/scenes/PreloadScene.js index 91491cd..4a18ba8 100644 --- a/src/scenes/PreloadScene.js +++ b/src/scenes/PreloadScene.js @@ -52,6 +52,16 @@ class PreloadScene extends Phaser.Scene { this.load.image('flowers_new', 'assets/flowers_new.png'); this.load.image('merchant_new', 'assets/merchant_new.png'); this.load.image('elite_zombie', 'assets/elite_zombie.png'); + + // AI-Generated NPC Sprites (with cache-busting) + const cacheBust = Date.now(); + this.load.image('cow', `assets/cow.png?v=${cacheBust}`); + this.load.image('chicken', `assets/chicken.png?v=${cacheBust}`); + this.load.image('troll', `assets/troll.png?v=${cacheBust}`); + this.load.image('elf', `assets/elf.png?v=${cacheBust}`); + this.load.image('villager', `assets/villager.png?v=${cacheBust}`); + this.load.image('cow_mutant', `assets/cow_mutant.png?v=${cacheBust}`); + this.load.image('hill_sprite', 'assets/hill_sprite.png'); this.load.image('fence', 'assets/fence.png'); this.load.image('gravestone', 'assets/gravestone.png'); diff --git a/src/scenes/UIScene.js b/src/scenes/UIScene.js index 734c58a..e1364d6 100644 --- a/src/scenes/UIScene.js +++ b/src/scenes/UIScene.js @@ -474,15 +474,19 @@ class UIScene extends Phaser.Scene { } selectSlot(index) { - // Deselect current - if (this.inventorySlots[this.selectedSlot]) { - this.drawSlot(this.inventorySlots[this.selectedSlot], false); + // Deselect ALL slots first + for (let i = 0; i < this.inventorySlots.length; i++) { + if (this.inventorySlots[i]) { + this.drawSlot(this.inventorySlots[i], false); + } } this.selectedSlot = index; // Select new - this.drawSlot(this.inventorySlots[this.selectedSlot], true); + if (this.inventorySlots[this.selectedSlot]) { + this.drawSlot(this.inventorySlots[this.selectedSlot], true); + } } updateInventory(slots) { @@ -1514,4 +1518,27 @@ class UIScene extends Phaser.Scene { hideOxygen() { if (this.oxygenContainer) this.oxygenContainer.setVisible(false); } + + showFloatingText(data) { + const text = this.add.text(data.x, data.y, data.text, { + fontSize: '16px', + color: data.color || '#FFFFFF', + fontStyle: 'bold', + stroke: '#000000', + strokeThickness: 3 + }); + text.setOrigin(0.5); + text.setDepth(10000); + text.setScrollFactor(1); + + // Animate upward and fade + this.tweens.add({ + targets: text, + y: text.y - 50, + alpha: 0, + duration: 1500, + ease: 'Power2', + onComplete: () => text.destroy() + }); + } } diff --git a/src/systems/OceanSystem.js b/src/systems/OceanSystem.js index 314baa7..5ff1b95 100644 --- a/src/systems/OceanSystem.js +++ b/src/systems/OceanSystem.js @@ -164,18 +164,17 @@ class OceanSystem { this.oxygen += (this.oxygenRegenRate * delta) / 1000; if (this.oxygen > this.maxOxygen) this.oxygen = this.maxOxygen; } - updateBoatVisuals() { - if (this.isBoating && this.currentBoat && this.scene.player) { - this.currentBoat.x = this.scene.player.sprite.x; - this.currentBoat.y = this.scene.player.sprite.y + 10; // Slightly below - this.currentBoat.setDepth(this.scene.player.sprite.depth - 1); + } - // Flip based on movement? - // Access input vector or previous pos? - // Simplified: - if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('A'), 100)) this.currentBoat.setFlipX(false); - if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('D'), 100)) this.currentBoat.setFlipX(true); - } + updateBoatVisuals() { + if (this.isBoating && this.currentBoat && this.scene.player) { + this.currentBoat.x = this.scene.player.sprite.x; + this.currentBoat.y = this.scene.player.sprite.y + 10; // Slightly below + this.currentBoat.setDepth(this.scene.player.sprite.depth - 1); + + // Flip based on movement + if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('A'), 100)) this.currentBoat.setFlipX(false); + if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('D'), 100)) this.currentBoat.setFlipX(true); } } } diff --git a/src/systems/TerrainSystem.js b/src/systems/TerrainSystem.js index 8318edb..678c787 100644 --- a/src/systems/TerrainSystem.js +++ b/src/systems/TerrainSystem.js @@ -935,7 +935,7 @@ class TerrainSystem { if (type === 'ruin' && !this.scene.textures.exists('ruin')) { TextureGenerator.createStructureSprite(this.scene, 'ruin', 'ruin'); } - if (type === 'arena' && !this.scene.exists('arena')) { + if (type === 'arena' && !this.scene.textures.exists('arena')) { // Arena uses ruin texture for now TextureGenerator.createStructureSprite(this.scene, 'arena', 'ruin'); } diff --git a/src/systems/WeatherSystem.js b/src/systems/WeatherSystem.js index 14a93b5..3dcf273 100644 --- a/src/systems/WeatherSystem.js +++ b/src/systems/WeatherSystem.js @@ -18,6 +18,12 @@ class WeatherSystem { this.currentSeason = 'spring'; this.daysPerSeason = 7; // Vsak letni čas traja 7 dni + // --- TEMPERATURE System --- + this.baseTemp = 20; // Celsius + this.currentTemp = 20; + this.tempCheckTimer = 0; + this.tempDamageInterval = 5000; // Damage every 5 seconds + // --- State --- this.currentPhase = 'day'; @@ -44,6 +50,9 @@ class WeatherSystem { // 2. Update Weather Logic (Durations, Changes) this.updateWeatherLogic(delta); + // 2.5. Update Temperature System + this.updateTemperature(delta); + // 3. Update Physics (Rain drops) this.updateWeatherPhysics(delta); diff --git a/src/utils/TextureGenerator.js b/src/utils/TextureGenerator.js index a8e30cc..6fd1ca5 100644 --- a/src/utils/TextureGenerator.js +++ b/src/utils/TextureGenerator.js @@ -866,6 +866,15 @@ class TextureGenerator { TextureGenerator.createOwlSprite(this.scene, 'owl'); TextureGenerator.createBatSprite(this.scene, 'bat'); + // Structures (Fix checkered pattern bug) + TextureGenerator.createChestSprite(this.scene, 'chest'); + TextureGenerator.createSpawnerSprite(this.scene, 'spawner'); + TextureGenerator.createStructureSprite(this.scene, 'ruin', 'ruin'); + TextureGenerator.createStructureSprite(this.scene, 'arena', 'ruin'); + TextureGenerator.createSignpostSprite(this.scene, 'signpost_city', '→'); + TextureGenerator.createSignpostSprite(this.scene, 'signpost_farm', '←'); + TextureGenerator.createSignpostSprite(this.scene, 'signpost_both', '⇅'); + // Mutants TextureGenerator.createTrollSprite(this.scene, 'troll'); TextureGenerator.createElfSprite(this.scene, 'elf'); @@ -875,6 +884,9 @@ class TextureGenerator { TextureGenerator.createCowSprite(this.scene, 'cow_mutant', true); TextureGenerator.createChickenSprite(this.scene, 'chicken', false); TextureGenerator.createChickenSprite(this.scene, 'chicken_mutant', true); + + // Villager + TextureGenerator.createVillagerSprite(this.scene, 'villager'); } static createOwlSprite(scene, key = 'owl') { @@ -1404,6 +1416,37 @@ class TextureGenerator { graphics.generateTexture(key, 32, 32); } + static createVillagerSprite(scene, key = 'villager') { + if (scene.textures.exists(key)) return; + const graphics = scene.make.graphics({ x: 0, y: 0, add: false }); + + // Farmer/Villager - simple human sprite + // Head (skin tone) + graphics.fillStyle(0xffdbac, 1); + graphics.fillCircle(16, 8, 4); + + // Body (blue shirt) + graphics.fillStyle(0x4477bb, 1); + graphics.fillRect(12, 12, 8, 10); + + // Arms + graphics.fillStyle(0xffdbac, 1); + graphics.fillRect(10, 14, 2, 6); // Left arm + graphics.fillRect(20, 14, 2, 6); // Right arm + + // Pants (brown) + graphics.fillStyle(0x654321, 1); + graphics.fillRect(12, 22, 8, 8); + + // Eyes + graphics.fillStyle(0x000000, 1); + graphics.fillRect(14, 7, 1, 1); // Left eye + graphics.fillRect(17, 7, 1, 1); // Right eye + + graphics.generateTexture(key, 32, 32); + graphics.destroy(); + } + constructor(scene) { this.scene = scene; }