discipline: elemental revamp - rename, lock, merge tabs, add missing, dedupe
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m22s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m22s
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Circular Dependencies
|
# Circular Dependencies
|
||||||
Generated: 2026-05-28T10:28:32.589Z
|
Generated: 2026-05-28T10:41:19.223Z
|
||||||
|
|
||||||
No circular dependencies found. ✅
|
No circular dependencies found. ✅
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"generated": "2026-05-28T10:28:30.836Z",
|
"generated": "2026-05-28T10:41:17.557Z",
|
||||||
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
|
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
|
||||||
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
|
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,9 +27,7 @@ interface AttunementTab {
|
|||||||
|
|
||||||
const ATTUNEMENT_TABS: AttunementTab[] = [
|
const ATTUNEMENT_TABS: AttunementTab[] = [
|
||||||
{ key: 'base', label: 'Base', items: baseDisciplines },
|
{ key: 'base', label: 'Base', items: baseDisciplines },
|
||||||
{ key: 'elements', label: 'Mana Types', items: elementalAttunementDisciplines },
|
{ key: 'elemental', label: 'Elemental', items: [...elementalAttunementDisciplines, ...elementalRegenDisciplines, ...elementalRegenAdvancedDisciplines] },
|
||||||
{ key: 'elemental-regen', label: 'Elemental Flow', items: elementalRegenDisciplines },
|
|
||||||
{ key: 'elemental-regen-advanced', label: 'Advanced Flow', items: elementalRegenAdvancedDisciplines },
|
|
||||||
{ key: 'enchanter', label: 'Enchanter', items: enchanterDisciplines },
|
{ key: 'enchanter', label: 'Enchanter', items: enchanterDisciplines },
|
||||||
{ key: 'fabricator', label: 'Fabricator', items: fabricatorDisciplines },
|
{ key: 'fabricator', label: 'Fabricator', items: fabricatorDisciplines },
|
||||||
{ key: 'invoker', label: 'Invoker', items: invokerDisciplines },
|
{ key: 'invoker', label: 'Invoker', items: invokerDisciplines },
|
||||||
|
|||||||
@@ -32,11 +32,18 @@ describe('DisciplineStore', () => {
|
|||||||
expect(useDisciplineStore.getState().activeIds.length).toBe(1);
|
expect(useDisciplineStore.getState().activeIds.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should activate when no prior discipline state (optimistic)', () => {
|
it('should not activate capacity discipline when mana type is locked', () => {
|
||||||
// canProceedDiscipline returns true when disciplineState is undefined
|
// capacity disciplines now require the mana type to be unlocked
|
||||||
useDisciplineStore.getState().activate('attune-fire', {
|
useDisciplineStore.getState().activate('attune-fire', {
|
||||||
elements: { fire: { unlocked: false, current: 100, max: 100 } },
|
elements: { fire: { unlocked: false, current: 100, max: 100 } },
|
||||||
});
|
});
|
||||||
|
expect(useDisciplineStore.getState().activeIds).not.toContain('attune-fire');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should activate capacity discipline when mana type element is unlocked', () => {
|
||||||
|
useDisciplineStore.getState().activate('attune-fire', {
|
||||||
|
elements: { fire: { unlocked: true, current: 100, max: 100 } },
|
||||||
|
});
|
||||||
expect(useDisciplineStore.getState().activeIds).toContain('attune-fire');
|
expect(useDisciplineStore.getState().activeIds).toContain('attune-fire');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,229 +5,148 @@
|
|||||||
import { DisciplinesAttunementType } from '../../types/disciplines';
|
import { DisciplinesAttunementType } from '../../types/disciplines';
|
||||||
import type { DisciplineDefinition } from '../../types/disciplines';
|
import type { DisciplineDefinition } from '../../types/disciplines';
|
||||||
|
|
||||||
// ── Composite Elements ─────────────────────────────────────────────────────
|
interface AdvancedConversionConfig {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
manaType: DisciplineDefinition['manaType'];
|
||||||
|
cost: number;
|
||||||
|
description: string;
|
||||||
|
conversionRate: number;
|
||||||
|
difficultyFactor: number;
|
||||||
|
scalingFactor: number;
|
||||||
|
drainBase: number;
|
||||||
|
sourceManaTypes: DisciplineDefinition['manaType'][];
|
||||||
|
customOnceDescription?: string;
|
||||||
|
customOnceAmount?: number;
|
||||||
|
customInfiniteDescription?: string;
|
||||||
|
customInfiniteAmount?: number;
|
||||||
|
infiniteThreshold?: number;
|
||||||
|
}
|
||||||
|
|
||||||
const COMP_CONVERSION = 0.35;
|
function createAdvancedConversionDiscipline(cfg: AdvancedConversionConfig): DisciplineDefinition {
|
||||||
const COMP_DRAIN = 2;
|
const nameLower = cfg.name.toLowerCase();
|
||||||
const COMP_DIFF = 160;
|
const onceDesc = cfg.customOnceDescription ?? `+${cfg.conversionRate} ${cfg.name} Conversion/sec`;
|
||||||
const COMP_SCALE = 80;
|
const onceAmt = cfg.customOnceAmount ?? cfg.conversionRate;
|
||||||
|
const infDesc = cfg.customInfiniteDescription ?? `Every 100 XP: +${cfg.conversionRate * 0.5} ${cfg.name} Conversion/sec`;
|
||||||
|
const infAmt = cfg.customInfiniteAmount ?? cfg.conversionRate * 0.5;
|
||||||
|
const infThreshold = cfg.infiniteThreshold ?? 400;
|
||||||
|
|
||||||
const metalDiscipline: DisciplineDefinition = {
|
return {
|
||||||
id: 'regen-metal',
|
id: cfg.id,
|
||||||
name: 'Metal Mana Flow',
|
name: `${cfg.name} Mana Conversion Speed`,
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
attunement: DisciplinesAttunementType.BASE,
|
||||||
manaType: 'metal',
|
manaType: cfg.manaType,
|
||||||
baseCost: 12,
|
baseCost: cfg.cost,
|
||||||
description: 'Convert raw mana + fire mana + earth mana into metal mana over time.',
|
description: cfg.description,
|
||||||
statBonus: { stat: 'conversion_metal', baseValue: COMP_CONVERSION, label: 'Metal Conversion/tick' },
|
statBonus: {
|
||||||
difficultyFactor: COMP_DIFF,
|
stat: `conversion_${cfg.manaType}` as DisciplineDefinition['statBonus']['stat'],
|
||||||
scalingFactor: COMP_SCALE,
|
baseValue: cfg.conversionRate,
|
||||||
drainBase: COMP_DRAIN,
|
label: `${cfg.name} Conversion/sec`,
|
||||||
conversionRate: COMP_CONVERSION,
|
|
||||||
sourceManaTypes: ['raw', 'fire', 'earth'],
|
|
||||||
requires: ['metal'],
|
|
||||||
perks: [
|
|
||||||
{
|
|
||||||
id: 'regen-metal-1',
|
|
||||||
type: 'once',
|
|
||||||
threshold: 150,
|
|
||||||
value: 0,
|
|
||||||
description: '+0.35 Metal Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_metal', amount: COMP_CONVERSION },
|
|
||||||
},
|
},
|
||||||
{
|
difficultyFactor: cfg.difficultyFactor,
|
||||||
id: 'regen-metal-inf',
|
scalingFactor: cfg.scalingFactor,
|
||||||
type: 'infinite',
|
drainBase: cfg.drainBase,
|
||||||
threshold: 400,
|
conversionRate: cfg.conversionRate,
|
||||||
value: 100,
|
sourceManaTypes: cfg.sourceManaTypes,
|
||||||
description: 'Every 100 XP: +0.15 Metal Conversion/tick',
|
requires: [cfg.manaType],
|
||||||
bonus: { stat: 'conversion_metal', amount: 0.15 },
|
perks: [
|
||||||
},
|
{
|
||||||
],
|
id: `${cfg.id}-1`,
|
||||||
};
|
type: 'once',
|
||||||
|
threshold: 150,
|
||||||
const sandDiscipline: DisciplineDefinition = {
|
value: 0,
|
||||||
id: 'regen-sand',
|
description: onceDesc,
|
||||||
name: 'Sand Mana Flow',
|
bonus: { stat: `conversion_${cfg.manaType}`, amount: onceAmt },
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
},
|
||||||
manaType: 'sand',
|
{
|
||||||
baseCost: 12,
|
id: `${cfg.id}-inf`,
|
||||||
description: 'Convert raw mana + earth mana + water mana into sand mana over time.',
|
type: 'infinite',
|
||||||
statBonus: { stat: 'conversion_sand', baseValue: COMP_CONVERSION, label: 'Sand Conversion/tick' },
|
threshold: infThreshold,
|
||||||
difficultyFactor: COMP_DIFF,
|
value: 100,
|
||||||
scalingFactor: COMP_SCALE,
|
description: infDesc,
|
||||||
drainBase: COMP_DRAIN,
|
bonus: { stat: `conversion_${cfg.manaType}`, amount: infAmt },
|
||||||
conversionRate: COMP_CONVERSION,
|
},
|
||||||
sourceManaTypes: ['raw', 'earth', 'water'],
|
],
|
||||||
requires: ['sand'],
|
};
|
||||||
perks: [
|
}
|
||||||
{
|
|
||||||
id: 'regen-sand-1',
|
|
||||||
type: 'once',
|
|
||||||
threshold: 150,
|
|
||||||
value: 0,
|
|
||||||
description: '+0.35 Sand Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_sand', amount: COMP_CONVERSION },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'regen-sand-inf',
|
|
||||||
type: 'infinite',
|
|
||||||
threshold: 400,
|
|
||||||
value: 100,
|
|
||||||
description: 'Every 100 XP: +0.15 Sand Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_sand', amount: 0.15 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const lightningDiscipline: DisciplineDefinition = {
|
|
||||||
id: 'regen-lightning',
|
|
||||||
name: 'Lightning Mana Flow',
|
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
|
||||||
manaType: 'lightning',
|
|
||||||
baseCost: 12,
|
|
||||||
description: 'Convert raw mana + fire mana + air mana into lightning mana over time.',
|
|
||||||
statBonus: { stat: 'conversion_lightning', baseValue: COMP_CONVERSION, label: 'Lightning Conversion/tick' },
|
|
||||||
difficultyFactor: COMP_DIFF,
|
|
||||||
scalingFactor: COMP_SCALE,
|
|
||||||
drainBase: COMP_DRAIN,
|
|
||||||
conversionRate: COMP_CONVERSION,
|
|
||||||
sourceManaTypes: ['raw', 'fire', 'air'],
|
|
||||||
requires: ['lightning'],
|
|
||||||
perks: [
|
|
||||||
{
|
|
||||||
id: 'regen-lightning-1',
|
|
||||||
type: 'once',
|
|
||||||
threshold: 150,
|
|
||||||
value: 0,
|
|
||||||
description: '+0.35 Lightning Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_lightning', amount: COMP_CONVERSION },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'regen-lightning-inf',
|
|
||||||
type: 'infinite',
|
|
||||||
threshold: 400,
|
|
||||||
value: 100,
|
|
||||||
description: 'Every 100 XP: +0.15 Lightning Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_lightning', amount: 0.15 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// ── Exotic Elements ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
const EXO_CONVERSION = 0.25;
|
|
||||||
const EXO_DRAIN = 3;
|
|
||||||
const EXO_DIFF = 220;
|
|
||||||
const EXO_SCALE = 110;
|
|
||||||
|
|
||||||
const crystalDiscipline: DisciplineDefinition = {
|
|
||||||
id: 'regen-crystal',
|
|
||||||
name: 'Crystal Mana Flow',
|
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
|
||||||
manaType: 'crystal',
|
|
||||||
baseCost: 18,
|
|
||||||
description: 'Convert raw mana + sand mana + light mana into crystal mana over time.',
|
|
||||||
statBonus: { stat: 'conversion_crystal', baseValue: EXO_CONVERSION, label: 'Crystal Conversion/tick' },
|
|
||||||
difficultyFactor: EXO_DIFF,
|
|
||||||
scalingFactor: EXO_SCALE,
|
|
||||||
drainBase: EXO_DRAIN,
|
|
||||||
conversionRate: EXO_CONVERSION,
|
|
||||||
sourceManaTypes: ['raw', 'sand', 'light'],
|
|
||||||
requires: ['crystal'],
|
|
||||||
perks: [
|
|
||||||
{
|
|
||||||
id: 'regen-crystal-1',
|
|
||||||
type: 'once',
|
|
||||||
threshold: 200,
|
|
||||||
value: 0,
|
|
||||||
description: '+0.25 Crystal Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_crystal', amount: EXO_CONVERSION },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'regen-crystal-inf',
|
|
||||||
type: 'infinite',
|
|
||||||
threshold: 500,
|
|
||||||
value: 100,
|
|
||||||
description: 'Every 100 XP: +0.1 Crystal Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_crystal', amount: 0.1 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const stellarDiscipline: DisciplineDefinition = {
|
|
||||||
id: 'regen-stellar',
|
|
||||||
name: 'Stellar Mana Flow',
|
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
|
||||||
manaType: 'stellar',
|
|
||||||
baseCost: 18,
|
|
||||||
description: 'Convert raw mana + fire mana + light mana into stellar mana over time.',
|
|
||||||
statBonus: { stat: 'conversion_stellar', baseValue: EXO_CONVERSION, label: 'Stellar Conversion/tick' },
|
|
||||||
difficultyFactor: EXO_DIFF,
|
|
||||||
scalingFactor: EXO_SCALE,
|
|
||||||
drainBase: EXO_DRAIN,
|
|
||||||
conversionRate: EXO_CONVERSION,
|
|
||||||
sourceManaTypes: ['raw', 'fire', 'light'],
|
|
||||||
requires: ['stellar'],
|
|
||||||
perks: [
|
|
||||||
{
|
|
||||||
id: 'regen-stellar-1',
|
|
||||||
type: 'once',
|
|
||||||
threshold: 200,
|
|
||||||
value: 0,
|
|
||||||
description: '+0.25 Stellar Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_stellar', amount: EXO_CONVERSION },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'regen-stellar-inf',
|
|
||||||
type: 'infinite',
|
|
||||||
threshold: 500,
|
|
||||||
value: 100,
|
|
||||||
description: 'Every 100 XP: +0.1 Stellar Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_stellar', amount: 0.1 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const voidDiscipline: DisciplineDefinition = {
|
|
||||||
id: 'regen-void',
|
|
||||||
name: 'Void Mana Flow',
|
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
|
||||||
manaType: 'void',
|
|
||||||
baseCost: 18,
|
|
||||||
description: 'Convert raw mana + dark mana + death mana into void mana over time.',
|
|
||||||
statBonus: { stat: 'conversion_void', baseValue: EXO_CONVERSION, label: 'Void Conversion/tick' },
|
|
||||||
difficultyFactor: EXO_DIFF,
|
|
||||||
scalingFactor: EXO_SCALE,
|
|
||||||
drainBase: EXO_DRAIN,
|
|
||||||
conversionRate: EXO_CONVERSION,
|
|
||||||
sourceManaTypes: ['raw', 'dark', 'death'],
|
|
||||||
requires: ['void'],
|
|
||||||
perks: [
|
|
||||||
{
|
|
||||||
id: 'regen-void-1',
|
|
||||||
type: 'once',
|
|
||||||
threshold: 200,
|
|
||||||
value: 0,
|
|
||||||
description: '+0.25 Void Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_void', amount: EXO_CONVERSION },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'regen-void-inf',
|
|
||||||
type: 'infinite',
|
|
||||||
threshold: 500,
|
|
||||||
value: 100,
|
|
||||||
description: 'Every 100 XP: +0.1 Void Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_void', amount: 0.1 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export const elementalRegenAdvancedDisciplines: DisciplineDefinition[] = [
|
export const elementalRegenAdvancedDisciplines: DisciplineDefinition[] = [
|
||||||
metalDiscipline,
|
// ── Composite Elements ─────────────────────────────────────────────────────
|
||||||
sandDiscipline,
|
createAdvancedConversionDiscipline({
|
||||||
lightningDiscipline,
|
id: 'regen-metal',
|
||||||
crystalDiscipline,
|
name: 'Metal',
|
||||||
stellarDiscipline,
|
manaType: 'metal',
|
||||||
voidDiscipline,
|
cost: 12,
|
||||||
|
description: 'Convert raw mana + fire mana + earth mana into metal mana over time.',
|
||||||
|
conversionRate: 0.35,
|
||||||
|
difficultyFactor: 160,
|
||||||
|
scalingFactor: 80,
|
||||||
|
drainBase: 2,
|
||||||
|
sourceManaTypes: ['raw', 'fire', 'earth'],
|
||||||
|
}),
|
||||||
|
createAdvancedConversionDiscipline({
|
||||||
|
id: 'regen-sand',
|
||||||
|
name: 'Sand',
|
||||||
|
manaType: 'sand',
|
||||||
|
cost: 12,
|
||||||
|
description: 'Convert raw mana + earth mana + water mana into sand mana over time.',
|
||||||
|
conversionRate: 0.35,
|
||||||
|
difficultyFactor: 160,
|
||||||
|
scalingFactor: 80,
|
||||||
|
drainBase: 2,
|
||||||
|
sourceManaTypes: ['raw', 'earth', 'water'],
|
||||||
|
}),
|
||||||
|
createAdvancedConversionDiscipline({
|
||||||
|
id: 'regen-lightning',
|
||||||
|
name: 'Lightning',
|
||||||
|
manaType: 'lightning',
|
||||||
|
cost: 12,
|
||||||
|
description: 'Convert raw mana + fire mana + air mana into lightning mana over time.',
|
||||||
|
conversionRate: 0.35,
|
||||||
|
difficultyFactor: 160,
|
||||||
|
scalingFactor: 80,
|
||||||
|
drainBase: 2,
|
||||||
|
sourceManaTypes: ['raw', 'fire', 'air'],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// ── Exotic Elements ────────────────────────────────────────────────────────
|
||||||
|
createAdvancedConversionDiscipline({
|
||||||
|
id: 'regen-crystal',
|
||||||
|
name: 'Crystal',
|
||||||
|
manaType: 'crystal',
|
||||||
|
cost: 18,
|
||||||
|
description: 'Convert raw mana + sand mana + light mana into crystal mana over time.',
|
||||||
|
conversionRate: 0.25,
|
||||||
|
difficultyFactor: 220,
|
||||||
|
scalingFactor: 110,
|
||||||
|
drainBase: 3,
|
||||||
|
sourceManaTypes: ['raw', 'sand', 'light'],
|
||||||
|
infiniteThreshold: 500,
|
||||||
|
}),
|
||||||
|
createAdvancedConversionDiscipline({
|
||||||
|
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,
|
||||||
|
drainBase: 3,
|
||||||
|
sourceManaTypes: ['raw', 'fire', 'light'],
|
||||||
|
infiniteThreshold: 500,
|
||||||
|
}),
|
||||||
|
createAdvancedConversionDiscipline({
|
||||||
|
id: 'regen-void',
|
||||||
|
name: 'Void',
|
||||||
|
manaType: 'void',
|
||||||
|
cost: 18,
|
||||||
|
description: 'Convert raw mana + dark mana + death mana into void mana over time.',
|
||||||
|
conversionRate: 0.25,
|
||||||
|
difficultyFactor: 220,
|
||||||
|
scalingFactor: 110,
|
||||||
|
drainBase: 3,
|
||||||
|
sourceManaTypes: ['raw', 'dark', 'death'],
|
||||||
|
infiniteThreshold: 500,
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -10,46 +10,60 @@ const BASE_DRAIN = 1.5;
|
|||||||
const BASE_DIFF = 120;
|
const BASE_DIFF = 120;
|
||||||
const BASE_SCALE = 60;
|
const BASE_SCALE = 60;
|
||||||
|
|
||||||
function makeBaseConversion(
|
interface BaseConversionConfig {
|
||||||
id: string,
|
id: string;
|
||||||
name: string,
|
name: string;
|
||||||
manaType: string,
|
manaType: string;
|
||||||
cost: number,
|
cost: number;
|
||||||
): DisciplineDefinition {
|
conversionRate?: number;
|
||||||
|
difficultyFactor?: number;
|
||||||
|
scalingFactor?: number;
|
||||||
|
drainBase?: number;
|
||||||
|
sourceManaTypes?: DisciplineDefinition['manaType'][];
|
||||||
|
}
|
||||||
|
|
||||||
|
function createManaConversionDiscipline(cfg: BaseConversionConfig): DisciplineDefinition {
|
||||||
|
const rate = cfg.conversionRate ?? BASE_CONVERSION;
|
||||||
|
const diff = cfg.difficultyFactor ?? BASE_DIFF;
|
||||||
|
const scale = cfg.scalingFactor ?? BASE_SCALE;
|
||||||
|
const drain = cfg.drainBase ?? BASE_DRAIN;
|
||||||
|
const sources = cfg.sourceManaTypes ?? ['raw' as DisciplineDefinition['manaType']];
|
||||||
|
const nameLower = cfg.name.toLowerCase();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id: cfg.id,
|
||||||
name: `${name} Mana Flow`,
|
name: `${cfg.name} Mana Conversion Speed`,
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
attunement: DisciplinesAttunementType.BASE,
|
||||||
manaType: manaType as DisciplineDefinition['manaType'],
|
manaType: cfg.manaType as DisciplineDefinition['manaType'],
|
||||||
baseCost: cost,
|
baseCost: cfg.cost,
|
||||||
description: `Convert raw mana into ${name.toLowerCase()} mana over time.`,
|
description: `Convert raw mana into ${nameLower} mana over time.`,
|
||||||
statBonus: {
|
statBonus: {
|
||||||
stat: `conversion_${manaType}` as DisciplineDefinition['statBonus']['stat'],
|
stat: `conversion_${cfg.manaType}` as DisciplineDefinition['statBonus']['stat'],
|
||||||
baseValue: BASE_CONVERSION,
|
baseValue: rate,
|
||||||
label: `${name} Conversion/tick`,
|
label: `${cfg.name} Conversion/sec`,
|
||||||
},
|
},
|
||||||
difficultyFactor: BASE_DIFF,
|
difficultyFactor: diff,
|
||||||
scalingFactor: BASE_SCALE,
|
scalingFactor: scale,
|
||||||
drainBase: BASE_DRAIN,
|
drainBase: drain,
|
||||||
conversionRate: BASE_CONVERSION,
|
conversionRate: rate,
|
||||||
sourceManaTypes: ['raw' as DisciplineDefinition['manaType']],
|
sourceManaTypes: sources,
|
||||||
requires: [manaType],
|
requires: [cfg.manaType],
|
||||||
perks: [
|
perks: [
|
||||||
{
|
{
|
||||||
id: `${id}-1`,
|
id: `${cfg.id}-1`,
|
||||||
type: 'once',
|
type: 'once',
|
||||||
threshold: 100,
|
threshold: 100,
|
||||||
value: 0,
|
value: 0,
|
||||||
description: `+${BASE_CONVERSION} ${name} Conversion/tick`,
|
description: `+${rate} ${cfg.name} Conversion/sec`,
|
||||||
bonus: { stat: `conversion_${manaType}`, amount: BASE_CONVERSION },
|
bonus: { stat: `conversion_${cfg.manaType}`, amount: rate },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-inf`,
|
id: `${cfg.id}-inf`,
|
||||||
type: 'infinite',
|
type: 'infinite',
|
||||||
threshold: 300,
|
threshold: 300,
|
||||||
value: 100,
|
value: 100,
|
||||||
description: `Every 100 XP: +0.25 ${name} Conversion/tick`,
|
description: `Every 100 XP: +0.25 ${cfg.name} Conversion/sec`,
|
||||||
bonus: { stat: `conversion_${manaType}`, amount: 0.25 },
|
bonus: { stat: `conversion_${cfg.manaType}`, amount: 0.25 },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -57,46 +71,24 @@ function makeBaseConversion(
|
|||||||
|
|
||||||
export const elementalRegenDisciplines: DisciplineDefinition[] = [
|
export const elementalRegenDisciplines: DisciplineDefinition[] = [
|
||||||
// ── Base Elements ──────────────────────────────────────────────────────────
|
// ── Base Elements ──────────────────────────────────────────────────────────
|
||||||
makeBaseConversion('regen-fire', 'Fire', 'fire', 8),
|
createManaConversionDiscipline({ id: 'regen-fire', name: 'Fire', manaType: 'fire', cost: 8 }),
|
||||||
makeBaseConversion('regen-water', 'Water', 'water', 8),
|
createManaConversionDiscipline({ id: 'regen-water', name: 'Water', manaType: 'water', cost: 8 }),
|
||||||
makeBaseConversion('regen-air', 'Air', 'air', 8),
|
createManaConversionDiscipline({ id: 'regen-air', name: 'Air', manaType: 'air', cost: 8 }),
|
||||||
makeBaseConversion('regen-earth', 'Earth', 'earth', 8),
|
createManaConversionDiscipline({ id: 'regen-earth', name: 'Earth', manaType: 'earth', cost: 8 }),
|
||||||
makeBaseConversion('regen-light', 'Light', 'light', 8),
|
createManaConversionDiscipline({ id: 'regen-light', name: 'Light', manaType: 'light', cost: 8 }),
|
||||||
makeBaseConversion('regen-dark', 'Dark', 'dark', 8),
|
createManaConversionDiscipline({ id: 'regen-dark', name: 'Dark', manaType: 'dark', cost: 8 }),
|
||||||
makeBaseConversion('regen-death', 'Death', 'death', 8),
|
createManaConversionDiscipline({ id: 'regen-death', name: 'Death', manaType: 'death', cost: 8 }),
|
||||||
|
|
||||||
// ── Utility Element ────────────────────────────────────────────────────────
|
// ── Utility Element ────────────────────────────────────────────────────────
|
||||||
{
|
createManaConversionDiscipline({
|
||||||
id: 'regen-transference',
|
id: 'regen-transference',
|
||||||
name: 'Transference Mana Flow',
|
name: 'Transference',
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
|
||||||
manaType: 'transference',
|
manaType: 'transference',
|
||||||
baseCost: 6,
|
cost: 6,
|
||||||
description: 'Convert raw mana into transference mana over time.',
|
conversionRate: 0.4,
|
||||||
statBonus: { stat: 'conversion_transference', baseValue: 0.4, label: 'Transference Conversion/tick' },
|
|
||||||
difficultyFactor: 100,
|
difficultyFactor: 100,
|
||||||
scalingFactor: 50,
|
scalingFactor: 50,
|
||||||
drainBase: 1,
|
drainBase: 1,
|
||||||
conversionRate: 0.4,
|
|
||||||
sourceManaTypes: ['transference'],
|
sourceManaTypes: ['transference'],
|
||||||
requires: ['transference'],
|
}),
|
||||||
perks: [
|
|
||||||
{
|
|
||||||
id: 'regen-transference-1',
|
|
||||||
type: 'once',
|
|
||||||
threshold: 100,
|
|
||||||
value: 0,
|
|
||||||
description: '+0.4 Transference Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_transference', amount: 0.4 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'regen-transference-inf',
|
|
||||||
type: 'infinite',
|
|
||||||
threshold: 300,
|
|
||||||
value: 100,
|
|
||||||
description: 'Every 100 XP: +0.2 Transference Conversion/tick',
|
|
||||||
bonus: { stat: 'conversion_transference', amount: 0.2 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// ─── Elemental Attunement Disciplines ──────────────────────────────────────────
|
// ─── Elemental Capacity Disciplines ──────────────────────────────────────────────
|
||||||
// One discipline per base mana type that increases that element's capacity.
|
// One discipline per mana type that increases that element's capacity.
|
||||||
// All are BASE attunement so they are available to every role once the element is unlocked.
|
// All are BASE attunement so they are available to every role once the element is unlocked.
|
||||||
|
|
||||||
import { DisciplinesAttunementType } from '../../types/disciplines';
|
import { DisciplinesAttunementType } from '../../types/disciplines';
|
||||||
import type { DisciplineDefinition } from '../../types/disciplines';
|
import type { DisciplineDefinition } from '../../types/disciplines';
|
||||||
|
|
||||||
interface ElementalAttunementConfig {
|
interface ManaCapacityConfig {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
manaType: DisciplineDefinition['manaType'];
|
manaType: DisciplineDefinition['manaType'];
|
||||||
@@ -16,24 +16,15 @@ interface ElementalAttunementConfig {
|
|||||||
drainBase: number;
|
drainBase: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ELEMENTAL_ATTUNEMENTS: ElementalAttunementConfig[] = [
|
function createManaCapacityDiscipline(cfg: ManaCapacityConfig): DisciplineDefinition {
|
||||||
{ id: 'attune-fire', name: 'Fire', manaType: 'fire', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
|
||||||
{ id: 'attune-water', name: 'Water', manaType: 'water', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
|
||||||
{ id: 'attune-air', name: 'Air', manaType: 'air', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
|
||||||
{ id: 'attune-earth', name: 'Earth', manaType: 'earth', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
|
||||||
{ id: 'attune-light', name: 'Light', manaType: 'light', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
|
||||||
{ id: 'attune-dark', name: 'Dark', manaType: 'dark', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
|
||||||
{ id: 'attune-death', name: 'Death', manaType: 'death', cost: 12, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 3 },
|
|
||||||
];
|
|
||||||
|
|
||||||
function makeElementalAttunement(cfg: ElementalAttunementConfig): DisciplineDefinition {
|
|
||||||
return {
|
return {
|
||||||
id: cfg.id,
|
id: cfg.id,
|
||||||
name: `${cfg.name} Attunement`,
|
name: `${cfg.name} Mana Capacity`,
|
||||||
attunement: DisciplinesAttunementType.BASE,
|
attunement: DisciplinesAttunementType.BASE,
|
||||||
manaType: cfg.manaType,
|
manaType: cfg.manaType,
|
||||||
baseCost: cfg.cost,
|
baseCost: cfg.cost,
|
||||||
description: `Increase your ${cfg.name.toLowerCase()} mana capacity.`,
|
description: `Increase your ${cfg.name.toLowerCase()} mana capacity.`,
|
||||||
|
requires: [cfg.manaType],
|
||||||
statBonus: { stat: `elementCap_${cfg.manaType}`, baseValue: cfg.baseValue, label: `${cfg.name} Mana Capacity` },
|
statBonus: { stat: `elementCap_${cfg.manaType}`, baseValue: cfg.baseValue, label: `${cfg.name} Mana Capacity` },
|
||||||
difficultyFactor: cfg.difficultyFactor,
|
difficultyFactor: cfg.difficultyFactor,
|
||||||
scalingFactor: cfg.scalingFactor,
|
scalingFactor: cfg.scalingFactor,
|
||||||
@@ -51,5 +42,29 @@ function makeElementalAttunement(cfg: ElementalAttunementConfig): DisciplineDefi
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MANA_CAPACITY_CONFIGS: ManaCapacityConfig[] = [
|
||||||
|
// ── Base Elements ──────────────────────────────────────────────────────────
|
||||||
|
{ id: 'attune-fire', name: 'Fire', manaType: 'fire', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
||||||
|
{ id: 'attune-water', name: 'Water', manaType: 'water', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
||||||
|
{ id: 'attune-air', name: 'Air', manaType: 'air', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
||||||
|
{ id: 'attune-earth', name: 'Earth', manaType: 'earth', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
||||||
|
{ id: 'attune-light', name: 'Light', manaType: 'light', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
||||||
|
{ id: 'attune-dark', name: 'Dark', manaType: 'dark', cost: 10, baseValue: 5, difficultyFactor: 150, scalingFactor: 75, drainBase: 2 },
|
||||||
|
{ id: 'attune-death', name: 'Death', manaType: 'death', cost: 12, baseValue: 4, difficultyFactor: 180, scalingFactor: 90, drainBase: 3 },
|
||||||
|
|
||||||
|
// ── Utility Element ────────────────────────────────────────────────────────
|
||||||
|
{ 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 },
|
||||||
|
|
||||||
|
// ── 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 },
|
||||||
|
];
|
||||||
|
|
||||||
export const elementalAttunementDisciplines: DisciplineDefinition[] =
|
export const elementalAttunementDisciplines: DisciplineDefinition[] =
|
||||||
ELEMENTAL_ATTUNEMENTS.map(makeElementalAttunement);
|
MANA_CAPACITY_CONFIGS.map(createManaCapacityDiscipline);
|
||||||
|
|||||||
Reference in New Issue
Block a user