feature: add new composite and exotic mana types (ticket #202)
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 17s

This commit is contained in:
2026-05-29 21:51:45 +02:00
parent 7bd28e2085
commit e3ce18c601
31 changed files with 1279 additions and 170 deletions
+22 -1
View File
@@ -32,10 +32,18 @@ export const ELEMENTS: Record<string, ElementDef> = {
sand: { name: "Sand", sym: "⏳", color: "#D4AC0D", glow: "#D4AC0D40", cat: "composite", recipe: ["earth", "water"] },
lightning: { name: "Lightning", sym: "⚡", color: "#FFEB3B", glow: "#FFEB3B40", cat: "composite", recipe: ["fire", "air"] },
frost: { name: "Frost", sym: "❄️", color: "#A8D8EA", glow: "#A8D8EA40", cat: "composite", recipe: ["air", "water"] },
blackflame: { name: "BlackFlame", sym: "🌋", color: "#8B2500", glow: "#8B250040", cat: "composite", recipe: ["dark", "fire"] },
radiantflames: { name: "Radiant Flames", sym: "🌟", color: "#FFAA33", glow: "#FFAA3340", cat: "composite", recipe: ["light", "fire"] },
miasma: { name: "Miasma", sym: "☁️", color: "#6B8E23", glow: "#6B8E2340", cat: "composite", recipe: ["air", "death"] },
shadowglass: { name: "Shadow Glass", sym: "🖤", color: "#2C2C54", glow: "#2C2C5440", cat: "composite", recipe: ["earth", "dark"] },
// Exotic Elements
crystal: { name: "Crystal", sym: "💎", color: "#85C1E9", glow: "#85C1E940", cat: "exotic", recipe: ["sand", "sand", "light"] },
stellar: { name: "Stellar", sym: "⭐", color: "#F0E68C", glow: "#F0E68C40", cat: "exotic", recipe: ["fire", "fire", "light"] },
stellar: { name: "Stellar", sym: "⭐", color: "#F0E68C", glow: "#F0E68C40", cat: "exotic", recipe: ["plasma", "light", "fire"] },
void: { name: "Void", sym: "🕳️", color: "#4A235A", glow: "#4A235A40", cat: "exotic", recipe: ["dark", "dark", "death"] },
soul: { name: "Soul", sym: "💫", color: "#E8D5F5", glow: "#E8D5F540", cat: "exotic", recipe: ["light", "dark", "transference"] },
time: { name: "Time", sym: "⏱️", color: "#C5B99A", glow: "#C5B99A40", cat: "exotic", recipe: ["soul", "sand", "transference"] },
plasma: { name: "Plasma", sym: "⚡", color: "#FF6B9D", glow: "#FF6B9D40", cat: "exotic", recipe: ["lightning", "fire", "transference"] },
};
// NOTE: Life, Blood, Wood, Mental, and Force mana types have been removed.
@@ -50,6 +58,11 @@ export const ELEMENT_OPPOSITES: Record<string, string> = {
air: 'earth', earth: 'air',
light: 'dark', dark: 'light',
lightning: 'earth', // Lightning is weak to earth (grounding)
frost: 'fire', // Frost is weak to fire (melting)
blackflame: 'light', // BlackFlame is weak to light (purification)
radiantflames: 'dark', // Radiant Flames are weak to dark (extinguishing)
miasma: 'air', // Miasma is weak to air (dispersion)
shadowglass: 'light', // Shadow Glass is weak to light (shattering)
};
// ─── Element Icon Mapping (Lucide Icons) ──────────────────────────────────────
@@ -71,6 +84,14 @@ export const ELEMENT_ICON_NAMES: Record<string, string> = {
stellar: 'Star',
void: 'CircleDot',
raw: 'Circle',
frost: 'Snowflake',
blackflame: 'Flame',
radiantflames: 'Sun',
miasma: 'Cloud',
shadowglass: 'EyeOff',
soul: 'Ghost',
time: 'Clock',
plasma: 'Zap',
};
// ─── Base Unlocked Elements ───────────────────────────────────────────────────
@@ -0,0 +1,72 @@
// ─── BlackFlame Spells ───────────────────────────────────────────────────────
// BlackFlame magic - Dark + Fire compound, curse/DoT focus
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const BLACKFLAME_SPELLS: Record<string, SpellDef> = {
// Tier 1 - Basic BlackFlame
blackFire: {
name: "Black Fire",
elem: "blackflame",
dmg: 12,
cost: elemCost("blackflame", 2),
tier: 1,
castSpeed: 2.2,
unlock: 200,
studyTime: 3,
desc: "Dark fire that burns with cursed flames. Applies curse DoT.",
effects: [{ type: 'burn', value: 0.15 }, { type: 'curse', value: 0.1 }]
},
shadowEmber: {
name: "Shadow Ember",
elem: "blackflame",
dmg: 20,
cost: elemCost("blackflame", 3),
tier: 1,
castSpeed: 1.8,
unlock: 320,
studyTime: 4,
desc: "Embers of shadow fire. Reduces enemy resistances.",
effects: [{ type: 'curse', value: 0.15 }]
},
// Tier 2 - Advanced BlackFlame
darkInferno: {
name: "Dark Inferno",
elem: "blackflame",
dmg: 38,
cost: elemCost("blackflame", 6),
tier: 2,
castSpeed: 1.3,
unlock: 1000,
studyTime: 9,
desc: "A cursed inferno that weakens and burns.",
effects: [{ type: 'burn', value: 0.25 }, { type: 'curse', value: 0.2 }]
},
umbralBlaze: {
name: "Umbral Blaze",
elem: "blackflame",
dmg: 55,
cost: elemCost("blackflame", 8),
tier: 2,
castSpeed: 1,
unlock: 1500,
studyTime: 12,
desc: "Flames from the abyss. Stacks curse on enemies.",
effects: [{ type: 'curse', value: 0.3 }, { type: 'burn', value: 0.2 }]
},
// Tier 3 - Master BlackFlame
hellfireCurse: {
name: "Hellfire Curse",
elem: "blackflame",
dmg: 140,
cost: elemCost("blackflame", 20),
tier: 3,
castSpeed: 0.5,
unlock: 15000,
studyTime: 30,
desc: "Ultimate cursed flames. Devastating DoT and resistance shred.",
effects: [{ type: 'burn', value: 0.35 }, { type: 'curse', value: 0.35 }]
},
};
@@ -0,0 +1,74 @@
// ─── Frost Spells ────────────────────────────────────────────────────────────
// Frost magic - Air + Water compound, freeze/slow focus
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const FROST_SPELLS: Record<string, SpellDef> = {
// Tier 1 - Basic Frost
frostBite: {
name: "Frost Bite",
elem: "frost",
dmg: 10,
cost: elemCost("frost", 2),
tier: 1,
castSpeed: 2.5,
unlock: 180,
studyTime: 3,
desc: "A chilling bite of frost. Fast casting with freeze chance.",
effects: [{ type: 'freeze', value: 0.15 }]
},
iceShard: {
name: "Ice Shard",
elem: "frost",
dmg: 18,
cost: elemCost("frost", 3),
tier: 1,
castSpeed: 2,
unlock: 250,
studyTime: 4,
desc: "A sharp shard of ice. Moderate speed, freeze effect.",
effects: [{ type: 'freeze', value: 0.2 }]
},
// Tier 2 - Advanced Frost
frostNova: {
name: "Frost Nova",
elem: "frost",
dmg: 30,
cost: elemCost("frost", 5),
tier: 2,
castSpeed: 1.5,
unlock: 800,
studyTime: 8,
desc: "An explosion of freezing cold. Slows all enemies.",
isAoe: true,
aoeTargets: 3,
effects: [{ type: 'slow', value: 0.3 }, { type: 'freeze', value: 0.15 }]
},
glacialSpike: {
name: "Glacial Spike",
elem: "frost",
dmg: 45,
cost: elemCost("frost", 7),
tier: 2,
castSpeed: 1.2,
unlock: 1200,
studyTime: 10,
desc: "A massive spike of ice. High damage with guaranteed freeze.",
effects: [{ type: 'freeze', value: 0.35 }]
},
// Tier 3 - Master Frost
absoluteZero: {
name: "Absolute Zero",
elem: "frost",
dmg: 120,
cost: elemCost("frost", 18),
tier: 3,
castSpeed: 0.6,
unlock: 12000,
studyTime: 28,
desc: "Freeze the very air. Devastating cold that stops all movement.",
effects: [{ type: 'freeze', value: 0.5 }, { type: 'slow', value: 0.4 }]
},
};
@@ -14,7 +14,7 @@ export const LEGENDARY_SPELLS: Record<string, SpellDef> = {
castSpeed: 0.4,
unlock: 50000,
studyTime: 48,
desc: "A nova of stellar energy."
desc: "A nova of stellar energy. Blinding and devastating."
},
voidCollapse: {
name: "Void Collapse",
@@ -0,0 +1,76 @@
// ─── Miasma Spells ────────────────────────────────────────────────────────────
// Miasma magic - Air + Death compound, toxic/plague/armor corrosion focus
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const MIASMA_SPELLS: Record<string, SpellDef> = {
// Tier 1 - Basic Miasma
toxicCloud: {
name: "Toxic Cloud",
elem: "miasma",
dmg: 9,
cost: elemCost("miasma", 2),
tier: 1,
castSpeed: 2.8,
unlock: 190,
studyTime: 3,
desc: "A cloud of toxic gas. Spreads to nearby enemies.",
effects: [{ type: 'poison', value: 0.12 }]
},
plagueTouch: {
name: "Plague Touch",
elem: "miasma",
dmg: 16,
cost: elemCost("miasma", 3),
tier: 1,
castSpeed: 2.2,
unlock: 280,
studyTime: 4,
desc: "Touch of plague. Corrodes armor and poisons.",
effects: [{ type: 'poison', value: 0.15 }, { type: 'armor_corrode', value: 0.1 }]
},
// Tier 2 - Advanced Miasma
miasmaBurst: {
name: "Miasma Burst",
elem: "miasma",
dmg: 32,
cost: elemCost("miasma", 5),
tier: 2,
castSpeed: 1.6,
unlock: 900,
studyTime: 8,
desc: "A burst of toxic miasma. Hits all enemies in swarm rooms.",
isAoe: true,
aoeTargets: 4,
effects: [{ type: 'poison', value: 0.2 }, { type: 'armor_corrode', value: 0.15 }]
},
pestilence: {
name: "Pestilence",
elem: "miasma",
dmg: 48,
cost: elemCost("miasma", 7),
tier: 2,
castSpeed: 1.2,
unlock: 1300,
studyTime: 11,
desc: "Spreading plague. Reduces armor and stacks poison.",
effects: [{ type: 'poison', value: 0.25 }, { type: 'armor_corrode', value: 0.2 }]
},
// Tier 3 - Master Miasma
deathMiasma: {
name: "Death Miasma",
elem: "miasma",
dmg: 130,
cost: elemCost("miasma", 18),
tier: 3,
castSpeed: 0.5,
unlock: 14000,
studyTime: 28,
desc: "Ultimate toxic cloud. Melts armor and spreads deadly plague.",
isAoe: true,
aoeTargets: 5,
effects: [{ type: 'poison', value: 0.35 }, { type: 'armor_corrode', value: 0.3 }]
},
};
@@ -0,0 +1,34 @@
// ─── Plasma Spells ────────────────────────────────────────────────────────────
// Plasma magic - Lightning + Fire + Transference exotic, high raw damage
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const PLASMA_SPELLS: Record<string, SpellDef> = {
// Tier 4 - Plasma Spells (raw energy devastation)
plasmaBolt: {
name: "Plasma Bolt",
elem: "plasma",
dmg: 320,
cost: elemCost("plasma", 10),
tier: 4,
castSpeed: 0.65,
unlock: 40000,
studyTime: 38,
desc: "A bolt of superheated plasma. Extremely high raw damage.",
effects: [{ type: 'raw_damage', value: 0.3 }]
},
plasmaStorm: {
name: "Plasma Storm",
elem: "plasma",
dmg: 600,
cost: elemCost("plasma", 18),
tier: 4,
castSpeed: 0.35,
unlock: 75000,
studyTime: 55,
desc: "A storm of plasma energy. Devastating area damage.",
isAoe: true,
aoeTargets: 4,
effects: [{ type: 'raw_damage', value: 0.4 }, { type: 'chain', value: 2 }]
},
};
@@ -0,0 +1,74 @@
// ─── Radiant Flames Spells ───────────────────────────────────────────────────
// Radiant Flames magic - Light + Fire compound, blinding/heavy DoT focus
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const RADIANTFLAMES_SPELLS: Record<string, SpellDef> = {
// Tier 1 - Basic Radiant Flames
radiantBurst: {
name: "Radiant Burst",
elem: "radiantflames",
dmg: 14,
cost: elemCost("radiantflames", 2),
tier: 1,
castSpeed: 2,
unlock: 210,
studyTime: 3,
desc: "A burst of blinding holy fire. Chance to blind enemies.",
effects: [{ type: 'burn', value: 0.18 }, { type: 'blind', value: 0.1 }]
},
holyFlame: {
name: "Holy Flame",
elem: "radiantflames",
dmg: 22,
cost: elemCost("radiantflames", 3),
tier: 1,
castSpeed: 1.7,
unlock: 340,
studyTime: 4,
desc: "Sacred fire that sears the unholy. Heavy burn effect.",
effects: [{ type: 'burn', value: 0.22 }]
},
// Tier 2 - Advanced Radiant Flames
blindingSun: {
name: "Blinding Sun",
elem: "radiantflames",
dmg: 40,
cost: elemCost("radiantflames", 6),
tier: 2,
castSpeed: 1.2,
unlock: 1100,
studyTime: 10,
desc: "Summon a miniature sun. Blinds and burns all enemies.",
isAoe: true,
aoeTargets: 3,
effects: [{ type: 'blind', value: 0.25 }, { type: 'burn', value: 0.25 }]
},
purifyingFire: {
name: "Purifying Fire",
elem: "radiantflames",
dmg: 58,
cost: elemCost("radiantflames", 8),
tier: 2,
castSpeed: 0.9,
unlock: 1600,
studyTime: 12,
desc: "Holy flames that purify. Highest burn damage.",
effects: [{ type: 'burn', value: 0.35 }]
},
// Tier 3 - Master Radiant Flames
supernovaBlast: {
name: "Supernova Blast",
elem: "radiantflames",
dmg: 150,
cost: elemCost("radiantflames", 20),
tier: 3,
castSpeed: 0.5,
unlock: 16000,
studyTime: 30,
desc: "Unleash the fury of a supernova. Blinds and incinerates.",
effects: [{ type: 'blind', value: 0.4 }, { type: 'burn', value: 0.4 }]
},
};
@@ -0,0 +1,74 @@
// ─── Shadow Glass Spells ─────────────────────────────────────────────────────
// Shadow Glass magic - Earth + Dark compound, spike/armor pierce focus
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const SHADOWGLASS_SPELLS: Record<string, SpellDef> = {
// Tier 1 - Basic Shadow Glass
shadowSpike: {
name: "Shadow Spike",
elem: "shadowglass",
dmg: 15,
cost: elemCost("shadowglass", 2),
tier: 1,
castSpeed: 2,
unlock: 220,
studyTime: 3,
desc: "A spike of shadow glass erupts from the ground. Sharp and fast.",
effects: [{ type: 'armor_pierce', value: 0.2 }]
},
darkShard: {
name: "Dark Shard",
elem: "shadowglass",
dmg: 24,
cost: elemCost("shadowglass", 3),
tier: 1,
castSpeed: 1.6,
unlock: 360,
studyTime: 4,
desc: "A shard of pure shadow glass. High armor pierce.",
effects: [{ type: 'armor_pierce', value: 0.28 }]
},
// Tier 2 - Advanced Shadow Glass
obsidianStorm: {
name: "Obsidian Storm",
elem: "shadowglass",
dmg: 42,
cost: elemCost("shadowglass", 6),
tier: 2,
castSpeed: 1.3,
unlock: 1000,
studyTime: 9,
desc: "A storm of shadow glass shards. Hits multiple enemies.",
isAoe: true,
aoeTargets: 3,
effects: [{ type: 'armor_pierce', value: 0.3 }]
},
voidBlade: {
name: "Void Blade",
elem: "shadowglass",
dmg: 60,
cost: elemCost("shadowglass", 9),
tier: 2,
castSpeed: 0.9,
unlock: 1700,
studyTime: 12,
desc: "A blade of condensed shadow. Ignores most armor.",
effects: [{ type: 'armor_pierce', value: 0.42 }]
},
// Tier 3 - Master Shadow Glass
shadowGlassCataclysm: {
name: "Shadow Glass Cataclysm",
elem: "shadowglass",
dmg: 155,
cost: elemCost("shadowglass", 20),
tier: 3,
castSpeed: 0.5,
unlock: 17000,
studyTime: 30,
desc: "Shatter the earth into a storm of shadow glass. Ignores all armor.",
effects: [{ type: 'armor_pierce', value: 0.55 }]
},
};
@@ -0,0 +1,32 @@
// ─── Soul Spells ──────────────────────────────────────────────────────────────
// Soul magic - Light + Dark + Transference exotic, bypasses defenses
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const SOUL_SPELLS: Record<string, SpellDef> = {
// Tier 4 - Soul Spells (defense bypass)
soulPierce: {
name: "Soul Pierce",
elem: "soul",
dmg: 350,
cost: elemCost("soul", 10),
tier: 4,
castSpeed: 0.6,
unlock: 30000,
studyTime: 36,
desc: "Strike at the soul. Bypasses all armor and resistances.",
effects: [{ type: 'defense_bypass', value: 1.0 }]
},
spiritBlast: {
name: "Spirit Blast",
elem: "soul",
dmg: 550,
cost: elemCost("soul", 16),
tier: 4,
castSpeed: 0.4,
unlock: 60000,
studyTime: 50,
desc: "A blast of pure soul energy. Ignores all defenses entirely.",
effects: [{ type: 'defense_bypass', value: 1.0 }, { type: 'resist_ignore', value: 0.5 }]
},
};
@@ -0,0 +1,32 @@
// ─── Time Spells ──────────────────────────────────────────────────────────────
// Time magic - Soul + Sand + Transference exotic, slow/temporal focus
import type { SpellDef } from '../../types';
import { elemCost } from '../elements';
export const TIME_SPELLS: Record<string, SpellDef> = {
// Tier 4 - Time Spells (temporal manipulation)
temporalWarp: {
name: "Temporal Warp",
elem: "time",
dmg: 280,
cost: elemCost("time", 10),
tier: 4,
castSpeed: 0.7,
unlock: 45000,
studyTime: 40,
desc: "Warp time around enemies. Slows speed, reduces dodge.",
effects: [{ type: 'slow', value: 0.5 }, { type: 'temporal_dodge_reduction', value: 0.4 }]
},
chronoStasis: {
name: "Chrono Stasis",
elem: "time",
dmg: 500,
cost: elemCost("time", 18),
tier: 4,
castSpeed: 0.35,
unlock: 70000,
studyTime: 55,
desc: "Freeze enemies in time. Stops mage room recast entirely.",
effects: [{ type: 'slow', value: 0.7 }, { type: 'temporal_dodge_reduction', value: 0.6 }, { type: 'mage_lock', value: 1.0 }]
},
};
+24
View File
@@ -12,6 +12,14 @@ export { LEGENDARY_SPELLS } from './spells-modules/legendary-spells';
export { ENCHANTMENT_SPELLS } from './spells-modules/enchantment-spells';
export { COMPOUND_SPELLS } from './spells-modules/compound-spells';
export { UTILITY_SPELLS } from './spells-modules/utility-spells';
export { FROST_SPELLS } from './spells-modules/frost-spells';
export { BLACKFLAME_SPELLS } from './spells-modules/blackflame-spells';
export { RADIANTFLAMES_SPELLS } from './spells-modules/radiantflames-spells';
export { MIASMA_SPELLS } from './spells-modules/miasma-spells';
export { SHADOWGLASS_SPELLS } from './spells-modules/shadowglass-spells';
export { SOUL_SPELLS } from './spells-modules/soul-spells';
export { TIME_SPELLS } from './spells-modules/time-spells';
export { PLASMA_SPELLS } from './spells-modules/plasma-spells';
// Convenience: export combined SPELLS_DEF for backward compatibility
import { RAW_SPELLS } from './spells-modules/raw-spells';
@@ -24,6 +32,14 @@ import { LEGENDARY_SPELLS } from './spells-modules/legendary-spells';
import { ENCHANTMENT_SPELLS } from './spells-modules/enchantment-spells';
import { COMPOUND_SPELLS } from './spells-modules/compound-spells';
import { UTILITY_SPELLS } from './spells-modules/utility-spells';
import { FROST_SPELLS } from './spells-modules/frost-spells';
import { BLACKFLAME_SPELLS } from './spells-modules/blackflame-spells';
import { RADIANTFLAMES_SPELLS } from './spells-modules/radiantflames-spells';
import { MIASMA_SPELLS } from './spells-modules/miasma-spells';
import { SHADOWGLASS_SPELLS } from './spells-modules/shadowglass-spells';
import { SOUL_SPELLS } from './spells-modules/soul-spells';
import { TIME_SPELLS } from './spells-modules/time-spells';
import { PLASMA_SPELLS } from './spells-modules/plasma-spells';
export const SPELLS_DEF: Record<string, import('../types').SpellDef> = {
...RAW_SPELLS,
@@ -36,4 +52,12 @@ export const SPELLS_DEF: Record<string, import('../types').SpellDef> = {
...ENCHANTMENT_SPELLS,
...COMPOUND_SPELLS,
...UTILITY_SPELLS,
...FROST_SPELLS,
...BLACKFLAME_SPELLS,
...RADIANTFLAMES_SPELLS,
...MIASMA_SPELLS,
...SHADOWGLASS_SPELLS,
...SOUL_SPELLS,
...TIME_SPELLS,
...PLASMA_SPELLS,
};
@@ -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,
}),
];
+11 -3
View File
@@ -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' }
},
};
+14 -1
View File
@@ -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',
};
+99 -61
View File
@@ -1,14 +1,14 @@
// ─── Static Guardian Definitions ─────────────────────────────────────────────────
// New 9-tier progression for guardians:
// Expanded guardian progression:
//
// Tier 1: Base Elements (floors 1080)
// Fire, Water, Air, Earth, Light, Dark, Death, Transference
// Tier 2: Composite Elements (floors 90120)
// Metal, Sand, Lightning
// Tier 3: Composite + Components (floors 130160)
// Tier 4: Exotic Elements (floors 170200)
// Tier 2: Composite Elements (floors 90160)
// Metal, Sand, Lightning, Frost, BlackFlame, Radiant Flames, Miasma, Shadow Glass
// Tier 3: Exotic Elements (floors 170240)
// 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 90120)
// TIER 2: Composite Elements (Floors 90160) — 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 130160)
// TIER 3: Exotic Elements (Floors 170240) — 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 170200)
// ═══════════════════════════════════════════════════════════════════════════════
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 };
+80 -67
View File
@@ -3,14 +3,13 @@
//
// Guardian progression (9 tiers):
// Tier 1: Base Elements (static, floors 1080, guardian-data.ts)
// Tier 2: Composite Elements (static, floors 90120, guardian-data.ts)
// Tier 3: Composite+Components (static, floors 130160, guardian-data.ts)
// Tier 4: Exotic Elements (static, floors 170200, guardian-data.ts)
// Tier 5: Dual Element Pairs (dynamic, floors 210240, this file)
// Tier 6: Dual Comp+Components (dynamic, floors 250290, this file)
// Tier 7: Exotic+Components (dynamic, floors 300340, this file)
// Tier 8: Exotic+Comp+Components (dynamic, floors 350390, this file)
// Tier 9: Full Fusion (dynamic, floors 400+, this file)
// Tier 2: Composite Elements (static, floors 90160, guardian-data.ts)
// Tier 3: Exotic Elements (static, floors 170240, guardian-data.ts)
// Tier 4: Dual Element Pairs (dynamic, floors 250280, this file)
// Tier 5: Dual Comp+Components (dynamic, floors 290330, this file)
// Tier 6: Exotic+Components (dynamic, floors 340380, this file)
// Tier 7: Exotic+Comp+Components (dynamic, floors 390430, 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 210240)
// TIER 4: Dual Element Pairs (Floors 250280)
// ═══════════════════════════════════════════════════════════════════════════════
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 250290)
// TIER 5: Dual Composite + Components (Floors 290330)
// 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 300340)
// TIER 6: Exotic + Components (Floors 340380)
// 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 350390)
// TIER 7: Exotic + Composite + Components (Floors 390430)
// 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]);
+1 -1
View File
@@ -2,7 +2,7 @@
export type ElementCategory = 'base' | 'utility' | 'composite' | 'exotic';
export type ManaType = 'raw' | 'fire' | 'water' | 'air' | 'earth' | 'light' | 'dark' | 'death' | 'transference' | 'metal' | 'sand' | 'lightning' | 'crystal' | 'stellar' | 'void';
export type ManaType = 'raw' | 'fire' | 'water' | 'air' | 'earth' | 'light' | 'dark' | 'death' | 'transference' | 'metal' | 'sand' | 'lightning' | 'frost' | 'blackflame' | 'radiantflames' | 'miasma' | 'shadowglass' | 'crystal' | 'stellar' | 'void' | 'soul' | 'time' | 'plasma';
export interface ElementDef {
name: string;
+1 -1
View File
@@ -26,7 +26,7 @@ export interface SpellDef {
}
export interface SpellEffect {
type: 'burn' | 'freeze' | 'stun' | 'pierce' | 'multicast' | 'shield' | 'buff' | 'chain' | 'aoe' | 'armor_pierce';
type: 'burn' | 'freeze' | 'stun' | 'pierce' | 'multicast' | 'shield' | 'buff' | 'chain' | 'aoe' | 'armor_pierce' | 'curse' | 'slow' | 'poison' | 'armor_corrode' | 'blind' | 'defense_bypass' | 'resist_ignore' | 'raw_damage' | 'temporal_dodge_reduction' | 'mage_lock';
value: number; // Effect potency
duration?: number; // Duration in hours for timed effects
targets?: number; // For AOE: number of targets
+10 -7
View File
@@ -13,8 +13,11 @@ import { ELEMENTS } from '../constants/elements';
* resolveUnlockChain('fire') → ['fire']
* resolveUnlockChain('metal') → ['fire', 'earth', 'metal']
* resolveUnlockChain('crystal') → ['earth', 'water', 'light', 'sand', 'crystal']
* resolveUnlockChain('stellar') → ['fire', 'light', 'stellar']
* resolveUnlockChain('stellar') → ['fire', 'air', 'transference', 'lightning', 'light', 'plasma', 'stellar']
* resolveUnlockChain('void') → ['dark', 'death', 'void']
* resolveUnlockChain('soul') → ['light', 'dark', 'transference', 'soul']
* resolveUnlockChain('time') → ['light', 'dark', 'transference', 'earth', 'water', 'sand', 'soul', 'time']
* resolveUnlockChain('plasma') → ['fire', 'air', 'transference', 'lightning', 'plasma']
*/
export function resolveUnlockChain(element: string): string[] {
const result: string[] = [];
@@ -74,12 +77,12 @@ const TIER_CONFIG = [
{ start: 10, end: 80, spacing: 10 }, // Base + utility: floors 10-80
{ start: 90, end: 120, spacing: 10 }, // Composite: floors 90-120
{ start: 130, end: 160, spacing: 10 }, // Composite + Components
{ start: 170, end: 200, spacing: 10 }, // Exotic
{ start: 210, end: 240, spacing: 10 }, // Dual Element
{ start: 250, end: 290, spacing: 10 }, // Dual Composite + Components
{ start: 300, end: 340, spacing: 10 }, // Exotic + Components
{ start: 350, end: 390, spacing: 10 }, // Exotic + Composite + Components
{ start: 400, end: 450, spacing: 10 }, // 1 Exotic + 2 Composite + All Components
{ start: 170, end: 240, spacing: 10 }, // Exotic (8 guardians)
{ start: 250, end: 280, spacing: 10 }, // Dual Element
{ start: 290, end: 330, spacing: 10 }, // Dual Composite + Components
{ start: 340, end: 380, spacing: 10 }, // Exotic + Components
{ start: 390, end: 430, spacing: 10 }, // Exotic + Composite + Components
{ start: 440, end: 490, spacing: 10 }, // 1 Exotic + 2 Composite + All Components
] as const;
/** Get all guardian floors from a given start, dynamically computed. */