import type { CharacterProfile } from "../app/types"; import { abilitiesForCharacter, abilityTalentNodeId, defaultActionBarForCharacter, learnedAbilityForBuild, resourceProfileForClass, type AbilityDefinition, type ClassResourceProfile, } from "./abilityCatalog"; import { normalizeActionBindings } from "./actionBindings"; import type { ArenaCharacterKit } from "./arenaTypes"; import { deriveCharacterStats } from "./wotlkStats"; import { activeEquipmentStatsForClass, PLAYER_EQUIPMENT_OWNER_ID } from "./equipment"; export function arenaCharacterAbilities(character: CharacterProfile, level = character.level): readonly AbilityDefinition[] { return abilitiesForCharacter(character.classId, character.secondaryClassId) .filter((ability) => !ability.passive) .map((ability) => learnedAbilityForBuild(ability, level, character.talentRanks)) .filter((ability): ability is AbilityDefinition => ability !== null); } export function arenaAbilityIsLearned(ability: AbilityDefinition, character: CharacterProfile, level = character.level): boolean { return ability.unlockLevel <= level && (!abilityTalentNodeId(ability) || learnedAbilityForBuild(ability, level, character.talentRanks) !== null); } export function createArenaCharacterKit(character: CharacterProfile, level = character.level): ArenaCharacterKit { const stats = deriveCharacterStats( character.classId, level, activeEquipmentStatsForClass(character.equipment, character.inventory, PLAYER_EQUIPMENT_OWNER_ID, character.classId), character.raceId, {}, character.secondaryClassId, character.gender, character.statRuleset ?? "wow", ); const profile = resourceProfileForClass(character.classId); const resource = profile.type === "mana" ? { ...profile, maximum: stats.mana, initial: stats.mana, regenerationPerSecond: stats.mana * 0.004 } : profile; const abilities = arenaCharacterAbilities(character, level).filter((ability) => arenaAbilityIsLearned(ability, character, level)); const all = abilitiesForCharacter(character.classId, character.secondaryClassId); const actionBindings = normalizeActionBindings(character.actionBindings, [ ...defaultActionBarForCharacter(character.classId, character.secondaryClassId, level), ...all.filter((ability) => abilityTalentNodeId(ability) && !ability.passive).map((ability) => ability.id), ]); return { seed: { ...character, level, settings: { ...character.settings, autoTargetNearest: false } }, classId: character.classId, level, resource: resource as ClassResourceProfile, stats: { health: stats.health, spellPower: stats.spellPower }, abilities: Object.fromEntries(abilities.map((ability) => [ability.id, ability])), actionBindings, }; }