Files
healer-man/src/game/romRogueEnergizedHandsRuntime.ts
T
2026-10-02 10:38:12 -04:00

104 lines
4.2 KiB
TypeScript

import type { ActiveAura, AuraDefinition, AuraModifier } from "./combatAuras";
import type { AbilityEffect } from "./abilityCatalog";
export const ROM_ROGUE_ENERGIZED_HANDS_SKILL_ID = 490347;
export const ROM_ROGUE_ENERGIZED_HANDS_AURA_TAG = "rom-energized-hands";
export const ROM_ROGUE_POISONOUS_HANDS_EXCLUSIVE_GROUP = "rom-rogue-hands";
export const ROM_ROGUE_ENERGIZED_HANDS_DURATION_MS = 900_000;
export const ROM_ROGUE_ENERGIZED_HANDS_COOLDOWN_REDUCTION_MS = 100;
export const ROM_ROGUE_ENERGIZED_HANDS_MAX_ENERGY_PERCENT = 50;
export const ROM_ROGUE_ENERGIZED_HANDS_REGENERATION_PERCENT = 100;
export const ROM_ROGUE_ENERGIZED_HANDS_COST_PERCENT = 20;
export const ROM_ROGUE_ENERGIZED_HANDS_DESCRIPTION =
"Increases Energy recovery by 100%, reduces skill cooldowns by 0.1 seconds, and increases maximum Energy by 50%, but increases Energy costs by 20% for 900 seconds. Mutually exclusive with Poisonous Hands.";
export const ROM_ROGUE_POISONOUS_HANDS_DESCRIPTION =
"Uses 1 Poison Bottle. For 900 seconds, regular attacks have a 50% chance to apply Poisonous Hands to the target, reducing damage dealt by the target by 8%. Each successful application stacks up to 10 times and grants you 1% Physical Attack Speed per stack applied to your current target. Attacking a new target resets this attack-speed sequence. Mutually exclusive with Energized Hands.";
export function romRogueEnergizedHandsAuraDefinition(): AuraDefinition {
const modifiers: readonly AuraModifier[] = [
{
kind: "resource",
resource: "energy",
property: "maximum",
operation: "percent",
value: ROM_ROGUE_ENERGIZED_HANDS_MAX_ENERGY_PERCENT / 100,
},
{
kind: "resource",
resource: "energy",
property: "regeneration",
operation: "percent",
value: ROM_ROGUE_ENERGIZED_HANDS_REGENERATION_PERCENT / 100,
},
{
kind: "resource",
resource: "energy",
property: "cost",
operation: "percent",
value: ROM_ROGUE_ENERGIZED_HANDS_COST_PERCENT / 100,
},
];
return {
id: "rom-rogue-energized-hands",
name: "Energized Hands",
description: ROM_ROGUE_ENERGIZED_HANDS_DESCRIPTION,
disposition: "buff",
durationMs: ROM_ROGUE_ENERGIZED_HANDS_DURATION_MS,
exclusiveGroup: ROM_ROGUE_POISONOUS_HANDS_EXCLUSIVE_GROUP,
utilityTags: [ROM_ROGUE_ENERGIZED_HANDS_AURA_TAG],
modifiers,
};
}
export function romRogueEnergizedHandsApplyEffect(): AbilityEffect {
return {
kind: "apply-aura",
recipient: "caster",
sourceEffectType: 6,
sourceAuraType: 0,
miscValue: 0,
triggerSpellId: 0,
aura: romRogueEnergizedHandsAuraDefinition(),
};
}
export function romRogueEnergizedHandsActive(
auras: readonly ActiveAura[],
actorId: string,
now?: number,
): boolean {
return auras.some((aura) => aura.targetId === actorId
&& aura.definition.utilityTags?.includes(ROM_ROGUE_ENERGIZED_HANDS_AURA_TAG)
&& (now === undefined || aura.expiresAt === null || aura.expiresAt > now));
}
/**
* Translate the current max-Energy aura between snapshots without changing
* current Energy. The stored pool maximum is the runtime authority, so apply
* only the ratio of the old and new aura modifiers (refreshes remain neutral).
*/
export function romRogueEnergyMaximumAfterAuraTransition(
currentMaximum: number,
previousAuras: readonly ActiveAura[],
nextAuras: readonly ActiveAura[],
targetId: string,
): number {
const maximumModifier = (auras: readonly ActiveAura[]) => auras
.filter((aura) => aura.targetId === targetId)
.reduce((total, aura) => {
const hasEnergizedHands = aura.definition.utilityTags?.includes(ROM_ROGUE_ENERGIZED_HANDS_AURA_TAG);
if (!hasEnergizedHands) return total;
const percent = (aura.definition.modifiers ?? []).reduce((value, modifier) => (
modifier.kind === "resource" && modifier.resource === "energy" && modifier.property === "maximum"
? value + (modifier.operation === "percent" ? modifier.value : 0)
: value
), 0);
return total * (1 + percent);
}, 1);
const previous = maximumModifier(previousAuras);
const next = maximumModifier(nextAuras);
return Math.max(0, Math.round(currentMaximum * next / Math.max(0.0001, previous)));
}