import { describe, expect, it } from "vitest"; import { TALENT_NODES, allocateTalentPoint } from "./talentCatalog"; import { applyTalentModifierValue, parseTalentModifiers, talentModifiersForRanks, } from "./talentModifiers"; describe("talent runtime modifiers", () => { it("turns Twin Disciplines ranks into scoped damage and healing benefits", () => { const twinDisciplines = TALENT_NODES.find((node) => node.name === "Twin Disciplines")!; let ranks = {}; ranks = allocateTalentPoint(ranks, "priest", twinDisciplines.id, 80).ranks; const rankOne = talentModifiersForRanks(ranks, "priest"); expect(rankOne).toEqual(expect.arrayContaining([ expect.objectContaining({ kind: "damage-percent", amount: 1, rank: 1, sourceTalentId: twinDisciplines.id }), expect.objectContaining({ kind: "healing-percent", amount: 1, rank: 1, sourceTalentId: twinDisciplines.id }), ])); expect(applyTalentModifierValue(100, rankOne, "healing-percent", { tags: ["instant", "holy"] })).toBe(101); expect(applyTalentModifierValue(100, rankOne, "healing-percent", { tags: ["cast-time", "holy"] })).toBe(101); for (let rank = 1; rank < twinDisciplines.maxRank; rank += 1) { ranks = allocateTalentPoint(ranks, "priest", twinDisciplines.id, 80).ranks; } const maxRank = talentModifiersForRanks(ranks, "priest"); expect(applyTalentModifierValue(100, maxRank, "damage-percent", { tags: ["instant", "shadow"] })).toBe(100); expect(applyTalentModifierValue(100, maxRank, "damage-percent", { tags: ["cast-time", "holy"] })).toBe(105); }); it("parses common passive stat, cost, cast-time, cooldown, and mitigation categories", () => { expect(parseTalentModifiers("Increases your maximum health by 10%.")).toContainEqual( expect.objectContaining({ kind: "max-health-percent", amount: 10 }), ); expect(parseTalentModifiers("Reduces the mana cost of your healing spells by 6%.")).toContainEqual( expect.objectContaining({ kind: "resource-cost-percent", amount: -6 }), ); expect(parseTalentModifiers("Reduces the casting time of Heal by 0.5 sec.")).toContainEqual( expect.objectContaining({ kind: "cast-time-flat-ms", amount: -500 }), ); expect(parseTalentModifiers("Reduces the cooldown on Penance by 2 sec.")).toContainEqual( expect.objectContaining({ kind: "cooldown-flat-ms", amount: -2000 }), ); expect(parseTalentModifiers("Reduces all damage taken by 3%.")).toContainEqual( expect.objectContaining({ kind: "damage-taken-percent", amount: -3 }), ); expect(parseTalentModifiers( "Chrono SorceryRank 2Instant castIncreases maximum mana by 12% and spell damage by 15% of Intellect.", )).toContainEqual( expect.objectContaining({ kind: "max-resource-percent", amount: 12 }), ); expect(parseTalentModifiers("Increases spell power by 30% of your Intellect.")).not.toContainEqual( expect.objectContaining({ kind: "attribute-percent", attribute: "intellect" }), ); expect(parseTalentModifiers("Increases your Strength and Intellect by 10%.")).toEqual( expect.arrayContaining([ expect.objectContaining({ kind: "attribute-percent", attribute: "strength", amount: 10 }), expect.objectContaining({ kind: "attribute-percent", attribute: "intellect", amount: 10 }), ]), ); const focusedWill = parseTalentModifiers( "Increases your spell critical effect chance by 3%, reducing all damage taken by 4% and increasing healing effects on you by 5%.", ); expect(focusedWill).toEqual(expect.arrayContaining([ expect.objectContaining({ kind: "critical-chance-percent", amount: 3 }), expect.objectContaining({ kind: "damage-taken-percent", amount: -4 }), expect.objectContaining({ kind: "healing-percent", amount: 5 }), ])); }); it("keeps critical damage bonuses out of ordinary hit damage", () => { const modifiers = parseTalentModifiers("Increases the critical damage of your spells by 150%.") .map((modifier) => ({ ...modifier, sourceTalentId: "test", sourceTalentName: "Thunderous", rank: 1, description: "" })); expect(modifiers).toContainEqual(expect.objectContaining({ kind: "critical-damage-percent", amount: 150 })); expect(applyTalentModifierValue(100, modifiers, "damage-percent", { abilityName: "Arm of Thorim" })).toBe(100); expect(applyTalentModifierValue(2, modifiers, "critical-damage-percent", { abilityName: "Arm of Thorim" })).toBe(5); }); });