forked from phenom/healer-man
48 lines
2.0 KiB
TypeScript
48 lines
2.0 KiB
TypeScript
import type { AbilityDefinition } from "./abilityCatalog";
|
|
|
|
/** CoA tree node 5744 / source spell 804414: Decapitate is usable below 35% health. */
|
|
export const COA_BARBARIAN_DECAPITATE_TALENT_ENTRY_ID = 5744;
|
|
export const COA_BARBARIAN_DECAPITATE_HEALTH_THRESHOLD = 0.35;
|
|
/** Source node 6744 / spell 705222 refunds maximum Energy on a Decapitate kill. */
|
|
export const COA_BARBARIAN_BEHEADER_TALENT_ENTRY_ID = 6744;
|
|
|
|
type CoaBarbarianDecapitateIdentity = Pick<AbilityDefinition, "classId" | "talentEntryId">;
|
|
|
|
export interface CoaBarbarianExecuteTargetHealth {
|
|
readonly health?: number;
|
|
readonly maxHealth?: number;
|
|
readonly dead?: boolean;
|
|
}
|
|
|
|
export function isCoaBarbarianDecapitate(
|
|
ability: CoaBarbarianDecapitateIdentity | null | undefined,
|
|
): boolean {
|
|
return ability?.classId === "barbarian"
|
|
&& ability.talentEntryId === COA_BARBARIAN_DECAPITATE_TALENT_ENTRY_ID;
|
|
}
|
|
|
|
/** Other actions pass through; Decapitate requires a living, valid target strictly below 35%. */
|
|
export function coaBarbarianDecapitateTargetAllowed(
|
|
ability: CoaBarbarianDecapitateIdentity | null | undefined,
|
|
target: CoaBarbarianExecuteTargetHealth | null | undefined,
|
|
): boolean {
|
|
if (!isCoaBarbarianDecapitate(ability)) return true;
|
|
if (!target || target.dead === true
|
|
|| !Number.isFinite(target.health) || !Number.isFinite(target.maxHealth)
|
|
|| target.health! <= 0 || target.maxHealth! <= 0) return false;
|
|
return target.health! / target.maxHealth! < COA_BARBARIAN_DECAPITATE_HEALTH_THRESHOLD;
|
|
}
|
|
|
|
export function coaBarbarianBeheaderEnergyRefund(
|
|
ability: CoaBarbarianDecapitateIdentity,
|
|
talentRanks: Readonly<Record<string, number>>,
|
|
maximumEnergy: number,
|
|
result: { readonly amount: number; readonly killed: boolean },
|
|
): number {
|
|
if (!isCoaBarbarianDecapitate(ability)
|
|
|| !(talentRanks[`coa-entry-${COA_BARBARIAN_BEHEADER_TALENT_ENTRY_ID}`] > 0)
|
|
|| !result.killed || !(result.amount > 0)
|
|
|| !Number.isFinite(maximumEnergy) || maximumEnergy <= 0) return 0;
|
|
return maximumEnergy;
|
|
}
|