feature: add new composite and exotic mana types (ticket #202)
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 17s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 17s
This commit is contained in:
@@ -108,6 +108,66 @@ export const elementalRegenAdvancedDisciplines: DisciplineDefinition[] = [
|
||||
drainBase: 2,
|
||||
sourceManaTypes: ['raw', 'fire', 'air'],
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-frost',
|
||||
name: 'Frost',
|
||||
manaType: 'frost',
|
||||
cost: 12,
|
||||
description: 'Convert raw mana + air mana + water mana into frost mana over time.',
|
||||
conversionRate: 0.35,
|
||||
difficultyFactor: 160,
|
||||
scalingFactor: 80,
|
||||
drainBase: 2,
|
||||
sourceManaTypes: ['raw', 'air', 'water'],
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-blackflame',
|
||||
name: 'BlackFlame',
|
||||
manaType: 'blackflame',
|
||||
cost: 14,
|
||||
description: 'Convert raw mana + dark mana + fire mana into blackflame mana over time.',
|
||||
conversionRate: 0.3,
|
||||
difficultyFactor: 170,
|
||||
scalingFactor: 85,
|
||||
drainBase: 2,
|
||||
sourceManaTypes: ['raw', 'dark', 'fire'],
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-radiantflames',
|
||||
name: 'Radiant Flames',
|
||||
manaType: 'radiantflames',
|
||||
cost: 14,
|
||||
description: 'Convert raw mana + light mana + fire mana into radiant flames mana over time.',
|
||||
conversionRate: 0.3,
|
||||
difficultyFactor: 170,
|
||||
scalingFactor: 85,
|
||||
drainBase: 2,
|
||||
sourceManaTypes: ['raw', 'light', 'fire'],
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-miasma',
|
||||
name: 'Miasma',
|
||||
manaType: 'miasma',
|
||||
cost: 14,
|
||||
description: 'Convert raw mana + air mana + death mana into miasma mana over time.',
|
||||
conversionRate: 0.3,
|
||||
difficultyFactor: 170,
|
||||
scalingFactor: 85,
|
||||
drainBase: 2,
|
||||
sourceManaTypes: ['raw', 'air', 'death'],
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-shadowglass',
|
||||
name: 'Shadow Glass',
|
||||
manaType: 'shadowglass',
|
||||
cost: 15,
|
||||
description: 'Convert raw mana + earth mana + dark mana into shadow glass mana over time.',
|
||||
conversionRate: 0.3,
|
||||
difficultyFactor: 175,
|
||||
scalingFactor: 88,
|
||||
drainBase: 2,
|
||||
sourceManaTypes: ['raw', 'earth', 'dark'],
|
||||
}),
|
||||
|
||||
// ── Exotic Elements ────────────────────────────────────────────────────────
|
||||
createAdvancedConversionDiscipline({
|
||||
@@ -127,13 +187,13 @@ export const elementalRegenAdvancedDisciplines: DisciplineDefinition[] = [
|
||||
id: 'regen-stellar',
|
||||
name: 'Stellar',
|
||||
manaType: 'stellar',
|
||||
cost: 18,
|
||||
description: 'Convert raw mana + fire mana + light mana into stellar mana over time.',
|
||||
conversionRate: 0.25,
|
||||
difficultyFactor: 220,
|
||||
scalingFactor: 110,
|
||||
cost: 20,
|
||||
description: 'Convert raw mana + plasma mana + light mana into stellar mana over time.',
|
||||
conversionRate: 0.2,
|
||||
difficultyFactor: 230,
|
||||
scalingFactor: 115,
|
||||
drainBase: 3,
|
||||
sourceManaTypes: ['raw', 'fire', 'light'],
|
||||
sourceManaTypes: ['raw', 'plasma', 'light'],
|
||||
infiniteThreshold: 500,
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
@@ -149,4 +209,43 @@ export const elementalRegenAdvancedDisciplines: DisciplineDefinition[] = [
|
||||
sourceManaTypes: ['raw', 'dark', 'death'],
|
||||
infiniteThreshold: 500,
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-soul',
|
||||
name: 'Soul',
|
||||
manaType: 'soul',
|
||||
cost: 20,
|
||||
description: 'Convert raw mana + light mana + dark mana + transference mana into soul mana over time.',
|
||||
conversionRate: 0.2,
|
||||
difficultyFactor: 240,
|
||||
scalingFactor: 120,
|
||||
drainBase: 3,
|
||||
sourceManaTypes: ['raw', 'light', 'dark', 'transference'],
|
||||
infiniteThreshold: 550,
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-plasma',
|
||||
name: 'Plasma',
|
||||
manaType: 'plasma',
|
||||
cost: 20,
|
||||
description: 'Convert raw mana + lightning mana + fire mana + transference mana into plasma mana over time.',
|
||||
conversionRate: 0.2,
|
||||
difficultyFactor: 240,
|
||||
scalingFactor: 120,
|
||||
drainBase: 3,
|
||||
sourceManaTypes: ['raw', 'lightning', 'fire', 'transference'],
|
||||
infiniteThreshold: 550,
|
||||
}),
|
||||
createAdvancedConversionDiscipline({
|
||||
id: 'regen-time',
|
||||
name: 'Time',
|
||||
manaType: 'time',
|
||||
cost: 22,
|
||||
description: 'Convert raw mana + soul mana + sand mana + transference mana into time mana over time.',
|
||||
conversionRate: 0.15,
|
||||
difficultyFactor: 260,
|
||||
scalingFactor: 130,
|
||||
drainBase: 3,
|
||||
sourceManaTypes: ['raw', 'soul', 'sand', 'transference'],
|
||||
infiniteThreshold: 600,
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -56,14 +56,22 @@ const MANA_CAPACITY_CONFIGS: ManaCapacityConfig[] = [
|
||||
{ id: 'attune-transference', name: 'Transference', manaType: 'transference', cost: 8, baseValue: 5, difficultyFactor: 120, scalingFactor: 60, drainBase: 1.5 },
|
||||
|
||||
// ── Composite Elements ─────────────────────────────────────────────────────
|
||||
{ id: 'attune-metal', name: 'Metal', manaType: 'metal', cost: 15, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 2.5 },
|
||||
{ id: 'attune-sand', name: 'Sand', manaType: 'sand', cost: 15, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 2.5 },
|
||||
{ id: 'attune-lightning', name: 'Lightning', manaType: 'lightning', cost: 15, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 2.5 },
|
||||
{ id: 'attune-metal', name: 'Metal', manaType: 'metal', cost: 15, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 2.5 },
|
||||
{ id: 'attune-sand', name: 'Sand', manaType: 'sand', cost: 15, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 2.5 },
|
||||
{ id: 'attune-lightning', name: 'Lightning', manaType: 'lightning', cost: 15, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 2.5 },
|
||||
{ id: 'attune-frost', name: 'Frost', manaType: 'frost', cost: 15, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 2.5 },
|
||||
{ id: 'attune-blackflame', name: 'BlackFlame', manaType: 'blackflame', cost: 16, baseValue: 4, difficultyFactor: 190, scalingFactor: 95, drainBase: 2.5 },
|
||||
{ id: 'attune-radiantflames', name: 'Radiant Flames', manaType: 'radiantflames', cost: 16, baseValue: 4, difficultyFactor: 190, scalingFactor: 95, drainBase: 2.5 },
|
||||
{ id: 'attune-miasma', name: 'Miasma', manaType: 'miasma', cost: 16, baseValue: 4, difficultyFactor: 190, scalingFactor: 95, drainBase: 2.5 },
|
||||
{ id: 'attune-shadowglass', name: 'Shadow Glass', manaType: 'shadowglass', cost: 17, baseValue: 4, difficultyFactor: 200, scalingFactor: 100, drainBase: 2.5 },
|
||||
|
||||
// ── Exotic Elements ────────────────────────────────────────────────────────
|
||||
{ id: 'attune-crystal', name: 'Crystal', manaType: 'crystal', cost: 20, baseValue: 3, difficultyFactor: 240, scalingFactor: 120, drainBase: 3 },
|
||||
{ id: 'attune-stellar', name: 'Stellar', manaType: 'stellar', cost: 20, baseValue: 3, difficultyFactor: 240, scalingFactor: 120, drainBase: 3 },
|
||||
{ id: 'attune-void', name: 'Void', manaType: 'void', cost: 22, baseValue: 3, difficultyFactor: 260, scalingFactor: 130, drainBase: 3.5 },
|
||||
{ id: 'attune-soul', name: 'Soul', manaType: 'soul', cost: 22, baseValue: 3, difficultyFactor: 260, scalingFactor: 130, drainBase: 3.5 },
|
||||
{ id: 'attune-time', name: 'Time', manaType: 'time', cost: 24, baseValue: 3, difficultyFactor: 280, scalingFactor: 140, drainBase: 4 },
|
||||
{ id: 'attune-plasma', name: 'Plasma', manaType: 'plasma', cost: 22, baseValue: 3, difficultyFactor: 250, scalingFactor: 125, drainBase: 3.5 },
|
||||
];
|
||||
|
||||
export const elementalAttunementDisciplines: DisciplineDefinition[] =
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// ─── BlackFlame Spell Effects ──────────────────────────────────
|
||||
// BlackFlame spells - Dark + Fire compound, curse/DoT focus
|
||||
|
||||
import type { EnchantmentEffectDef } from './types';
|
||||
import { ALL_CASTER } from './types';
|
||||
|
||||
export const BLACKFLAME_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_blackFire: {
|
||||
id: 'spell_blackFire',
|
||||
name: 'Black Fire',
|
||||
description: 'Grants the ability to cast Black Fire (12 blackflame damage, burn+curse)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 82,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'blackFire' }
|
||||
},
|
||||
spell_shadowEmber: {
|
||||
id: 'spell_shadowEmber',
|
||||
name: 'Shadow Ember',
|
||||
description: 'Grants the ability to cast Shadow Ember (20 blackflame damage, curse)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 105,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'shadowEmber' }
|
||||
},
|
||||
spell_darkInferno: {
|
||||
id: 'spell_darkInferno',
|
||||
name: 'Dark Inferno',
|
||||
description: 'Grants the ability to cast Dark Inferno (38 blackflame damage, burn+curse)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 175,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'darkInferno' }
|
||||
},
|
||||
spell_umbralBlaze: {
|
||||
id: 'spell_umbralBlaze',
|
||||
name: 'Umbral Blaze',
|
||||
description: 'Grants the ability to cast Umbral Blaze (55 blackflame damage, curse+burn)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 210,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'umbralBlaze' }
|
||||
},
|
||||
spell_hellfireCurse: {
|
||||
id: 'spell_hellfireCurse',
|
||||
name: 'Hellfire Curse',
|
||||
description: 'Grants the ability to cast Hellfire Curse (140 blackflame damage, burn+curse)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 410,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'hellfireCurse' }
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
// ─── New Exotic Spell Effects ──────────────────────────────────
|
||||
// Soul, Time, Plasma spells - Tier 4 exotic elements
|
||||
|
||||
import type { EnchantmentEffectDef } from './types';
|
||||
import { ALL_CASTER } from './types';
|
||||
|
||||
export const SOUL_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_soulPierce: {
|
||||
id: 'spell_soulPierce',
|
||||
name: 'Soul Pierce',
|
||||
description: 'Grants the ability to cast Soul Pierce (350 soul damage, defense bypass)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 500,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'soulPierce' }
|
||||
},
|
||||
spell_spiritBlast: {
|
||||
id: 'spell_spiritBlast',
|
||||
name: 'Spirit Blast',
|
||||
description: 'Grants the ability to cast Spirit Blast (550 soul damage, full defense bypass)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 650,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'spiritBlast' }
|
||||
},
|
||||
};
|
||||
|
||||
export const TIME_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_temporalWarp: {
|
||||
id: 'spell_temporalWarp',
|
||||
name: 'Temporal Warp',
|
||||
description: 'Grants the ability to cast Temporal Warp (280 time damage, slow+dodge reduction)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 520,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'temporalWarp' }
|
||||
},
|
||||
spell_chronoStasis: {
|
||||
id: 'spell_chronoStasis',
|
||||
name: 'Chrono Stasis',
|
||||
description: 'Grants the ability to cast Chrono Stasis (500 time damage, mage lock)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 680,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'chronoStasis' }
|
||||
},
|
||||
};
|
||||
|
||||
export const PLASMA_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_plasmaBolt: {
|
||||
id: 'spell_plasmaBolt',
|
||||
name: 'Plasma Bolt',
|
||||
description: 'Grants the ability to cast Plasma Bolt (320 plasma damage, raw damage)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 510,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'plasmaBolt' }
|
||||
},
|
||||
spell_plasmaStorm: {
|
||||
id: 'spell_plasmaStorm',
|
||||
name: 'Plasma Storm',
|
||||
description: 'Grants the ability to cast Plasma Storm (600 plasma damage, AoE raw damage)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 660,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'plasmaStorm' }
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
// ─── Frost Spell Effects ──────────────────────────────────────
|
||||
// Frost spells - Air + Water compound, freeze/slow focus
|
||||
|
||||
import type { EnchantmentEffectDef } from './types';
|
||||
import { ALL_CASTER } from './types';
|
||||
|
||||
export const FROST_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_frostBite: {
|
||||
id: 'spell_frostBite',
|
||||
name: 'Frost Bite',
|
||||
description: 'Grants the ability to cast Frost Bite (10 frost damage, freeze)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 78,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'frostBite' }
|
||||
},
|
||||
spell_iceShard: {
|
||||
id: 'spell_iceShard',
|
||||
name: 'Ice Shard',
|
||||
description: 'Grants the ability to cast Ice Shard (18 frost damage, freeze)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 95,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'iceShard' }
|
||||
},
|
||||
spell_frostNova: {
|
||||
id: 'spell_frostNova',
|
||||
name: 'Frost Nova',
|
||||
description: 'Grants the ability to cast Frost Nova (30 frost damage, AoE slow+freeze)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 165,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'frostNova' }
|
||||
},
|
||||
spell_glacialSpike: {
|
||||
id: 'spell_glacialSpike',
|
||||
name: 'Glacial Spike',
|
||||
description: 'Grants the ability to cast Glacial Spike (45 frost damage, freeze)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 200,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'glacialSpike' }
|
||||
},
|
||||
spell_absoluteZero: {
|
||||
id: 'spell_absoluteZero',
|
||||
name: 'Absolute Zero',
|
||||
description: 'Grants the ability to cast Absolute Zero (120 frost damage, AoE freeze+slow)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 380,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'absoluteZero' }
|
||||
},
|
||||
};
|
||||
@@ -13,6 +13,12 @@ import { SAND_SPELL_EFFECTS } from './sand-spells';
|
||||
import { TIER2_SPELL_EFFECTS } from './tier2-spells';
|
||||
import { TIER3_SPELL_EFFECTS } from './tier3-spells';
|
||||
import { LEGENDARY_SPELL_EFFECTS } from './legendary-spells';
|
||||
import { FROST_SPELL_EFFECTS } from './frost-spells';
|
||||
import { BLACKFLAME_SPELL_EFFECTS } from './blackflame-spells';
|
||||
import { RADIANTFLAMES_SPELL_EFFECTS } from './radiantflames-spells';
|
||||
import { MIASMA_SPELL_EFFECTS } from './miasma-spells';
|
||||
import { SHADOWGLASS_SPELL_EFFECTS } from './shadowglass-spells';
|
||||
import { SOUL_SPELL_EFFECTS, TIME_SPELL_EFFECTS, PLASMA_SPELL_EFFECTS } from './exotic-new-spells';
|
||||
|
||||
// Combine all spell effects into SPELL_EFFECTS
|
||||
export const SPELL_EFFECTS = {
|
||||
@@ -23,4 +29,12 @@ export const SPELL_EFFECTS = {
|
||||
...TIER2_SPELL_EFFECTS,
|
||||
...TIER3_SPELL_EFFECTS,
|
||||
...LEGENDARY_SPELL_EFFECTS,
|
||||
...FROST_SPELL_EFFECTS,
|
||||
...BLACKFLAME_SPELL_EFFECTS,
|
||||
...RADIANTFLAMES_SPELL_EFFECTS,
|
||||
...MIASMA_SPELL_EFFECTS,
|
||||
...SHADOWGLASS_SPELL_EFFECTS,
|
||||
...SOUL_SPELL_EFFECTS,
|
||||
...TIME_SPELL_EFFECTS,
|
||||
...PLASMA_SPELL_EFFECTS,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// ─── Miasma Spell Effects ───────────────────────────────────────
|
||||
// Miasma spells - Air + Death compound, toxic/plague/armor corrosion focus
|
||||
|
||||
import type { EnchantmentEffectDef } from './types';
|
||||
import { ALL_CASTER } from './types';
|
||||
|
||||
export const MIASMA_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_toxicCloud: {
|
||||
id: 'spell_toxicCloud',
|
||||
name: 'Toxic Cloud',
|
||||
description: 'Grants the ability to cast Toxic Cloud (9 miasma damage, poison)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 76,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'toxicCloud' }
|
||||
},
|
||||
spell_plagueTouch: {
|
||||
id: 'spell_plagueTouch',
|
||||
name: 'Plague Touch',
|
||||
description: 'Grants the ability to cast Plague Touch (16 miasma damage, poison+corrode)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 100,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'plagueTouch' }
|
||||
},
|
||||
spell_miasmaBurst: {
|
||||
id: 'spell_miasmaBurst',
|
||||
name: 'Miasma Burst',
|
||||
description: 'Grants the ability to cast Miasma Burst (32 miasma damage, AoE poison+corrode)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 165,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'miasmaBurst' }
|
||||
},
|
||||
spell_pestilence: {
|
||||
id: 'spell_pestilence',
|
||||
name: 'Pestilence',
|
||||
description: 'Grants the ability to cast Pestilence (48 miasma damage, poison+corrode)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 195,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'pestilence' }
|
||||
},
|
||||
spell_deathMiasma: {
|
||||
id: 'spell_deathMiasma',
|
||||
name: 'Death Miasma',
|
||||
description: 'Grants the ability to cast Death Miasma (130 miasma damage, AoE poison+corrode)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 390,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'deathMiasma' }
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
// ─── Radiant Flames Spell Effects ──────────────────────────────
|
||||
// Radiant Flames spells - Light + Fire compound, blinding/heavy DoT focus
|
||||
|
||||
import type { EnchantmentEffectDef } from './types';
|
||||
import { ALL_CASTER } from './types';
|
||||
|
||||
export const RADIANTFLAMES_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_radiantBurst: {
|
||||
id: 'spell_radiantBurst',
|
||||
name: 'Radiant Burst',
|
||||
description: 'Grants the ability to cast Radiant Burst (14 radiantflames damage, burn+blind)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 85,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'radiantBurst' }
|
||||
},
|
||||
spell_holyFlame: {
|
||||
id: 'spell_holyFlame',
|
||||
name: 'Holy Flame',
|
||||
description: 'Grants the ability to cast Holy Flame (22 radiantflames damage, burn)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 108,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'holyFlame' }
|
||||
},
|
||||
spell_blindingSun: {
|
||||
id: 'spell_blindingSun',
|
||||
name: 'Blinding Sun',
|
||||
description: 'Grants the ability to cast Blinding Sun (40 radiantflames damage, AoE blind+burn)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 180,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'blindingSun' }
|
||||
},
|
||||
spell_purifyingFire: {
|
||||
id: 'spell_purifyingFire',
|
||||
name: 'Purifying Fire',
|
||||
description: 'Grants the ability to cast Purifying Fire (58 radiantflames damage, heavy burn)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 215,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'purifyingFire' }
|
||||
},
|
||||
spell_supernovaBlast: {
|
||||
id: 'spell_supernovaBlast',
|
||||
name: 'Supernova Blast',
|
||||
description: 'Grants the ability to cast Supernova Blast (150 radiantflames damage, blind+burn)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 420,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'supernovaBlast' }
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
// ─── Shadow Glass Spell Effects ──────────────────────────────────
|
||||
// Shadow Glass spells - Earth + Dark compound, spike/armor pierce focus
|
||||
|
||||
import type { EnchantmentEffectDef } from './types';
|
||||
import { ALL_CASTER } from './types';
|
||||
|
||||
export const SHADOWGLASS_SPELL_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
spell_shadowSpike: {
|
||||
id: 'spell_shadowSpike',
|
||||
name: 'Shadow Spike',
|
||||
description: 'Grants the ability to cast Shadow Spike (15 shadowglass damage, armor pierce)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 88,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'shadowSpike' }
|
||||
},
|
||||
spell_darkShard: {
|
||||
id: 'spell_darkShard',
|
||||
name: 'Dark Shard',
|
||||
description: 'Grants the ability to cast Dark Shard (24 shadowglass damage, armor pierce)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 115,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'darkShard' }
|
||||
},
|
||||
spell_obsidianStorm: {
|
||||
id: 'spell_obsidianStorm',
|
||||
name: 'Obsidian Storm',
|
||||
description: 'Grants the ability to cast Obsidian Storm (42 shadowglass damage, AoE armor pierce)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 185,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'obsidianStorm' }
|
||||
},
|
||||
spell_voidBlade: {
|
||||
id: 'spell_voidBlade',
|
||||
name: 'Void Blade',
|
||||
description: 'Grants the ability to cast Void Blade (60 shadowglass damage, high armor pierce)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 225,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'voidBlade' }
|
||||
},
|
||||
spell_shadowGlassCataclysm: {
|
||||
id: 'spell_shadowGlassCataclysm',
|
||||
name: 'Shadow Glass Cataclysm',
|
||||
description: 'Grants the ability to cast Shadow Glass Cataclysm (155 shadowglass damage, armor pierce)',
|
||||
category: 'spell',
|
||||
baseCapacityCost: 415,
|
||||
maxStacks: 1,
|
||||
allowedEquipmentCategories: ALL_CASTER,
|
||||
effect: { type: 'spell', spellId: 'shadowGlassCataclysm' }
|
||||
},
|
||||
};
|
||||
@@ -41,7 +41,20 @@ export const MANA_TYPE_LABELS: Record<string, string> = {
|
||||
earth: '⛰️ Earth',
|
||||
light: '☀️ Light',
|
||||
dark: '🌑 Dark',
|
||||
death: '💀 Death',
|
||||
transference: '🔗 Transference',
|
||||
metal: '🔩 Metal',
|
||||
crystal: '💎 Crystal',
|
||||
sand: '🏜️ Sand',
|
||||
lightning: '⚡ Lightning',
|
||||
frost: '❄️ Frost',
|
||||
blackflame: '🌋 BlackFlame',
|
||||
radiantflames: '🌟 Radiant Flames',
|
||||
miasma: '☁️ Miasma',
|
||||
shadowglass: '🖤 Shadow Glass',
|
||||
crystal: '💎 Crystal',
|
||||
stellar: '⭐ Stellar',
|
||||
void: '🕳️ Void',
|
||||
soul: '💫 Soul',
|
||||
time: '⏱️ Time',
|
||||
plasma: '⚡ Plasma',
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// ─── Static Guardian Definitions ─────────────────────────────────────────────────
|
||||
// New 9-tier progression for guardians:
|
||||
// Expanded guardian progression:
|
||||
//
|
||||
// Tier 1: Base Elements (floors 10–80)
|
||||
// Fire, Water, Air, Earth, Light, Dark, Death, Transference
|
||||
// Tier 2: Composite Elements (floors 90–120)
|
||||
// Metal, Sand, Lightning
|
||||
// Tier 3: Composite + Components (floors 130–160)
|
||||
// Tier 4: Exotic Elements (floors 170–200)
|
||||
// Tier 2: Composite Elements (floors 90–160)
|
||||
// Metal, Sand, Lightning, Frost, BlackFlame, Radiant Flames, Miasma, Shadow Glass
|
||||
// Tier 3: Exotic Elements (floors 170–240)
|
||||
// Crystal, Stellar, Void, Soul, Time, Plasma + convergence guards
|
||||
//
|
||||
// Floors 210+ are procedurally generated in guardian-encounters.ts.
|
||||
// Floors 250+ are procedurally generated in guardian-encounters.ts.
|
||||
|
||||
import type { GuardianDef } from '../types';
|
||||
import { resolveMultiUnlockChain } from '../utils/guardian-utils';
|
||||
@@ -156,7 +156,9 @@ const TIER1: Record<number, GuardianDef> = {
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 2: Composite Elements (Floors 90–120)
|
||||
// TIER 2: Composite Elements (Floors 90–160) — 8 guardians
|
||||
// Original: Metal, Sand, Lightning
|
||||
// New: Frost, BlackFlame, Radiant Flames, Miasma, Shadow Glass
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
const TIER2: Record<number, GuardianDef> = {
|
||||
@@ -187,60 +189,60 @@ const TIER2: Record<number, GuardianDef> = {
|
||||
[{ type: 'chain', value: 2 }],
|
||||
{ shield: 800, shieldRegen: 20, barrier: 0.05, barrierRegen: 0.01 },
|
||||
),
|
||||
120: mk(120, '', ['frost'], '#A8D8EA', 0.28, 4.25,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Frost damage' },
|
||||
{ type: 'castingSpeed', value: 10, desc: '+10% casting speed' },
|
||||
],
|
||||
'Frost spells freeze enemies, reducing their attack speed by 20%',
|
||||
[{ type: 'freeze', value: 0.2 }],
|
||||
{ shield: 900, shieldRegen: 22, barrier: 0.08, barrierRegen: 0.02 },
|
||||
),
|
||||
130: mk(130, '', ['blackflame'], '#8B2500', 0.32, 4.5,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 20, desc: '+20% BlackFlame damage' },
|
||||
{ type: 'rawDamage', value: 10, desc: '+10% raw damage' },
|
||||
],
|
||||
'BlackFlame spells apply a curse that reduces enemy resistances by 15%',
|
||||
[{ type: 'curse', value: 0.15 }, { type: 'burn', value: 0.15 }],
|
||||
{ shield: 1000, shieldRegen: 25, healthRegen: 5, healthRegenIsPercent: true },
|
||||
),
|
||||
140: mk(140, '', ['radiantflames'], '#FFAA33', 0.25, 4.75,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Radiant Flames damage' },
|
||||
{ type: 'insightGain', value: 10, desc: '+10% insight gain' },
|
||||
],
|
||||
'Radiant Flames spells blind enemies, reducing their accuracy and damage by 15%',
|
||||
[{ type: 'blind', value: 0.15 }, { type: 'burn', value: 0.1 }],
|
||||
{ barrier: 0.12, barrierRegen: 0.03, healthRegen: 6, healthRegenIsPercent: true },
|
||||
),
|
||||
150: mk(150, '', ['miasma'], '#6B8E23', 0.28, 5.0,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Miasma damage' },
|
||||
{ type: 'maxMana', value: 200, desc: '+200 max mana' },
|
||||
],
|
||||
'Miasma spells corrode armor and spread plague in swarm rooms',
|
||||
[{ type: 'corrosion', value: 0.2 }, { type: 'poison', value: 0.15 }],
|
||||
{ shield: 1100, shieldRegen: 28, barrier: 0.05, barrierRegen: 0.01 },
|
||||
),
|
||||
160: mk(160, '', ['shadowglass'], '#2C2C54', 0.33, 5.25,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 20, desc: '+20% Shadow Glass damage' },
|
||||
{ type: 'critDamage', value: 15, desc: '+15% crit damage' },
|
||||
],
|
||||
'Shadow Glass spells create piercing spikes ignoring 30% armor',
|
||||
[{ type: 'armor_pierce', value: 0.3 }, { type: 'pierce', value: 0.25 }],
|
||||
{ shield: 1200, shieldRegen: 30, healthRegen: 5, healthRegenIsPercent: true },
|
||||
),
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 3: Composite + Their Components (Floors 130–160)
|
||||
// TIER 3: Exotic Elements (Floors 170–240) — 6 exotics + 2 convergence guards
|
||||
// Original: Crystal, Stellar, Void (floors 170-200)
|
||||
// New: Soul, Time, Plasma + a convergence guardian
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
const TIER3: Record<number, GuardianDef> = {
|
||||
130: mk(130, '', ['metal', 'fire', 'earth'], '#D4A574', 0.35, 4.5,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 20, desc: '+20% Metal damage' },
|
||||
{ type: 'elementalDamage', value: 10, desc: '+10% Fire damage' },
|
||||
{ type: 'elementalDamage', value: 10, desc: '+10% Earth damage' },
|
||||
],
|
||||
'Tri-aspect: Metal, Fire, and Earth spells gain +10% effectiveness',
|
||||
[{ type: 'armor_pierce', value: 0.25 }, { type: 'burn', value: 0.1 }],
|
||||
{ shield: 1000, shieldRegen: 25, barrier: 0.05, barrierRegen: 0.01 },
|
||||
),
|
||||
140: mk(140, '', ['sand', 'earth', 'water'], '#C9B896', 0.30, 4.75,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 20, desc: '+20% Sand damage' },
|
||||
{ type: 'elementalDamage', value: 10, desc: '+10% Earth damage' },
|
||||
{ type: 'elementalDamage', value: 10, desc: '+10% Water damage' },
|
||||
],
|
||||
'Tri-aspect: Sand, Earth, and Water spells gain +10% effectiveness',
|
||||
[{ type: 'slow', value: 0.3 }, { type: 'armor_pierce', value: 0.15 }],
|
||||
{ barrier: 0.12, barrierRegen: 0.03, healthRegen: 6, healthRegenIsPercent: true },
|
||||
),
|
||||
150: mk(150, '', ['lightning', 'fire', 'air'], '#FFE066', 0.28, 5.0,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 20, desc: '+20% Lightning damage' },
|
||||
{ type: 'elementalDamage', value: 10, desc: '+10% Fire damage' },
|
||||
{ type: 'elementalDamage', value: 10, desc: '+10% Air damage' },
|
||||
],
|
||||
'Tri-aspect: Lightning, Fire, and Air spells gain +10% effectiveness',
|
||||
[{ type: 'chain', value: 2 }, { type: 'cast_speed', value: 0.1 }],
|
||||
{ shield: 1200, shieldRegen: 30, healthRegen: 5, healthRegenIsPercent: true },
|
||||
),
|
||||
160: mk(160, '', ['metal', 'lightning', 'fire', 'earth', 'air'], '#E8C872', 0.35, 5.25,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Metal damage' },
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Lightning damage' },
|
||||
{ type: 'rawDamage', value: 10, desc: '+10% raw damage' },
|
||||
],
|
||||
'Fused aspects: Lightning spells gain +20% armor pierce; Metal spells chain once',
|
||||
[{ type: 'armor_pierce', value: 0.3 }, { type: 'chain', value: 1 }],
|
||||
{ shield: 1500, shieldRegen: 40, barrier: 0.08, barrierRegen: 0.02, healthRegen: 7, healthRegenIsPercent: true },
|
||||
),
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 4: Exotic Elements (Floors 170–200)
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
const TIER4: Record<number, GuardianDef> = {
|
||||
170: mk(170, '', ['crystal'], '#85C1E9', 0.35, 5.5,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 20, desc: '+20% Crystal damage' },
|
||||
@@ -270,15 +272,52 @@ const TIER4: Record<number, GuardianDef> = {
|
||||
[{ type: 'resist_ignore', value: 0.4 }],
|
||||
{ shield: 2500, shieldRegen: 60, barrier: 0.10, barrierRegen: 0.02, healthRegen: 6, healthRegenIsPercent: true },
|
||||
),
|
||||
200: mk(200, '', ['crystal', 'stellar', 'void'], '#B39DDB', 0.40, 7.0,
|
||||
200: mk(200, '', ['soul'], '#E8D5F5', 0.30, 7.0,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 25, desc: '+25% Soul damage' },
|
||||
{ type: 'rawDamage', value: 20, desc: '+20% raw damage' },
|
||||
],
|
||||
'Soul spells bypass all defenses and shields',
|
||||
[{ type: 'defense_pierce', value: 0.5 }, { type: 'mana_drain', value: 0.2 }],
|
||||
{ shield: 2800, shieldRegen: 55, barrier: 0.08, barrierRegen: 0.02 },
|
||||
),
|
||||
210: mk(210, '', ['time'], '#C5B99A', 0.32, 7.5,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 20, desc: '+20% Time damage' },
|
||||
{ type: 'castingSpeed', value: 20, desc: '+20% casting speed' },
|
||||
],
|
||||
'Time spells slow enemies by 30% and reduce dodge by 20%',
|
||||
[{ type: 'slow', value: 0.3 }, { type: 'temporal_snap', value: 0.15 }],
|
||||
{ barrier: 0.15, barrierRegen: 0.04, healthRegen: 9, healthRegenIsPercent: true },
|
||||
),
|
||||
220: mk(220, '', ['plasma'], '#FF6B9D', 0.28, 8.0,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 25, desc: '+25% Plasma damage' },
|
||||
{ type: 'manaRegen', value: 2.5, desc: '+2.5 mana regen' },
|
||||
],
|
||||
'Plasma spells chain to 3 targets with 30% damage each',
|
||||
[{ type: 'chain', value: 3 }, { type: 'burn', value: 0.1 }],
|
||||
{ shield: 3200, shieldRegen: 70, barrier: 0.10, barrierRegen: 0.02 },
|
||||
),
|
||||
230: mk(230, '', ['crystal', 'stellar', 'void'], '#B39DDB', 0.40, 8.5,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Crystal damage' },
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Stellar damage' },
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Void damage' },
|
||||
],
|
||||
'Exotic convergence: All exotic spells gain +15% effectiveness',
|
||||
[{ type: 'reflect', value: 0.1 }, { type: 'resist_ignore', value: 0.1 }],
|
||||
{ shield: 3000, shieldRegen: 80, barrier: 0.12, barrierRegen: 0.03, healthRegen: 10, healthRegenIsPercent: true },
|
||||
'Primordial gaze: Crystal/Stellar/Void spells gain +20% effectiveness',
|
||||
[{ type: 'reflect', value: 0.1 }, { type: 'resist_ignore', value: 0.15 }],
|
||||
{ shield: 3500, shieldRegen: 90, barrier: 0.12, barrierRegen: 0.03 },
|
||||
),
|
||||
240: mk(240, '', ['soul', 'time', 'plasma'], '#D5A0E0', 0.42, 9.0,
|
||||
[
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Soul damage' },
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Time damage' },
|
||||
{ type: 'elementalDamage', value: 15, desc: '+15% Plasma damage' },
|
||||
],
|
||||
'Astral convergence: Soul/Time/Plasma spells gain +20% effectiveness',
|
||||
[{ type: 'defense_pierce', value: 0.2 }, { type: 'chain', value: 1 }],
|
||||
{ shield: 3800, shieldRegen: 100, barrier: 0.14, barrierRegen: 0.03, healthRegen: 12, healthRegenIsPercent: true },
|
||||
),
|
||||
};
|
||||
|
||||
@@ -290,7 +329,6 @@ const STATIC_GUARDIANS: Record<number, GuardianDef> = {
|
||||
...TIER1,
|
||||
...TIER2,
|
||||
...TIER3,
|
||||
...TIER4,
|
||||
};
|
||||
|
||||
export { STATIC_GUARDIANS, TIER1, TIER2, TIER3, TIER4 };
|
||||
export { STATIC_GUARDIANS, TIER1, TIER2, TIER3 };
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
//
|
||||
// Guardian progression (9 tiers):
|
||||
// Tier 1: Base Elements (static, floors 10–80, guardian-data.ts)
|
||||
// Tier 2: Composite Elements (static, floors 90–120, guardian-data.ts)
|
||||
// Tier 3: Composite+Components (static, floors 130–160, guardian-data.ts)
|
||||
// Tier 4: Exotic Elements (static, floors 170–200, guardian-data.ts)
|
||||
// Tier 5: Dual Element Pairs (dynamic, floors 210–240, this file)
|
||||
// Tier 6: Dual Comp+Components (dynamic, floors 250–290, this file)
|
||||
// Tier 7: Exotic+Components (dynamic, floors 300–340, this file)
|
||||
// Tier 8: Exotic+Comp+Components (dynamic, floors 350–390, this file)
|
||||
// Tier 9: Full Fusion (dynamic, floors 400+, this file)
|
||||
// Tier 2: Composite Elements (static, floors 90–160, guardian-data.ts)
|
||||
// Tier 3: Exotic Elements (static, floors 170–240, guardian-data.ts)
|
||||
// Tier 4: Dual Element Pairs (dynamic, floors 250–280, this file)
|
||||
// Tier 5: Dual Comp+Components (dynamic, floors 290–330, this file)
|
||||
// Tier 6: Exotic+Components (dynamic, floors 340–380, this file)
|
||||
// Tier 7: Exotic+Comp+Components (dynamic, floors 390–430, this file)
|
||||
// Tier 8: Full Fusion (dynamic, floors 440+, this file)
|
||||
//
|
||||
// All lookups go through getGuardianForFloor() which merges static + procedural.
|
||||
|
||||
@@ -35,6 +34,14 @@ const GUARDIAN_PREFIXES: Record<string, string[]> = {
|
||||
crystal: ['Prism', 'Gemma', 'Crystal', 'Shard', 'Facet'],
|
||||
stellar: ['Astro', 'Stella', 'Nova', 'Cosmo', 'Lumin'],
|
||||
void: ['Void', 'Abyss', 'Null', 'Nihil', 'Obliv'],
|
||||
frost: ['Glac', 'Cryo', 'Bore', 'Rime', 'Frost'],
|
||||
blackflame: ['Umbra', 'Cinder', 'Ash', 'Smoke', 'Ember'],
|
||||
radiantflames: ['Sol', 'Radi', 'Aura', 'Glow', 'Flare'],
|
||||
miasma: ['Mias', 'Tox', 'Plague', 'Virus', 'Blight'],
|
||||
shadowglass: ['Shade', 'Obsid', 'Night', 'Gloom', 'Void'],
|
||||
soul: ['Psy', 'Anima', 'Spirit', 'Ghost', 'Wraith'],
|
||||
time: ['Chron', 'Temp', 'Epoch', 'Aeon', 'Hour'],
|
||||
plasma: ['Ion', 'Plasm', 'Spark', 'Arc', 'Flux'],
|
||||
};
|
||||
|
||||
const GUARDIAN_TITLES: string[] = [
|
||||
@@ -67,8 +74,8 @@ export function getGuardianHP(floor: number): number {
|
||||
// ─── Tier Helpers ───────────────────────────────────────────────────────────────
|
||||
|
||||
const BASE_ELEMENTS = ['fire', 'water', 'air', 'earth', 'light', 'dark', 'death'];
|
||||
const COMPOSITE_ELEMENTS = ['metal', 'sand', 'lightning'];
|
||||
const EXOTIC_ELEMENTS = ['crystal', 'stellar', 'void'];
|
||||
const COMPOSITE_ELEMENTS = ['metal', 'sand', 'lightning', 'frost', 'blackflame', 'radiantflames', 'miasma', 'shadowglass'];
|
||||
const EXOTIC_ELEMENTS = ['crystal', 'stellar', 'void', 'soul', 'time', 'plasma'];
|
||||
|
||||
/** Generate boon elements (max 3) */
|
||||
function makeBoons(elements: string[], floor: number): GuardianBoon[] {
|
||||
@@ -80,16 +87,16 @@ function makeBoons(elements: string[], floor: number): GuardianBoon[] {
|
||||
}
|
||||
|
||||
function getTier(floor: number): number {
|
||||
if (floor >= 400) return 9;
|
||||
if (floor >= 350) return 8;
|
||||
if (floor >= 300) return 7;
|
||||
if (floor >= 250) return 6;
|
||||
if (floor >= 210) return 5;
|
||||
if (floor >= 440) return 8;
|
||||
if (floor >= 390) return 7;
|
||||
if (floor >= 340) return 6;
|
||||
if (floor >= 290) return 5;
|
||||
if (floor >= 250) return 4;
|
||||
return 0; // Static tiers
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 5: Dual Element Pairs (Floors 210–240)
|
||||
// TIER 4: Dual Element Pairs (Floors 250–280)
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
const DUAL_PAIRS: [string, string][] = [
|
||||
@@ -104,23 +111,23 @@ const DUAL_PAIRS: [string, string][] = [
|
||||
['earth', 'death'],
|
||||
];
|
||||
|
||||
function getTier5Guardian(floor: number): GuardianDef {
|
||||
const idx = Math.floor((floor - 210) / 10) % DUAL_PAIRS.length;
|
||||
function getTier4Guardian(floor: number): GuardianDef {
|
||||
const idx = Math.floor((floor - 250) / 10) % DUAL_PAIRS.length;
|
||||
const [el1, el2] = DUAL_PAIRS[idx];
|
||||
const elements = [el1, el2];
|
||||
const hpVal = getGuardianHP(floor);
|
||||
const armor = Math.min(0.5, 0.30 + (floor - 210) * 0.003);
|
||||
const armor = Math.min(0.5, 0.30 + (floor - 250) * 0.003);
|
||||
|
||||
return {
|
||||
name: '',
|
||||
element: elements,
|
||||
hp: hpVal,
|
||||
pact: 7.5 + (floor - 210) * 0.05,
|
||||
pact: 7.5 + (floor - 250) * 0.05,
|
||||
color: blendColors(el1, el2),
|
||||
armor,
|
||||
boons: makeBoons(elements, floor),
|
||||
pactCost: Math.floor(hpVal * 0.3 + hpVal * armor * 0.5),
|
||||
pactTime: 20 + Math.floor((floor - 210) / 10),
|
||||
pactTime: 20 + Math.floor((floor - 250) / 10),
|
||||
uniquePerk: `Dual-aspect: ${el1} and ${el2} spells gain +20% effectiveness`,
|
||||
power: Math.floor(hpVal * 0.5),
|
||||
effects: [
|
||||
@@ -129,16 +136,16 @@ function getTier5Guardian(floor: number): GuardianDef {
|
||||
],
|
||||
signingCost: {
|
||||
mana: Math.floor(hpVal * 0.3),
|
||||
time: 20 + Math.floor((floor - 210) / 10),
|
||||
time: 20 + Math.floor((floor - 250) / 10),
|
||||
},
|
||||
unlocksMana: resolveMultiUnlockChain(elements),
|
||||
damageMultiplier: 3.5 + (floor - 210) * 0.02,
|
||||
insightMultiplier: 3.0 + (floor - 210) * 0.01,
|
||||
damageMultiplier: 3.5 + (floor - 250) * 0.02,
|
||||
insightMultiplier: 3.0 + (floor - 250) * 0.01,
|
||||
};
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 6: Dual Composite + Components (Floors 250–290)
|
||||
// TIER 5: Dual Composite + Components (Floors 290–330)
|
||||
// Pairs of composites with all their base components.
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -146,25 +153,28 @@ const DUAL_COMP_PAIRS: [string, string][] = [
|
||||
['metal', 'sand'],
|
||||
['metal', 'lightning'],
|
||||
['sand', 'lightning'],
|
||||
['frost', 'blackflame'],
|
||||
['radiantflames', 'miasma'],
|
||||
['shadowglass', 'frost'],
|
||||
];
|
||||
|
||||
function getTier6Guardian(floor: number): GuardianDef {
|
||||
const idx = Math.floor((floor - 250) / 10) % DUAL_COMP_PAIRS.length;
|
||||
function getTier5Guardian(floor: number): GuardianDef {
|
||||
const idx = Math.floor((floor - 290) / 10) % DUAL_COMP_PAIRS.length;
|
||||
const [comp1, comp2] = DUAL_COMP_PAIRS[idx];
|
||||
const elements = resolveMultiUnlockChain([comp1, comp2]);
|
||||
const hpVal = getGuardianHP(floor);
|
||||
const armor = Math.min(0.55, 0.35 + (floor - 250) * 0.003);
|
||||
const armor = Math.min(0.55, 0.35 + (floor - 290) * 0.003);
|
||||
|
||||
return {
|
||||
name: '',
|
||||
element: elements,
|
||||
hp: hpVal,
|
||||
pact: 9.0 + (floor - 250) * 0.05,
|
||||
pact: 9.0 + (floor - 290) * 0.05,
|
||||
color: blendColors(comp1, comp2),
|
||||
armor,
|
||||
boons: makeBoons([comp1, comp2], floor),
|
||||
pactCost: Math.floor(hpVal * 0.3 + hpVal * armor * 0.5),
|
||||
pactTime: 24 + Math.floor((floor - 250) / 10),
|
||||
pactTime: 24 + Math.floor((floor - 290) / 10),
|
||||
uniquePerk: `Fusion twin-aspect: ${comp1} and ${comp2} spells gain +25% effectiveness`,
|
||||
power: Math.floor(hpVal * 0.55),
|
||||
effects: [
|
||||
@@ -173,36 +183,36 @@ function getTier6Guardian(floor: number): GuardianDef {
|
||||
],
|
||||
signingCost: {
|
||||
mana: Math.floor(hpVal * 0.35),
|
||||
time: 24 + Math.floor((floor - 250) / 10),
|
||||
time: 24 + Math.floor((floor - 290) / 10),
|
||||
},
|
||||
unlocksMana: resolveMultiUnlockChain(elements),
|
||||
damageMultiplier: 4.0 + (floor - 250) * 0.02,
|
||||
insightMultiplier: 3.5 + (floor - 250) * 0.01,
|
||||
damageMultiplier: 4.0 + (floor - 290) * 0.02,
|
||||
insightMultiplier: 3.5 + (floor - 290) * 0.01,
|
||||
};
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 7: Exotic + Components (Floors 300–340)
|
||||
// TIER 6: Exotic + Components (Floors 340–380)
|
||||
// Each exotic element paired with all its component base elements.
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function getTier7Guardian(floor: number): GuardianDef {
|
||||
const exoticIdx = Math.floor((floor - 300) / 10) % EXOTIC_ELEMENTS.length;
|
||||
function getTier6Guardian(floor: number): GuardianDef {
|
||||
const exoticIdx = Math.floor((floor - 340) / 10) % EXOTIC_ELEMENTS.length;
|
||||
const exoticEl = EXOTIC_ELEMENTS[exoticIdx];
|
||||
const chain = resolveMultiUnlockChain([exoticEl]);
|
||||
const hpVal = getGuardianHP(floor);
|
||||
const armor = Math.min(0.6, 0.40 + (floor - 300) * 0.003);
|
||||
const armor = Math.min(0.6, 0.40 + (floor - 340) * 0.003);
|
||||
|
||||
return {
|
||||
name: '',
|
||||
element: chain,
|
||||
hp: hpVal,
|
||||
pact: 10.5 + (floor - 300) * 0.05,
|
||||
pact: 10.5 + (floor - 340) * 0.05,
|
||||
color: '#B8A9C9',
|
||||
armor,
|
||||
boons: [makeBoons([exoticEl], floor)[0]],
|
||||
pactCost: Math.floor(hpVal * 0.35 + hpVal * armor * 0.5),
|
||||
pactTime: 28 + Math.floor((floor - 300) / 10),
|
||||
pactTime: 28 + Math.floor((floor - 340) / 10),
|
||||
uniquePerk: `Exotic resonance: ${exoticEl} spells gain +30% effectiveness`,
|
||||
power: Math.floor(hpVal * 0.6),
|
||||
effects: [
|
||||
@@ -211,38 +221,38 @@ function getTier7Guardian(floor: number): GuardianDef {
|
||||
],
|
||||
signingCost: {
|
||||
mana: Math.floor(hpVal * 0.35),
|
||||
time: 28 + Math.floor((floor - 300) / 10),
|
||||
time: 28 + Math.floor((floor - 340) / 10),
|
||||
},
|
||||
unlocksMana: chain,
|
||||
damageMultiplier: 4.5 + (floor - 300) * 0.02,
|
||||
insightMultiplier: 4.0 + (floor - 300) * 0.01,
|
||||
damageMultiplier: 4.5 + (floor - 340) * 0.02,
|
||||
insightMultiplier: 4.0 + (floor - 340) * 0.01,
|
||||
};
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 8: Exotic + Composite + Components (Floors 350–390)
|
||||
// TIER 7: Exotic + Composite + Components (Floors 390–430)
|
||||
// One exotic + one composite + all base elements.
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function getTier8Guardian(floor: number): GuardianDef {
|
||||
const exoticIdx = Math.floor((floor - 350) / 10) % EXOTIC_ELEMENTS.length;
|
||||
const compIdx = Math.floor((floor - 350) / 10) % COMPOSITE_ELEMENTS.length;
|
||||
function getTier7Guardian(floor: number): GuardianDef {
|
||||
const exoticIdx = Math.floor((floor - 390) / 10) % EXOTIC_ELEMENTS.length;
|
||||
const compIdx = Math.floor((floor - 390) / 10) % COMPOSITE_ELEMENTS.length;
|
||||
const exoticEl = EXOTIC_ELEMENTS[exoticIdx];
|
||||
const compEl = COMPOSITE_ELEMENTS[compIdx];
|
||||
const elements = resolveMultiUnlockChain([exoticEl, compEl]);
|
||||
const hpVal = getGuardianHP(floor);
|
||||
const armor = Math.min(0.65, 0.45 + (floor - 350) * 0.003);
|
||||
const armor = Math.min(0.65, 0.45 + (floor - 390) * 0.003);
|
||||
|
||||
return {
|
||||
name: '',
|
||||
element: elements,
|
||||
hp: hpVal,
|
||||
pact: 12.0 + (floor - 350) * 0.05,
|
||||
pact: 12.0 + (floor - 390) * 0.05,
|
||||
color: '#9B72AA',
|
||||
armor,
|
||||
boons: makeBoons([exoticEl, compEl], floor),
|
||||
pactCost: Math.floor(hpVal * 0.4 + hpVal * armor * 0.5),
|
||||
pactTime: 32 + Math.floor((floor - 350) / 10),
|
||||
pactTime: 32 + Math.floor((floor - 390) / 10),
|
||||
uniquePerk: `Primordial fusion: ${exoticEl} and ${compEl} spells gain +25% effectiveness`,
|
||||
power: Math.floor(hpVal * 0.65),
|
||||
effects: [
|
||||
@@ -252,38 +262,38 @@ function getTier8Guardian(floor: number): GuardianDef {
|
||||
],
|
||||
signingCost: {
|
||||
mana: Math.floor(hpVal * 0.4),
|
||||
time: 32 + Math.floor((floor - 350) / 10),
|
||||
time: 32 + Math.floor((floor - 390) / 10),
|
||||
},
|
||||
unlocksMana: elements,
|
||||
damageMultiplier: 5.0 + (floor - 350) * 0.02,
|
||||
insightMultiplier: 4.5 + (floor - 350) * 0.01,
|
||||
damageMultiplier: 5.0 + (floor - 390) * 0.02,
|
||||
insightMultiplier: 4.5 + (floor - 390) * 0.01,
|
||||
};
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// TIER 9: Full Fusion — 1 Exotic + 2 Composite + All Components (Floors 400+)
|
||||
// TIER 8: Full Fusion — 1 Exotic + 2 Composite + All Components (Floors 440+)
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function getTier9Guardian(floor: number): GuardianDef {
|
||||
const exoticIdx = (Math.floor((floor - 400) / 10)) % EXOTIC_ELEMENTS.length;
|
||||
function getTier8Guardian(floor: number): GuardianDef {
|
||||
const exoticIdx = (Math.floor((floor - 440) / 10)) % EXOTIC_ELEMENTS.length;
|
||||
const exoticEl = EXOTIC_ELEMENTS[exoticIdx];
|
||||
// Pick 2 different composites
|
||||
const comp1 = COMPOSITE_ELEMENTS[Math.floor((floor - 400) / 10) % COMPOSITE_ELEMENTS.length];
|
||||
const comp2 = COMPOSITE_ELEMENTS[(Math.floor((floor - 400) / 10) + 1) % COMPOSITE_ELEMENTS.length];
|
||||
const comp1 = COMPOSITE_ELEMENTS[Math.floor((floor - 440) / 10) % COMPOSITE_ELEMENTS.length];
|
||||
const comp2 = COMPOSITE_ELEMENTS[(Math.floor((floor - 440) / 10) + 1) % COMPOSITE_ELEMENTS.length];
|
||||
const elements = resolveMultiUnlockChain([exoticEl, comp1, comp2]);
|
||||
const hpVal = getGuardianHP(floor);
|
||||
const armor = Math.min(0.7, 0.50 + (floor - 400) * 0.002);
|
||||
const armor = Math.min(0.7, 0.50 + (floor - 440) * 0.002);
|
||||
|
||||
return {
|
||||
name: '',
|
||||
element: elements,
|
||||
hp: hpVal,
|
||||
pact: 14.0 + (floor - 400) * 0.05,
|
||||
pact: 14.0 + (floor - 440) * 0.05,
|
||||
color: '#7B5E9A',
|
||||
armor,
|
||||
boons: makeBoons([exoticEl, comp1, comp2], floor),
|
||||
pactCost: Math.floor(hpVal * 0.45 + hpVal * armor * 0.5),
|
||||
pactTime: 36 + Math.floor((floor - 400) / 10),
|
||||
pactTime: 36 + Math.floor((floor - 440) / 10),
|
||||
uniquePerk: `Cosmic convergence: All exotic, composite, and base spells gain +15% effectiveness`,
|
||||
power: Math.floor(hpVal * 0.7),
|
||||
effects: [
|
||||
@@ -294,11 +304,11 @@ function getTier9Guardian(floor: number): GuardianDef {
|
||||
],
|
||||
signingCost: {
|
||||
mana: Math.floor(hpVal * 0.45),
|
||||
time: 36 + Math.floor((floor - 400) / 10),
|
||||
time: 36 + Math.floor((floor - 440) / 10),
|
||||
},
|
||||
unlocksMana: elements,
|
||||
damageMultiplier: 5.5 + (floor - 400) * 0.02,
|
||||
insightMultiplier: 5.0 + (floor - 400) * 0.01,
|
||||
damageMultiplier: 5.5 + (floor - 440) * 0.02,
|
||||
insightMultiplier: 5.0 + (floor - 440) * 0.01,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -309,6 +319,9 @@ const ELEMENT_COLORS: Record<string, string> = {
|
||||
light: '#FFD700', dark: '#9B59B6', death: '#778CA3', transference: '#1ABC9C',
|
||||
metal: '#BDC3C7', sand: '#D4AC0D', lightning: '#FFEB3B',
|
||||
crystal: '#85C1E9', stellar: '#F0E68C', void: '#4A235A',
|
||||
frost: '#A8D8EA', blackflame: '#8B2500', radiantflames: '#FFAA33',
|
||||
miasma: '#6B8E23', shadowglass: '#2C2C54',
|
||||
soul: '#E8D5F5', time: '#C5B99A', plasma: '#FF6B9D',
|
||||
};
|
||||
|
||||
function blendColors(el1: string, el2: string): string {
|
||||
@@ -327,17 +340,17 @@ function blendColors(el1: string, el2: string): string {
|
||||
// ─── Procedural Guardian Generator ─────────────────────────────────────────────
|
||||
|
||||
function getProceduralGuardian(floor: number): GuardianDef | null {
|
||||
if (floor < 210 || floor % 10 !== 0) return null;
|
||||
if (floor < 250 || floor % 10 !== 0) return null;
|
||||
|
||||
const tier = getTier(floor);
|
||||
let g: GuardianDef;
|
||||
|
||||
switch (tier) {
|
||||
case 4: g = getTier4Guardian(floor); break;
|
||||
case 5: g = getTier5Guardian(floor); break;
|
||||
case 6: g = getTier6Guardian(floor); break;
|
||||
case 7: g = getTier7Guardian(floor); break;
|
||||
case 8: g = getTier8Guardian(floor); break;
|
||||
case 9: g = getTier9Guardian(floor); break;
|
||||
default: return null;
|
||||
}
|
||||
|
||||
@@ -363,9 +376,9 @@ export function getGuardianForFloor(floor: number): GuardianDef | null {
|
||||
export function getAllGuardianFloors(): number[] {
|
||||
// Static floors from guardian-data.ts
|
||||
const staticFloors = Object.keys(STATIC_GUARDIANS).map(Number);
|
||||
// Procedural floors: every 10th floor from 210 to 450
|
||||
// Procedural floors: every 10th floor from 250 to 490
|
||||
const proceduralFloors: number[] = [];
|
||||
for (let f = 210; f <= 450; f += 10) {
|
||||
for (let f = 250; f <= 490; f += 10) {
|
||||
proceduralFloors.push(f);
|
||||
}
|
||||
const all = new Set([...staticFloors, ...proceduralFloors]);
|
||||
|
||||
Reference in New Issue
Block a user