Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/CentralPopupSystem.js
2026-01-16 02:43:46 +01:00

360 lines
11 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* CENTRAL POPUP SYSTEM
* Displays important messages, quests, and dialogs in center of screen
* Always appears in front of player for easy reading
*/
class CentralPopupSystem {
constructor(scene) {
this.scene = scene;
this.enabled = true;
// Current popup
this.currentPopup = null;
this.popupQueue = [];
this.isShowing = false;
// Settings
this.settings = {
enabled: true,
autoClose: true,
autoCloseDelay: 5000, // 5 seconds
pauseGameOnPopup: true,
soundOnPopup: true
};
this.loadSettings();
console.log('✅ Central Popup System initialized');
}
/**
* Show popup in center of screen
*/
showPopup(config) {
const popup = {
title: config.title || 'Notification',
message: config.message || '',
type: config.type || 'info', // info, quest, warning, success, story
icon: config.icon || '📋',
buttons: config.buttons || [{ text: 'OK', action: 'close' }],
image: config.image || null,
autoClose: config.autoClose !== undefined ? config.autoClose : this.settings.autoClose,
onClose: config.onClose || null,
priority: config.priority || 'normal' // low, normal, high, critical
};
// Add to queue
this.popupQueue.push(popup);
// Show if not already showing
if (!this.isShowing) {
this.displayNextPopup();
}
}
/**
* Display next popup from queue
*/
displayNextPopup() {
if (this.popupQueue.length === 0) {
this.isShowing = false;
return;
}
this.isShowing = true;
const popup = this.popupQueue.shift();
// Get UIScene
const uiScene = this.scene.scene.get('UIScene');
if (!uiScene) return;
// Pause game if needed
if (this.settings.pauseGameOnPopup) {
this.scene.physics.pause();
}
// Create popup container
const centerX = uiScene.scale.width / 2;
const centerY = uiScene.scale.height / 2;
this.currentPopup = uiScene.add.container(centerX, centerY);
this.currentPopup.setDepth(10000); // Always on top
this.currentPopup.setScrollFactor(0);
// Popup size based on type
const width = popup.type === 'story' ? 600 : 500;
const height = popup.type === 'story' ? 400 : 300;
// Background overlay (darken screen)
const overlay = uiScene.add.rectangle(0, 0, uiScene.scale.width * 2, uiScene.scale.height * 2, 0x000000, 0.7);
overlay.setOrigin(0.5);
this.currentPopup.add(overlay);
// Main popup background
const bg = uiScene.add.graphics();
// Color based on type
let bgColor = 0x2a2a3e;
let borderColor = 0x4e4e6e;
if (popup.type === 'quest') {
bgColor = 0x3a2a1e;
borderColor = 0xFFD700;
} else if (popup.type === 'warning') {
bgColor = 0x3e2a2a;
borderColor = 0xff4444;
} else if (popup.type === 'success') {
bgColor = 0x2a3e2a;
borderColor = 0x44ff44;
} else if (popup.type === 'story') {
bgColor = 0x1a1a2e;
borderColor = 0x8888ff;
}
// Draw background with rounded corners
bg.fillStyle(bgColor, 0.95);
bg.fillRoundedRect(-width / 2, -height / 2, width, height, 16);
bg.lineStyle(4, borderColor, 1);
bg.strokeRoundedRect(-width / 2, -height / 2, width, height, 16);
this.currentPopup.add(bg);
// Icon
const iconText = uiScene.add.text(-width / 2 + 30, -height / 2 + 30, popup.icon, {
fontSize: '48px'
});
this.currentPopup.add(iconText);
// Title
const title = uiScene.add.text(0, -height / 2 + 50, popup.title, {
fontSize: '28px',
fontFamily: 'Arial',
fill: '#ffffff',
fontStyle: 'bold',
align: 'center'
}).setOrigin(0.5);
this.currentPopup.add(title);
// Separator line
const separator = uiScene.add.graphics();
separator.lineStyle(2, borderColor, 0.5);
separator.lineBetween(-width / 2 + 20, -height / 2 + 90, width / 2 - 20, -height / 2 + 90);
this.currentPopup.add(separator);
// Message
const message = uiScene.add.text(0, -height / 2 + 150, popup.message, {
fontSize: '18px',
fontFamily: 'Arial',
fill: '#dddddd',
align: 'center',
wordWrap: { width: width - 80 }
}).setOrigin(0.5, 0);
this.currentPopup.add(message);
// Image (if provided)
if (popup.image) {
const img = uiScene.add.image(0, -height / 2 + 120, popup.image);
img.setScale(0.5);
this.currentPopup.add(img);
}
// Buttons
const buttonY = height / 2 - 50;
const buttonSpacing = 150;
const buttonStartX = -(popup.buttons.length - 1) * buttonSpacing / 2;
popup.buttons.forEach((btn, index) => {
const btnX = buttonStartX + index * buttonSpacing;
// Button background
const btnBg = uiScene.add.graphics();
btnBg.fillStyle(0x4a4a6e, 1);
btnBg.fillRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.lineStyle(2, borderColor, 1);
btnBg.strokeRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.setInteractive(
new Phaser.Geom.Rectangle(btnX - 60, buttonY - 20, 120, 40),
Phaser.Geom.Rectangle.Contains
);
// Hover effect
btnBg.on('pointerover', () => {
btnBg.clear();
btnBg.fillStyle(0x6a6a8e, 1);
btnBg.fillRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.lineStyle(2, borderColor, 1);
btnBg.strokeRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
});
btnBg.on('pointerout', () => {
btnBg.clear();
btnBg.fillStyle(0x4a4a6e, 1);
btnBg.fillRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.lineStyle(2, borderColor, 1);
btnBg.strokeRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
});
// Click handler
btnBg.on('pointerdown', () => {
if (btn.action === 'close') {
this.closePopup(popup);
} else if (btn.callback) {
btn.callback();
this.closePopup(popup);
}
});
this.currentPopup.add(btnBg);
// Button text
const btnText = uiScene.add.text(btnX, buttonY, btn.text, {
fontSize: '18px',
fontFamily: 'Arial',
fill: '#ffffff',
fontStyle: 'bold'
}).setOrigin(0.5);
this.currentPopup.add(btnText);
});
// Auto-close timer
if (popup.autoClose && this.settings.autoClose) {
uiScene.time.delayedCall(this.settings.autoCloseDelay, () => {
this.closePopup(popup);
});
}
// Play sound
if (this.settings.soundOnPopup && this.scene.soundManager) {
this.scene.soundManager.beepPickup();
}
// Animate in
this.currentPopup.setScale(0.8);
this.currentPopup.setAlpha(0);
uiScene.tweens.add({
targets: this.currentPopup,
scale: 1,
alpha: 1,
duration: 300,
ease: 'Back.easeOut'
});
console.log(`📋 Popup shown: ${popup.title}`);
}
/**
* Close current popup
*/
closePopup(popup) {
if (!this.currentPopup) return;
const uiScene = this.scene.scene.get('UIScene');
if (!uiScene) return;
// Animate out
uiScene.tweens.add({
targets: this.currentPopup,
scale: 0.8,
alpha: 0,
duration: 200,
ease: 'Power2',
onComplete: () => {
this.currentPopup.destroy();
this.currentPopup = null;
// Resume game
if (this.settings.pauseGameOnPopup) {
this.scene.physics.resume();
}
// Call onClose callback
if (popup.onClose) {
popup.onClose();
}
// Show next popup
this.displayNextPopup();
}
});
}
/**
* Show quest popup
*/
showQuest(title, description, objectives) {
this.showPopup({
title: title,
message: description + '\n\nObjectives:\n' + objectives.map((obj, i) => `${i + 1}. ${obj}`).join('\n'),
type: 'quest',
icon: '📜',
buttons: [
{ text: 'Accept', action: 'close' },
{ text: 'Decline', action: 'close' }
],
autoClose: false
});
}
/**
* Show story popup
*/
showStory(title, text, image = null) {
this.showPopup({
title: title,
message: text,
type: 'story',
icon: '📖',
image: image,
buttons: [{ text: 'Continue', action: 'close' }],
autoClose: false
});
}
/**
* Show notification
*/
showNotification(message, type = 'info') {
const icons = {
'info': '',
'success': '✅',
'warning': '⚠️',
'error': '❌'
};
this.showPopup({
title: type.charAt(0).toUpperCase() + type.slice(1),
message: message,
type: type,
icon: icons[type] || '',
buttons: [{ text: 'OK', action: 'close' }],
autoClose: true
});
}
/**
* Save settings
*/
saveSettings() {
localStorage.setItem('novafarma_popup_settings', JSON.stringify(this.settings));
}
/**
* Load settings
*/
loadSettings() {
const saved = localStorage.getItem('novafarma_popup_settings');
if (saved) {
this.settings = { ...this.settings, ...JSON.parse(saved) };
}
}
/**
* Destroy system
*/
destroy() {
if (this.currentPopup) {
this.currentPopup.destroy();
}
this.popupQueue = [];
console.log('📋 Central Popup System destroyed');
}
}