Release Healer Man 0.1.49

This commit is contained in:
phenom committed 2026-09-17 09:13:15 -04:00
1 parent 39425f2494
commit 612170afd0
91 files changed
+2278 -263

No files matched your search

+56 -1
View File
@@ -1,6 +1,7 @@
import { describe, expect, it } from "vitest";
import "./abilityCatalog";
import {
characterCombatAnimationForPresentation,
clipsForAnimationIds,
parseWoWAnimationName,
selectCharacterBaseClip,
@@ -8,6 +9,7 @@ import {
selectCharacterVerticalClip,
selectWoWAnimationVariation,
} from "./combatAnimation";
import type { CombatPresentationEvent } from "./combatPresentation";
const clips = [
{ name: "Stand (ID 0 variation 0)" },
@@ -32,6 +34,28 @@ const clips = [
{ name: "HoldBow (ID 109 variation 0)" },
];
function presentationEvent(
overrides: Partial<CombatPresentationEvent> = {},
): CombatPresentationEvent {
return {
id: 1,
sessionId: 1,
occurredAt: 1_000,
phase: "release",
actorGroup: "party",
sourceActorId: "party-1",
targetActorId: "mob-1",
abilityId: "party-auto-attack",
name: "Auto Attack",
source: "fallback",
school: "physical",
delivery: "melee",
origin: [0, 0, 0],
targetPosition: [1, 0, 0],
...overrides,
};
}
describe("WoW character animation selection", () => {
it("parses AnimationData IDs and preserves labels and variations", () => {
expect(parseWoWAnimationName("AttackUnarmed (ID 16 variation 1)")).toEqual({
@@ -108,13 +132,44 @@ describe("WoW character animation selection", () => {
it("maps melee, wound, and terminal death events to native clips", () => {
expect(selectCharacterEventClip(clips, "warrior", { revision: 1, kind: "attack" }))
.toMatchObject({ clip: clips[4], loop: false });
.toMatchObject({ clip: clips[3], loop: false });
expect(selectCharacterEventClip(clips, "warrior", { revision: 2, kind: "wound" }))
.toMatchObject({ clip: clips[7], loop: false });
expect(selectCharacterEventClip(clips, "warrior", { revision: 3, kind: "death" }))
.toMatchObject({ clip: clips[8], terminal: true });
});
it("reserves special melee clips for abilities instead of ordinary weapon swings", () => {
expect(selectCharacterEventClip(clips, "paladin", { revision: 1, kind: "attack" }))
.toMatchObject({ clip: clips[3], loop: false });
});
it("drives party animation only from actual combat presentation phases", () => {
expect(characterCombatAnimationForPresentation(presentationEvent(), 7)).toEqual({
revision: 7,
kind: "attack",
});
expect(characterCombatAnimationForPresentation(presentationEvent({
phase: "cast-start",
abilityId: "paladin-holy-light",
}), 8)).toEqual({
revision: 8,
kind: "ability-start",
abilityId: "paladin-holy-light",
});
expect(characterCombatAnimationForPresentation(presentationEvent({
abilityId: "warrior-mortal-strike",
}), 9)).toEqual({
revision: 9,
kind: "ability-release",
abilityId: "warrior-mortal-strike",
});
expect(characterCombatAnimationForPresentation(presentationEvent({ phase: "impact" }), 10))
.toBeNull();
expect(characterCombatAnimationForPresentation(presentationEvent({ actorGroup: "enemy" }), 11))
.toBeNull();
});
it("uses native RuneWaker spell, bow, and melee clips for RoM characters", () => {
const runewakerClips = [
{ name: "Action - 1h_charge_up" },