import type { AbilityDefinition } from "./abilityCatalog"; import { targetingRulesForAbility } from "./abilityRules"; import { ROM_PHYSICAL_DARK_DAMAGE_PROFILE } from "./combatDamageProfile"; import type { CombatDamageProfile } from "./combatDamageProfile"; export const ROM_PSYCHIC_WARRIOR_PASSIVE_ID = 499868; export const ROM_PSYCHIC_WARRIOR_PRIMARY_CLASS_ID = "rom-warlock"; export const ROM_PSYCHIC_WARRIOR_SECONDARY_CLASS_ID = "rom-warrior"; export interface RomPsychicWarriorCasterContext { readonly primaryClassId: AbilityDefinition["classId"]; readonly secondaryClassId: AbilityDefinition["classId"] | null; readonly learnedPassiveSpellIds: readonly number[]; /** True only when the triggering action is a CoA-style magical spell. */ readonly isMagicalSpell: boolean; } export interface RomPsychicWarriorWeaponRider { readonly damageProfile: CombatDamageProfile; readonly targetMode: "area" | "single-target"; readonly weaponHand: "main-hand"; /** Coefficient passed to the combat engine's main-hand weapon-DPS scaling. */ readonly weaponDpsCoefficient: number; } /** * Resolve CoA Psychic Warrior's quantified weapon choice for a damaging * Warlock spell. The combat model has no integrated Physical Dark composite * damage type yet, so this descriptor preserves both tags and must not be * collapsed to one DamageSchool by a caller. */ export function describeRomPsychicWarriorWeaponRider( ability: AbilityDefinition, caster: RomPsychicWarriorCasterContext, ): RomPsychicWarriorWeaponRider | null { if (caster.primaryClassId !== ROM_PSYCHIC_WARRIOR_PRIMARY_CLASS_ID || caster.secondaryClassId !== ROM_PSYCHIC_WARRIOR_SECONDARY_CLASS_ID || !caster.learnedPassiveSpellIds.includes(ROM_PSYCHIC_WARRIOR_PASSIVE_ID) || !caster.isMagicalSpell || ability.source !== "runewaker" || ability.classId !== "rom-warlock" || ability.passive || !ability.effects.some((effect) => effect.kind === "damage")) { return null; } const targeting = targetingRulesForAbility(ability); const isAreaDamage = targeting.shape !== "unit" || (targeting.maximumTargets ?? 0) > 1 || (targeting.radius ?? 0) > 0; return { damageProfile: ROM_PHYSICAL_DARK_DAMAGE_PROFILE, targetMode: isAreaDamage ? "area" : "single-target", weaponHand: "main-hand", weaponDpsCoefficient: isAreaDamage ? 1.875 : 10.5, }; }