fix: SLOT_NAMES export and refactor: split crafting-slice.ts into modules
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m51s

This commit is contained in:
Refactoring Agent
2026-05-02 10:59:36 +02:00
parent dc38445225
commit c9ae2576f4
14 changed files with 2213 additions and 942 deletions
+171
View File
@@ -0,0 +1,171 @@
// ─── Attunement System ──────────────────────────────────────────────────────
// Attunement system functions extracted from crafting-slice.ts
import type { AttunementState } from './types';
import { calculateEnchantingXP, getAttunementXPForLevel, MAX_ATTUNEMENT_LEVEL } from './data/attunements';
// ─── Enchanter Attunement ──────────────────────────────────────────────────
export function initEnchanterAttunement(): AttunementState {
return {
id: 'enchanter',
active: true,
level: 1,
experience: 0,
title: 'Novice Enchanter',
};
}
export function isEnchanterActive(attunements: Record<string, AttunementState>): boolean {
return attunements.enchanter?.active === true;
}
// ─── XP Gain & Leveling ────────────────────────────────────────────────────
export function gainEnchantingXP(
attunements: Record<string, AttunementState>,
xpAmount: number
): {
attunements: Record<string, AttunementState>;
leveledUp: boolean;
previousLevel: number;
newLevel: number;
} {
if (!attunements?.enchanter?.active || xpAmount <= 0) {
return {
attunements,
leveledUp: false,
previousLevel: attunements.enchanter?.level || 0,
newLevel: attunements.enchanter?.level || 0,
};
}
const previousLevel = attunements.enchanter.level;
let newXP = attunements.enchanter.experience + xpAmount;
let newLevel = attunements.enchanter.level;
let leveledUp = false;
while (newLevel < MAX_ATTUNEMENT_LEVEL) {
const xpNeeded = getAttunementXPForLevel(newLevel + 1);
if (newXP >= xpNeeded) {
newXP -= xpNeeded;
newLevel++;
leveledUp = true;
} else {
break;
}
}
const updatedAttunements: Record<string, AttunementState> = {
...attunements,
enchanter: {
...attunements.enchanter,
level: newLevel,
experience: newXP,
},
};
return {
attunements: updatedAttunements,
leveledUp,
previousLevel,
newLevel,
};
}
export function getXpToNextLevel(currentLevel: number): number {
if (currentLevel >= MAX_ATTUNEMENT_LEVEL) return 0;
return getAttunementXPForLevel(currentLevel + 1);
}
export function getLevelProgress(attunements: Record<string, AttunementState>): {
currentLevel: number;
currentXP: number;
xpToNextLevel: number;
progressPercent: number;
maxLevel: number;
} {
const enchanter = attunements?.enchanter;
if (!enchanter?.active) {
return {
currentLevel: 0,
currentXP: 0,
xpToNextLevel: 0,
progressPercent: 0,
maxLevel: MAX_ATTUNEMENT_LEVEL,
};
}
const xpToNext = getXpToNextLevel(enchanter.level);
return {
currentLevel: enchanter.level,
currentXP: enchanter.experience,
xpToNextLevel: xpToNext,
progressPercent: xpToNext > 0 ? (enchanter.experience / xpToNext) * 100 : 100,
maxLevel: MAX_ATTUNEMENT_LEVEL,
};
}
export function calculateEnchantingXpFromDesignCapacity(capacityCost: number): number {
return calculateEnchantingXP(capacityCost);
}
export function calculateXpFromEquipmentInstance(
instance: { enchantments: Array<{ effectId: string; stacks: number; actualCost: number }> }
): number {
let totalXp = 0;
for (const ench of instance.enchantments) {
totalXp += calculateEnchantingXP(ench.actualCost);
}
return totalXp;
}
export function getEnchanterTitle(level: number): string {
if (level >= 10) return 'Grandmaster Enchanter';
if (level >= 8) return 'Master Enchanter';
if (level >= 6) return 'Expert Enchanter';
if (level >= 4) return 'Journeyman Enchanter';
if (level >= 2) return 'Apprentice Enchanter';
return 'Novice Enchanter';
}
export function updateEnchanterTitle(attunements: Record<string, AttunementState>): Record<string, AttunementState> {
if (!attunements.enchanter?.active) return attunements;
const title = getEnchanterTitle(attunements.enchanter.level);
return {
...attunements,
enchanter: { ...attunements.enchanter, title },
};
}
export function resetEnchanterExperience(attunements: Record<string, AttunementState>): Record<string, AttunementState> {
if (!attunements.enchanter) return attunements;
return {
...attunements,
enchanter: { ...attunements.enchanter, experience: 0, level: 1, title: 'Novice Enchanter' },
};
}
export function initAttunements(): Record<string, AttunementState> {
return { enchanter: initEnchanterAttunement() };
}
export function batchGainXP(
attunements: Record<string, AttunementState>,
xpAmounts: number[]
): { attunements: Record<string, AttunementState>; totalXP: number; totalLevelUps: number; finalLevel: number } {
let result = {
attunements,
totalXP: 0,
totalLevelUps: 0,
finalLevel: attunements.enchanter?.level || 1,
};
for (const xpAmount of xpAmounts) {
const gain = gainEnchantingXP(result.attunements, xpAmount);
result.attunements = gain.attunements;
result.totalXP += xpAmount;
if (gain.leveledUp) result.totalLevelUps++;
result.finalLevel = gain.newLevel;
}
return result;
}