|
import { db } from './index'; |
|
import type { PicletInstance, Monster, BattleMove } from './schema'; |
|
|
|
|
|
export async function monsterToPicletInstance(monster: Monster, level: number = 5): Promise<Omit<PicletInstance, 'id'>> { |
|
if (!monster.stats) { |
|
throw new Error('Monster must have stats to create PicletInstance'); |
|
} |
|
|
|
const stats = monster.stats; |
|
|
|
|
|
const baseHp = Math.floor(stats.HP * 2 + 50); |
|
const baseAttack = Math.floor(stats.attack * 1.5 + 30); |
|
const baseDefense = Math.floor(stats.defence * 1.5 + 30); |
|
const baseSpeed = Math.floor(stats.speed * 1.5 + 30); |
|
|
|
|
|
const baseFieldAttack = Math.floor(baseAttack * 0.8); |
|
const baseFieldDefense = Math.floor(baseDefense * 0.8); |
|
|
|
|
|
const calculateStat = (base: number, level: number) => Math.floor((base * level) / 50 + 5); |
|
const calculateHp = (base: number, level: number) => Math.floor((base * level) / 50 + level + 10); |
|
|
|
const maxHp = calculateHp(baseHp, level); |
|
|
|
|
|
const moves: BattleMove[] = [ |
|
{ |
|
name: stats.attackActionName, |
|
type: 'normal', |
|
power: 50, |
|
accuracy: 95, |
|
pp: 20, |
|
currentPp: 20, |
|
description: stats.attackActionDescription |
|
}, |
|
{ |
|
name: stats.buffActionName, |
|
type: 'status', |
|
power: 0, |
|
accuracy: 100, |
|
pp: 15, |
|
currentPp: 15, |
|
description: stats.buffActionDescription |
|
}, |
|
{ |
|
name: stats.debuffActionName, |
|
type: 'status', |
|
power: 0, |
|
accuracy: 85, |
|
pp: 15, |
|
currentPp: 15, |
|
description: stats.debuffActionDescription |
|
}, |
|
{ |
|
name: stats.specialActionName, |
|
type: 'special', |
|
power: 80, |
|
accuracy: 90, |
|
pp: 5, |
|
currentPp: 5, |
|
description: stats.specialActionDescription |
|
} |
|
]; |
|
|
|
const bst = baseHp + baseAttack + baseDefense + baseFieldAttack + baseFieldDefense + baseSpeed; |
|
|
|
return { |
|
|
|
typeId: monster.name.toLowerCase().replace(/\s+/g, '-'), |
|
nickname: monster.name, |
|
primaryTypeString: 'normal', |
|
secondaryTypeString: undefined, |
|
|
|
|
|
currentHp: maxHp, |
|
maxHp, |
|
level, |
|
xp: 0, |
|
attack: calculateStat(baseAttack, level), |
|
defense: calculateStat(baseDefense, level), |
|
fieldAttack: calculateStat(baseFieldAttack, level), |
|
fieldDefense: calculateStat(baseFieldDefense, level), |
|
speed: calculateStat(baseSpeed, level), |
|
|
|
|
|
baseHp, |
|
baseAttack, |
|
baseDefense, |
|
baseFieldAttack, |
|
baseFieldDefense, |
|
baseSpeed, |
|
|
|
|
|
moves, |
|
nature: 'hardy', |
|
|
|
|
|
isInRoster: false, |
|
rosterPosition: undefined, |
|
|
|
|
|
caughtAt: new Date(), |
|
bst, |
|
tier: stats.rarity > 80 ? 'legendary' : stats.rarity > 60 ? 'rare' : stats.rarity > 40 ? 'uncommon' : 'common', |
|
role: 'balanced', |
|
variance: 0, |
|
|
|
|
|
imageUrl: monster.imageUrl, |
|
imageData: monster.imageData, |
|
imageCaption: monster.imageCaption, |
|
concept: monster.concept, |
|
imagePrompt: monster.imagePrompt |
|
}; |
|
} |
|
|
|
|
|
export async function savePicletInstance(piclet: Omit<PicletInstance, 'id'>): Promise<number> { |
|
return await db.picletInstances.add(piclet); |
|
} |
|
|
|
|
|
export async function getAllPicletInstances(): Promise<PicletInstance[]> { |
|
return await db.picletInstances.toArray(); |
|
} |
|
|
|
|
|
export async function getRosterPiclets(): Promise<PicletInstance[]> { |
|
return await db.picletInstances |
|
.where('isInRoster') |
|
.equals(1) |
|
.sortBy('rosterPosition'); |
|
} |
|
|
|
|
|
export async function updateRosterPosition(id: number, position: number | undefined): Promise<void> { |
|
await db.picletInstances.update(id, { |
|
isInRoster: position !== undefined, |
|
rosterPosition: position |
|
}); |
|
} |
|
|
|
|
|
export async function deletePicletInstance(id: number): Promise<void> { |
|
await db.picletInstances.delete(id); |
|
} |