forked from phenom/healer-man
Release Healer Man 0.1.59
This commit is contained in:
1 parent
11934a3979
commit
ab1434a3b8
44 files changed
+1242
-103
No files matched your search
@@ -2,6 +2,9 @@ import { describe, expect, it } from "vitest";
|
||||
import { abilityAtLevel, type AbilityDefinition, type AbilityEffect } from "./abilityCatalog";
|
||||
import { aiHintsForAbility, targetingRulesForAbility } from "./abilityRules";
|
||||
import { WOW335_ABILITIES_BY_CLASS } from "./wow335AbilityCatalog";
|
||||
import generatedData from "./wow335AbilityData.generated.json";
|
||||
import { talentNodeById } from "./talentCatalog";
|
||||
import { runtimeTalentNodeById } from "./talentRuntimeCatalog";
|
||||
|
||||
function byId(id: string): AbilityDefinition {
|
||||
const ability = Object.values(WOW335_ABILITIES_BY_CLASS)
|
||||
@@ -21,6 +24,14 @@ function effectsOfKind<K extends AbilityEffect["kind"]>(
|
||||
}
|
||||
|
||||
describe("WoW 3.3.5 executable effect mapping", () => {
|
||||
it("uses the same legal talent-node set as the full catalog", () => {
|
||||
const talentNodeIds = new Set(Object.values(generatedData.classes)
|
||||
.flatMap((chains) => chains.flatMap((chain) => chain.talentNodeId ? [chain.talentNodeId] : [])));
|
||||
for (const nodeId of talentNodeIds) {
|
||||
expect(Boolean(runtimeTalentNodeById(nodeId)), nodeId).toBe(Boolean(talentNodeById(nodeId)));
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves source spells that do not trigger a global cooldown", () => {
|
||||
expect(byId("wow335-priest-inner-focus").gcdMs).toBe(0);
|
||||
expect(byId("wow335-rogue-cold-blood").gcdMs).toBe(0);
|
||||
@@ -213,19 +224,37 @@ describe("WoW 3.3.5 executable effect mapping", () => {
|
||||
|
||||
it("models Penance as three healing or damaging pulses", () => {
|
||||
const penance = byId("wow335-priest-penance");
|
||||
expect(penance).toMatchObject({ castMode: "channel", castTimeMs: 2_000, channelTickMs: 1_000,
|
||||
channelStartsWithPulse: true });
|
||||
expect(penance.target).toBe("any");
|
||||
expect(effectsOfKind(penance, "heal")).toEqual([
|
||||
expect.objectContaining({ coefficient: 0.6 }),
|
||||
]);
|
||||
expect(effectsOfKind(penance, "hot")).toEqual([
|
||||
expect.objectContaining({ coefficient: 0.6, ticks: 2, intervalMs: 1_000 }),
|
||||
]);
|
||||
expect(effectsOfKind(penance, "hot")).toEqual([]);
|
||||
expect(effectsOfKind(penance, "damage")).toEqual([
|
||||
expect.objectContaining({ coefficient: 0.6 }),
|
||||
]);
|
||||
expect(effectsOfKind(penance, "dot")).toEqual([
|
||||
expect.objectContaining({ coefficient: 0.6, ticks: 2, intervalMs: 1_000 }),
|
||||
]);
|
||||
expect(effectsOfKind(penance, "dot")).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps ground-channel damage children out of learned cast ranks", () => {
|
||||
for (const id of ["wow335-mage-blizzard", "wow335-warlock-rain-of-fire", "wow335-druid-hurricane"]) {
|
||||
const ability = byId(id);
|
||||
expect(ability.ranks?.every((rank) => rank.castMode === "channel"), id).toBe(true);
|
||||
expect(abilityAtLevel(ability, 80).castMode, id).toBe("channel");
|
||||
}
|
||||
const hurricane = abilityAtLevel(byId("wow335-druid-hurricane"), 80);
|
||||
expect(hurricane).toMatchObject({ dbcSpellId: 48467, castTimeMs: 10_000,
|
||||
channelTickMs: 1_000, channelPulses: 10 });
|
||||
expect(hurricane.cost.amount).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("keeps every rank of imported channels in channel mode", () => {
|
||||
const mismatches = Object.values(WOW335_ABILITIES_BY_CLASS).flat()
|
||||
.filter((ability) => ability.castMode === "channel" && ability.ranks?.some((rank) => rank.castMode !== "channel"))
|
||||
.map((ability) => `${ability.name}: ${ability.ranks?.filter((rank) => rank.castMode !== "channel")
|
||||
.map((rank) => rank.spellId).join(", ")}`);
|
||||
expect(mismatches).toEqual([]);
|
||||
});
|
||||
|
||||
it("maps the Ready-five missing spell payloads without cast-time damage on self buffs", () => {
|
||||
|
||||
Reference in new issue
Block a user