/** * Utility functions for calculating unlock levels for moves and abilities */ import type { BattleMove } from '$lib/db/schema'; import type { SpecialAbility } from '$lib/battle-engine/types'; /** * Calculate unlock level for a move based on its power and characteristics * More powerful moves unlock later, with some randomness */ export function calculateMoveUnlockLevel(move: BattleMove, moveIndex: number): number { // Base unlock level based on power let baseLevel = 1; if (move.power === 0) { // Status/support moves - unlock early to mid game baseLevel = Math.floor(Math.random() * 20) + 5; // Level 5-25 } else if (move.power <= 40) { // Weak moves - unlock early baseLevel = Math.floor(Math.random() * 15) + 1; // Level 1-15 } else if (move.power <= 60) { // Medium moves - unlock early to mid baseLevel = Math.floor(Math.random() * 25) + 10; // Level 10-35 } else if (move.power <= 80) { // Strong moves - unlock mid to late baseLevel = Math.floor(Math.random() * 30) + 25; // Level 25-55 } else { // Very powerful moves - unlock late baseLevel = Math.floor(Math.random() * 25) + 40; // Level 40-65 } // Adjust based on move position (later moves tend to be more powerful) const positionBonus = moveIndex * 5; // 0, 5, 10, 15 for moves 1-4 baseLevel += positionBonus; // Ensure first move is always available at level 1 if (moveIndex === 0) { baseLevel = 1; } // Cap at level 80 (everything must be unlocked by then) return Math.min(baseLevel, 80); } /** * Calculate unlock level for special ability based on its power and effects */ export function calculateSpecialAbilityUnlockLevel(ability: SpecialAbility): number { // Base level based on ability impact let baseLevel = 15; // Default mid-level unlock // Analyze ability effects to determine power level const effects = ability.effects || []; let powerScore = 0; for (const effect of effects) { switch (effect.type) { case 'damage': powerScore += effect.amount === 'strong' ? 3 : effect.amount === 'normal' ? 2 : 1; break; case 'heal': powerScore += effect.amount === 'large' ? 3 : effect.amount === 'medium' ? 2 : 1; break; case 'modifyStats': // Stat modifications are powerful powerScore += 2; break; case 'applyStatus': powerScore += 2; break; case 'removeStatus': powerScore += 1; break; case 'manipulatePP': powerScore += 1; break; default: powerScore += 1; } } // Convert power score to unlock level if (powerScore <= 2) { baseLevel = Math.floor(Math.random() * 20) + 10; // Level 10-30 } else if (powerScore <= 4) { baseLevel = Math.floor(Math.random() * 25) + 20; // Level 20-45 } else if (powerScore <= 6) { baseLevel = Math.floor(Math.random() * 25) + 30; // Level 30-55 } else { baseLevel = Math.floor(Math.random() * 25) + 40; // Level 40-65 } // Cap at level 80 return Math.min(baseLevel, 80); } /** * Get all unlocked moves for a Piclet at a given level */ export function getUnlockedMoves(moves: BattleMove[], currentLevel: number): BattleMove[] { return moves.filter(move => move.unlockLevel <= currentLevel); } /** * Check if special ability is unlocked at given level */ export function isSpecialAbilityUnlocked(unlockLevel: number, currentLevel: number): boolean { return currentLevel >= unlockLevel; } /** * Generate unlock levels for a new Piclet's moves and ability * This should be called when a Piclet is first generated */ export function generateUnlockLevels(moves: BattleMove[], specialAbility: SpecialAbility): { movesWithUnlocks: BattleMove[]; abilityUnlockLevel: number; } { const movesWithUnlocks = moves.map((move, index) => ({ ...move, unlockLevel: calculateMoveUnlockLevel(move, index) })); const abilityUnlockLevel = calculateSpecialAbilityUnlockLevel(specialAbility); return { movesWithUnlocks, abilityUnlockLevel }; }