531 lines
14 KiB
JavaScript
531 lines
14 KiB
JavaScript
/**
|
|
* BossArenaSystem.js
|
|
* ==================
|
|
* KRVAVA ŽETEV - Boss Arena System
|
|
*
|
|
* Features:
|
|
* - Special arena locations
|
|
* - Dynamic environment
|
|
* - Escape routes
|
|
* - Boss encounter management
|
|
* - Arena hazards
|
|
*
|
|
* @author NovaFarma Team
|
|
* @date 2025-12-23
|
|
*/
|
|
|
|
export default class BossArenaSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
// Arena registry
|
|
this.arenas = new Map();
|
|
this.currentArena = null;
|
|
this.inBossFight = false;
|
|
|
|
// Arena state
|
|
this.arenaEntered = false;
|
|
this.exitBlocked = false;
|
|
this.hazardsActive = [];
|
|
|
|
console.log('🏛️ BossArenaSystem initialized');
|
|
|
|
// Register all boss arenas
|
|
this.registerArenas();
|
|
}
|
|
|
|
/**
|
|
* Register all boss arenas
|
|
*/
|
|
registerArenas() {
|
|
const arenas = [
|
|
{
|
|
id: 'troll_king_arena',
|
|
name: 'The Facility Reactor',
|
|
boss: 'alpha_troll_king',
|
|
location: { x: 250, y: 250 },
|
|
size: { width: 30, height: 30 }, // In tiles
|
|
tiledMap: 'boss_arena_reactor.tmx',
|
|
environment: 'city',
|
|
hazards: ['toxic_gas', 'electricity_sparks'],
|
|
escapeRoutes: [
|
|
{ x: 240, y: 240, blocked: true },
|
|
{ x: 260, y: 260, blocked: true }
|
|
],
|
|
music: 'boss_battle_final',
|
|
icon: '👹'
|
|
},
|
|
{
|
|
id: 'forest_boss_arena',
|
|
name: 'Enchanted Forest Arena',
|
|
boss: 'forest_guardian',
|
|
location: { x: 350, y: 200 },
|
|
size: { width: 25, height: 25 },
|
|
tiledMap: 'boss_arena_forest.tmx',
|
|
environment: 'forest',
|
|
hazards: ['poison_vines', 'thorns'],
|
|
escapeRoutes: [
|
|
{ x: 340, y: 190, blocked: true },
|
|
{ x: 360, y: 210, blocked: true }
|
|
],
|
|
music: 'boss_battle_nature',
|
|
icon: '🌲'
|
|
},
|
|
{
|
|
id: 'volcano_arena',
|
|
name: 'Volcanic Crater Arena',
|
|
boss: 'lava_titan',
|
|
location: { x: 50, y: 50 },
|
|
size: { width: 35, height: 35 },
|
|
tiledMap: 'boss_arena_volcano.tmx',
|
|
environment: 'volcano',
|
|
hazards: ['lava_eruptions', 'fire_geysers', 'falling_meteors'],
|
|
escapeRoutes: [
|
|
{ x: 40, y: 40, blocked: true }
|
|
],
|
|
music: 'boss_battle_inferno',
|
|
icon: '🌋'
|
|
},
|
|
{
|
|
id: 'ice_arena',
|
|
name: 'Frozen Wasteland Arena',
|
|
boss: 'frost_giant',
|
|
location: { x: 450, y: 100 },
|
|
size: { width: 28, height: 28 },
|
|
tiledMap: 'boss_arena_ice.tmx',
|
|
environment: 'ice',
|
|
hazards: ['ice_spikes', 'blizzard', 'frozen_ground'],
|
|
escapeRoutes: [
|
|
{ x: 440, y: 90, blocked: true },
|
|
{ x: 460, y: 110, blocked: true }
|
|
],
|
|
music: 'boss_battle_frost',
|
|
icon: '❄️'
|
|
},
|
|
{
|
|
id: 'catacombs_arena',
|
|
name: 'Ancient Catacombs Arena',
|
|
boss: 'lich_king',
|
|
location: { x: 300, y: 300 },
|
|
size: { width: 32, height: 32 },
|
|
tiledMap: 'boss_arena_catacombs.tmx',
|
|
environment: 'catacombs',
|
|
hazards: ['zombie_summons', 'curse_zones', 'collapsing_ceiling'],
|
|
escapeRoutes: [
|
|
{ x: 290, y: 290, blocked: true }
|
|
],
|
|
music: 'boss_battle_undead',
|
|
icon: '💀'
|
|
}
|
|
];
|
|
|
|
arenas.forEach(arena => this.arenas.set(arena.id, arena));
|
|
|
|
console.log(`✅ Registered ${this.arenas.size} boss arenas`);
|
|
}
|
|
|
|
/**
|
|
* Load boss arena
|
|
*/
|
|
loadArena(arenaId) {
|
|
const arena = this.arenas.get(arenaId);
|
|
if (!arena) {
|
|
console.error(`Arena ${arenaId} not found!`);
|
|
return false;
|
|
}
|
|
|
|
console.log(`🏛️ Loading ${arena.name}...`);
|
|
|
|
// Load Tiled map
|
|
this.loadTiledMap(arena);
|
|
|
|
// Setup arena boundaries
|
|
this.setupArenaBoundaries(arena);
|
|
|
|
// Block escape routes
|
|
this.blockEscapeRoutes(arena);
|
|
|
|
// Activate environmental hazards
|
|
this.activateHazards(arena);
|
|
|
|
// Change music
|
|
this.changeMusicTo(arena.music);
|
|
|
|
this.currentArena = arena;
|
|
this.arenaEntered = true;
|
|
|
|
this.showNotification({
|
|
title: 'Boss Arena',
|
|
text: `${arena.icon} Entered ${arena.name}!`,
|
|
icon: '⚔️'
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Load Tiled map for arena
|
|
*/
|
|
loadTiledMap(arena) {
|
|
console.log(`📋 Loading Tiled map: ${arena.tiledMap}`);
|
|
|
|
// TODO: Actually load and display Tiled map
|
|
// this.scene.load.tilemapTiledJSON(arena.id, `assets/maps/${arena.tiledMap}`);
|
|
// this.scene.load.once('complete', () => {
|
|
// const map = this.scene.make.tilemap({ key: arena.id });
|
|
// // ... setup tilemap
|
|
// });
|
|
|
|
// For now, create placeholder
|
|
this.createPlaceholderArena(arena);
|
|
}
|
|
|
|
/**
|
|
* Create placeholder arena (until Tiled maps ready)
|
|
*/
|
|
createPlaceholderArena(arena) {
|
|
const centerX = arena.location.x * 48;
|
|
const centerY = arena.location.y * 48;
|
|
const width = arena.size.width * 48;
|
|
const height = arena.size.height * 48;
|
|
|
|
// Arena floor
|
|
const floor = this.scene.add.rectangle(
|
|
centerX, centerY,
|
|
width, height,
|
|
this.getArenaColor(arena.environment),
|
|
0.3
|
|
);
|
|
floor.setDepth(-1);
|
|
|
|
// Arena border
|
|
const border = this.scene.add.rectangle(
|
|
centerX, centerY,
|
|
width, height
|
|
);
|
|
border.setStrokeStyle(5, 0xFF0000);
|
|
border.setFillStyle(null);
|
|
border.setDepth(10);
|
|
|
|
console.log(`✅ Created placeholder arena at (${centerX}, ${centerY})`);
|
|
}
|
|
|
|
/**
|
|
* Get arena color by environment
|
|
*/
|
|
getArenaColor(environment) {
|
|
const colors = {
|
|
ruins: 0x8B7355,
|
|
forest: 0x228B22,
|
|
volcano: 0xFF4500,
|
|
ice: 0x87CEEB,
|
|
catacombs: 0x2F4F4F
|
|
};
|
|
return colors[environment] || 0x808080;
|
|
}
|
|
|
|
/**
|
|
* Setup arena boundaries
|
|
*/
|
|
setupArenaBoundaries(arena) {
|
|
const bounds = {
|
|
x: arena.location.x * 48,
|
|
y: arena.location.y * 48,
|
|
width: arena.size.width * 48,
|
|
height: arena.size.height * 48
|
|
};
|
|
|
|
// TODO: Create physics boundaries
|
|
console.log(`🔒 Arena boundaries set: ${bounds.width}x${bounds.height}`);
|
|
}
|
|
|
|
/**
|
|
* Block escape routes
|
|
*/
|
|
blockEscapeRoutes(arena) {
|
|
this.exitBlocked = true;
|
|
|
|
arena.escapeRoutes.forEach(route => {
|
|
route.blocked = true;
|
|
|
|
// TODO: Create physical barriers at exit points
|
|
console.log(`🚫 Blocked exit at (${route.x}, ${route.y})`);
|
|
});
|
|
|
|
console.log(`🔒 All ${arena.escapeRoutes.length} exits blocked!`);
|
|
}
|
|
|
|
/**
|
|
* Unblock escape routes (after boss defeat)
|
|
*/
|
|
unblockEscapeRoutes() {
|
|
if (!this.currentArena) return;
|
|
|
|
this.exitBlocked = false;
|
|
|
|
this.currentArena.escapeRoutes.forEach(route => {
|
|
route.blocked = false;
|
|
console.log(`✅ Unblocked exit at (${route.x}, ${route.y})`);
|
|
});
|
|
|
|
this.showNotification({
|
|
title: 'Victory!',
|
|
text: '✅ Escape routes unlocked! You can leave!',
|
|
icon: '🎉'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Activate environmental hazards
|
|
*/
|
|
activateHazards(arena) {
|
|
arena.hazards.forEach(hazard => {
|
|
this.activateHazard(hazard);
|
|
});
|
|
|
|
console.log(`⚠️ Activated ${arena.hazards.length} hazards`);
|
|
}
|
|
|
|
/**
|
|
* Activate single hazard
|
|
*/
|
|
activateHazard(hazardType) {
|
|
const hazard = {
|
|
type: hazardType,
|
|
active: true,
|
|
interval: null
|
|
};
|
|
|
|
switch (hazardType) {
|
|
case 'falling_rocks':
|
|
hazard.interval = setInterval(() => {
|
|
this.spawnFallingRock();
|
|
}, 3000);
|
|
break;
|
|
|
|
case 'lava_pools':
|
|
hazard.interval = setInterval(() => {
|
|
this.createLavaPool();
|
|
}, 5000);
|
|
break;
|
|
|
|
case 'lava_eruptions':
|
|
hazard.interval = setInterval(() => {
|
|
this.triggerLavaEruption();
|
|
}, 4000);
|
|
break;
|
|
|
|
case 'ice_spikes':
|
|
hazard.interval = setInterval(() => {
|
|
this.spawnIceSpikes();
|
|
}, 3500);
|
|
break;
|
|
|
|
case 'poison_vines':
|
|
hazard.interval = setInterval(() => {
|
|
this.growPoisonVines();
|
|
}, 6000);
|
|
break;
|
|
|
|
case 'zombie_summons':
|
|
hazard.interval = setInterval(() => {
|
|
this.summonZombies();
|
|
}, 10000);
|
|
break;
|
|
}
|
|
|
|
this.hazardsActive.push(hazard);
|
|
console.log(`⚠️ Hazard active: ${hazardType}`);
|
|
}
|
|
|
|
/**
|
|
* Hazard effects
|
|
*/
|
|
spawnFallingRock() {
|
|
console.log('💥 Rock falling!');
|
|
// TODO: Create falling rock sprite with damage AoE
|
|
}
|
|
|
|
createLavaPool() {
|
|
console.log('🌋 Lava pool forming!');
|
|
// TODO: Create lava pool damage zone
|
|
}
|
|
|
|
triggerLavaEruption() {
|
|
console.log('🔥 LAVA ERUPTION!');
|
|
// TODO: Create eruption effect with knockback
|
|
}
|
|
|
|
spawnIceSpikes() {
|
|
console.log('❄️ Ice spikes emerging!');
|
|
// TODO: Create ice spike hazards
|
|
}
|
|
|
|
growPoisonVines() {
|
|
console.log('🌿 Poison vines growing!');
|
|
// TODO: Create poison vine damage zones
|
|
}
|
|
|
|
summonZombies() {
|
|
console.log('💀 Zombies summoned!');
|
|
// TODO: Spawn weak zombies as adds
|
|
}
|
|
|
|
/**
|
|
* Deactivate all hazards
|
|
*/
|
|
deactivateAllHazards() {
|
|
this.hazardsActive.forEach(hazard => {
|
|
if (hazard.interval) {
|
|
clearInterval(hazard.interval);
|
|
}
|
|
hazard.active = false;
|
|
});
|
|
|
|
this.hazardsActive = [];
|
|
console.log('✅ All hazards deactivated');
|
|
}
|
|
|
|
/**
|
|
* Start boss fight
|
|
*/
|
|
startBossFight(bossId) {
|
|
if (!this.currentArena) {
|
|
console.error('Not in an arena!');
|
|
return false;
|
|
}
|
|
|
|
this.inBossFight = true;
|
|
|
|
console.log(`⚔️ Boss fight started: ${bossId}`);
|
|
|
|
// Block exits
|
|
this.exitBlocked = true;
|
|
|
|
// Activate hazards
|
|
this.activateHazards(this.currentArena);
|
|
|
|
// TODO: Spawn boss
|
|
|
|
this.showNotification({
|
|
title: 'BOSS FIGHT!',
|
|
text: `${this.currentArena.icon} ${this.currentArena.boss} awakens!`,
|
|
icon: '⚔️'
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* End boss fight (boss defeated)
|
|
*/
|
|
endBossFight(victory = true) {
|
|
if (!this.inBossFight) return;
|
|
|
|
this.inBossFight = false;
|
|
|
|
// Deactivate hazards
|
|
this.deactivateAllHazards();
|
|
|
|
// Unblock exits
|
|
if (victory) {
|
|
this.unblockEscapeRoutes();
|
|
}
|
|
|
|
console.log(`${victory ? '✅ Victory!' : '💀 Defeat!'}`);
|
|
|
|
if (victory) {
|
|
this.grantBossRewards();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Grant boss rewards
|
|
*/
|
|
grantBossRewards() {
|
|
if (!this.currentArena) return;
|
|
|
|
console.log('🎁 Boss rewards:');
|
|
console.log(' 👑 Legendary loot');
|
|
console.log(' 💰 1000 Zlatniki');
|
|
console.log(' ⭐ 5000 XP');
|
|
|
|
// TODO: Actually grant rewards
|
|
|
|
this.showNotification({
|
|
title: 'Boss Defeated!',
|
|
text: '🏆 Legendary loot acquired!',
|
|
icon: '👑'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Change music
|
|
*/
|
|
changeMusicTo(trackName) {
|
|
console.log(`🎵 Music: ${trackName}`);
|
|
// TODO: Actually change music
|
|
}
|
|
|
|
/**
|
|
* Leave arena
|
|
*/
|
|
leaveArena() {
|
|
if (this.exitBlocked) {
|
|
this.showNotification({
|
|
title: 'Blocked!',
|
|
text: '🚫 You cannot leave during boss fight!',
|
|
icon: '⚔️'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
if (this.currentArena) {
|
|
console.log(`🚪 Leaving ${this.currentArena.name}`);
|
|
|
|
// Cleanup
|
|
this.deactivateAllHazards();
|
|
this.currentArena = null;
|
|
this.arenaEntered = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get arena info
|
|
*/
|
|
getArenaInfo(arenaId) {
|
|
return this.arenas.get(arenaId);
|
|
}
|
|
|
|
/**
|
|
* Get all arenas
|
|
*/
|
|
getAllArenas() {
|
|
return Array.from(this.arenas.values());
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
if (!this.inBossFight) return;
|
|
|
|
// Update hazards, check arena bounds, etc.
|
|
// TODO: Implement arena updates
|
|
}
|
|
}
|