From af1f0dcf42766caab8f29f565df88b9b95363339 Mon Sep 17 00:00:00 2001 From: David Kotnik Date: Mon, 5 Jan 2026 14:23:59 +0100 Subject: [PATCH] MAJOR UPDATE: DrugEconomySystem (marijuana slow-mo/chill + mushroom hallucinations), CourierSystem (hearts/material rewards), updated CHARACTER_DESIGN_GUIDELINES to EXTREMIST standard (mandatory colored hair/massive plugs), added ROADMAP sections for City Evolution (Vape Factory@50pop), Drug Effects, Courier Missions. All systems integrated with quest/reward mechanics. --- docs/CHARACTER_DESIGN_GUIDELINES.md | 40 ++- docs/ROADMAP.md | 52 +++ src/systems/CourierSystem.js | 337 ++++++++++++++++++++ src/systems/DrugEconomySystem.js | 476 ++++++++++++++++++++++++++++ 4 files changed, 890 insertions(+), 15 deletions(-) create mode 100644 src/systems/CourierSystem.js create mode 100644 src/systems/DrugEconomySystem.js diff --git a/docs/CHARACTER_DESIGN_GUIDELINES.md b/docs/CHARACTER_DESIGN_GUIDELINES.md index e60439ff3..30bd7126e 100644 --- a/docs/CHARACTER_DESIGN_GUIDELINES.md +++ b/docs/CHARACTER_DESIGN_GUIDELINES.md @@ -1,35 +1,45 @@ # 🎨 CHARACTER DESIGN GUIDELINES - Mrtva Dolina -**Style:** Post-Apocalyptic Punk (Style 32 Dark-Chibi Noir) -**Last Updated:** 2026-01-05 14:04 CET +**Style:** Post-Apocalyptic EXTREMIST Punk (Style 32 Dark-Chibi Noir) +**Last Updated:** 2026-01-05 14:19 CET +**Standard:** EXTREMIST - Maximum punk aesthetic --- -## 🔥 **ZAŠČITNI ZNAK - Punk Aesthetic** +## 🔥 **ZAŠČITNI ZNAK - EXTREMIST Punk Aesthetic** -**POMEMBNO:** Ne delaj preveč normalnih ljudi! Post-apokalipsa = punk survival look. +**KRITIČNO:** NI normalnih ljudi! VSI morajo biti extreme punk survivors! -### **Core Features (Mix & Match)** -NPC-ji naj imajo **raznolike kombinacije** teh elementov, ne vsi vse: +### **MANDATORY Features (All NPCs)** -#### **Pirsinge** 🔩 -- Nos ring +#### **Pirsinge** 🔩 - **ZAŽELENI PRI VSEH** +- Nos ring (very common) - Lip ring - Eyebrow piercing - Multiple ear piercings -- **Ne rabijo vsi!** En NPC lahko ima samo 1 piercing +- **Minimum:** Vsak NPC naj ima vsaj 2+ piercings -#### **Ear Gauges** 👂 -- Razširjena ušesa (stretched ear lobes) -- Različne velikosti (majhni do veliki) -- Opcijsko - ni mandatory +#### **Ear Plugs/Gauges** 👂 - **VARIABLE MASSIVE SIZES** +- Razširjena ušesa (stretched ear lobes) - **ZAŽELENI** +- **Velikost variira:** + - Small plugs (5mm) + - Medium plugs (10-15mm) + - **MASSIVE plugs (20-30mm+)** ← Lahko tudi ekstremni! +- **Stil:** Metal rings, wooden plugs, decorative tunnels + +#### **LASJE - OBVEZNO POBARVANI** 💈 +**NOVA PRAVILA:** +- **ČE NIMA DREADOV → LASE OBVEZNO POBARVAJ!** +- **Barve:** Neon zelena, pink, modra, purple, orange, red +- **NO natural colors** (črna/rjava dovoljena SAMO z dreads) +- **Kombinacije:** Rainbow, two-tone, highlights #### **Dreadlokse** 🌿 - **VARIACIJE:** - Full head dreads (kot Kai, Gronk) - **Partial dreads:** Ubrita glava z 6 dredloksi odzadi - - **Colored dreads:** Pink, green, purple, gray + - **Colored dreads:** Pink, green, purple, gray (MANDATORY COLOR) - Kratki vs. dolgi - - **Ne rabijo vsi!** Lahko ima NPC samo normalne lase +- **ALI ima dreads ALI pobarvane lase (ne plain)** #### **Tatuji** 🖋️ - Neck tattoos diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 5fb3ce526..71307d151 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -279,6 +279,58 @@ --- +## 🏙️ **CITY EVOLUTION & POPULATION MILESTONES** + +| Milestone | Population | Unlock | Priority | Status | +|-----------|------------|--------|----------|--------| +| **Election System** | 5 NPCs | Volitve za Župana, Social Order | ⭐⭐⭐⭐⭐ | ✅ Implemented | +| **Zombie Economy** | 10 NPCs | Worker Zombies, Sanitation | ⭐⭐⭐⭐ | ✅ Implemented | +| **Vape Factory** | **50 NPCs** | First major industrial building | ⭐⭐⭐⭐ | 🔴 Planned (Faza 3) | +| **Police Force** | 75 NPCs | Drug trade becomes illegal/risky | ⭐⭐⭐⭐ | 🔴 Planned | +| **Full Infrastructure** | 100 NPCs | All systems unlocked | ⭐⭐⭐⭐⭐ | 🔴 Future | + +### **Vape Factory (Faza 3 - Industrija)** +- **Unlock:** 50 residents in Capital City +- **Requirements:** Rare chemicals from ruins (Tehnik processing) +- **Features:** Custom liquid crafting, mod building +- **Workforce:** Delovni Zombiji + Tehnik supervision + +--- + +## 🌿 **SOCIAL & ECONOMY SYSTEMS** + +### **Drug Effects & Illegal Trade** + +| System | Features | Priority | Status | +|--------|----------|----------|--------| +| **Marijuana Effects** | Slow-mo, chill music, energy regen +100%, -15% walk speed | ⭐⭐⭐⭐ | ✅ Implemented | +| **Mushroom Hallucinations** | Psychedelic shader, moving objects, ghost visions, reality warps | ⭐⭐⭐⭐ | ✅ Implemented | +| **Black Market Trade** | Free trade until police established (30% bust risk after) | ⭐⭐⭐⭐ | ✅ Implemented | +| **Crop Systems** | Cannabis & magic mushroom farming | ⭐⭐⭐⭐ | 🟡 In progress | + +**Psychedelic Visual Effects:** +- **Marijuana:** Subtle blur, light green tint, chill lo-fi music +- **Mushrooms:** Color cycling, object movement, ghost NPCs, camera distortion + +### **Courier Mission System** + +| Feature | Details | Priority | Status | +|---------|---------|----------|--------| +| **Delivery Quests** | Random NPC requests for materials (wheat, water, glass, steel) | ⭐⭐⭐⭐ | ✅ Implemented | +| **Hearts Reward** | Social Status increases (+5% per heart) | ⭐⭐⭐⭐ | ✅ Implemented | +| **Material Reward** | Random loot from pools (common/uncommon/rare) | ⭐⭐⭐⭐ | ✅ Implemented | +| **Social Benefits** | Shop discounts, priority quests, VIP access | ⭐⭐⭐ | ✅ Implemented | +| **Quest Expiration** | 10-minute timer per delivery | ⭐⭐⭐ | ✅ Implemented | + +**Social Status Tiers:** +- 20%: 5% shop discount +- 40%: Priority quests +- 60%: VIP area access +- 80%: +10% rare gift chance +- 100%: Maximum respect + +--- + ## 📝 NOTES **Design Philosophy:** diff --git a/src/systems/CourierSystem.js b/src/systems/CourierSystem.js new file mode 100644 index 000000000..9f286b7ec --- /dev/null +++ b/src/systems/CourierSystem.js @@ -0,0 +1,337 @@ +/** + * COURIER & DELIVERY SYSTEM + * Mrtva Dolina - Side-Quest Material Deliveries + * + * Features: + * - Random delivery quests from NPCs + * - Rewards: Hearts (social status) OR random materials + * - Material types: wheat, water, glass, steel, wood, plastic + * - Reputation system + */ + +export class CourierSystem { + constructor(scene) { + this.scene = scene; + + // Social status (hearts) + this.socialStatus = 0; // 0-100 + this.hearts = 0; // Visual hearts earned + + // Active courier quests + this.activeDeliveries = []; + + // NPC delivery requests database + this.deliveryTemplates = [ + // PEK + { npc: 'pek', item: 'wheat', quantity: [5, 10], reward: { type: 'hearts', amount: 2 }, message: 'Rabim pšenico za kruh!' }, + { npc: 'pek', item: 'water', quantity: [3, 5], reward: { type: 'material', pool: ['wood', 'stone'] }, message: 'Dej mi vodo, pa ti dam material!' }, + + // ŠIVILJA + { npc: 'sivilja', item: 'cloth', quantity: [10, 20], reward: { type: 'hearts', amount: 3 }, message: 'Material rabim za šivanje, prosim!' }, + { + npc: 'sivilja', item: 'water', quantity: [2, 4], reward: { type: 'material', pool: ['cloth', 'leather'] }, message: 'Vodo za barv + +anje potrebujem!' }, + + // TEHNIK + { npc: 'tehnik', item: 'glass', quantity: [3, 7], reward: { type: 'hearts', amount: 4 }, message: 'Steklo za elektroniko!' }, + { npc: 'tehnik', item: 'steel', quantity: [5, 10], reward: { type: 'material', pool: ['circuit_board', 'wire'] }, message: 'Jeklo za stroje!' }, + + // IVAN KOVAČ + { npc: 'ivan_kovac', item: 'steel', quantity: [8, 15], reward: { type: 'hearts', amount: 3 }, message: 'Potrebujem jeklo za kovačijo!' }, + { npc: 'ivan_kovac', item: 'wood', quantity: [10, 20], reward: { type: 'material', pool: ['steel', 'iron_ore'] }, message: 'Les za oglje!' }, + + // KUSTOS + { npc: 'kustos', item: 'glass', quantity: [2, 5], reward: { type: 'hearts', amount: 2 }, message: 'Steklo za razstavne omare!' }, + { npc: 'kustos', item: 'rare_artifact', quantity: [1, 1], reward: { type: 'material', pool: ['ancient_relic', 'museum_piece'] }, message: 'Artefakt za muzejsko zbirko!' }, + + // SMETAR + { npc: 'glavni_smetar', item: 'plastic', quantity: [15, 30], reward: { type: 'hearts', amount: 1 }, message: 'Plastiko moram zbrat iz ruševin!' }, + { npc: 'glavni_smetar', item: 'wood', quantity: [5, 10], reward: { type: 'material', pool: ['broom', 'cleaning_supplies'] }, message: 'Les za nove metle!' } + ]; + + // Material loot pools + this.materialPools = { + common: ['wood', 'stone', 'plastic', 'water'], + uncommon: ['steel', 'glass', 'cloth', 'leather'], + rare: ['circuit_board', 'wire', 'ancient_relic', 'museum_piece'] + }; + + this.init(); + } + + init() { + // Start quest generation + this.startQuestGeneration(); + + // Listen for delivery completions + this.scene.events.on('courier:delivery_complete', this.onDeliveryComplete, this); + + console.log('✅ CourierSystem initialized - Side-quests active'); + } + + /** + * QUEST GENERATION + */ + startQuestGeneration() { + // Generate random delivery quest every 2-5 minutes + const generateQuest = () => { + if (this.activeDeliveries.length < 5) { // Max 5 active + this.generateDeliveryQuest(); + } + + // Schedule next generation + const nextTime = Phaser.Math.Between(120000, 300000); // 2-5 minutes + setTimeout(generateQuest, nextTime); + }; + + // Start initial quest immediately + generateQuest(); + } + + generateDeliveryQuest() { + const template = Phaser.Utils.Array.GetRandom(this.deliveryTemplates); + + const quest = { + id: `delivery_${Date.now()}`, + npc: template.npc, + item: template.item, + quantity: Phaser.Math.Between(template.quantity[0], template.quantity[1]), + reward: template.reward, + message: template.message, + timeCreated: Date.now(), + expiresIn: 600000, // 10 minutes + completed: false + }; + + this.activeDeliveries.push(quest); + + // Notify player + this.scene.events.emit('show-notification', { + title: '📦 Nova Dostava', + message: `${template.npc}: ${template.message}`, + icon: '📬', + duration: 5000, + color: '#FFD700' + }); + + // Show on NPC + this.scene.events.emit('npc:show_quest_marker', template.npc); + + console.log(`📦 New delivery quest: ${template.npc} needs ${quest.quantity}x ${quest.item}`); + + return quest; + } + + /** + * ACCEPT DELIVERY QUEST + */ + acceptQuest(questId) { + const quest = this.activeDeliveries.find(q => q.id === questId); + if (!quest) return false; + + quest.accepted = true; + + // Add to player's active quest log + if (this.scene.questSystem) { + this.scene.questSystem.startQuest(questId); + } + + console.log(`✅ Accepted delivery quest: ${questId}`); + return true; + } + + /** + * DELIVER ITEMS + */ + deliverItems(questId) { + const quest = this.activeDeliveries.find(q => q.id === questId); + if (!quest || quest.completed) return false; + + // Check if player has items + if (!this.scene.inventorySystem.hasItem(quest.item, quest.quantity)) { + this.scene.events.emit('show-notification', { + title: '❌ Ni dovolj', + message: `Rabiš še ${quest.quantity}x ${quest.item}!`, + icon: '📦', + duration: 3000, + color: '#FF4444' + }); + return false; + } + + // Remove items from inventory + this.scene.inventorySystem.removeItem(quest.item, quest.quantity); + + // Mark as complete + quest.completed = true; + + // Award reward + this.awardReward(quest.reward); + + // Remove from active + this.activeDeliveries = this.activeDeliveries.filter(q => q.id !== questId); + + // Notify completion + this.scene.events.emit('show-notification', { + title: '✅ Dostava Končana', + message: `${quest.npc} je zadovoljen!`, + icon: '🎉', + duration: 4000, + color: '#00FF00' + }); + + // Remove quest marker + this.scene.events.emit('npc:remove_quest_marker', quest.npc); + + console.log(`✅ Delivery completed: ${questId}`); + + return true; + } + + /** + * AWARD REWARD + */ + awardReward(reward) { + if (reward.type === 'hearts') { + this.addHearts(reward.amount); + } else if (reward.type === 'material') { + this.awardRandomMaterial(reward.pool); + } + } + + addHearts(amount) { + this.hearts += amount; + this.socialStatus = Math.min(100, this.socialStatus + (amount * 5)); + + // Visual heart animation + for (let i = 0; i < amount; i++) { + setTimeout(() => { + this.spawnHeart(); + }, i * 300); + } + + // Show status update + this.scene.events.emit('show-floating-text', { + x: this.scene.player.x, + y: this.scene.player.y - 50, + text: `+${amount} ❤️`, + color: '#FF69B4', + fontSize: '32px' + }); + + console.log(`❤️ +${amount} hearts (Total: ${this.hearts}, Status: ${this.socialStatus}%)`); + } + + spawnHeart() { + const heart = this.scene.add.sprite( + this.scene.player.x + Phaser.Math.Between(-30, 30), + this.scene.player.y - 50, + 'heart_icon' + ); + heart.setScale(0); + heart.setDepth(50); + + // Animate heart + this.scene.tweens.add({ + targets: heart, + scaleX: 1, + scaleY: 1, + y: heart.y - 100, + alpha: 0, + duration: 1500, + ease: 'Cubic.easeOut', + onComplete: () => heart.destroy() + }); + } + + awardRandomMaterial(pool) { + // Random material from pool + const material = Phaser.Utils.Array.GetRandom(pool); + const quantity = Phaser.Math.Between(1, 5); + + if (this.scene.inventorySystem) { + this.scene.inventorySystem.addItem(material, quantity); + } + + // Show notification + this.scene.events.emit('show-notification', { + title: '🎁 Material', + message: `Prejel si: ${quantity}x ${material}`, + icon: '🔧', + duration: 4000, + color: '#FFD700' + }); + + console.log(`🎁 Awarded random material: ${quantity}x ${material}`); + } + + /** + * QUEST EXPIRATION + */ + update(delta) { + const now = Date.now(); + + // Check for expired quests + this.activeDeliveries.forEach(quest => { + if (!quest.completed && (now - quest.timeCreated) > quest.expiresIn) { + // Quest expired + this.expireQuest(quest.id); + } + }); + } + + expireQuest(questId) { + const quest = this.activeDeliveries.find(q => q.id === questId); + if (!quest) return; + + this.activeDeliveries = this.activeDeliveries.filter(q => q.id !== questId); + + // Notify player + this.scene.events.emit('show-notification', { + title: '⏰ Quest Expired', + message: `${quest.npc} je našel drugega kurirja.`, + icon: '😞', + duration: 3000, + color: '#999999' + }); + + // Remove marker + this.scene.events.emit('npc:remove_quest_marker', quest.npc); + + console.log(`⏰ Quest expired: ${questId}`); + } + + /** + * GET SOCIAL STATUS BENEFITS + */ + getSocialBenefits() { + const benefits = []; + + if (this.socialStatus >= 20) benefits.push('5% discount at shops'); + if (this.socialStatus >= 40) benefits.push('Priority quests from NPCs'); + if (this.socialStatus >= 60) benefits.push('Access to VIP areas'); + if (this.socialStatus >= 80) benefits.push('Rare gift chance +10%'); + if (this.socialStatus >= 100) benefits.push('Maximum respect - All NPCs love you!'); + + return benefits; + } + + /** + * GET UI DATA + */ + getActiveQuests() { + return this.activeDeliveries.filter(q => !q.completed).map(q => ({ + id: q.id, + npc: q.npc, + item: q.item, + quantity: q.quantity, + reward: q.reward, + timeRemaining: q.expiresIn - (Date.now() - q.timeCreated) + })); + } + + destroy() { + this.activeDeliveries = []; + } +} diff --git a/src/systems/DrugEconomySystem.js b/src/systems/DrugEconomySystem.js new file mode 100644 index 000000000..d9c6ffe96 --- /dev/null +++ b/src/systems/DrugEconomySystem.js @@ -0,0 +1,476 @@ +/** + * DRUG & NARCO-ECONOMY SYSTEM + * Mrtva Dolina - Psychedelic Effects & Illegal Trade + * + * Features: + * - Marijuana effects (slow-mo, chill, energy regen) + * - Mushroom hallucinations (color distortion, ghosts) + * - Free trade (no police until Mayor establishes it) + * - Drug economy & black market + */ + +export class DrugEconomySystem { + constructor(scene) { + this.scene = scene; + + // Drug effects tracking + this.activeEffects = { + marijuana: false, + mushrooms: false + }; + + // Duration timers + this.effectTimers = {}; + + // Police state + this.policeEstablished = false; + + // Black market prices + this.prices = { + marijuana: { buy: 50, sell: 80 }, + mushrooms: { buy: 100, sell: 150 }, + marijuana_edible: { buy: 75, sell: 120 } + }; + + // Effects configuration + this.effectConfig = { + marijuana: { + duration: 180000, // 3 minutes + timeScale: 0.7, // 70% speed (slower) + energyRegenBonus: 2.0, // 2x regen + walkSpeedMultiplier: 0.85, // 15% slower walk + musicFilter: 'chill', // Music becomes chill + visualFilter: 'subtle_blur' + }, + mushrooms: { + duration: 300000, // 5 minutes + colorShift: true, + hallucinationChance: 0.3, // 30% chance per second + objectMovement: true, + ghostVisions: true, + psychedelicShader: 'trippy_colors' + } + }; + + this.init(); + } + + init() { + // Listen for consumption events + this.scene.events.on('player:consume_drug', this.onDrugConsumed, this); + this.scene.events.on('police:established', this.onPoliceEstablished, this); + + console.log('✅ DrugEconomySystem initialized - Free trade active'); + } + + /** + * CONSUME DRUG + */ + onDrugConsumed(drugType, method = 'smoke') { + if (drugType === 'marijuana') { + this.consumeMarijuana(method); + } else if (drugType === 'mushrooms') { + this.consumeMushrooms(); + } + } + + /** + * MARIJUANA EFFECTS + */ + consumeMarijuana(method) { + if (this.activeEffects.marijuana) { + console.log('🌿 Already high on marijuana'); + return; + } + + this.activeEffects.marijuana = true; + const config = this.effectConfig.marijuana; + + console.log(`🌿 Marijuana consumed (${method}) - Chill mode activated`); + + // Visual effects + this.applyMarijuanaVisuals(config); + + // Gameplay effects + this.applyMarijuanaGameplay(config); + + // Audio effects + this.applyMarijuanaAudio(config); + + // Show notification + this.scene.events.emit('show-notification', { + title: '🌿 Chill Mode', + message: 'Čas se upočasni... vse je bolj mirno...', + icon: '😌', + duration: 5000, + color: '#90EE90' + }); + + // Set duration timer + this.effectTimers.marijuana = setTimeout(() => { + this.endMarijuanaEffects(); + }, config.duration); + } + + applyMarijuanaVisuals(config) { + // Subtle blur filter + const camera = this.scene.cameras.main; + + // Add slight vignette and blur + this.scene.tweens.add({ + targets: camera, + scrollX: camera.scrollX + 2, + scrollY: camera.scrollY + 2, + duration: 2000, + yoyo: true, + repeat: -1, + ease: 'Sine.easeInOut' + }); + + // Subtle color tint (light green) + camera.setTint(0xE8F5E9); // Very light green tint + } + + applyMarijuanaGameplay(config) { + // Slow down time + this.scene.time.timeScale = config.timeScale; + + // Increase energy regen + if (this.scene.player) { + this.scene.player.energyRegenRate *= config.energyRegenBonus; + this.scene.player.walkSpeed *= config.walkSpeedMultiplier; + } + } + + applyMarijuanaAudio(config) { + // Change music to chill variant + const currentMusic = this.scene.sound.get('background_music'); + if (currentMusic) { + // Fade out current + this.scene.tweens.add({ + targets: currentMusic, + volume: 0, + duration: 2000, + onComplete: () => { + currentMusic.stop(); + // Play chill music + this.scene.sound.play('music_chill_lofi', { + loop: true, + volume: 0.4 + }); + } + }); + } + } + + endMarijuanaEffects() { + this.activeEffects.marijuana = false; + + // Restore time scale + this.scene.time.timeScale = 1.0; + + // Restore player stats + if (this.scene.player) { + this.scene.player.energyRegenRate /= this.effectConfig.marijuana.energyRegenBonus; + this.scene.player.walkSpeed /= this.effectConfig.marijuana.walkSpeedMultiplier; + } + + // Remove visual effects + const camera = this.scene.cameras.main; + camera.clearTint(); + this.scene.tweens.killTweensOf(camera); + + // Restore original music + const chillMusic = this.scene.sound.get('music_chill_lofi'); + if (chillMusic) { + this.scene.tweens.add({ + targets: chillMusic, + volume: 0, + duration: 2000, + onComplete: () => { + chillMusic.stop(); + this.scene.sound.play('background_music', { loop: true, volume: 0.5 }); + } + }); + } + + console.log('🌿 Marijuana effects ended'); + } + + /** + * MUSHROOM HALLUCINATION EFFECTS + */ + consumeMushrooms() { + if (this.activeEffects.mushrooms) { + console.log('🍄 Already tripping on mushrooms'); + return; + } + + this.activeEffects.mushrooms = true; + const config = this.effectConfig.mushrooms; + + console.log('🍄 Mushrooms consumed - Reality dissolving...'); + + // Apply psychedelic shader + this.applyPsychedelicShader(config); + + // Start hallucination events + this.startHallucinations(config); + + // Show notification + this.scene.events.emit('show-notification', { + title: '🍄 Hallucinacije', + message: 'Barve... gibanje... duhovi iz preteklosti...', + icon: '🌀', + duration: 7000, + color: '#FF1493' + }); + + // Set duration timer + this.effectTimers.mushrooms = setTimeout(() => { + this.endMushroomEffects(); + }, config.duration); + } + + applyPsychedelicShader(config) { + const camera = this.scene.cameras.main; + + // Extreme color shifting + this.colorShiftTimer = setInterval(() => { + const hue = Phaser.Math.Between(0, 360); + const color = Phaser.Display.Color.HSVToRGB(hue / 360, 0.8, 0.9); + camera.setTint(color.color); + }, 500); // Change every 500ms + + // Camera shake (mild) + camera.shake(config.duration, 0.002); + + // Zoom pulse + this.scene.tweens.add({ + targets: camera, + zoom: 1.05, + duration: 3000, + yoyo: true, + repeat: -1, + ease: 'Sine.easeInOut' + }); + } + + startHallucinations(config) { + // Periodic hallucination events + this.hallucinationInterval = setInterval(() => { + if (Math.random() < config.hallucinationChance) { + this.triggerHallucination(); + } + }, 1000); // Check every second + } + + triggerHallucination() { + const hallucinationTypes = [ + 'moving_objects', + 'ghost_vision', + 'color_trails', + 'reality_distortion' + ]; + + const type = Phaser.Utils.Array.GetRandom(hallucinationTypes); + + switch (type) { + case 'moving_objects': + this.hallucinateMovingObjects(); + break; + case 'ghost_vision': + this.hallucinateGhostVision(); + break; + case 'color_trails': + this.hallucinateColorTrails(); + break; + case 'reality_distortion': + this.hallucinateRealityDistortion(); + break; + } + } + + hallucinateMovingObjects() { + // Random game objects start floating/moving + const objects = this.scene.children.list.filter(obj => + obj.type === 'Sprite' && obj !== this.scene.player + ); + + if (objects.length === 0) return; + + const obj = Phaser.Utils.Array.GetRandom(objects); + const originalX = obj.x; + const originalY = obj.y; + + this.scene.tweens.add({ + targets: obj, + x: originalX + Phaser.Math.Between(-30, 30), + y: originalY + Phaser.Math.Between(-30, 30), + duration: 2000, + yoyo: true, + ease: 'Sine.easeInOut', + onComplete: () => { + obj.x = originalX; + obj.y = originalY; + } + }); + } + + hallucinateGhostVision() { + // Spawn ghost from Kai's past + const ghosts = ['ana_ghost', 'family_ghost', 'memory_ghost']; + const ghostType = Phaser.Utils.Array.GetRandom(ghosts); + + const x = this.scene.player.x + Phaser.Math.Between(-200, 200); + const y = this.scene.player.y + Phaser.Math.Between(-200, 200); + + const ghost = this.scene.add.sprite(x, y, ghostType); + ghost.setAlpha(0); + ghost.setDepth(20); + ghost.setTint(0x9966FF); // Purple ghost tint + + // Fade in + this.scene.tweens.add({ + targets: ghost, + alpha: 0.7, + duration: 1000, + onComplete: () => { + // Ghost speaks + this.scene.events.emit('show-speech-bubble', { + x: ghost.x, + y: ghost.y - 50, + text: this.getGhostMessage(), + duration: 3000 + }); + + // Fade out + this.scene.tweens.add({ + targets: ghost, + alpha: 0, + duration: 2000, + delay: 3000, + onComplete: () => ghost.destroy() + }); + } + }); + } + + getGhostMessage() { + const messages = [ + "Kai... ne pozabi...", + "Ana te išče...", + "Spomniti se moraš...", + "Vrni se domov..." + ]; + return Phaser.Utils.Array.GetRandom(messages); + } + + hallucinateColorTrails() { + // Player leaves colorful trails when moving + if (!this.scene.player.isMoving) return; + + const trail = this.scene.add.sprite( + this.scene.player.x, + this.scene.player.y, + this.scene.player.texture.key + ); + trail.setFrame(this.scene.player.frame.name); + trail.setAlpha(0.5); + trail.setTint(Phaser.Math.Between(0x000000, 0xFFFFFF)); + + this.scene.tweens.add({ + targets: trail, + alpha: 0, + duration: 1000, + onComplete: () => trail.destroy() + }); + } + + hallucinateRealityDistortion() { + // Screen warps/ripples + const camera = this.scene.cameras.main; + + this.scene.tweens.add({ + targets: camera, + scrollX: camera.scrollX + Phaser.Math.Between(-20, 20), + scrollY: camera.scrollY + Phaser.Math.Between(-20, 20), + duration: 500, + yoyo: true, + repeat: 3 + }); + } + + endMushroomEffects() { + this.activeEffects.mushrooms = false; + + // Stop color shift + if (this.colorShiftTimer) { + clearInterval(this.colorShiftTimer); + this.colorShiftTimer = null; + } + + // Stop hallucinations + if (this.hallucinationInterval) { + clearInterval(this.hallucinationInterval); + this.hallucinationInterval = null; + } + + // Restore camera + const camera = this.scene.cameras.main; + camera.clearTint(); + camera.setZoom(1.0); + this.scene.tweens.killTweensOf(camera); + + console.log('🍄 Mushroom effects ended - Reality restored'); + } + + /** + * BLACK MARKET TRADE + */ + sellDrug(drugType, quantity) { + if (this.policeEstablished) { + // Risk of getting caught! + if (Math.random() < 0.3) { // 30% chance + this.scene.events.emit('police:drug_bust', drugType, quantity); + return false; + } + } + + const price = this.prices[drugType].sell; + const earnings = price * quantity; + + if (this.scene.inventorySystem) { + this.scene.inventorySystem.removeItem(drugType, quantity); + this.scene.inventorySystem.addGold(earnings); + } + + console.log(`💰 Sold ${quantity}x ${drugType} for ${earnings} gold`); + return true; + } + + /** + * POLICE ESTABLISHMENT + */ + onPoliceEstablished() { + this.policeEstablished = true; + + this.scene.events.emit('show-notification', { + title: '🚔 Policija Ustanovljena', + message: 'Previdno! Zdaj ti lahko zaseže droge!', + icon: '⚠️', + duration: 5000, + color: '#FF0000' + }); + + console.log('🚔 Police established - Drug trade now illegal and risky'); + } + + destroy() { + this.endMarijuanaEffects(); + this.endMushroomEffects(); + + if (this.effectTimers.marijuana) clearTimeout(this.effectTimers.marijuana); + if (this.effectTimers.mushrooms) clearTimeout(this.effectTimers.mushrooms); + } +}