Release Healer Man 0.1.54
This commit is contained in:
1 parent
d6976e6ef6
commit
2dbb0acfc1
26 files changed
+1893
-912
No files matched your search
@@ -20,7 +20,9 @@ import {
|
||||
import { createDeathKnightRunes } from "./combatActors";
|
||||
import { aiHintsForAbility } from "./abilityRules";
|
||||
import { runtimePartyTalentRanksForLevel } from "./partyTalentRuntime";
|
||||
import { partyTalentPrimaryTreeId } from "./partyTalents";
|
||||
import { specializationsForClass } from "./specializationCatalog";
|
||||
import { talentNodeById } from "./talentCatalog";
|
||||
|
||||
const SIGNATURES = Object.freeze({
|
||||
warrior: "Mortal Strike",
|
||||
@@ -156,6 +158,26 @@ describe("shared combat rotations", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("learns every primary-tree action named by its level-80 rotation", () => {
|
||||
for (const classId of BASE_CLASS_IDS) {
|
||||
for (const specialization of specializationsForClass(classId)) {
|
||||
const profile = rotationProfileFor(classId, specialization.id)!;
|
||||
const primaryTreeId = partyTalentPrimaryTreeId(classId, specialization.displayName);
|
||||
const ranks = runtimePartyTalentRanksForLevel(classId, specialization.displayName, 80);
|
||||
const primaryActions = profile.abilityPriority
|
||||
.map((name) => ability(classId, name))
|
||||
.filter((candidate) => candidate.talentNodeId
|
||||
&& talentNodeById(candidate.talentNodeId)?.treeId === primaryTreeId);
|
||||
for (const candidate of primaryActions) {
|
||||
expect(
|
||||
learnedAbilityForBuild(candidate, 80, ranks),
|
||||
`${specialization.id}:${candidate.name}`,
|
||||
).not.toBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps specialization talent actions isolated", () => {
|
||||
const furyTalents = runtimePartyTalentRanksForLevel("warrior", "Fury", 80);
|
||||
const armsTalents = runtimePartyTalentRanksForLevel("warrior", "Arms", 80);
|
||||
@@ -438,6 +460,45 @@ describe("shared combat rotations", () => {
|
||||
.toBe(lightningBolt.id);
|
||||
});
|
||||
|
||||
it("maintains Earth Shield on a valid full-health ally", () => {
|
||||
const earthShield = ability("shaman", "Earth Shield");
|
||||
const shaman = context({
|
||||
classId: "shaman",
|
||||
specializationId: "shaman:restoration",
|
||||
role: "healer",
|
||||
selfId: "shaman",
|
||||
primaryResource: "mana",
|
||||
resources: { mana: 10_000 },
|
||||
maximumResources: { mana: 10_000 },
|
||||
abilities: [earthShield],
|
||||
friendlyTargets: [{ id: "tank", health: 1_000, maxHealth: 1_000 }],
|
||||
maintainedAbilityIds: new Set(),
|
||||
activeAuraExclusiveGroups: new Set(),
|
||||
});
|
||||
|
||||
expect(evaluateCombatRotation(shaman)).toMatchObject({
|
||||
ability: { id: earthShield.id },
|
||||
targetId: "tank",
|
||||
});
|
||||
expect(evaluateCombatRotation({ ...shaman, friendlyTargets: [] })).toBeNull();
|
||||
});
|
||||
|
||||
it("uses Feral Spirit as an Enhancement major cooldown on a durable target", () => {
|
||||
const feralSpirit = ability("shaman", "Feral Spirit");
|
||||
const shaman = context({
|
||||
classId: "shaman",
|
||||
specializationId: "shaman:enhancement",
|
||||
primaryResource: "mana",
|
||||
resources: { mana: 10_000 },
|
||||
maximumResources: { mana: 10_000 },
|
||||
abilities: [feralSpirit],
|
||||
hostileTarget: { id: "boss", health: 100_000, maxHealth: 100_000, boss: true },
|
||||
activeSummonAbilityIds: new Set(),
|
||||
});
|
||||
|
||||
expect(evaluateCombatRotation(shaman)?.ability.id).toBe(feralSpirit.id);
|
||||
});
|
||||
|
||||
it("enters a learned Death Knight presence before attacking", () => {
|
||||
const bloodPresence = learnedAbilityForBuild(ability("death-knight", "Blood Presence"), 1, {})!;
|
||||
const icyTouch = learnedAbilityForBuild(ability("death-knight", "Icy Touch"), 1, {})!;
|
||||
|
||||
Reference in new issue
Block a user