512 lines
15 KiB
JavaScript
512 lines
15 KiB
JavaScript
/**
|
|
* CHURCH & SPIRITUAL SYSTEM
|
|
* Mrtva Dolina - Cerkev, Pokopališče, Župnik
|
|
*
|
|
* Features:
|
|
* - Župnik NPC with blessing system
|
|
* - Church building (ruined → restored)
|
|
* - Graveyard with ghost spawns
|
|
* - Fog atmosphere effects
|
|
* - Zombie Scout graveyard shortcuts
|
|
* - Tool blessing for dark forces bonus
|
|
*/
|
|
|
|
export class ChurchSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
// Župnik NPC
|
|
this.priest = {
|
|
name: 'Župnik',
|
|
x: 0,
|
|
y: 0,
|
|
sprite: null,
|
|
dialogues: [],
|
|
blessingCost: 50, // Gold per blessing
|
|
blessingDuration: 300000 // 5 minutes
|
|
};
|
|
|
|
// Church building states
|
|
this.churchStates = {
|
|
ruined: {
|
|
sprite: 'church_ruined',
|
|
accessible: false,
|
|
description: 'Uničena cerkev, polna ruševin'
|
|
},
|
|
restored: {
|
|
sprite: 'church_restored',
|
|
accessible: true,
|
|
description: 'Obnovljena cerkev, varno zavetje'
|
|
}
|
|
};
|
|
|
|
this.currentChurchState = 'ruined';
|
|
|
|
// Graveyard
|
|
this.graveyard = {
|
|
x: 0,
|
|
y: 0,
|
|
width: 500,
|
|
height: 500,
|
|
gravestones: [],
|
|
ghostSpawnPoints: [],
|
|
fogActive: false,
|
|
fogParticles: null
|
|
};
|
|
|
|
// Blessed tools tracking
|
|
this.blessedTools = new Map(); // toolId -> expiryTime
|
|
|
|
// Zombie Scout graveyard shortcuts
|
|
this.graveyardShortcuts = [];
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Setup priest dialogues
|
|
this.setupPriestDialogues();
|
|
|
|
// Listen for graveyard entry
|
|
this.scene.events.on('player:enter_graveyard', this.onEnterGraveyard, this);
|
|
this.scene.events.on('player:exit_graveyard', this.onExitGraveyard, this);
|
|
|
|
console.log('✅ ChurchSystem initialized');
|
|
}
|
|
|
|
/**
|
|
* ŽUPNIK DIALOGUES & BLESSING
|
|
*/
|
|
setupPriestDialogues() {
|
|
this.priest.dialogues = [
|
|
{
|
|
id: 'intro',
|
|
text: 'Pozdravljen, potnik. Sem Župnik, varovatelj te cerkve od leta 2084...',
|
|
responses: [
|
|
{ text: 'Povej mi o letu 2084', action: 'lore_2084' },
|
|
{ text: 'Lahko blagosloviš moje orodje?', action: 'request_blessing' },
|
|
{ text: 'Nasvidenje', action: 'exit' }
|
|
]
|
|
},
|
|
{
|
|
id: 'lore_2084',
|
|
text: 'Leta 2084 je svet padel... Apokalipsa je prišla iz teme. Samo z blagoslovljenim orožjem lahko preživiš proti mračnim silam.',
|
|
responses: [
|
|
{ text: 'Razumem. Blagoslovi mojo katano!', action: 'request_blessing' },
|
|
{ text: 'Hvala za zgodbo', action: 'exit' }
|
|
]
|
|
},
|
|
{
|
|
id: 'request_blessing',
|
|
text: `Blagoslov zahteva darovnino ${this.priest.blessingCost} zlata. Kateri predmet želiš blagosloviti?`,
|
|
responses: [
|
|
{ text: 'Katano', action: 'bless_katana' },
|
|
{ text: 'Sekiro', action: 'bless_axe' },
|
|
{ text: 'Kasneje', action: 'exit' }
|
|
]
|
|
}
|
|
];
|
|
}
|
|
|
|
interactWithPriest() {
|
|
// Show dialogue UI
|
|
this.showPriestDialogue('intro');
|
|
}
|
|
|
|
showPriestDialogue(dialogueId) {
|
|
const dialogue = this.priest.dialogues.find(d => d.id === dialogueId);
|
|
if (!dialogue) return;
|
|
|
|
this.scene.events.emit('show-dialogue', {
|
|
npc: 'Župnik',
|
|
portrait: 'priest_portrait',
|
|
text: dialogue.text,
|
|
responses: dialogue.responses.map(r => ({
|
|
text: r.text,
|
|
callback: () => this.handleDialogueResponse(r.action)
|
|
}))
|
|
});
|
|
}
|
|
|
|
handleDialogueResponse(action) {
|
|
switch (action) {
|
|
case 'lore_2084':
|
|
this.showPriestDialogue('lore_2084');
|
|
break;
|
|
case 'request_blessing':
|
|
this.showPriestDialogue('request_blessing');
|
|
break;
|
|
case 'bless_katana':
|
|
this.blessTool('katana');
|
|
break;
|
|
case 'bless_axe':
|
|
this.blessTool('axe');
|
|
break;
|
|
case 'exit':
|
|
this.scene.events.emit('close-dialogue');
|
|
break;
|
|
}
|
|
}
|
|
|
|
blessTool(toolType) {
|
|
// Check if player has gold
|
|
if (!this.scene.inventorySystem.hasGold(this.priest.blessingCost)) {
|
|
this.scene.events.emit('show-notification', {
|
|
title: '❌ Premalo zlata',
|
|
message: `Rabiš ${this.priest.blessingCost} zlata za blagoslov!`,
|
|
icon: '💰',
|
|
duration: 3000,
|
|
color: '#FF4444'
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Deduct gold
|
|
this.scene.inventorySystem.removeGold(this.priest.blessingCost);
|
|
|
|
// Add blessing
|
|
const expiryTime = Date.now() + this.priest.blessingDuration;
|
|
this.blessedTools.set(toolType, expiryTime);
|
|
|
|
// Blessing VFX
|
|
this.showBlessingEffect();
|
|
|
|
// Update tool stats
|
|
this.applyBlessingBonus(toolType);
|
|
|
|
this.scene.events.emit('show-notification', {
|
|
title: '✨ Blagoslovljeno!',
|
|
message: `${toolType.toUpperCase()} je blagoslovljen za 5 minut! +50% damage proti mračnim silam!`,
|
|
icon: '🙏',
|
|
duration: 5000,
|
|
color: '#FFD700'
|
|
});
|
|
|
|
console.log(`✨ Blessed ${toolType} for ${this.priest.blessingDuration}ms`);
|
|
}
|
|
|
|
showBlessingEffect() {
|
|
// Golden particles around player
|
|
const particles = this.scene.add.particles(0, 0, 'vfx_sparkle_star', {
|
|
speed: { min: 50, max: 100 },
|
|
scale: { start: 1, end: 0 },
|
|
alpha: { start: 1, end: 0 },
|
|
lifespan: 1000,
|
|
quantity: 20,
|
|
tint: 0xFFD700
|
|
});
|
|
|
|
particles.setPosition(this.scene.player.x, this.scene.player.y);
|
|
particles.explode();
|
|
|
|
setTimeout(() => particles.destroy(), 2000);
|
|
}
|
|
|
|
applyBlessingBonus(toolType) {
|
|
// Apply bonus to tool
|
|
if (this.scene.combatSystem) {
|
|
this.scene.combatSystem.setToolBonus(toolType, 'dark_forces', 1.5); // +50% vs dark enemies
|
|
}
|
|
}
|
|
|
|
isBlessedTool(toolType) {
|
|
const expiryTime = this.blessedTools.get(toolType);
|
|
if (!expiryTime) return false;
|
|
|
|
if (Date.now() > expiryTime) {
|
|
// Blessing expired
|
|
this.blessedTools.delete(toolType);
|
|
this.removeBlessingBonus(toolType);
|
|
|
|
this.scene.events.emit('show-notification', {
|
|
title: '⏰ Blagoslov Potekel',
|
|
message: `${toolType.toUpperCase()} blessing has expired.`,
|
|
icon: '💫',
|
|
duration: 3000,
|
|
color: '#999999'
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
removeBlessingBonus(toolType) {
|
|
if (this.scene.combatSystem) {
|
|
this.scene.combatSystem.removeToolBonus(toolType, 'dark_forces');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* CHURCH RESTORATION
|
|
*/
|
|
restoreChurch() {
|
|
if (this.currentChurchState === 'restored') {
|
|
console.log('Church already restored');
|
|
return;
|
|
}
|
|
|
|
this.currentChurchState = 'restored';
|
|
|
|
// Update building sprite
|
|
if (this.churchSprite) {
|
|
this.churchSprite.setTexture('church_restored');
|
|
}
|
|
|
|
// Enable priest NPC
|
|
this.spawnPriest();
|
|
|
|
this.scene.events.emit('show-notification', {
|
|
title: '⛪ Cerkev Obnovljena',
|
|
message: 'Župnik je zdaj na voljo za blagoslove!',
|
|
icon: '✨',
|
|
duration: 5000,
|
|
color: '#FFD700'
|
|
});
|
|
|
|
console.log('⛪ Church restored');
|
|
}
|
|
|
|
spawnPriest() {
|
|
// Spawn priest NPC at church entrance
|
|
this.priest.sprite = this.scene.add.sprite(
|
|
this.priest.x,
|
|
this.priest.y,
|
|
'priest_portrait'
|
|
);
|
|
this.priest.sprite.setDepth(10);
|
|
this.priest.sprite.setInteractive();
|
|
|
|
this.priest.sprite.on('pointerdown', () => {
|
|
this.interactWithPriest();
|
|
});
|
|
|
|
console.log('✅ Priest spawned');
|
|
}
|
|
|
|
/**
|
|
* GRAVEYARD SYSTEM
|
|
*/
|
|
setupGraveyard(x, y, width, height) {
|
|
this.graveyard.x = x;
|
|
this.graveyard.y = y;
|
|
this.graveyard.width = width;
|
|
this.graveyard.height = height;
|
|
|
|
// Generate gravestones
|
|
this.generateGravestones();
|
|
|
|
// Setup ghost spawn points
|
|
this.setupGhostSpawns();
|
|
|
|
// Setup Zombie Scout shortcuts
|
|
this.setupGraveyardShortcuts();
|
|
|
|
console.log(`⚰️ Graveyard setup at (${x}, ${y})`);
|
|
}
|
|
|
|
generateGravestones() {
|
|
const count = 20; // 20 gravestones
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
const gravestone = {
|
|
x: this.graveyard.x + Phaser.Math.Between(0, this.graveyard.width),
|
|
y: this.graveyard.y + Phaser.Math.Between(0, this.graveyard.height),
|
|
type: Phaser.Math.Between(1, 3), // 3 types
|
|
sprite: null
|
|
};
|
|
|
|
// Create sprite
|
|
gravestone.sprite = this.scene.add.sprite(
|
|
gravestone.x,
|
|
gravestone.y,
|
|
`gravestone_${gravestone.type}`
|
|
);
|
|
gravestone.sprite.setDepth(5);
|
|
|
|
this.graveyard.gravestones.push(gravestone);
|
|
}
|
|
|
|
console.log(`⚰️ Generated ${count} gravestones`);
|
|
}
|
|
|
|
setupGhostSpawns() {
|
|
// 5 ghost spawn points
|
|
for (let i = 0; i < 5; i++) {
|
|
this.graveyard.ghostSpawnPoints.push({
|
|
x: this.graveyard.x + Phaser.Math.Between(0, this.graveyard.width),
|
|
y: this.graveyard.y + Phaser.Math.Between(0, this.graveyard.height)
|
|
});
|
|
}
|
|
|
|
// Start ghost spawning
|
|
this.startGhostSpawns();
|
|
}
|
|
|
|
startGhostSpawns() {
|
|
// Spawn ghost every 30 seconds
|
|
setInterval(() => {
|
|
if (this.isPlayerInGraveyard()) {
|
|
this.spawnGhost();
|
|
}
|
|
}, 30000);
|
|
}
|
|
|
|
spawnGhost() {
|
|
const spawnPoint = Phaser.Utils.Array.GetRandom(this.graveyard.ghostSpawnPoints);
|
|
|
|
this.scene.events.emit('enemy:spawn', {
|
|
type: 'ghost',
|
|
x: spawnPoint.x,
|
|
y: spawnPoint.y,
|
|
level: Phaser.Math.Between(1, 5)
|
|
});
|
|
|
|
console.log(`👻 Ghost spawned at (${spawnPoint.x}, ${spawnPoint.y})`);
|
|
}
|
|
|
|
setupGraveyardShortcuts() {
|
|
// 3 secret shortcuts for Zombie Scout
|
|
for (let i = 0; i < 3; i++) {
|
|
this.graveyardShortcuts.push({
|
|
x: this.graveyard.x + Phaser.Math.Between(0, this.graveyard.width),
|
|
y: this.graveyard.y + Phaser.Math.Between(0, this.graveyard.height),
|
|
leadsTo: 'rare_tomb',
|
|
discovered: false
|
|
});
|
|
}
|
|
|
|
console.log('🔍 Graveyard shortcuts setup for Zombie Scout');
|
|
}
|
|
|
|
/**
|
|
* FOG ATMOSPHERE
|
|
*/
|
|
onEnterGraveyard() {
|
|
if (this.graveyard.fogActive) return;
|
|
|
|
// Activate fog
|
|
this.graveyard.fogActive = true;
|
|
this.createFogEffect();
|
|
|
|
this.scene.events.emit('show-notification', {
|
|
title: '🌫️ Pokopališče',
|
|
message: 'Mračna megla te objame...',
|
|
icon: '⚰️',
|
|
duration: 3000,
|
|
color: '#666666'
|
|
});
|
|
|
|
console.log('🌫️ Graveyard fog activated');
|
|
}
|
|
|
|
createFogEffect() {
|
|
// Add fog particle layer
|
|
this.graveyard.fogParticles = this.scene.add.particles(0, 0, 'fog_particle', {
|
|
x: { min: this.graveyard.x, max: this.graveyard.x + this.graveyard.width },
|
|
y: { min: this.graveyard.y, max: this.graveyard.y + this.graveyard.height },
|
|
speed: 10,
|
|
scale: { start: 1, end: 1.5 },
|
|
alpha: { start: 0.3, end: 0 },
|
|
lifespan: 5000,
|
|
frequency: 100,
|
|
tint: 0x666666
|
|
});
|
|
|
|
this.graveyard.fogParticles.setDepth(20);
|
|
|
|
// Darken screen slightly
|
|
if (this.scene.cameras.main) {
|
|
this.scene.cameras.main.setAlpha(0.8);
|
|
}
|
|
}
|
|
|
|
onExitGraveyard() {
|
|
if (!this.graveyard.fogActive) return;
|
|
|
|
// Deactivate fog
|
|
this.graveyard.fogActive = false;
|
|
|
|
if (this.graveyard.fogParticles) {
|
|
this.graveyard.fogParticles.destroy();
|
|
this.graveyard.fogParticles = null;
|
|
}
|
|
|
|
// Restore camera alpha
|
|
if (this.scene.cameras.main) {
|
|
this.scene.cameras.main.setAlpha(1);
|
|
}
|
|
|
|
console.log('🌫️ Graveyard fog deactivated');
|
|
}
|
|
|
|
isPlayerInGraveyard() {
|
|
if (!this.scene.player) return false;
|
|
|
|
const px = this.scene.player.x;
|
|
const py = this.scene.player.y;
|
|
|
|
return (
|
|
px >= this.graveyard.x &&
|
|
px <= this.graveyard.x + this.graveyard.width &&
|
|
py >= this.graveyard.y &&
|
|
py <= this.graveyard.y + this.graveyard.height
|
|
);
|
|
}
|
|
|
|
/**
|
|
* ZOMBIE SCOUT GRAVEYARD SYNERGY
|
|
*/
|
|
discoverShortcut(zombieScout) {
|
|
const undiscovered = this.graveyardShortcuts.filter(s => !s.discovered);
|
|
if (undiscovered.length === 0) {
|
|
console.log('All shortcuts already discovered');
|
|
return null;
|
|
}
|
|
|
|
const shortcut = undiscovered[0];
|
|
shortcut.discovered = true;
|
|
|
|
this.scene.events.emit('show-notification', {
|
|
title: '🔍 Zombie Scout našel bližnjico!',
|
|
message: 'Odkrita skrivna pot do redkih grobnic!',
|
|
icon: '⚰️',
|
|
duration: 5000,
|
|
color: '#00FF00'
|
|
});
|
|
|
|
console.log(`🔍 Shortcut discovered at (${shortcut.x}, ${shortcut.y})`);
|
|
|
|
return shortcut;
|
|
}
|
|
|
|
update(delta) {
|
|
// Check if player entered/exited graveyard
|
|
const inGraveyard = this.isPlayerInGraveyard();
|
|
|
|
if (inGraveyard && !this.graveyard.fogActive) {
|
|
this.onEnterGraveyard();
|
|
} else if (!inGraveyard && this.graveyard.fogActive) {
|
|
this.onExitGraveyard();
|
|
}
|
|
|
|
// Update blessed tools expiry
|
|
this.blessedTools.forEach((expiryTime, toolType) => {
|
|
this.isBlessedTool(toolType); // Auto-removes expired
|
|
});
|
|
}
|
|
|
|
destroy() {
|
|
if (this.graveyard.fogParticles) {
|
|
this.graveyard.fogParticles.destroy();
|
|
}
|
|
|
|
this.graveyard.gravestones.forEach(g => {
|
|
if (g.sprite) g.sprite.destroy();
|
|
});
|
|
|
|
this.blessedTools.clear();
|
|
}
|
|
}
|