From 5de27d0b046106979f5c1e861bf943e6b8fb872f Mon Sep 17 00:00:00 2001 From: NovaFarma Dev Date: Mon, 8 Dec 2025 03:25:58 +0100 Subject: [PATCH] zacetek je dolg --- DNEVNIK.md | 5 ++ KICKSTARTER_PLAN.md | 6 ++ src/entities/NPC.js | 108 +++++++++--------------------- src/systems/ZombieWorkerSystem.js | 61 ++++++++++------- 4 files changed, 79 insertions(+), 101 deletions(-) diff --git a/DNEVNIK.md b/DNEVNIK.md index 6623d91..ff3ac4e 100644 --- a/DNEVNIK.md +++ b/DNEVNIK.md @@ -1,5 +1,10 @@ # 📔 DNEVNIK RAZVOJA: KRVAVA ŽETEV (ZOMBIE ROOTS) +**Lokacija:** Nova Farma +**Engine:** Phaser 3 + Antigravity +**Razvoj:** Pionirski AI-Assisted Development (Human Lead + AI Code) +**Stil:** 2.5D Izometrični Pixel Art / Voxel + ## 📖 Zgodba in Lore **Protagonist:** Najstnik z značilnimi dredloksi, ki je preživel napad mutanta "Zmaj-Volka" (najvišji plenilec) in v procesu postal **Hibrid**. Okužen je z virusom, a imun, kar mu daje status **Alfe** med zombiji. diff --git a/KICKSTARTER_PLAN.md b/KICKSTARTER_PLAN.md index 2cf2e21..8803bbb 100644 --- a/KICKSTARTER_PLAN.md +++ b/KICKSTARTER_PLAN.md @@ -45,5 +45,11 @@ Pred snemanjem je treba urediti: * **€100k:** Port za Switch in Mobile. * **€200k:** *Dubbing* (Glasovna igra) v 5 jezikih. +## 🌟 5. Zgodba v Ozadju (The "AI" Hook) +To ni le igra, to je eksperiment prihodnosti. +* **Narrative:** "Krvava Žetev" je ena prvih kompleksnih RPG iger na svetu, ustvarjena v popolni simbiozi med enim Vizionarjem (človek) in Naprednim AI (koda). +* **Sporočilo:** Dokaz, da lahko posameznik s pravo vizijo in orodji ustvari svetove, ki so bili včasih rezervirani za velike studie. +* **Media Angle:** To bo pritegnilo pozornost Tech medijev (ne le Gaming medijev). + --- *Ta dokument služi kot vodič za pripravo marketinških materialov.* diff --git a/src/entities/NPC.js b/src/entities/NPC.js index 712cf0d..70f8a36 100644 --- a/src/entities/NPC.js +++ b/src/entities/NPC.js @@ -51,73 +51,7 @@ class NPC { } } - tame() { - if (this.state === 'TAMED' || this.type !== 'zombie') return; - - this.state = 'TAMED'; - console.log('🧟❤️ Zombie TAMED!'); - - // Visual Feedback - const headX = this.sprite.x; - const headY = this.sprite.y - 40; - - const heart = this.scene.add.text(headX, headY, '❤️', { fontSize: '20px' }); - heart.setOrigin(0.5); - heart.setDepth(this.sprite.depth + 100); - - this.scene.tweens.add({ - targets: heart, - y: headY - 30, - alpha: 0, - duration: 1500, - onComplete: () => heart.destroy() - }); - - // Change color slightly to indicate friend - this.sprite.setTint(0xAAFFAA); - - // Hide Health Bar if tamed - if (this.healthBarBg) { - this.healthBarBg.setVisible(false); - this.healthBar.setVisible(false); - } - - // Change Eyes to Friendly (Cyan) - this.addTamedEyes(); - } - - addTamedEyes() { - if (this.eyesGroup) return; - - // Container for eyes - // Coordinates relative to sprite center bottom (0.5, 1) - // Head is roughly at y - height. - // Assuming sprite height ~50-60px visual. - - this.eyesGroup = this.scene.add.container(this.sprite.x, this.sprite.y); - - // Eyes - const eyeL = this.scene.add.rectangle(-5, -55, 3, 3, 0x00FFFF); - const eyeR = this.scene.add.rectangle(5, -55, 3, 3, 0x00FFFF); - - this.eyesGroup.add([eyeL, eyeR]); - this.eyesGroup.setDepth(this.sprite.depth + 2); - } - - toggleState() { - if (this.state === 'WANDER') { - this.tame(); - } else { - // Command to stay/follow - this.state = this.state === 'FOLLOW' ? 'STAY' : 'FOLLOW'; - console.log(`Command: ${this.state}`); - - // Visual feedback for command - const txt = this.scene.add.text(this.sprite.x, this.sprite.y - 60, this.state, { fontSize: '12px', color: '#FFF' }); - txt.setOrigin(0.5); - this.scene.tweens.add({ targets: txt, y: txt.y - 20, alpha: 0, duration: 1000, onComplete: () => txt.destroy() }); - } - } + // Methods moved/consolidated below createSprite() { let texKey = `npc_${this.type}`; @@ -697,17 +631,22 @@ class NPC { this.state = 'TAMED'; console.log('🧟❤️ Zombie TAMED!'); + // Register to ZombieWorkerSystem + if (this.scene.zombieSystem) { + this.scene.zombieSystem.registerWorker(this); + } + // Visual Feedback const headX = this.sprite.x; - const headY = this.sprite.y - 40; + const headY = this.sprite.y - 50; - const heart = this.scene.add.text(headX, headY, '❤️', { fontSize: '20px' }); + const heart = this.scene.add.text(headX, headY, '❤️', { fontSize: '24px' }); heart.setOrigin(0.5); - heart.setDepth(this.sprite.depth + 100); + heart.setDepth(this.sprite.depth + 200); this.scene.tweens.add({ targets: heart, - y: headY - 30, + y: headY - 40, alpha: 0, duration: 1500, onComplete: () => heart.destroy() @@ -716,7 +655,7 @@ class NPC { // Change color slightly to indicate friend this.sprite.setTint(0xAAFFAA); - // Hide Health Bar if tamed (optional) + // Hide Health Bar if tamed if (this.healthBarBg) { this.healthBarBg.setVisible(false); this.healthBar.setVisible(false); @@ -728,12 +667,30 @@ class NPC { interact() { console.log('🗣️ Inteacting with NPC:', this.type); - // Quest Check + // ZOMBIE LOGIC + if (this.type === 'zombie') { + if (this.state !== 'TAMED') { + // Try tame (For now instant) + this.tame(); + } else { + // Command: Toggle FOLLOW / STAY + if (this.state === 'FOLLOW') { + this.state = 'STAY'; + this.showEmote('🛑'); // Stop + if (this.workerStats) this.workerStats.task = 'IDLE'; + } else { + this.state = 'FOLLOW'; + this.showEmote('👣'); // Footprints + if (this.workerStats) this.workerStats.task = 'FOLLOW'; + } + } + return; + } + + // NPC QUEST LOGIC if (this.scene.questSystem) { const availableQuest = this.scene.questSystem.getAvailableQuest(this.type); if (availableQuest) { - console.log('Quest Available from NPC!'); - // Open Dialog UI const ui = this.scene.scene.get('UIScene'); if (ui && ui.showQuestDialog) { ui.showQuestDialog(availableQuest, () => { @@ -746,7 +703,6 @@ class NPC { // Default behavior (Emote) this.showEmote('👋'); - // Small jump or animation? if (this.sprite) { this.scene.tweens.add({ targets: this.sprite, y: this.sprite.y - 10, yoyo: true, duration: 100 }); } diff --git a/src/systems/ZombieWorkerSystem.js b/src/systems/ZombieWorkerSystem.js index 329cf74..0003c52 100644 --- a/src/systems/ZombieWorkerSystem.js +++ b/src/systems/ZombieWorkerSystem.js @@ -1,39 +1,50 @@ class ZombieWorkerSystem { constructor(scene) { this.scene = scene; - this.workers = []; // Array of tames zombies - this.graves = []; // Array of grave locations + this.workers = []; // Array of tamed zombies (NPC objects) + console.log('🧟 ZombieWorkerSystem: Initialized'); } - // Dodaj zombija med delavce - addWorker(zombieEntity) { - this.workers.push({ - entity: zombieEntity, - task: 'IDLE', // FARM, MINE, GUARD, REST - energy: 100, // Decay meter - xp: 0 - }); - console.log('🧟 New Worker Assigned!'); + registerWorker(npc) { + if (!this.workers.includes(npc)) { + this.workers.push(npc); + npc.workerStats = { + energy: 100, // Energija (pada ob delu) + decay: 0, // Razpadanje (0-100%, 100% = smrt) + xp: 0, // Izkušnje zombija + level: 1, + task: 'IDLE' // IDLE, FARM, MINE, GUARD, FOLLOW + }; + console.log(`🧟 Zombie ${this.workers.length} registered as Worker!`); + + // UI Feedback + this.scene.events.emit('show-floating-text', { + x: npc.sprite.x, + y: npc.sprite.y - 50, + text: "New Worker!", + color: "#00FF00" + }); + } } - // Dodelitev naloge - assignTask(workerIndex, taskType, location) { - if (this.workers[workerIndex]) { - this.workers[workerIndex].task = taskType; - this.workers[workerIndex].targetLocation = location; + unregisterWorker(npc) { + const idx = this.workers.indexOf(npc); + if (idx > -1) { + this.workers.splice(idx, 1); + console.log('🧟 Zombie Worker removed.'); } } update(time, delta) { - // Logic for worker AI, decay, and farming automation - this.workers.forEach(worker => { - if (worker.energy > 0) { - worker.energy -= 0.01; // Decay over time - // TODO: Execute Task Logic - } else { - // TODO: Rot / Die logic - } - }); + // Update logic for all workers (e.g. decay, energy regen if sleeping) + // This is called every frame, so keep it light. + + // Example: Decay tick every 10 seconds (handled by timer, or simplified here) + } + + // Assign a task to all idle workers or specific one + assignTask(taskName, targetPos) { + // TODO: Poišči prostega delavca in mu daj nalogo } }