114 lines
4.4 KiB
TypeScript
114 lines
4.4 KiB
TypeScript
// ─── Crafting Preparation System ────────────────────────────────────────────
|
|
// Preparation system functions
|
|
|
|
import type { EquipmentInstance, PreparationProgress } from './types';
|
|
import { calculatePrepTime, calculatePrepManaCost, calculateManaPerHourForPrep } from './crafting-utils';
|
|
import { HOURS_PER_TICK } from './constants';
|
|
|
|
// ─── Preparation Validation ─────────────────────────────────────────────────
|
|
|
|
export function canPrepareEquipment(
|
|
instance: EquipmentInstance | undefined,
|
|
currentTags: string[]
|
|
): { canPrepare: boolean; reason?: string } {
|
|
if (!instance) return { canPrepare: false, reason: 'Equipment instance not found' };
|
|
if (currentTags.includes('Ready for Enchantment')) return { canPrepare: false, reason: 'Equipment is already prepared for enchanting' };
|
|
return { canPrepare: true };
|
|
}
|
|
|
|
// ─── Preparation Costs ──────────────────────────────────────────────────────
|
|
|
|
export interface PreparationCosts {
|
|
time: number;
|
|
manaTotal: number;
|
|
manaPerHour: number;
|
|
manaPerTick: number;
|
|
}
|
|
|
|
export function calculatePreparationCosts(totalCapacity: number): PreparationCosts {
|
|
const time = calculatePrepTime(totalCapacity);
|
|
const manaTotal = calculatePrepManaCost(totalCapacity);
|
|
const manaPerHour = calculateManaPerHourForPrep(totalCapacity, time);
|
|
return { time, manaTotal, manaPerHour, manaPerTick: manaPerHour * HOURS_PER_TICK };
|
|
}
|
|
|
|
export function initializePreparationProgress(
|
|
equipmentInstanceId: string,
|
|
totalCapacity: number,
|
|
manaCostPaid: number = 0
|
|
): PreparationProgress {
|
|
const costs = calculatePreparationCosts(totalCapacity);
|
|
return { equipmentInstanceId, progress: 0, required: costs.time, manaCostPaid };
|
|
}
|
|
|
|
// ─── Preparation Tick ───────────────────────────────────────────────────────
|
|
|
|
export interface PreparationTickResult {
|
|
progress: number;
|
|
manaCostPaid: number;
|
|
manaConsumed: number;
|
|
isComplete: boolean;
|
|
}
|
|
|
|
export function calculatePreparationTick(
|
|
currentProgress: number,
|
|
required: number,
|
|
currentManaCostPaid: number,
|
|
manaPerTick: number
|
|
): PreparationTickResult {
|
|
const progress = currentProgress + HOURS_PER_TICK;
|
|
const manaConsumed = manaPerTick;
|
|
return {
|
|
progress,
|
|
manaCostPaid: currentManaCostPaid + manaConsumed,
|
|
manaConsumed,
|
|
isComplete: progress >= required,
|
|
};
|
|
}
|
|
|
|
// ─── Preparation Completion ─────────────────────────────────────────────────
|
|
|
|
const BASE_DISENCHANT_RECOVERY_RATE = 0.1;
|
|
const DISENCHANT_RECOVERY_PER_LEVEL = 0.2;
|
|
|
|
export function completePreparation(
|
|
instance: EquipmentInstance,
|
|
disenchantLevel: number = 0
|
|
): { updatedInstance: EquipmentInstance; manaRecovered: number; logMessage: string } {
|
|
const recoveryRate = BASE_DISENCHANT_RECOVERY_RATE + disenchantLevel * DISENCHANT_RECOVERY_PER_LEVEL;
|
|
let totalRecovered = 0;
|
|
for (const ench of instance.enchantments) {
|
|
totalRecovered += Math.floor(ench.actualCost * recoveryRate);
|
|
}
|
|
|
|
return {
|
|
updatedInstance: {
|
|
...instance,
|
|
enchantments: [],
|
|
usedCapacity: 0,
|
|
rarity: 'common',
|
|
tags: [...(instance.tags || []), 'Ready for Enchantment'],
|
|
},
|
|
manaRecovered: totalRecovered,
|
|
logMessage: `✅ Equipment prepared for enchanting! Recovered ${totalRecovered} mana.`,
|
|
};
|
|
}
|
|
|
|
export function cancelPreparation() {
|
|
return { logMessage: 'Preparation cancelled.' };
|
|
}
|
|
|
|
// ─── Preparation State Calculations ─────────────────────────────────────────
|
|
|
|
export function getPreparationManaCostForTick(instance: EquipmentInstance): number {
|
|
return calculatePreparationCosts(instance.totalCapacity).manaPerTick;
|
|
}
|
|
|
|
export function getPreparationRemainingTime(currentProgress: number, required: number): number {
|
|
return Math.max(0, required - currentProgress);
|
|
}
|
|
|
|
export function getPreparationCompletionPercent(currentProgress: number, required: number): number {
|
|
return Math.min(100, Math.floor((currentProgress / required) * 100));
|
|
}
|