export type GameClass = { id: number slug: string name: string resourceName: string maxResource: number themeColor: string description: string spells: Ability[] talents: Talent[] } export type Ability = { id: number classId: number slug: string name: string spellType: string cost: number cooldown: number power: number unlockLevel: number glyph: string description: string } export type Talent = { id: number classId: number slug: string name: string maxRank: number tier: number branch: number prerequisiteTalentId: number | null prerequisiteRank: number prerequisiteName: string | null effectType: string effectValuePerRank: number glyph: string description: string rank: number } export type EquipmentSlot = | 'weapon' | 'helmet' | 'chest' | 'gloves' | 'boots' | 'pants' | 'ring' | 'necklace' | 'trinket' | 'component' export type Item = { id: number slug: string name: string slot: EquipmentSlot rarity: 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary' itemLevel: number healingPower: number maxResourceBonus: number glyph: string description: string setId?: number | null setSlug?: string | null setName?: string | null quantity: number equipped: boolean } export type SetBonus = { setId: number setSlug: string setName: string requiredPieces: number effectType: 'mend_extra_target' | 'renew_extra_target' | 'mend_applies_renew' | string description: string equippedPieces: number active: boolean } export type Difficulty = { dungeonId: number id: number slug: string name: string droppedItemLevel: number unlockLevel: number healthMultiplier: number damageMultiplier: number experienceMultiplier: number description: string } export type DungeonEncounter = { id: number dungeonId: number sequence: number slug: string enemyName: string encounterType: 'trash' | 'boss' maxHealth: number damage: number tankDamage: number partyDamage: number description: string imageUrl: string isBoss: boolean lootTables: LootTableEntry[] } export type LootTableEntry = Omit & { encounterId: number difficultyId: number dropWeight: number dropChance: number } export type CraftingRecipe = { id: number difficultyId: number | null sourceDungeonId: number | null sourceEncounterId: number | null item: Omit components: Array<{ item: Omit quantity: number owned: number }> canCraft: boolean } export type GearUpgradePath = { fromItemId: number toItemId: number } export type LootRollItem = Omit & { quantity: number duplicate: boolean quantityAfter: number } export type LootRoll = { encounterId: number encounterName: string difficultyId: number difficultyName: string dropChance: number dropped: boolean item: LootRollItem | null items: LootRollItem[] awarded: boolean duplicate: boolean quantityAfter: number } export type Dungeon = { id: number slug: string name: string recommendedLevel: number contentType: 'dungeon' | 'raid' partySize: number completionItemLevel: number | null experienceReward: number imageUrl: string description: string locationName: string difficulties: Difficulty[] encounters: DungeonEncounter[] completionLoot: Array> completionCount?: number leaderboard: LeaderboardEntry[] leaderboards: { part_1: LeaderboardEntry[] part_2: LeaderboardEntry[] part_3: LeaderboardEntry[] full_run: LeaderboardEntry[] } } export type LeaderboardEntry = { rank: number dungeonId: number difficultyId: number characterName: string className: string characterLevel: number averageItemLevel: number resourceSpent: number durationSeconds: number completedAt: string } export type CharacterProfile = { character: { id: number name: string level: number experience: number currentLevelExperience: number nextLevelExperience: number talentPoints: number classId: number classSlug: string className: string resourceName: string maxResource: number themeColor: string classDescription: string } classes: GameClass[] abilitySlots: Array maxLevel: number maxTalentPoints: number allocatedTalentPoints: number equipmentSlots: EquipmentSlot[] inventory: Item[] completedDungeonParts: number completedRaidPhases: number gearStats: { averageItemLevel: number healingPower: number maxResourceBonus: number } setBonuses: SetBonus[] craftingRecipes: CraftingRecipe[] gearUpgradePaths: GearUpgradePath[] dungeons: Dungeon[] } export type Account = { id: number username: string } export type AuthSession = { account: Account | null profile: CharacterProfile | null token?: string } export type BonusItem = { id: number slug: string name: string slot: string rarity: string itemLevel: number healingPower: number maxResourceBonus: number glyph: string description: string quantity: number duplicate: boolean quantityAfter: number } export type DungeonReward = { dungeonName: string difficultyName: string droppedItemLevel: number experienceGained: number previousLevel: number newLevel: number levelsGained: number talentPointsGained: number resourceSpent: number durationSeconds: number averageItemLevel: number unlockedAbilities: Array<{ id: number name: string unlockLevel: number glyph: string }> bonusItem: BonusItem | null profile: CharacterProfile } import { activeGameRepository } from './gameRepository' export function loadAuthSession(): Promise { return activeGameRepository().loadSession() } export function registerAccount( username: string, password: string, characterName: string, ): Promise { return activeGameRepository().register(username, password, characterName) } export function loginAccount( username: string, password: string, ): Promise { return activeGameRepository().login(username, password) } export async function logoutAccount(): Promise { await activeGameRepository().logout() } export async function loadProfile(): Promise { return activeGameRepository().loadProfile() } export async function saveProfile( classId: number, abilitySlots: Array, ): Promise { return activeGameRepository().saveProfile(classId, abilitySlots) } export async function completeDungeon( dungeonId: number, difficultyId: number, resourceSpent: number, durationSeconds: number, completedPart?: number, startPart?: number, partDurationSeconds?: [number, number, number], hardMode?: boolean, ): Promise { return activeGameRepository().completeDungeon( dungeonId, difficultyId, resourceSpent, durationSeconds, completedPart, startPart, partDurationSeconds, hardMode, ) } export async function completeRoguelike( dungeonId: number, difficultyId: number, encountersCleared: number, resourceSpent: number, durationSeconds: number, options?: { bossesCleared?: number experienceMode?: 'default' | 'pvp-boss-quarter-level' lootSourceEncounterId?: number roguelikeStage?: number }, ): Promise { return activeGameRepository().completeRoguelike( dungeonId, difficultyId, encountersCleared, resourceSpent, durationSeconds, options, ) } export async function allocateTalent(talentId: number): Promise { return activeGameRepository().allocateTalent(talentId) } export async function resetTalents(): Promise { return activeGameRepository().resetTalents() } export async function equipItem(itemId: number): Promise { return activeGameRepository().equipItem(itemId) } export async function discardExtraItem(itemId: number): Promise { return activeGameRepository().discardExtraItem(itemId) } export async function breakdownItem(itemId: number): Promise { return activeGameRepository().breakdownItem(itemId) } export async function craftItem(recipeId: number): Promise { return activeGameRepository().craftItem(recipeId) } export async function upgradeItem(itemId: number): Promise { return activeGameRepository().upgradeItem(itemId) } export async function rollEncounterLoot( encounterId: number, difficultyId: number, runToken: string, ): Promise { return activeGameRepository().rollEncounterLoot( encounterId, difficultyId, runToken, ) }