| |
| |
| |
|
|
| import type { PicletInstance, BattleMove } from '$lib/db/schema'; |
| import type { PicletDefinition, Move, BaseStats, SpecialAbility } from '$lib/battle-engine/types'; |
| import type { PicletStats, BattleEffect, AbilityTrigger } from '$lib/types'; |
| import { PicletType, AttackType } from '$lib/types/picletTypes'; |
| import { recalculatePicletStats } from '$lib/services/levelingService'; |
| import { getUnlockedMoves, isSpecialAbilityUnlocked } from '$lib/services/unlockLevels'; |
|
|
| |
| |
| |
| |
| export function picletInstanceToBattleDefinition(instance: PicletInstance): PicletDefinition { |
| |
| const updatedInstance = recalculatePicletStats(instance); |
| |
| |
| const baseStats: BaseStats = { |
| hp: updatedInstance.maxHp, |
| attack: updatedInstance.attack, |
| defense: updatedInstance.defense, |
| speed: updatedInstance.speed |
| }; |
|
|
| |
| const unlockedMoves = getUnlockedMoves(instance.moves, updatedInstance.level); |
| const movepool: Move[] = unlockedMoves.map(move => convertBattleMoveToMove(move, instance.primaryType)); |
| |
| |
| if (movepool.length === 0) { |
| console.warn(`Piclet ${instance.nickname} has no unlocked moves at level ${updatedInstance.level}!`); |
| |
| if (instance.moves.length > 0) { |
| const firstMove = convertBattleMoveToMove(instance.moves[0], instance.primaryType); |
| movepool.push(firstMove); |
| } |
| } |
|
|
| |
| if (!instance.specialAbility) { |
| throw new Error('Piclet must have a special ability.'); |
| } |
| |
| |
| let specialAbility: SpecialAbility | undefined; |
| if (isSpecialAbilityUnlocked(instance.specialAbilityUnlockLevel, updatedInstance.level)) { |
| specialAbility = instance.specialAbility; |
| } else { |
| |
| specialAbility = { |
| name: "Locked Ability", |
| description: `Unlocks at level ${instance.specialAbilityUnlockLevel}`, |
| trigger: "onBattleStart" as any, |
| effects: [] |
| }; |
| } |
|
|
| |
| const bst = baseStats.hp + baseStats.attack + baseStats.defense + baseStats.speed; |
| let tier: 'low' | 'medium' | 'high' | 'legendary'; |
| if (bst <= 300) tier = 'low'; |
| else if (bst <= 400) tier = 'medium'; |
| else if (bst <= 500) tier = 'high'; |
| else tier = 'legendary'; |
|
|
| return { |
| name: instance.nickname || instance.typeId, |
| description: instance.concept, |
| tier, |
| primaryType: instance.primaryType, |
| secondaryType: instance.secondaryType, |
| baseStats, |
| nature: instance.nature, |
| specialAbility, |
| movepool |
| }; |
| } |
|
|
| |
| |
| |
| function convertBattleMoveToMove(battleMove: BattleMove, primaryType: PicletType): Move { |
| |
| const effects: any[] = []; |
| |
| if (battleMove.power > 0) { |
| effects.push({ |
| type: 'damage', |
| target: 'opponent', |
| amount: battleMove.power >= 80 ? 'strong' : |
| battleMove.power >= 60 ? 'normal' : 'weak' |
| }); |
| } |
|
|
| |
| if (battleMove.power === 0) { |
| effects.push({ |
| type: 'modifyStats', |
| target: 'self', |
| stats: { attack: 'increase' } |
| }); |
| } |
|
|
| return { |
| name: battleMove.name, |
| type: battleMove.type, |
| power: battleMove.power, |
| accuracy: battleMove.accuracy, |
| pp: battleMove.pp, |
| priority: 0, |
| flags: battleMove.power > 0 && battleMove.name.toLowerCase().includes('tackle') ? ['contact'] : [], |
| effects |
| }; |
| } |
|
|
|
|
| |
| |
| |
| export function battlePicletToInstance(battlePiclet: any, originalInstance: PicletInstance): PicletInstance { |
| return { |
| ...originalInstance, |
| currentHp: battlePiclet.currentHp, |
| level: battlePiclet.level, |
| attack: battlePiclet.attack, |
| defense: battlePiclet.defense, |
| speed: battlePiclet.speed, |
| |
| moves: battlePiclet.moves.map((moveData: any, index: number) => ({ |
| ...originalInstance.moves[index], |
| currentPp: moveData.currentPP |
| })) |
| }; |
| } |
|
|
| |
| |
| |
| export function picletStatsToBattleDefinition(stats: PicletStats, name: string, concept: string): PicletDefinition { |
| return { |
| name: stats.name || name, |
| description: stats.description || concept, |
| tier: stats.tier, |
| primaryType: stats.primaryType, |
| secondaryType: stats.secondaryType || undefined, |
| baseStats: stats.baseStats, |
| nature: stats.nature, |
| specialAbility: stats.specialAbility, |
| movepool: stats.movepool |
| }; |
| } |
|
|
| |
| |
| |
| |
| export function stripBattlePrefix(name: string): string { |
| if (name.startsWith('player-')) { |
| return name.substring('player-'.length); |
| } |
| if (name.startsWith('enemy-')) { |
| return name.substring('enemy-'.length); |
| } |
| return name; |
| } |