549 lines
20 KiB
JavaScript
549 lines
20 KiB
JavaScript
#!/usr/bin/env node
|
|
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const { DUNGEONS } = require('./src/data/dungeons');
|
|
|
|
const themeColors = {
|
|
stone: { body: '#696969', eye: '#FFD700', accent: '#A9A9A9' },
|
|
forest: { body: '#228B22', eye: '#90EE90', accent: '#006400' },
|
|
desert: { body: '#DAA520', eye: '#8B4513', accent: '#FFD700' },
|
|
mountain: { body: '#4682B4', eye: '#E0E0E0', accent: '#87CEEB' },
|
|
underground: { body: '#4B0082', eye: '#DA70D6', accent: '#9400D3' },
|
|
ocean: { body: '#006994', eye: '#00CED1', accent: '#4682B4' },
|
|
sky: { body: '#FFD700', eye: '#FFFACD', accent: '#FF8C00' },
|
|
shadow: { body: '#1A0A2A', eye: '#9400D3', accent: '#4B0082' },
|
|
final: { body: '#8B0000', eye: '#FFD700', accent: '#FF4500' },
|
|
};
|
|
|
|
const templateAssignments = {
|
|
0: 'gleeok', 11: 'gleeok', 22: 'gleeok', 33: 'gleeok', 44: 'gleeok',
|
|
55: 'gleeok', 66: 'gleeok', 77: 'gleeok', 88: 'gleeok', 99: 'gleeok',
|
|
1: 'darknut', 10: 'darknut', 21: 'darknut', 32: 'darknut', 43: 'darknut',
|
|
54: 'darknut', 65: 'darknut', 76: 'darknut', 87: 'darknut', 98: 'darknut',
|
|
2: 'wizzrobe', 12: 'wizzrobe', 23: 'wizzrobe', 34: 'wizzrobe', 45: 'wizzrobe',
|
|
56: 'wizzrobe', 67: 'wizzrobe', 78: 'wizzrobe', 89: 'wizzrobe', 97: 'wizzrobe',
|
|
3: 'moldorm', 13: 'moldorm', 24: 'moldorm', 35: 'moldorm', 46: 'moldorm',
|
|
57: 'moldorm', 68: 'moldorm', 79: 'moldorm', 90: 'moldorm', 96: 'moldorm',
|
|
4: 'genie', 14: 'genie', 25: 'genie', 36: 'genie', 47: 'genie',
|
|
58: 'genie', 69: 'genie', 80: 'genie', 91: 'genie', 95: 'genie',
|
|
5: 'liklike', 15: 'liklike', 26: 'liklike', 37: 'liklike', 48: 'liklike',
|
|
59: 'liklike', 70: 'liklike', 81: 'liklike', 92: 'liklike', 94: 'liklike',
|
|
6: 'aquamentus', 16: 'aquamentus', 27: 'aquamentus', 38: 'aquamentus', 49: 'aquamentus',
|
|
60: 'aquamentus', 71: 'aquamentus', 82: 'aquamentus', 93: 'aquamentus',
|
|
7: 'manhandla', 17: 'manhandla', 28: 'manhandla', 39: 'manhandla', 50: 'manhandla',
|
|
61: 'manhandla', 72: 'manhandla', 83: 'manhandla',
|
|
8: 'gleeok_variant', 18: 'gleeok_variant', 29: 'gleeok_variant', 40: 'gleeok_variant',
|
|
51: 'gleeok_variant', 62: 'gleeok_variant', 73: 'gleeok_variant', 84: 'gleeok_variant',
|
|
9: 'agahnim', 19: 'agahnim', 30: 'agahnim', 41: 'agahnim', 52: 'agahnim',
|
|
63: 'agahnim', 74: 'agahnim', 85: 'agahnim',
|
|
// Fill remaining gaps not covered by the mod-11 pattern
|
|
20: 'genie', 31: 'liklike', 42: 'moldorm', 53: 'wizzrobe', 64: 'darknut', 75: 'gleeok',
|
|
86: 'moldorm',
|
|
};
|
|
|
|
// Verify all 100 indices covered
|
|
for (let i = 0; i < 100; i++) {
|
|
if (!templateAssignments[i]) {
|
|
console.error('ERROR: No template for index ' + i);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
const nameTemplates = {
|
|
gleeok: {
|
|
stone: 'Stone Gleeok', forest: 'Verdant Gleeok', desert: 'Sand Gleeok',
|
|
mountain: 'Frost Gleeok', underground: 'Shadow Gleeok', ocean: 'Tidal Gleeok',
|
|
sky: 'Storm Gleeok', shadow: 'Dark Gleeok', final: 'Infernal Gleeok',
|
|
},
|
|
darknut: {
|
|
stone: 'Stone Darknut', forest: 'Green Darknut', desert: 'Sand Darknut',
|
|
mountain: 'Iron Darknut', underground: 'Deep Darknut', ocean: 'Abyssal Darknut',
|
|
sky: 'Sky Darknut', shadow: 'Shadow Darknut', final: 'Demon Darknut',
|
|
},
|
|
wizzrobe: {
|
|
stone: 'Stone Wizzrobe', forest: 'Thorn Wizzrobe', desert: 'Mirage Wizzrobe',
|
|
mountain: 'Frost Wizzrobe', underground: 'Crystal Wizzrobe', ocean: 'Tide Wizzrobe',
|
|
sky: 'Storm Wizzrobe', shadow: 'Void Wizzrobe', final: 'Dark Wizzrobe',
|
|
},
|
|
moldorm: {
|
|
stone: 'Stone Moldorm', forest: 'Root Moldorm', desert: 'Dune Moldorm',
|
|
mountain: 'Frost Moldorm', underground: 'Deep Moldorm', ocean: 'Abyssal Moldorm',
|
|
sky: 'Cloud Moldorm', shadow: 'Shadow Moldorm', final: 'Abyssal Moldorm',
|
|
},
|
|
genie: {
|
|
stone: 'Stone Genie', forest: 'Moss Genie', desert: 'Sand Genie',
|
|
mountain: 'Ice Genie', underground: 'Crystal Genie', ocean: 'Tidal Genie',
|
|
sky: 'Sky Genie', shadow: 'Dark Genie', final: 'Demon Genie',
|
|
},
|
|
liklike: {
|
|
stone: 'Stone Like Like', forest: 'Moss Like Like', desert: 'Dune Like Like',
|
|
mountain: 'Frost Like Like', underground: 'Deep Like Like', ocean: 'Abyssal Like Like',
|
|
sky: 'Cloud Like Like', shadow: 'Shadow Like Like', final: 'Abyssal Like Like',
|
|
},
|
|
aquamentus: {
|
|
stone: 'Stone Aquamentus', forest: 'Verdant Aquamentus', desert: 'Sand Aquamentus',
|
|
mountain: 'Frost Aquamentus', underground: 'Crystal Aquamentus', ocean: 'Tidal Aquamentus',
|
|
sky: 'Storm Aquamentus', shadow: 'Dark Aquamentus', final: 'Infernal Aquamentus',
|
|
},
|
|
manhandla: {
|
|
stone: 'Stone Manhandla', forest: 'Verdant Manhandla', desert: 'Dune Manhandla',
|
|
mountain: 'Frost Manhandla', underground: 'Crystal Manhandla', ocean: 'Abyssal Manhandla',
|
|
sky: 'Storm Manhandla', shadow: 'Dark Manhandla', final: 'Infernal Manhandla',
|
|
},
|
|
gleeok_variant: {
|
|
stone: 'Stone Ice Gleeok', forest: 'Forest Ice Gleeok', desert: 'Desert Ice Gleeok',
|
|
mountain: 'Glacier Gleeok', underground: 'Shadow Ice Gleeok', ocean: 'Abyssal Water Gleeok',
|
|
sky: 'Sky Ice Gleeok', shadow: 'Dark Ice Gleeok', final: 'Infernal Ice Gleeok',
|
|
},
|
|
agahnim: {
|
|
stone: 'Stone Agahnim', forest: 'Verdant Agahnim', desert: 'Sand Agahnim',
|
|
mountain: 'Frost Agahnim', underground: 'Crystal Agahnim', ocean: 'Tidal Agahnim',
|
|
sky: 'Storm Agahnim', shadow: 'Void Agahnim', final: 'Dark Agahnim',
|
|
},
|
|
};
|
|
|
|
function getStatsByDifficulty(diff) {
|
|
if (diff <= 2) return { hp: 20 + (diff - 1) * 10, damage: 3 + (diff - 1), defense: diff - 1 };
|
|
if (diff <= 4) return { hp: 40 + (diff - 3) * 20, damage: 4 + (diff - 3), defense: Math.min(diff - 2, 2) };
|
|
if (diff <= 6) return { hp: 80 + (diff - 5) * 35, damage: 5 + (diff - 5), defense: Math.min(diff - 4, 3) };
|
|
if (diff <= 8) return { hp: 150 + (diff - 7) * 50, damage: 6 + (diff - 7) * 2, defense: Math.min(diff - 5, 4) };
|
|
return { hp: 250 + (diff - 9) * 250, damage: 8 + (diff - 9) * 7, defense: Math.min(diff - 6, 5) };
|
|
}
|
|
|
|
function generatePhases(template, diff, baseDamage) {
|
|
const phases = [];
|
|
const scaledDmg = Math.round(baseDamage * 1.3);
|
|
|
|
switch (template) {
|
|
case 'gleeok':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg, cooldown: 2000, count: 2, spreadAngle: 360, projectileSpeed: 2 },
|
|
{ type: 'melee', damage: baseDamage, cooldown: 1500, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
if (diff >= 4) {
|
|
phases.push({
|
|
hpThreshold: 60,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg + 1, cooldown: 1800, count: 3, spreadAngle: 360, projectileSpeed: 2.5 },
|
|
{ type: 'melee', damage: baseDamage + 1, cooldown: 1200, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
}
|
|
if (diff >= 7) {
|
|
phases.push({
|
|
hpThreshold: 30,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg + 2, cooldown: 1200, count: 4, spreadAngle: 360, projectileSpeed: 3 },
|
|
{ type: 'melee', damage: baseDamage + 2, cooldown: 1000, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'gleeok_variant':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg, cooldown: 2200, count: 2, spreadAngle: 360, projectileSpeed: 1.5 },
|
|
{ type: 'melee', damage: baseDamage, cooldown: 1800, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
if (diff >= 4) {
|
|
phases.push({
|
|
hpThreshold: 60,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg + 1, cooldown: 2000, count: 3, spreadAngle: 360, projectileSpeed: 2 },
|
|
{ type: 'melee', damage: baseDamage + 1, cooldown: 1500, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
}
|
|
if (diff >= 7) {
|
|
phases.push({
|
|
hpThreshold: 30,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg + 2, cooldown: 1400, count: 4, spreadAngle: 360, projectileSpeed: 2.5 },
|
|
{ type: 'melee', damage: baseDamage + 2, cooldown: 1100, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'darknut':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'melee', damage: baseDamage, cooldown: 1000, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
phases.push({
|
|
hpThreshold: 50,
|
|
attacks: [
|
|
{ type: 'melee', damage: scaledDmg, cooldown: 800, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
{ type: 'melee', damage: scaledDmg, cooldown: 1500, count: 3, spreadAngle: 120, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
if (diff >= 6) {
|
|
phases.push({
|
|
hpThreshold: 25,
|
|
attacks: [
|
|
{ type: 'melee', damage: scaledDmg + 2, cooldown: 600, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
{ type: 'aoe', damage: baseDamage, cooldown: 2000, count: 4, spreadAngle: 180, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'wizzrobe':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 1500, count: 2, spreadAngle: 60, projectileSpeed: 3 },
|
|
],
|
|
});
|
|
if (diff >= 3) {
|
|
phases.push({
|
|
hpThreshold: 40,
|
|
attacks: [
|
|
{ type: 'projectile', damage: scaledDmg + 1, cooldown: 1200, count: 3, spreadAngle: 90, projectileSpeed: 3.5 },
|
|
{ type: 'summon', damage: 0, cooldown: 4000, count: 2, spreadAngle: 0, projectileSpeed: 0, enemyType: diff < 6 ? 'keese' : 'stalfos' },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'moldorm':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'melee', damage: baseDamage, cooldown: 2000, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
phases.push({
|
|
hpThreshold: 30,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg, cooldown: 3000, count: 1, spreadAngle: 360, projectileSpeed: 0 },
|
|
{ type: 'melee', damage: scaledDmg, cooldown: 800, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
break;
|
|
|
|
case 'genie':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 1500, count: 1, spreadAngle: 0, projectileSpeed: 2.5 },
|
|
],
|
|
});
|
|
if (diff >= 3) {
|
|
phases.push({
|
|
hpThreshold: 50,
|
|
attacks: [
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 1200, count: 2, spreadAngle: 90, projectileSpeed: 2.5 },
|
|
],
|
|
});
|
|
}
|
|
if (diff >= 6) {
|
|
phases.push({
|
|
hpThreshold: 20,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg + 1, cooldown: 1000, count: 3, spreadAngle: 120, projectileSpeed: 3 },
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 800, count: 2, spreadAngle: 45, projectileSpeed: 3.5 },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'liklike':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'melee', damage: baseDamage, cooldown: 2000, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
if (diff >= 3) {
|
|
phases.push({
|
|
hpThreshold: 40,
|
|
attacks: [
|
|
{ type: 'melee', damage: scaledDmg, cooldown: 1500, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
{ type: 'summon', damage: 0, cooldown: 5000, count: 2, spreadAngle: 0, projectileSpeed: 0, enemyType: 'slime' },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'aquamentus':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 2000, count: 1, spreadAngle: 0, projectileSpeed: 2 },
|
|
],
|
|
});
|
|
phases.push({
|
|
hpThreshold: 50,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg, cooldown: 1800, count: 3, spreadAngle: 120, projectileSpeed: 2.5 },
|
|
],
|
|
});
|
|
if (diff >= 6) {
|
|
phases.push({
|
|
hpThreshold: 20,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg + 2, cooldown: 1200, count: 3, spreadAngle: 180, projectileSpeed: 3 },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'manhandla':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'melee', damage: baseDamage, cooldown: 1200, count: 4, spreadAngle: 360, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
if (diff >= 3) {
|
|
phases.push({
|
|
hpThreshold: 30,
|
|
attacks: [
|
|
{ type: 'aoe', damage: scaledDmg, cooldown: 2000, count: 4, spreadAngle: 360, projectileSpeed: 2 },
|
|
{ type: 'melee', damage: scaledDmg, cooldown: 800, count: 4, spreadAngle: 360, projectileSpeed: 0 },
|
|
],
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'agahnim':
|
|
phases.push({
|
|
hpThreshold: 100,
|
|
attacks: [
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 1500, count: 3, spreadAngle: 90, projectileSpeed: 2.5 },
|
|
],
|
|
});
|
|
phases.push({
|
|
hpThreshold: 60,
|
|
attacks: [
|
|
{ type: 'melee', damage: scaledDmg, cooldown: 1000, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 1200, count: 3, spreadAngle: 90, projectileSpeed: 2.5 },
|
|
],
|
|
});
|
|
phases.push({
|
|
hpThreshold: 30,
|
|
attacks: [
|
|
{ type: 'projectile', damage: scaledDmg, cooldown: 1500, count: 3, spreadAngle: 90, projectileSpeed: 2.5 },
|
|
],
|
|
});
|
|
phases.push({
|
|
hpThreshold: 10,
|
|
attacks: [
|
|
{ type: 'melee', damage: scaledDmg + 2, cooldown: 800, count: 1, spreadAngle: 0, projectileSpeed: 0 },
|
|
{ type: 'aoe', damage: scaledDmg, cooldown: 1500, count: 4, spreadAngle: 180, projectileSpeed: 3 },
|
|
],
|
|
});
|
|
break;
|
|
}
|
|
|
|
return phases;
|
|
}
|
|
|
|
function generateDrops(template, diff) {
|
|
const drops = [{ item: 'heart_piece', weight: 100 }];
|
|
|
|
if (diff >= 2) drops.push({ item: 'healing_potion', weight: 30 });
|
|
if (diff >= 4) drops.push({ item: 'super_potion', weight: 15 });
|
|
if (diff >= 6) drops.push({ item: 'magic_potion', weight: 10 });
|
|
if (diff >= 8) drops.push({ item: 'heart_piece', weight: 20 });
|
|
|
|
switch (template) {
|
|
case 'gleeok':
|
|
case 'gleeok_variant':
|
|
if (diff >= 5) drops.push({ item: 'fire_rod', weight: 5 });
|
|
if (diff >= 8) drops.push({ item: 'master_sword', weight: 3 });
|
|
break;
|
|
case 'darknut':
|
|
if (diff >= 3) drops.push({ item: 'hammer', weight: 8 });
|
|
if (diff >= 7) drops.push({ item: 'magic_sword', weight: 3 });
|
|
break;
|
|
case 'wizzrobe':
|
|
if (diff >= 4) drops.push({ item: 'ice_rod', weight: 5 });
|
|
if (diff >= 7) drops.push({ item: 'magic_potion', weight: 15 });
|
|
break;
|
|
case 'agahnim':
|
|
if (diff >= 6) drops.push({ item: 'magic_sword', weight: 5 });
|
|
break;
|
|
case 'aquamentus':
|
|
if (diff >= 5) drops.push({ item: 'fire_rod', weight: 5 });
|
|
break;
|
|
case 'manhandla':
|
|
if (diff >= 4) drops.push({ item: 'boomerang', weight: 5 });
|
|
break;
|
|
case 'moldorm':
|
|
if (diff >= 6) drops.push({ item: 'hookshot', weight: 3 });
|
|
break;
|
|
case 'genie':
|
|
if (diff >= 5) drops.push({ item: 'magic_crystal', weight: 10 });
|
|
break;
|
|
case 'liklike':
|
|
if (diff >= 3) drops.push({ item: 'super_potion', weight: 20 });
|
|
break;
|
|
}
|
|
|
|
return drops;
|
|
}
|
|
|
|
function generateBosses() {
|
|
const bosses = [];
|
|
const descriptions = {
|
|
gleeok: 'A multi-headed dragon whose fiery breath devastates all.',
|
|
darknut: 'A heavily-armored knight wielding a massive sword.',
|
|
wizzrobe: 'A teleporting mage who commands destructive magic.',
|
|
moldorm: 'A giant segmented worm that charges relentlessly.',
|
|
genie: 'A lamp spirit that unleashes devastating elemental blasts.',
|
|
liklike: 'A voracious worm that steals hearts and shields.',
|
|
aquamentus: 'A dragon that breathes flames at everything in sight.',
|
|
manhandla: 'A spinning plant monster with razor-sharp limbs.',
|
|
gleeok_variant: 'A spectral dragon wielding ice and shadow.',
|
|
agahnim: 'A dark mage protected by impenetrable barriers.',
|
|
};
|
|
|
|
for (let i = 0; i < 100; i++) {
|
|
const dungeon = DUNGEONS[i];
|
|
const template = templateAssignments[i];
|
|
const theme = dungeon.theme;
|
|
const diff = dungeon.difficulty;
|
|
const stats = getStatsByDifficulty(diff);
|
|
const colors = themeColors[theme];
|
|
|
|
let hp = stats.hp;
|
|
let damage = stats.damage;
|
|
let defense = stats.defense;
|
|
let speed = 0;
|
|
let behavior = 'chase';
|
|
let drawFunction = 'drawGeneric';
|
|
|
|
switch (template) {
|
|
case 'gleeok':
|
|
case 'gleeok_variant':
|
|
hp = Math.round(hp * 1.3);
|
|
speed = 1.5;
|
|
behavior = 'charge';
|
|
drawFunction = 'drawGleeok';
|
|
break;
|
|
case 'darknut':
|
|
defense = Math.min(defense + 1, 5);
|
|
speed = 1.2;
|
|
behavior = 'chase';
|
|
drawFunction = 'drawDarknut';
|
|
break;
|
|
case 'wizzrobe':
|
|
damage = Math.round(damage * 0.8);
|
|
defense = Math.max(defense - 1, 0);
|
|
speed = 0;
|
|
behavior = 'teleport';
|
|
drawFunction = 'drawWizzrobe';
|
|
break;
|
|
case 'moldorm':
|
|
hp = Math.round(hp * 0.7);
|
|
speed = 2.0;
|
|
behavior = 'charge';
|
|
break;
|
|
case 'genie':
|
|
hp = Math.round(hp * 1.1);
|
|
speed = 0;
|
|
behavior = 'stationary';
|
|
break;
|
|
case 'liklike':
|
|
hp = Math.round(hp * 0.8);
|
|
speed = 1.0;
|
|
behavior = 'chase';
|
|
break;
|
|
case 'aquamentus':
|
|
hp = Math.round(hp * 1.2);
|
|
speed = 0;
|
|
behavior = 'stationary';
|
|
drawFunction = 'drawGleeok';
|
|
break;
|
|
case 'manhandla':
|
|
speed = 1.8;
|
|
behavior = 'charge';
|
|
break;
|
|
case 'agahnim':
|
|
damage = Math.round(damage * 1.2);
|
|
defense = Math.min(defense + 1, 5);
|
|
speed = 0;
|
|
behavior = 'stationary';
|
|
drawFunction = 'drawWizzrobe';
|
|
break;
|
|
}
|
|
|
|
const name = nameTemplates[template] ? nameTemplates[template][theme] : (theme + ' ' + template);
|
|
const phases = generatePhases(template, diff, damage);
|
|
const drops = generateDrops(template, diff);
|
|
|
|
bosses.push({
|
|
id: i, name, hp, damage, defense, speed, colors, behavior,
|
|
drawFunction, phases, drops, description: descriptions[template],
|
|
});
|
|
}
|
|
|
|
return bosses;
|
|
}
|
|
|
|
const bosses = generateBosses();
|
|
|
|
let output = "'use strict';\n\nconst BOSS_TYPES = [\n";
|
|
|
|
for (const boss of bosses) {
|
|
output += ' { id: ' + boss.id + ', ';
|
|
output += "name: '" + boss.name + "', ";
|
|
output += 'hp: ' + boss.hp + ', ';
|
|
output += 'damage: ' + boss.damage + ', ';
|
|
output += 'defense: ' + boss.defense + ', ';
|
|
output += 'speed: ' + boss.speed + ', ';
|
|
output += 'colors: { body: "' + boss.colors.body + '", eye: "' + boss.colors.eye + '", accent: "' + boss.colors.accent + '" }, ';
|
|
output += 'behavior: "' + boss.behavior + '", ';
|
|
output += 'drawFunction: "' + boss.drawFunction + '", ';
|
|
output += 'description: "' + boss.description + '", ';
|
|
|
|
output += 'phases: [';
|
|
for (let p = 0; p < boss.phases.length; p++) {
|
|
const phase = boss.phases[p];
|
|
output += '{ hpThreshold: ' + phase.hpThreshold + ', attacks: [';
|
|
for (let a = 0; a < phase.attacks.length; a++) {
|
|
const attack = phase.attacks[a];
|
|
output += '{ type: "' + attack.type + '", damage: ' + attack.damage + ', cooldown: ' + attack.cooldown + ', count: ' + attack.count + ', spreadAngle: ' + attack.spreadAngle + ', projectileSpeed: ' + attack.projectileSpeed;
|
|
if (attack.enemyType) output += ', enemyType: "' + attack.enemyType + '"';
|
|
output += '}';
|
|
if (a < phase.attacks.length - 1) output += ', ';
|
|
}
|
|
output += ']}';
|
|
if (p < boss.phases.length - 1) output += ', ';
|
|
}
|
|
output += '], ';
|
|
|
|
output += 'drops: [';
|
|
for (let d = 0; d < boss.drops.length; d++) {
|
|
const drop = boss.drops[d];
|
|
output += '{ item: "' + drop.item + '", weight: ' + drop.weight + ' }';
|
|
if (d < boss.drops.length - 1) output += ', ';
|
|
}
|
|
output += ']';
|
|
output += ' },\n';
|
|
}
|
|
|
|
output += '];\n\n';
|
|
output += 'function getBossType(id) {\n';
|
|
output += ' return BOSS_TYPES.find(b => b.id === id);\n';
|
|
output += '}\n\n';
|
|
output += 'module.exports = { BOSS_TYPES, getBossType };\n';
|
|
|
|
fs.writeFileSync(path.join(__dirname, 'src/data/bosses.js'), output);
|
|
console.log('Generated ' + bosses.length + ' bosses successfully.');
|
|
|
|
const { BOSS_TYPES } = require('./src/data/bosses');
|
|
console.log('Verification: ' + BOSS_TYPES.length + ' bosses loaded.'); |