Initial I Want to Heal app

This commit is contained in:
Warren H
2026-06-17 20:04:36 -04:00
parent 3880db1b58
commit 3c90998a61
109 changed files with 32775 additions and 0 deletions
+387
View File
@@ -0,0 +1,387 @@
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'
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<Item, 'quantity' | 'equipped'> & {
encounterId: number
difficultyId: number
dropWeight: number
dropChance: number
}
export type CraftingRecipe = {
id: number
difficultyId: number | null
sourceDungeonId: number | null
sourceEncounterId: number | null
item: Omit<Item, 'quantity' | 'equipped'>
components: Array<{
item: Omit<Item, 'quantity' | 'equipped'>
quantity: number
owned: number
}>
canCraft: boolean
}
export type LootRollItem = Omit<Item, 'quantity' | 'equipped'> & {
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
description: string
locationName: string
difficulties: Difficulty[]
encounters: DungeonEncounter[]
completionLoot: Array<Omit<Item, 'quantity' | 'equipped'>>
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<number | null>
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[]
dungeons: Dungeon[]
}
export type Account = {
id: number
username: string
}
export type AuthSession = {
account: Account | null
profile: CharacterProfile | null
}
export type BonusItem = {
id: number
slug: string
name: string
slot: string
rarity: string
itemLevel: number
healingPower: number
maxResourceBonus: number
glyph: string
description: string
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<AuthSession> {
return activeGameRepository().loadSession()
}
export function registerAccount(
username: string,
password: string,
characterName: string,
): Promise<AuthSession> {
return activeGameRepository().register(username, password, characterName)
}
export function loginAccount(
username: string,
password: string,
): Promise<AuthSession> {
return activeGameRepository().login(username, password)
}
export async function logoutAccount(): Promise<void> {
await activeGameRepository().logout()
}
export async function loadProfile(): Promise<CharacterProfile> {
return activeGameRepository().loadProfile()
}
export async function saveProfile(
classId: number,
abilitySlots: Array<number | null>,
): Promise<CharacterProfile> {
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],
): Promise<DungeonReward> {
return activeGameRepository().completeDungeon(
dungeonId,
difficultyId,
resourceSpent,
durationSeconds,
completedPart,
startPart,
partDurationSeconds,
)
}
export async function completeRoguelike(
dungeonId: number,
difficultyId: number,
encountersCleared: number,
resourceSpent: number,
durationSeconds: number,
options?: {
bossesCleared?: number
experienceMode?: 'default' | 'pvp-boss-quarter-level'
},
): Promise<DungeonReward> {
return activeGameRepository().completeRoguelike(
dungeonId,
difficultyId,
encountersCleared,
resourceSpent,
durationSeconds,
options,
)
}
export async function allocateTalent(talentId: number): Promise<CharacterProfile> {
return activeGameRepository().allocateTalent(talentId)
}
export async function resetTalents(): Promise<CharacterProfile> {
return activeGameRepository().resetTalents()
}
export async function equipItem(itemId: number): Promise<CharacterProfile> {
return activeGameRepository().equipItem(itemId)
}
export async function discardExtraItem(itemId: number): Promise<CharacterProfile> {
return activeGameRepository().discardExtraItem(itemId)
}
export async function breakdownItem(itemId: number): Promise<CharacterProfile> {
return activeGameRepository().breakdownItem(itemId)
}
export async function craftItem(recipeId: number): Promise<CharacterProfile> {
return activeGameRepository().craftItem(recipeId)
}
export async function rollEncounterLoot(
encounterId: number,
difficultyId: number,
runToken: string,
): Promise<LootRoll> {
return activeGameRepository().rollEncounterLoot(
encounterId,
difficultyId,
runToken,
)
}