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

561 lines
15 KiB
JavaScript

/**
* PortalNetworkSystem.js
* ======================
* KRVAVA ŽETEV - Portal Network System (P15)
*
* Features:
* - 9 Portal zones with activation quests
* - Portal mechanics (swirl effects, nausea)
* - Town Portal Hub (fast travel)
* - 3 Secret portals
* - Portal upgrades
*
* @author NovaFarma Team
* @date 2025-12-23
*/
export default class PortalNetworkSystem {
constructor(scene) {
this.scene = scene;
// Portal registry
this.portals = new Map();
this.activePortals = new Set();
// Portal hub
this.hubUnlocked = false;
this.zlatnikiBalance = 0;
// Upgrades
this.hasStabilizer = false;
this.hasBeacon = false;
// Travel state
this.isInTransit = false;
this.nauseaDebuff = null;
console.log('🌀 PortalNetworkSystem initialized');
// Register all portals
this.registerPortals();
}
/**
* 15.1 - Register all portal zones
*/
registerPortals() {
const portals = [
// Main Zone Portals
{
id: 'dino_valley',
name: 'Dino Valley Portal',
zone: 'Dino Valley',
location: { x: 50, y: 400 },
activationQuest: {
name: 'Jurassic Discovery',
objective: 'Find 3 Dino Eggs',
items: ['dino_egg'],
required: 3
},
icon: '🦕'
},
{
id: 'mythical',
name: 'Mythical Realm Portal',
zone: 'Mythical Realm',
location: { x: 400, y: 50 },
activationQuest: {
name: 'Dragon Slayer',
objective: 'Slay 5 Dragons',
enemies: ['dragon'],
required: 5
},
icon: '🐉'
},
{
id: 'endless_forest',
name: 'Endless Forest Portal',
zone: 'Endless Forest',
location: { x: 350, y: 200 },
activationQuest: {
name: 'Bigfoot Hunt',
objective: 'Find Bigfoot',
npc: 'bigfoot',
required: 1
},
icon: '🌲'
},
{
id: 'loch_ness',
name: 'Loch Ness Portal',
zone: 'Loch Ness',
location: { x: 100, y: 200 },
activationQuest: {
name: 'Nessie Summoning',
objective: 'Fish all lakes, summon Nessie',
actions: ['fish_all_lakes', 'summon_nessie'],
required: 2
},
icon: '🦕'
},
{
id: 'catacombs',
name: 'Catacombs Portal',
zone: 'Ancient Catacombs',
location: { x: 300, y: 300 },
activationQuest: {
name: 'Keymaster',
objective: 'Find 9 Ancient Keys',
items: ['ancient_key'],
required: 9
},
icon: '🗝️'
},
{
id: 'egypt',
name: 'Egyptian Portal',
zone: 'Egyptian Pyramids',
location: { x: 200, y: 400 },
activationQuest: {
name: 'Hieroglyph Master',
objective: 'Solve hieroglyph puzzle',
puzzle: 'hieroglyph',
required: 1
},
icon: '🔺'
},
{
id: 'amazon',
name: 'Amazon Portal',
zone: 'Amazon Jungle',
location: { x: 300, y: 450 },
activationQuest: {
name: 'Piranha Survivor',
objective: 'Survive piranha river crossing',
survival: 'piranha_river',
required: 1
},
icon: '🌴'
},
{
id: 'atlantis',
name: 'Atlantis Portal',
zone: 'Atlantis Ruins',
location: { x: 450, y: 450 },
activationQuest: {
name: 'Crystal Collector',
objective: 'Find 7 Atlantean Crystals',
items: ['atlantean_crystal'],
required: 7
},
icon: '🔱'
},
{
id: 'chernobyl',
name: 'Chernobyl Zone',
zone: 'Chernobyl Exclusion Zone',
location: { x: 150, y: 450 },
activationQuest: {
name: 'Train Access Only',
objective: 'Unlock via train system (no portal!)',
special: 'train_only',
required: 1
},
icon: '☢️',
noPortal: true
},
// 15.4 - Secret Portals
{
id: 'developer_realm',
name: 'Developer Realm',
zone: 'Developer Secret Area',
location: { x: 1, y: 1 }, // Hidden!
activationQuest: {
name: 'Easter Egg Challenge',
objective: 'Find the secret developer egg',
secret: true,
required: 1
},
icon: '👨‍💻',
secret: true
},
{
id: 'time_portal',
name: 'Time Portal',
zone: 'Pre-Outbreak Lab (Flashback)',
location: { x: 250, y: 250 }, // Spawn town
activationQuest: {
name: 'Ana\'s Memories',
objective: 'Complete main quest Act 2',
quest: 'act_2_complete',
required: 1
},
icon: '⏰',
secret: true
},
{
id: 'mirror_world',
name: 'Mirror World Portal',
zone: 'Reversed Reality',
location: { x: 500, y: 500 }, // Far corner
activationQuest: {
name: 'Shatter Reality',
objective: 'Break the Mirror of Truth',
item: 'mirror_of_truth',
required: 1
},
icon: '🪞',
secret: true
}
];
portals.forEach(portal => {
this.portals.set(portal.id, portal);
});
console.log(`✅ Registered ${this.portals.size} portals (${portals.filter(p => p.secret).length} secret)`);
}
/**
* 15.1 - Activate portal
*/
activatePortal(portalId) {
const portal = this.portals.get(portalId);
if (!portal) {
console.error(`Portal ${portalId} not found!`);
return false;
}
if (this.activePortals.has(portalId)) {
console.log(`Portal ${portal.name} already active!`);
return false;
}
// Check activation quest completion
// TODO: Integrate with quest system
// For now, just activate
this.activePortals.add(portalId);
console.log(`🌀 ${portal.icon} ${portal.name} ACTIVATED!`);
// Play activation animation
this.playPortalActivationAnimation(portal);
this.showNotification({
title: 'Portal Activated!',
text: `🌀 ${portal.icon} ${portal.name} is now online!`,
icon: '✨'
});
return true;
}
/**
* 15.2 - Portal activation animation
*/
playPortalActivationAnimation(portal) {
// TODO: Create actual portal sprite/animation
console.log(`✨ Portal activation animation for ${portal.name}`);
// Screen flash
this.scene.cameras.main.flash(1000, 100, 0, 255); // Blue flash
// Camera shake
this.scene.cameras.main.shake(500, 0.01);
}
/**
* 15.2 - Travel through portal
*/
travelThroughPortal(portalId, fromHub = false) {
const portal = this.portals.get(portalId);
if (!portal) {
console.error(`Portal ${portalId} not found!`);
return false;
}
if (!this.activePortals.has(portalId) && !fromHub) {
this.showNotification({
title: 'Portal Inactive',
text: `${portal.name} must be activated first!`,
icon: '🚫'
});
return false;
}
// Check payment if using hub
if (fromHub) {
const cost = this.calculatePortalCost(portal);
if (this.zlatnikiBalance < cost) {
this.showNotification({
title: 'Insufficient Funds',
text: `Need ${cost} Zlatniki for portal travel!`,
icon: '💰'
});
return false;
}
this.zlatnikiBalance -= cost;
}
// Start transit
this.isInTransit = true;
// Swirl effect
this.playPortalSwirlEffect();
// Loading screen (2 seconds)
setTimeout(() => {
this.completePortalTravel(portal);
}, 2000);
return true;
}
/**
* 15.2 - Portal swirl effect
*/
playPortalSwirlEffect() {
console.log('🌀 *SWIIIIIRL*');
// Create swirl particles
// TODO: Implement actual particle effect
// Screen spin effect
this.scene.cameras.main.rotateTo(Math.PI * 4, true, 2000);
// Fade out/in
this.scene.cameras.main.fadeOut(1000);
setTimeout(() => {
this.scene.cameras.main.fadeIn(1000);
}, 1000);
}
/**
* 15.2 - Complete portal travel
*/
completePortalTravel(portal) {
// Teleport player
if (this.scene.player) {
this.scene.player.x = portal.location.x * 48;
this.scene.player.y = portal.location.y * 48;
}
// Transit zombies
this.transitZombies(portal);
// Apply nausea debuff (unless stabilizer)
if (!this.hasStabilizer) {
this.applyNauseaDebuff();
}
this.isInTransit = false;
console.log(`🌀 Arrived at ${portal.zone}!`);
this.showNotification({
title: 'Portal Travel Complete',
text: `${portal.icon} Welcome to ${portal.zone}!`,
icon: '🌀'
});
}
/**
* 15.2 - Transit zombies through portal
*/
transitZombies(portal) {
// TODO: Move all tamed zombies to portal location
console.log('🧟 Zombies followed through portal!');
}
/**
* 15.2 - Apply nausea debuff
*/
applyNauseaDebuff() {
this.nauseaDebuff = {
duration: 5000, // 5 seconds
startTime: Date.now()
};
// Visual effect (screen wobble)
// TODO: Implement screen wobble
console.log('🤢 Nausea debuff applied (5s)');
this.showNotification({
title: 'Portal Sickness',
text: '🤢 You feel dizzy from portal travel...',
icon: '😵'
});
// Remove after duration
setTimeout(() => {
this.nauseaDebuff = null;
console.log('✅ Nausea debuff removed');
}, 5000);
}
/**
* 15.3 - Open town portal hub
*/
openPortalHub() {
if (!this.hubUnlocked) {
this.showNotification({
title: 'Hub Locked',
text: 'Build the Portal Hub building first! (After Town Hall)',
icon: '🏛️'
});
return false;
}
// Show portal hub UI
this.showPortalHubUI();
return true;
}
/**
* 15.3 - Portal hub UI
*/
showPortalHubUI() {
console.log('🌀 Portal Hub UI opened');
// TODO: Create actual UI
// For now, list active portals
console.log('Available Portals:');
this.activePortals.forEach(portalId => {
const portal = this.portals.get(portalId);
if (portal && !portal.noPortal) {
const cost = this.calculatePortalCost(portal);
console.log(`- ${portal.icon} ${portal.name} (${cost}Ž)`);
}
});
}
/**
* 15.3 - Calculate portal cost
*/
calculatePortalCost(portal) {
let cost = 5; // Base: 5 Zlatniki
// Add zombie transit cost (1Ž per zombie)
const zombieCount = this.scene.zombieSystem?.workers?.length || 0;
cost += zombieCount;
// Add animal transit cost (2Ž per animal)
const animalCount = this.scene.animalBreeding?.animals?.size || 0;
cost += animalCount * 2;
return cost;
}
/**
* 15.5 - Install portal stabilizer
*/
installStabilizer() {
// TODO: Check if player has stabilizer item
this.hasStabilizer = true;
console.log('✅ Portal Stabilizer installed!');
this.showNotification({
title: 'Stabilizer Installed',
text: '✨ Portal travel no longer causes nausea!',
icon: '🔧'
});
}
/**
* 15.5 - Install portal beacon
*/
installBeacon() {
// TODO: Check if player has beacon item
this.hasBeacon = true;
console.log('✅ Portal Beacon installed!');
this.showNotification({
title: 'Beacon Installed',
text: '💡 Portals now glow brighter and are easier to find!',
icon: '🔦'
});
}
/**
* Unlock portal hub
*/
unlockHub() {
this.hubUnlocked = true;
this.showNotification({
title: 'Portal Hub Unlocked!',
text: '🏛️ Fast travel to all active portals!',
icon: '🌀'
});
}
/**
* Get portal info
*/
getPortalInfo(portalId) {
return this.portals.get(portalId);
}
/**
* Get all active portals
*/
getActivePortals() {
return Array.from(this.activePortals).map(id => this.portals.get(id));
}
/**
* Get all portals
*/
getAllPortals() {
return Array.from(this.portals.values());
}
/**
* Check if portal active
*/
isPortalActive(portalId) {
return this.activePortals.has(portalId);
}
/**
* Get secret portals
*/
getSecretPortals() {
return this.getAllPortals().filter(p => p.secret);
}
/**
* Add zlatniki
*/
addZlatniki(amount) {
this.zlatnikiBalance += amount;
}
/**
* Helper: Show notification
*/
showNotification(notification) {
console.log(`📢 ${notification.icon} ${notification.title}: ${notification.text}`);
const ui = this.scene.scene.get('UIScene');
if (ui && ui.showNotification) {
ui.showNotification(notification);
}
}
/**
* Update system
*/
update(delta) {
// Update nausea debuff visual effects if active
if (this.nauseaDebuff) {
// TODO: Apply screen wobble effect
}
}
}