Release Healer Man 0.1.40

This commit is contained in:
phenom committed 2026-09-13 13:21:27 -04:00
1 parent ed0d2fea3d
commit 197a64117c
215 files changed
+5131 -181

No files matched your search

+3
View File
@@ -100,6 +100,9 @@ export function CombatBridge() {
if (state.inventory !== previousState.inventory) {
shell.saveActiveInventory(state.inventory);
}
if (state.bossCards !== previousState.bossCards) {
shell.saveActiveBossCards(state.bossCards);
}
if (state.equipment !== previousState.equipment) {
shell.saveActiveEquipment(state.equipment);
}
+1 -1
View File
@@ -19,7 +19,7 @@ function grantEncounterLoot(lootTableId: string, now: number): boolean {
if (!table) return false;
const combat = useCombatStore.getState();
const drops = rollBossLoot(table.bossKey, combat.level, { now });
if (!drops.length) return false;
if (!drops.length) return true;
const inventory = [...combat.inventory, ...drops];
useCombatStore.setState({ inventory });
useShellStore.getState().saveActiveInventory(inventory);
+16
View File
@@ -6,6 +6,7 @@ import {
resetDungeonEncounters,
} from "./dungeonEncounterRuntime";
import { applySharedWorld } from "./OnlineSessionBridge";
import { useCombatStore } from "./combatStore";
import { useGameStore } from "./store";
import {
WAILING_NARALEX_ENCOUNTER,
@@ -58,4 +59,19 @@ describe("online shared-world hydration", () => {
revision: authority.revision,
});
});
it("awards the authority's card rolls once to a follower, including after reconnect", () => {
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 20 });
useCombatStore.getState().registerMob("shared-boss", { name: "Lady Anacondra", boss: true, maxHealth: 1 });
const mob = useCombatStore.getState().mobs["shared-boss"];
const world = { ...EMPTY_SHARED_WORLD, mobs: { "shared-boss": { ...mob, dead: true, looted: true, health: 0, bossCardDrop: { bossKey: "wow:lady anacondra", spawnId: mob.id, claimId: "shared-kill:1", rarities: ["normal", "epic"] as const } } } };
applySharedWorld(world);
applySharedWorld(world);
expect(useCombatStore.getState().bossCards.counts["wow:lady anacondra"]).toEqual({ normal: 1, epic: 1 });
const bossCards = JSON.parse(JSON.stringify(useCombatStore.getState().bossCards));
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 20, bossCards });
applySharedWorld(world);
expect(useCombatStore.getState().bossCards.counts["wow:lady anacondra"]).toEqual({ normal: 1, epic: 1 });
expect(useCombatStore.getState().inventory).toEqual([]);
});
});
+5
View File
@@ -89,6 +89,11 @@ function sharedWorld(): OnlineSharedWorld {
export function applySharedWorld(world: OnlineSharedWorld): void {
useCombatStore.setState({ mobs: world.mobs });
for (const mob of Object.values(world.mobs)) {
if (mob.dead && mob.looted && mob.bossCardDrop) {
useCombatStore.getState().collectSharedBossCards(mob.bossCardDrop, mob.name, mob.diedAt ?? Date.now());
}
}
usePartyStore.setState({
members: world.partyMembers,
command: world.partyRuntime.command as ReturnType<typeof usePartyStore.getState>["command"],
+1 -1
View File
@@ -194,7 +194,7 @@ export type AbilityEffect =
/** Fraction of the target ability's remaining cooldown removed at execution time. */
readonly amountPercent?: number;
}
| { readonly kind: "trigger-spell"; readonly spellId: number; readonly withValue?: number }
| { readonly kind: "trigger-spell"; readonly spellId: number; readonly withValue?: number; readonly expanded?: boolean }
| {
/** A known combat-side DBC script hook that requires a spell-specific handler. */
readonly kind: "scripted";
@@ -0,0 +1,99 @@
import { preloadAbilityCatalogsForClasses } from "../abilityCatalog";
import { PLAYER_AGGRO_ID } from "../aggro";
import { installCombatClock } from "../combatClock";
import { subscribeCombatEvents } from "../combatEvents";
import { resetCombatSpatialProvider } from "../combatSpatial";
import { useCombatStore } from "../combatStore";
import { dungeonEnemyScaling } from "../dungeonBossScaling";
import { requireDungeonDefinition } from "../dungeonRegistry";
import { clearMobRuntimeRegistry, setMobPosition } from "../mobRuntimeRegistry";
import { advanceDungeonPartyCombat, partyCombatRangeBand, resetPartyRuntimeClock } from "../partyRuntime";
import { clearPartyRuntimeRegistry, registerPartyRuntimePosition, updatePartyRuntimeTargetVisibility } from "../partyRuntimeRegistry";
import { usePartyStore } from "../partyStore";
import { specializationsForClass } from "../specializationCatalog";
import { BenchmarkController } from "./benchmarkController";
import type { BenchmarkBuildDefinition, BenchmarkScenarioDefinition } from "./benchmarkTypes";
const scenario: BenchmarkScenarioDefinition = {
id: "dungeon-boss", version: 1, name: "Dungeon boss", description: "Full party against an authored dungeon boss",
family: "damage", roles: ["damage", "tank", "healer"], durationMs: 60_000, tickMs: 100,
hostileTargets: 1, partyLayout: "melee", attacks: [],
};
/** Uses the live boss stats, companion AI and baseline player policy with a controlled clock. */
export async function runDungeonBossBenchmark(
build: BenchmarkBuildDefinition, bossId: string, seed: string, mechanics = false,
) {
await preloadAbilityCatalogsForClasses([build.classId]);
const dungeon = requireDungeonDefinition("ragefire-chasm");
const spawn = dungeon.staticSpawns.find((entry) => entry.id === bossId)!;
const entity = dungeon.entities[spawn.entityId];
const scaling = dungeonEnemyScaling(dungeon, entity, bossId, build.level, "normal", 1);
const specs = specializationsForClass(build.classId).filter((spec) => spec.role === build.role);
const specialization = specs.find((spec) => spec.displayName === build.orientation) ?? specs[0];
clearMobRuntimeRegistry(); clearPartyRuntimeRegistry(); resetPartyRuntimeClock(); resetCombatSpatialProvider();
let now = 1_000_000;
const restoreClock = installCombatClock(() => now);
let playerDamage = 0; let partyDamage = 0; let incomingDamage = 0; let healing = 0; let casts = 0;
const damageByAbility: Record<string, number> = {};
const stop = subscribeCombatEvents((event) => {
if (event.kind === "damage" && event.targetActorId === bossId) {
if (event.sourceActorId === PLAYER_AGGRO_ID) playerDamage += event.effectiveAmount;
else partyDamage += event.effectiveAmount;
const key = `${event.sourceActorId}:${event.abilityId ?? "unknown"}`;
damageByAbility[key] = (damageByAbility[key] ?? 0) + event.effectiveAmount;
}
if (event.kind === "damage" && event.sourceActorId === bossId) incomingDamage += event.effectiveAmount;
if (event.kind === "healing") healing += event.effectiveAmount;
});
try {
const combat = useCombatStore.getState();
combat.initializeCharacter({ classId: build.classId, secondaryClassId: build.secondaryClassId,
specializationId: specialization?.id, role: build.role, level: build.level,
talentRanks: build.talentRanks, inventory: build.inventory, equipment: build.equipment });
combat.setPlayerPosition([-2, 0, 0]);
usePartyStore.getState().initializeParty(seed, build.level, useCombatStore.getState().maxHealth, build.role, 5, build.source);
combat.synchronizeActors();
combat.registerMob(bossId, { name: entity.name, boss: true, serverEntry: entity.combat?.serverEntry,
...scaling, attacks: entity.combat?.attacks, xpReward: 0 });
setMobPosition(bossId, [0, 0, 0]);
for (const member of usePartyStore.getState().members) {
registerPartyRuntimePosition(member.id, [-partyCombatRangeBand(member).preferred, 0, 0]);
updatePartyRuntimeTargetVisibility(member.id, bossId, true);
}
combat.selectMob(bossId);
const tank = usePartyStore.getState().members.find((member) => member.role === "tank");
combat.damageMob(bossId, 1, now, {
actorId: build.role === "tank" ? PLAYER_AGGRO_ID : tank!.id, role: "tank", abilityId: "benchmark-pull",
}, "physical");
const controller = new BenchmarkController();
for (let elapsed = 100; elapsed <= scenario.durationMs; elapsed += 100) {
now = 1_000_000 + elapsed;
combat.tick(.1, now);
advanceDungeonPartyCombat(now);
if (mechanics) combat.advanceMobCombat(now);
if (controller.act(now, build.role, scenario, false).cast) casts += 1;
const state = useCombatStore.getState();
const mob = state.mobs[bossId];
if (mob.dead || (mechanics && state.health <= 0)) {
return { seconds: mob.dead ? ((mob.diedAt ?? now) - 1_000_000) / 1000 : null,
elapsedSeconds: elapsed / 1000, outcome: mob.dead ? "defeated" : "player-death",
maxHealth: scaling.maxHealth, playerDamage, partyDamage, incomingDamage, healing, casts, damageByAbility,
playerAlive: state.health > 0, deaths: usePartyStore.getState().members.filter((member) => member.health <= 0).length,
attacks: mob.attackRevision, specialization: specialization?.displayName,
party: usePartyStore.getState().members.map((member) => `${member.classId}:${member.specialization}`) };
}
}
return { seconds: null, elapsedSeconds: scenario.durationMs / 1000, outcome: "timeout",
maxHealth: scaling.maxHealth, remainingHealth: useCombatStore.getState().mobs[bossId].health,
playerDamage, partyDamage, incomingDamage, healing, casts, damageByAbility,
playerAlive: useCombatStore.getState().health > 0,
deaths: usePartyStore.getState().members.filter((member) => member.health <= 0).length,
attacks: useCombatStore.getState().mobs[bossId].attackRevision,
specialization: specialization?.displayName,
party: usePartyStore.getState().members.map((member) => `${member.classId}:${member.specialization}`) };
} finally {
stop(); restoreClock(); clearMobRuntimeRegistry(); clearPartyRuntimeRegistry();
resetPartyRuntimeClock(); resetCombatSpatialProvider();
}
}
+97
View File
@@ -0,0 +1,97 @@
import { DUNGEON_DEFINITIONS } from "./dungeonRegistry";
import type { DungeonDefinition } from "./dungeonTypes";
import type { MobModelStyle } from "./mobPopulation";
import { BOSS_CARD_RARITIES, type BossCardCollection, type BossCardRarity } from "./bossCards";
export interface BossCardDefinition {
readonly key: string;
readonly name: string;
readonly category: "wow" | "rom";
readonly model?: MobModelStyle;
readonly dungeons: readonly { readonly id: string; readonly title: string }[];
readonly sources: readonly { readonly dungeonId: string; readonly entityId: string }[];
}
/** Same boss in multiple dungeons shares a collection, while WoW and RoM remain distinct. */
export function buildBossCardCatalog(definitions: readonly DungeonDefinition[]): readonly BossCardDefinition[] {
const bosses = new Map<string, BossCardDefinition>();
for (const dungeon of definitions) {
for (const entity of Object.values(dungeon.entities)) {
if (entity.kind !== "boss") continue;
const category = dungeon.expansion === "runewaker" ? "rom" : "wow";
const key = `${category}:${entity.name.trim().toLowerCase().replace(/\s+/g, " ")}`;
const existing = bosses.get(key);
bosses.set(key, {
key,
name: existing?.name ?? entity.name,
category,
model: existing?.model ?? entity.visual.model,
dungeons: existing?.dungeons.some((entry) => entry.id === dungeon.id)
? existing.dungeons
: [...(existing?.dungeons ?? []), { id: dungeon.id, title: dungeon.title }],
sources: [...(existing?.sources ?? []), { dungeonId: dungeon.id, entityId: entity.id }],
});
}
}
return [...bosses.values()].map((boss) => ({
...boss,
dungeons: [...boss.dungeons].sort((a, b) => a.title.localeCompare(b.title)),
})).sort((a, b) => a.name.localeCompare(b.name) || a.key.localeCompare(b.key));
}
export const BOSS_CARD_CATALOG = buildBossCardCatalog(DUNGEON_DEFINITIONS);
const cardsByKey = new Map(BOSS_CARD_CATALOG.map((card) => [card.key, card]));
export function bossCardByKey(key: string): BossCardDefinition | null {
return cardsByKey.get(key) ?? null;
}
export function bossCardForSource(sourceId: string, dungeonId: string, name?: string): BossCardDefinition | null {
return BOSS_CARD_CATALOG.find((card) => card.sources.some(
(source) => source.dungeonId === dungeonId && source.entityId === sourceId,
)) ?? BOSS_CARD_CATALOG.find((card) => card.sources.some((source) => source.entityId === sourceId))
?? BOSS_CARD_CATALOG.find((card) => card.name === name && card.dungeons.some((entry) => entry.id === dungeonId))
?? null;
}
export interface BossCardRow {
readonly boss: BossCardDefinition;
readonly rarity: BossCardRarity;
readonly copies: number;
}
export type BossCardGrouping = "all" | "dungeon" | "rarity";
export interface BossCardGroup {
readonly key: string;
readonly title: string;
readonly rows: readonly BossCardRow[];
}
export function groupBossCards(
collection: BossCardCollection,
options: { readonly earnedOnly: boolean; readonly grouping: BossCardGrouping; readonly search?: string; readonly category?: "all" | "wow" | "rom" },
catalog = BOSS_CARD_CATALOG,
): readonly BossCardGroup[] {
const query = options.search?.trim().toLowerCase() ?? "";
const rows = catalog.flatMap((boss) => {
if (options.category && options.category !== "all" && boss.category !== options.category) return [];
if (query && !`${boss.name} ${boss.dungeons.map((entry) => entry.title).join(" ")}`.toLowerCase().includes(query)) return [];
return BOSS_CARD_RARITIES.flatMap((rarity) => {
const copies = collection.counts[boss.key]?.[rarity] ?? 0;
return options.earnedOnly && !copies ? [] : [{ boss, rarity, copies }];
});
});
if (options.grouping === "rarity") {
return BOSS_CARD_RARITIES.map((rarity) => ({
key: rarity, title: `${rarity.charAt(0).toUpperCase()}${rarity.slice(1)} cards`, rows: rows.filter((row) => row.rarity === rarity),
})).filter((group) => group.rows.length);
}
if (options.grouping === "dungeon") {
const groups = new Map<string, BossCardGroup>();
for (const row of rows) for (const dungeon of row.boss.dungeons) {
const existing = groups.get(dungeon.id);
groups.set(dungeon.id, { key: dungeon.id, title: dungeon.title, rows: [...(existing?.rows ?? []), row] });
}
return [...groups.values()].sort((a, b) => a.title.localeCompare(b.title));
}
return rows.length ? [{ key: "all", title: "All boss cards", rows }] : [];
}
+91
View File
@@ -0,0 +1,91 @@
import { describe, expect, it, vi } from "vitest";
import { collectBossCardDrop, emptyBossCardCollection, normalizeBossCardCollection, rollBossCards, type BossCardDrop } from "./bossCards";
import { BOSS_CARD_CATALOG, bossCardForSource, buildBossCardCatalog, groupBossCards } from "./bossCardCatalog";
import { DUNGEON_DEFINITIONS } from "./dungeonRegistry";
import { useCombatStore } from "./combatStore";
import { useGameStore } from "./store";
import { allowedLootDrops } from "./lootPolicy";
import { EMPTY_ITEM_STATS } from "./itemStats";
describe("boss card rewards", () => {
it("guarantees Normal and rolls each bonus independently at its exact boundary", () => {
const random = vi.fn().mockReturnValueOnce(0.099).mockReturnValueOnce(0.02).mockReturnValueOnce(0.009);
expect(rollBossCards(random)).toEqual(["normal", "rare", "legendary"]);
expect(random).toHaveBeenCalledTimes(3);
expect(rollBossCards(() => 0)).toEqual(["normal", "rare", "epic", "legendary"]);
expect(rollBossCards(() => 0.1)).toEqual(["normal"]);
expect(rollBossCards(() => NaN)).toEqual(["normal"]);
});
it("counts copies and makes repeated world rewards idempotent after save normalization", () => {
const drop: BossCardDrop = { bossKey: "wow:lady anacondra", spawnId: "boss-spawn", claimId: "kill:1", rarities: ["normal", "rare"] };
const first = collectBossCardDrop(emptyBossCardCollection(), drop);
expect(collectBossCardDrop(first, drop)).toBe(first);
const restored = normalizeBossCardCollection(JSON.parse(JSON.stringify(first)));
expect(collectBossCardDrop(restored, drop)).toBe(restored);
expect(collectBossCardDrop(restored, { ...drop, claimId: "kill:2" }).counts[drop.bossKey]).toEqual({ normal: 2, rare: 2 });
const later = collectBossCardDrop(restored, { ...drop, claimId: "5000:2:boss-spawn" });
expect(collectBossCardDrop(later, { ...drop, claimId: "4000:1:boss-spawn" })).toBe(later);
});
it("migrates old profiles and rejects corrupt counts", () => {
expect(normalizeBossCardCollection(undefined)).toEqual(emptyBossCardCollection());
expect(normalizeBossCardCollection({ counts: { boss: { normal: 3.9, rare: -1, epic: Infinity, legendary: "5" } } }).counts).toEqual({ boss: { normal: 3 } });
});
it("grants cards from a boss without an equipment loot table exactly once", () => {
const dungeon = DUNGEON_DEFINITIONS.find((entry) => entry.id === "ragefire-chasm")!;
const boss = Object.values(dungeon.entities).find((entry) => entry.kind === "boss")!;
useGameStore.getState().activateDungeon(dungeon.id);
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 79 });
useCombatStore.getState().registerMob("no-loot-boss", { name: boss.name, boss: true, lootSourceId: boss.id, maxHealth: 1, xpReward: 0 });
useCombatStore.getState().damageMob("no-loot-boss", 1, 4000);
const key = bossCardForSource(boss.id, dungeon.id)!.key;
expect(useCombatStore.getState().bossCards.counts[key]?.normal).toBe(1);
expect(useCombatStore.getState().inventory).toEqual([]);
expect(useCombatStore.getState().lootMob("no-loot-boss", 4001)).toBe(false);
expect(useCombatStore.getState().bossCards.counts[key]?.normal).toBe(1);
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 79 });
expect(useCombatStore.getState().bossCards).toEqual(emptyBossCardCollection());
useGameStore.getState().activateDungeon("wailing-caverns");
});
it.each([1, 40, 79, 80])("preserves non-equipment while allowing equipment only at 80 (level %i)", (level) => {
const item = { instanceId: "i", itemId: 1, itemKey: "item", name: "Item", quality: "rare" as const, inventorySlot: "waist", armorType: "cloth", weaponType: null, itemLevel: level, sourceItemLevel: 1, stats: EMPTY_ITEM_STATS, quantity: 1, sourceBossKey: "boss", sourceBossName: "Boss", acquiredAt: 1 };
const misc = { ...item, instanceId: "m", inventorySlot: "misc" };
expect(allowedLootDrops([item, misc], level)).toEqual(level === 80 ? [item, misc] : [misc]);
});
});
describe("boss card catalogue and filters", () => {
it("covers every registered boss with its actual model and dungeon", () => {
expect(BOSS_CARD_CATALOG.length).toBeGreaterThan(100);
for (const dungeon of DUNGEON_DEFINITIONS) for (const boss of Object.values(dungeon.entities)) {
if (boss.kind !== "boss") continue;
const card = bossCardForSource(boss.id, dungeon.id)!;
expect(card, `${dungeon.id}:${boss.id}`).not.toBeNull();
expect(card.dungeons).toContainEqual({ id: dungeon.id, title: dungeon.title });
if (boss.visual.model) expect(card.model).toBeDefined();
}
});
it("merges the same boss across dungeons and groups without changing earned copies", () => {
const wc = DUNGEON_DEFINITIONS.find((entry) => entry.id === "wailing-caverns")!;
const boss = wc.entities["lady-anacondra"];
const catalog = buildBossCardCatalog([
{ ...wc, entities: { [boss.id]: boss } },
{ ...wc, id: "second-dungeon", title: "Second Dungeon", entities: { [boss.id]: boss } },
]);
expect(catalog).toHaveLength(1);
expect(catalog[0].dungeons).toHaveLength(2);
const collection = { counts: { [catalog[0].key]: { normal: 5, legendary: 1 } }, lastClaims: {} };
expect(groupBossCards(collection, { earnedOnly: false, grouping: "all" }, catalog)[0].rows).toHaveLength(4);
expect(groupBossCards(collection, { earnedOnly: true, grouping: "all" }, catalog)[0].rows.map((row) => row.copies)).toEqual([5, 1]);
const dungeons = groupBossCards(collection, { earnedOnly: true, grouping: "dungeon" }, catalog);
expect(dungeons).toHaveLength(2);
expect(dungeons.every((group) => group.rows[0].copies === 5)).toBe(true);
expect(groupBossCards(collection, { earnedOnly: true, grouping: "rarity" }, catalog).map((group) => group.key)).toEqual(["normal", "legendary"]);
expect(groupBossCards(collection, { earnedOnly: false, grouping: "all", search: "second dungeon" }, catalog)[0].rows).toHaveLength(4);
expect(groupBossCards(collection, { earnedOnly: true, grouping: "all", category: "rom" }, catalog)).toEqual([]);
});
});
+81
View File
@@ -0,0 +1,81 @@
export const BOSS_CARD_RARITIES = ["normal", "rare", "epic", "legendary"] as const;
export type BossCardRarity = (typeof BOSS_CARD_RARITIES)[number];
export const BOSS_CARD_RARITY_INFO = {
normal: { label: "Normal", chance: 1, odds: "100%", color: "#d8d5cb" },
rare: { label: "Rare", chance: 1 / 10, odds: "1 in 10", color: "#69b4ff" },
epic: { label: "Epic", chance: 1 / 50, odds: "1 in 50", color: "#c493ff" },
legendary: { label: "Legendary", chance: 1 / 100, odds: "1 in 100", color: "#ffb45b" },
} as const;
export type BossCardCounts = Partial<Record<BossCardRarity, number>>;
export interface BossCardCollection {
readonly counts: Readonly<Record<string, BossCardCounts>>;
/** Last reward per spawned boss prevents shared-world replay and reconnect duplicates. */
readonly lastClaims: Readonly<Record<string, string>>;
}
export interface BossCardDrop {
readonly bossKey: string;
readonly spawnId: string;
readonly claimId: string;
readonly rarities: readonly BossCardRarity[];
}
export function emptyBossCardCollection(): BossCardCollection {
return { counts: {}, lastClaims: {} };
}
export function normalizeBossCardCollection(value: unknown): BossCardCollection {
if (!value || typeof value !== "object" || Array.isArray(value)) return emptyBossCardCollection();
const raw = value as Partial<BossCardCollection>;
const counts: Record<string, BossCardCounts> = Object.create(null);
if (raw.counts && typeof raw.counts === "object" && !Array.isArray(raw.counts)) {
for (const [key, candidate] of Object.entries(raw.counts)) {
if (!key || !candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
const entry: BossCardCounts = {};
for (const rarity of BOSS_CARD_RARITIES) {
const count = candidate[rarity];
if (typeof count === "number" && Number.isFinite(count) && count >= 1) {
entry[rarity] = Math.min(Number.MAX_SAFE_INTEGER, Math.floor(count));
}
}
if (Object.keys(entry).length) counts[key] = entry;
}
}
const lastClaims = raw.lastClaims && typeof raw.lastClaims === "object" && !Array.isArray(raw.lastClaims)
? Object.fromEntries(Object.entries(raw.lastClaims).filter(([key, claim]) => key && typeof claim === "string"))
: {};
return { counts, lastClaims };
}
/** Independent bonus rolls; Normal is always awarded, including with all three bonuses. */
export function rollBossCards(random: () => number = Math.random): readonly BossCardRarity[] {
return BOSS_CARD_RARITIES.filter((rarity) => {
if (rarity === "normal") return true;
const roll = random();
return Number.isFinite(roll) && Math.max(0, Math.min(1, roll)) < BOSS_CARD_RARITY_INFO[rarity].chance;
});
}
export function collectBossCardDrop(collection: BossCardCollection, drop: BossCardDrop): BossCardCollection {
const lastClaim = collection.lastClaims[drop.spawnId];
if (lastClaim === drop.claimId) return collection;
// Generated claims begin with the death's epoch time. Ignore older snapshots
// even after the same spawn has awarded a subsequent kill.
if (lastClaim && /^\d+:/.test(lastClaim) && /^\d+:/.test(drop.claimId)) {
const [lastTime, lastRevision] = lastClaim.split(":").map(Number);
const [time, revision] = drop.claimId.split(":").map(Number);
if (time < lastTime || (time === lastTime && revision <= lastRevision)) return collection;
}
const counts = { ...collection.counts[drop.bossKey] };
for (const rarity of new Set(drop.rarities)) {
if (BOSS_CARD_RARITIES.includes(rarity)) {
counts[rarity] = Math.min(Number.MAX_SAFE_INTEGER, (counts[rarity] ?? 0) + 1);
}
}
return {
counts: { ...collection.counts, [drop.bossKey]: counts },
lastClaims: { ...collection.lastClaims, [drop.spawnId]: drop.claimId },
};
}
+9 -1
View File
@@ -188,11 +188,19 @@ describe("Ascension Conquest ability catalog", () => {
});
expect(Object.values(COA_TRIGGERED_ABILITIES_BY_SPELL_ID).filter((ability) => (
ability.effects.some((effect) => effect.kind !== "utility")
))).toHaveLength(547);
))).toHaveLength(546);
for (const [spellId, ability] of Object.entries(COA_TRIGGERED_ABILITIES_BY_SPELL_ID)) {
expect(ability.dbcSpellId, spellId).toBe(Number(spellId));
expect(ability.effects.length, spellId).toBeGreaterThan(0);
expect(ability.effects.some((effect) => effect.kind === "scripted" || effect.kind === "unsupported"), spellId).toBe(false);
}
});
it("does not invent damage for proc auras or cooldown-only trigger payloads", () => {
expect(COA_TRIGGERED_ABILITIES_BY_SPELL_ID[707821].effects.some((effect) => effect.kind === "damage")).toBe(false);
expect(COA_TRIGGERED_ABILITIES_BY_SPELL_ID[807661].effects.every((effect) => effect.kind === "utility")).toBe(true);
expect(COA_TRIGGERED_ABILITIES_BY_SPELL_ID[712682].effects).toContainEqual(
expect.objectContaining({ kind: "trigger-spell", spellId: 712476, expanded: true }),
);
});
});
+7 -3
View File
@@ -880,6 +880,9 @@ function effectsForSpell(
effects.push({
kind: "trigger-spell",
spellId: triggeredSpellId,
// Expanded payloads below execute in the parent; retain this marker
// for source lookup without executing the same payload a second time.
expanded: depth < 2 && !visitedSpellIds.has(triggeredSpellId) && Boolean(coaSourceSpellById(triggeredSpellId)),
...([141, 142, 183].includes(effect.effectType) ? { withValue: effect.basePoints } : {}),
});
if (depth < 2 && !visitedSpellIds.has(triggeredSpellId)) {
@@ -987,12 +990,13 @@ function effectsForSpell(
}
const hasHealing = effects.some((effect) => ["heal", "hot"].includes(effect.kind));
const hasDamage = effects.some((effect) => ["damage", "dot"].includes(effect.kind)
|| (effect.kind === "apply-aura" && effect.aura.procs?.some((proc) => proc.action.kind === "damage")));
const hasDamage = effects.some((effect) => ["damage", "dot", "trigger-spell"].includes(effect.kind)
|| (effect.kind === "apply-aura" && effect.aura.procs?.some((proc) => ["damage", "custom"].includes(proc.action.kind))));
const describesHealing = /\b(?:heal(?:s|ing|ed)?|restores? .*health|mends?|rejuvenat\w*)\b/i.test(description);
const describesDamage = /\b(?:deal(?:s|ing)?|inflict(?:s|ing)?|caus(?:e|es|ing)|damag(?:e|es|ing))\b[^.]*\bdamage\b/i.test(description);
if (!hasHealing && describesHealing) effects.unshift({ kind: "heal", coefficient: 1 });
if (!hasDamage && describesDamage) effects.unshift({ kind: "damage", coefficient: 1 });
const describesDamageCondition = /^\s*Dealing\b.*\b(?:reduces?|increases?)\b/i.test(description);
if (!hasDamage && describesDamage && !describesDamageCondition) effects.unshift({ kind: "damage", coefficient: 1 });
if (!effects.some((effect) => ["damage", "heal", "dot", "hot", "shield"].includes(effect.kind))) {
if (/\bswap health percentages\b/i.test(description)) {
const minimum = Number(description.match(/to\s+(\d+(?:\.\d+)?)%/)?.[1] ?? 40);
+28 -8
View File
@@ -798,7 +798,7 @@ describe("combat store", () => {
expect(useCombatStore.getState().lootMob("lootable", 30_000)).toBe(false);
});
it("rolls SQL boss loot at the killing player's level and grants it automatically exactly once", () => {
it("suppresses leveling equipment while granting boss cards automatically exactly once", () => {
useCombatStore.getState().initializeCharacter({
classId: "priest",
level: 1,
@@ -825,11 +825,9 @@ describe("combat store", () => {
looted: true,
corpseDespawnAt: 5_000 + MINIMUM_CORPSE_VISIBLE_MS,
});
expect(corpse.pendingLoot).toHaveLength(1);
expect(corpse.pendingLoot[0]).toMatchObject({
itemLevel: 1,
sourceBossKey: "lady-anacondra",
});
expect(corpse.pendingLoot).toEqual([]);
expect(corpse.bossCardDrop?.rarities).toContain("normal");
expect(useCombatStore.getState().bossCards.counts["wow:lady anacondra"]?.normal).toBe(1);
expect(useCombatStore.getState().inventory).toEqual(corpse.pendingLoot);
expect(useCombatStore.getState().bossLootRewards).toEqual([
@@ -846,7 +844,8 @@ describe("combat store", () => {
expect(useCombatStore.getState().bossLootRewards).toEqual([]);
expect(useCombatStore.getState().lootMob("anacondra-spawn", 5_100)).toBe(false);
expect(useCombatStore.getState().lootMob("anacondra-spawn", 5_200)).toBe(false);
expect(useCombatStore.getState().inventory).toHaveLength(1);
expect(useCombatStore.getState().inventory).toHaveLength(0);
expect(useCombatStore.getState().bossCards.counts["wow:lady anacondra"]?.normal).toBe(1);
});
it("aggros every surviving packmate even when the pulled mob dies to the opening hit", () => {
@@ -1073,6 +1072,26 @@ describe("combat store", () => {
}));
});
it("prevents Death Pact from instantly killing an encounter boss", () => {
useCombatStore.getState().initializeCharacter({ classId: "death-knight", level: 80 });
registerTarget("pact-boss", [2, 0, 0], 1_000_000, 0);
useCombatStore.getState().registerMob("pact-boss", { name: "Pact boss", boss: true, maxHealth: 1_000_000, xpReward: 0 });
useCombatStore.setState({ resource: 100, resourcePools: { "runic-power": 100 } });
expect(useCombatStore.getState().castAbility("wow335-death-knight-death-pact", undefined, 1_000).ok).toBe(true);
expect(useCombatStore.getState().mobs["pact-boss"]).toMatchObject({ dead: false, health: 1_000_000 });
});
it("prevents repeated Favor activations across branches of one Guardian hit", async () => {
const build = (await loadCanonicalBenchmarkBuilds(80, ["guardian"]))
.find((candidate) => candidate.role === "damage")!;
useCombatStore.getState().initializeCharacter({ classId: build.classId, level: build.level, talentRanks: build.talentRanks });
registerTarget("guardian-proc-dummy", [2, 0, 0], 1_000_000, 0);
expect(useCombatStore.getState().castAbility("coa-18-reprisal-69-800316", undefined, 1_000).ok).toBe(true);
const hits = useCombatStore.getState().combatEvents.filter((event) => event.kind === "damage"
&& event.abilityId === "coa-triggered-712476");
expect(hits.length).toBeLessThanOrEqual(2);
});
it("resets encounter health without erasing earned progression", () => {
registerTarget("mob", [2, 0, 0], 1, 100);
useCombatStore.getState().damageMob("mob", 5, 1000);
@@ -1478,6 +1497,7 @@ describe("combat store", () => {
});
useCombatStore.getState().damageMob("storm-boss", 10_000, 30_000);
expect(useCombatStore.getState().mobs["storm-boss"].pendingLoot).toHaveLength(2);
expect(useCombatStore.getState().mobs["storm-boss"].pendingLoot).toHaveLength(0);
expect(useCombatStore.getState().mobs["storm-boss"].bossCardDrop?.rarities).toContain("normal");
});
});
+70 -16
View File
@@ -128,6 +128,8 @@ import {
type TriggeredAuraProc,
} from "./combatAuras";
import { rollBossLoot } from "./lootCatalog";
import { bossCardForSource } from "./bossCardCatalog";
import { collectBossCardDrop, emptyBossCardCollection, normalizeBossCardCollection, rollBossCards, type BossCardCollection, type BossCardDrop } from "./bossCards";
import { adaptRunewakerEnemyDamage } from "./runewakerCombatFormula";
import { channelAmountEffects } from "./combatChannelAmounts";
import { normalizeInventory, type InventoryItem } from "./lootTypes";
@@ -357,6 +359,7 @@ export interface MobCombatState {
readonly dead: boolean;
readonly hasLoot: boolean;
readonly pendingLoot: readonly InventoryItem[];
readonly bossCardDrop?: BossCardDrop;
readonly looted: boolean;
readonly despawned: boolean;
readonly diedAt: number | null;
@@ -454,6 +457,7 @@ export interface BossLootReward {
readonly bossId: string;
readonly bossName: string;
readonly items: readonly InventoryItem[];
readonly cards?: BossCardDrop;
readonly acquiredAt: number;
}
@@ -525,6 +529,7 @@ export interface CharacterCombatSeed {
readonly talentRanks?: TalentRanks;
readonly actionBindings?: unknown;
readonly inventory?: unknown;
readonly bossCards?: unknown;
readonly equipment?: unknown;
readonly settings?: Partial<GameplaySettings>;
}
@@ -667,6 +672,8 @@ export interface CombatState {
talentModifiers: readonly TalentModifier[];
actionBindings: ActionBindings;
inventory: readonly InventoryItem[];
bossCards: BossCardCollection;
collectSharedBossCards: (drop: BossCardDrop, bossName: string, now: number) => void;
equipment: EquipmentAssignments;
gearStats: ItemStats;
settings: GameplaySettings;
@@ -785,6 +792,7 @@ interface MutableCastWork {
secondaryClassId: ClassId | null;
/** Active synchronous spell/source/target keys used to break proc cycles. */
triggeredSpellStack?: string[];
triggeredProcKeys?: Set<string>;
}
let feedbackSequence = 0;
@@ -1336,6 +1344,12 @@ function resolvePlayerDamageResult(
const attacker: CombatAttackerStats = {
...baseAttacker,
criticalChancePercent: (baseAttacker.criticalChancePercent ?? 0) + criticalChanceFromTalents,
criticalDamageMultiplier: applyTalentModifierValue(
2,
work.talentModifiers,
"critical-damage-percent",
ability ? abilityTalentContext(ability, periodic) : {},
),
};
const immune = mob.schoolImmunities.includes(school);
return resolveCombatResult({
@@ -2280,17 +2294,29 @@ function evaluateProcsInWork(
event: ProcEvent,
now: number,
): readonly TriggeredAuraProc[] {
const result = evaluateAuraProcs(
work.auras,
event,
now,
({ aura, proc }) => stableCombatUnit(
`${aura.instanceId}:${proc.id}:${event.trigger}:${event.abilityId ?? ""}:${event.otherId ?? ""}:${now}`,
),
);
work.auras = [...result.auras];
executeTriggeredAuraProcsInWork(work, result.triggered, now);
return result.triggered;
const root = work.triggeredProcKeys === undefined;
const triggeredKeys = work.triggeredProcKeys ?? new Set<string>();
work.triggeredProcKeys = triggeredKeys;
try {
const result = evaluateAuraProcs(
work.auras,
event,
now,
({ aura, proc }) => triggeredKeys.has(`${aura.instanceId}:${proc.id}`)
? 1
: stableCombatUnit(
`${aura.instanceId}:${proc.id}:${event.trigger}:${event.abilityId ?? ""}:${event.otherId ?? ""}:${now}`,
),
);
// A proc can activate once for the originating event. Its damage must not
// reactivate it through a different branch of the same triggered chain.
for (const proc of result.triggered) triggeredKeys.add(`${proc.auraInstanceId}:${proc.procId}`);
work.auras = [...result.auras];
executeTriggeredAuraProcsInWork(work, result.triggered, now);
return result.triggered;
} finally {
if (root) work.triggeredProcKeys = undefined;
}
}
function eligibleTargetIds(state: CombatState, origin: CombatPosition, maxRange: number): string[] {
@@ -2600,7 +2626,16 @@ function damageMobInWork(
bonusItemChance: mob.bonusLootChance,
})
: mob.pendingLoot;
const hasLoot = killed ? mob.hasLoot || pendingLoot.length > 0 : mob.hasLoot;
const card = killed && mob.boss
? bossCardForSource(mob.lootSourceId ?? mob.id, useGameStore.getState().activeDungeonId, mob.name)
: null;
const bossCardDrop = card ? {
bossKey: card.key,
spawnId: mob.id,
claimId: `${now}:${mob.deathRevision + 1}:${mob.id}`,
rarities: rollBossCards(),
} satisfies BossCardDrop : mob.bossCardDrop;
const hasLoot = killed ? mob.hasLoot || pendingLoot.length > 0 || Boolean(bossCardDrop) : mob.hasLoot;
const xpAwarded = canAward ? grantMobExperience(classId, work, mob.xpReward) : 0;
engageMobGroupInWork(work, id, now, source.actorId);
const engagedMob = work.mobs[id] ?? mob;
@@ -2618,6 +2653,7 @@ function damageMobInWork(
dead: killed,
hasLoot,
pendingLoot,
bossCardDrop,
looted: killed ? false : mob.looted,
despawned: false,
diedAt: killed ? now : mob.diedAt,
@@ -3025,7 +3061,7 @@ function executeTriggeredSpellInWork(
} else if (effect.kind === "execute") {
for (const mobId of mobTargets) {
const mob = work.mobs[mobId];
if (mob) damageMobInWork(
if (mob && !mob.boss) damageMobInWork(
work.classId,
work,
mobId,
@@ -3064,7 +3100,7 @@ function executeTriggeredSpellInWork(
work.cooldowns[candidate.id] = Math.max(now, readyAt - reduction);
}
}
} else if (effect.kind === "trigger-spell" && depth < 1 && effect.spellId !== spellId) {
} else if (effect.kind === "trigger-spell" && !effect.expanded && depth < 1 && effect.spellId !== spellId) {
executeTriggeredSpellInWork(work, effect.spellId, sourceId, targetId, now, depth + 1, allowCoaHidden);
}
}
@@ -3409,6 +3445,7 @@ function initialState() {
talentModifiers,
actionBindings: defaultActionBindings(defaultActionBarForClass(classId)),
inventory: [] as readonly InventoryItem[],
bossCards: emptyBossCardCollection(),
equipment: {} as EquipmentAssignments,
gearStats: EMPTY_ITEM_STATS,
settings: DEFAULT_GAMEPLAY_SETTINGS,
@@ -3481,6 +3518,7 @@ export const useCombatStore = create<CombatState>((set, get) => ({
talentModifiers,
actionBindings: normalizeActionBindings(profile.actionBindings, defaultActionBarForCharacter(classId, secondaryClassId, progression.level)),
inventory,
bossCards: normalizeBossCardCollection(profile.bossCards),
equipment,
gearStats,
settings: normalizedSettings(DEFAULT_GAMEPLAY_SETTINGS, profile.settings ?? {}),
@@ -3717,11 +3755,13 @@ export const useCombatStore = create<CombatState>((set, get) => ({
bossId: id,
bossName: mob.name,
items: mob.pendingLoot,
...(mob.bossCardDrop ? { cards: mob.bossCardDrop } : {}),
acquiredAt: now,
} satisfies BossLootReward
: null;
return {
inventory: [...state.inventory, ...mob.pendingLoot],
bossCards: mob.bossCardDrop ? collectBossCardDrop(state.bossCards, mob.bossCardDrop) : state.bossCards,
mobs: {
...state.mobs,
[id]: {
@@ -3745,6 +3785,17 @@ export const useCombatStore = create<CombatState>((set, get) => ({
: state.bossLootRewards.filter((reward) => reward.id !== id),
})),
collectSharedBossCards: (drop, bossName, now) => set((state) => {
const bossCards = collectBossCardDrop(state.bossCards, drop);
if (bossCards === state.bossCards) return state;
return {
bossCards,
bossLootRewards: [...state.bossLootRewards, {
id: ++bossLootRewardSequence, bossId: drop.spawnId, bossName, items: [], cards: drop, acquiredAt: now,
}],
};
}),
equipItem: (instanceId, ownerId = PLAYER_EQUIPMENT_OWNER_ID) => {
const state = get();
const ownerClassId = ownerId === PLAYER_EQUIPMENT_OWNER_ID
@@ -5166,7 +5217,9 @@ export const useCombatStore = create<CombatState>((set, get) => ({
} else if (effect.kind === "execute") {
for (const id of affectedMobIds) {
const mob = work.mobs[id];
if (!mob || mob.dead) continue;
// DBC instant-kill effects include pet sacrifices such as Death Pact.
// They must never bypass a boss encounter's health and mechanics.
if (!mob || mob.dead || mob.boss) continue;
damageMobInWork(
state.classId,
work,
@@ -5320,7 +5373,7 @@ export const useCombatStore = create<CombatState>((set, get) => ({
} else if (effect.kind === "cooldown-reset") {
cooldownAdjustments.push(effect);
} else if (effect.kind === "trigger-spell") {
if (effect.spellId !== ability.dbcSpellId) {
if (!effect.expanded && effect.spellId !== ability.dbcSpellId) {
executeTriggeredSpellInWork(
work,
effect.spellId,
@@ -8359,6 +8412,7 @@ export const useCombatStore = create<CombatState>((set, get) => ({
health: preserveDefeated ? 0 : mob.maxHealth,
dead: preserveDefeated,
pendingLoot: preserveDefeated ? mob.pendingLoot : [],
bossCardDrop: preserveDefeated ? mob.bossCardDrop : undefined,
looted: preserveDefeated ? mob.looted : false,
despawned: preserveDefeated ? mob.despawned : false,
diedAt: preserveDefeated ? mob.diedAt : null,
+55
View File
@@ -0,0 +1,55 @@
import { afterAll, describe, expect, it } from "vitest";
import { mkdirSync, writeFileSync } from "node:fs";
import { BASE_CLASS_IDS, COA_CLASS_IDS } from "../app/characterCatalog";
import { loadCanonicalBenchmarkBuilds } from "./benchmark/benchmarkBuilds";
import { runDungeonBossBenchmark } from "./benchmark/dungeonBossBenchmark";
import { requireDungeonDefinition } from "./dungeonRegistry";
import { finalDungeonBoss } from "./dungeonRunStore";
const dungeon = requireDungeonDefinition("ragefire-chasm");
const final = finalDungeonBoss(dungeon)!;
const ordinary = dungeon.bosses.find((boss) => boss.id !== final.id)!;
const samples: unknown[] = [];
afterAll(() => {
if (process.env.BOSS_BALANCE_REPORT !== "1") return;
mkdirSync("artifacts/boss-difficulty", { recursive: true });
writeFileSync("artifacts/boss-difficulty/wow-coa-balance.json", `${JSON.stringify({
difficulty: 1, dungeon: dungeon.id, durationLimitSeconds: 60,
targets: { ordinary: 25, final: 45 }, policy: "baseline-v1", gear: "resolved starter heirlooms", samples,
}, null, 2)}\n`);
});
describe("default boss difficulty with WoW and CoA classes", () => {
for (const level of [8, 20, 40, 80]) {
it(`benchmarks every class-role build at level ${level}`, async () => {
const builds = await loadCanonicalBenchmarkBuilds(level, [...BASE_CLASS_IDS, ...COA_CLASS_IDS]);
const tooFast: string[] = [];
for (const build of builds) {
// Let the test worker deliver progress between CPU-heavy simulations.
await new Promise<void>((resolve) => setTimeout(resolve, 0));
for (const seed of ["class-balance-1", "class-balance-2", "class-balance-3"]) {
const boss = await runDungeonBossBenchmark(build, ordinary.id, seed);
const last = await runDungeonBossBenchmark(build, final.id, seed);
samples.push({ level, classId: build.classId, source: build.source, role: build.role, orientation: build.orientation, seed, boss, final: last });
if ((boss.seconds ?? boss.elapsedSeconds) < 25 || (last.seconds ?? last.elapsedSeconds) < 45) {
tooFast.push(`${build.id}: ${boss.seconds}/${last.seconds}`);
}
}
}
expect(tooFast).toEqual([]);
}, 180_000);
}
for (const level of [8, 80]) {
it(`records healer outcomes with the final boss attacking at level ${level}`, async () => {
const builds = (await loadCanonicalBenchmarkBuilds(level, [...BASE_CLASS_IDS, ...COA_CLASS_IDS]))
.filter((build) => build.role === "healer");
for (const build of builds) {
const last = await runDungeonBossBenchmark(build, final.id, "class-balance-2", true);
samples.push({ level, classId: build.classId, source: build.source, role: build.role, mechanics: true, final: last });
expect(last.attacks, build.id).toBeGreaterThan(5);
expect(last.incomingDamage, build.id).toBeGreaterThan(0);
}
}, 60_000);
}
});
+123
View File
@@ -0,0 +1,123 @@
import { afterAll, describe, expect, it } from "vitest";
import { mkdirSync, writeFileSync } from "node:fs";
import { dungeonEnemyScaling } from "./dungeonBossScaling";
import { requireDungeonDefinition } from "./dungeonRegistry";
import { finalDungeonBoss } from "./dungeonRunStore";
import { useCombatStore } from "./combatStore";
import { usePartyStore } from "./partyStore";
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
import { clearPartyRuntimeRegistry, registerPartyRuntimePosition, updatePartyRuntimeTargetVisibility } from "./partyRuntimeRegistry";
import { advanceDungeonPartyCombat, partyCombatRangeBand, resetPartyRuntimeClock } from "./partyRuntime";
import { subscribeCombatEvents } from "./combatEvents";
import { bossDifficultyMultipliers } from "./dungeonDifficulty";
import { abilitiesForClass } from "./abilityCatalog";
const dungeon = requireDungeonDefinition("ragefire-chasm");
const final = finalDungeonBoss(dungeon)!;
const samples: { level: number; seed: string; boss: unknown; final: unknown }[] = [];
afterAll(() => {
if (process.env.BOSS_BALANCE_REPORT !== "1") return;
mkdirSync("artifacts/boss-difficulty", { recursive: true });
writeFileSync("artifacts/boss-difficulty/ragefire-balance.json", `${JSON.stringify({ samples }, null, 2)}\n`);
});
function fight(bossId: string, level: number, difficulty: number, seed: string, mechanics = false, playerDamage = false) {
clearMobRuntimeRegistry(); clearPartyRuntimeRegistry(); resetPartyRuntimeClock();
const entity = dungeon.entities[dungeon.staticSpawns.find((spawn) => spawn.id === bossId)!.entityId];
const scaling = dungeonEnemyScaling(dungeon, entity, bossId, level, "normal", difficulty);
const combat = useCombatStore.getState();
const classId = playerDamage ? "rom-mage" : "rom-priest";
combat.initializeCharacter({ classId, raceId: "rom-human", level });
combat.setPlayerPosition([-18, 0, 0]);
usePartyStore.getState().initializeParty(seed, level, useCombatStore.getState().health, playerDamage ? "damage" : "healer", 5, "rom");
combat.synchronizeActors();
combat.registerMob(bossId, { name: entity.name, boss: true, serverEntry: entity.combat?.serverEntry,
...scaling, attacks: entity.combat?.attacks, xpReward: 0 });
setMobPosition(bossId, [0, 0, 0]);
for (const member of usePartyStore.getState().members) {
registerPartyRuntimePosition(member.id, [-partyCombatRangeBand(member).preferred, 0, 0]);
updatePartyRuntimeTargetVisibility(member.id, bossId, true);
}
let firstDamage: number | undefined;
let incomingDamage = 0; let healing = 0;
const heal = abilitiesForClass("rom-priest").find((ability) => ability.name === "Urgent Heal")!;
const damage = abilitiesForClass(classId).find((ability) => ability.target === "hostile"
&& ability.effects.some((effect) => effect.kind === "damage"))!;
combat.selectMob(bossId);
const stop = subscribeCombatEvents((event) => {
if (event.kind === "damage" && event.targetActorId === bossId && event.effectiveAmount > 0) firstDamage ??= event.occurredAt;
if (event.kind === "damage" && event.sourceActorId === bossId) incomingDamage += event.effectiveAmount;
if (event.kind === "healing") healing += event.effectiveAmount;
});
combat.damageMob(bossId, 1, 1000);
try {
for (let now = 1100; now <= 241000; now += 100) {
combat.tick(.1, now); advanceDungeonPartyCombat(now);
if (playerDamage && !useCombatStore.getState().activeCast) combat.castAbility(damage.id, undefined, now);
if (mechanics) {
combat.advanceMobCombat(now);
const injured = usePartyStore.getState().members.filter((member) => member.health > 0)
.sort((left, right) => left.health / left.maxHealth - right.health / right.maxHealth)[0];
if (injured && injured.health < injured.maxHealth * .8 && !useCombatStore.getState().activeCast) {
usePartyStore.getState().selectMember(injured.id); combat.castAbility(heal.id, undefined, now);
}
}
const mob = useCombatStore.getState().mobs[bossId];
if (mob.dead) return { seconds: ((mob.diedAt ?? now) - firstDamage!) / 1000,
incomingDamage, healing, attacks: mob.attackRevision,
maxHealth: mob.maxHealth, classes: usePartyStore.getState().members.map((member) => member.classId) };
}
return { seconds: null, maxHealth: scaling.maxHealth };
} finally { stop(); }
}
describe("dungeon boss durability and difficulty", () => {
it("increases boss health and damage at every slider step without changing trash", () => {
const spawn = dungeon.staticSpawns.find((entry) => entry.id === final.id)!;
const entity = dungeon.entities[spawn.entityId];
const trash = dungeon.staticSpawns.find((entry) => dungeon.entities[entry.entityId].kind === "mob")!;
const easy = dungeonEnemyScaling(dungeon, entity, final.id, 8, "normal", 1);
for (let difficulty = 2; difficulty <= 10; difficulty += 1) {
const scaled = dungeonEnemyScaling(dungeon, entity, final.id, 8, "normal", difficulty);
expect(scaled.maxHealth).toBe(easy.maxHealth * bossDifficultyMultipliers(difficulty).health);
expect(scaled.damageMultiplier).toBe(easy.damageMultiplier * bossDifficultyMultipliers(difficulty).damage);
expect(dungeonEnemyScaling(dungeon, dungeon.entities[trash.entityId], trash.id, 8, "normal", difficulty))
.toEqual(dungeonEnemyScaling(dungeon, dungeon.entities[trash.entityId], trash.id, 8, "normal", 1));
}
});
it("allows real boss attacks and Priest healing before Ragefire's final boss dies", () => {
const result = fight(final.id, 8, 1, "rom-health-1", true);
expect(result.seconds).not.toBeNull(); expect(result.seconds!).toBeGreaterThanOrEqual(45);
expect(result.attacks).toBeGreaterThan(5); expect(result.incomingDamage).toBeGreaterThan(0);
expect(result.healing).toBeGreaterThan(0);
expect(usePartyStore.getState().members.every((member) => member.health > 0)).toBe(true);
});
it("retains encounter time with a damage-role Mage contributing to the RoM party", () => {
for (const level of [1, 8, 20, 40, 80]) {
const ordinary = dungeon.bosses.find((boss) => boss.id !== final.id)!;
const boss = fight(ordinary.id, level, 1, "rom-health-1", false, true);
const last = fight(final.id, level, 1, "rom-health-1", false, true);
samples.push({ level, seed: "player-mage", boss, final: last });
expect(boss.seconds).not.toBeNull(); expect(last.seconds).not.toBeNull();
expect(boss.seconds!, JSON.stringify({ level, boss, last })).toBeGreaterThanOrEqual(25);
expect(last.seconds!, JSON.stringify({ level, boss, last })).toBeGreaterThanOrEqual(45);
}
});
for (const level of [1, 8, 20, 40, 80]) {
it(`gives a RoM party time to play Ragefire boss mechanics at level ${level}`, () => {
const ordinary = dungeon.bosses.find((boss) => boss.id !== final.id)!;
for (let index = 0; index < 12; index += 1) {
const seed = `rom-health-${index}`;
const boss = fight(ordinary.id, level, 1, seed);
const last = fight(final.id, level, 1, seed);
samples.push({ level, seed, boss, final: last });
expect(boss.seconds).not.toBeNull(); expect(last.seconds).not.toBeNull();
expect(boss.seconds!).toBeGreaterThanOrEqual(25);
expect(last.seconds!).toBeGreaterThanOrEqual(45);
}
}, 30000);
}
});
+25
View File
@@ -0,0 +1,25 @@
import { creatureRuntimeBaseStats } from "./azerothCoreReference";
import { bossDifficultyMultipliers } from "./dungeonDifficulty";
import { dungeonEnemyHealthBaseline, scaledDungeonEnemyLevel } from "./dungeonLevelScaling";
import { finalDungeonBoss } from "./dungeonRunStore";
import type { DungeonDefinition } from "./dungeonTypes";
import type { PopulationEntityDefinition } from "./mobPopulation";
/** Shared by rendering and deterministic combat benchmarks; preserves authored stats above the floor. */
export function dungeonEnemyScaling(dungeon: DungeonDefinition, entity: PopulationEntityDefinition,
instanceId: string, characterLevel: number, difficultyId: string, bossDifficulty: number) {
const boss = entity.kind === "boss";
const level = scaledDungeonEnemyLevel(characterLevel, boss);
const authoredHealth = entity.combat?.healthMultiplier ?? 1;
const authoredDamage = entity.combat?.damageMultiplier ?? 1;
const baseline = dungeonEnemyHealthBaseline(level, dungeon.expansion);
const native = entity.combat?.serverEntry ? creatureRuntimeBaseStats(entity.combat.serverEntry, level) : null;
const originalHealth = (baseline ?? native?.health ?? (boss ? 260 + level * 65 : 72 + level * 22)) * authoredHealth;
const multipliers = boss ? bossDifficultyMultipliers(bossDifficulty) : { health: 1, damage: 1 };
const finalBoss = boss && finalDungeonBoss(dungeon, difficultyId)?.id === instanceId;
// Calibrated against active RoM, WoW and CoA class-role rotations with heirlooms.
// Every class faces the same floor; the margin covers stronger CoA burst builds.
const bossFloor = (1_000 + level * 1_200 + level * level * 22) * 1.75 * (finalBoss ? 1.8 : 1);
return { level, maxHealth: (boss ? Math.max(originalHealth, bossFloor) : originalHealth) * multipliers.health,
healthMultiplier: authoredHealth * multipliers.health, damageMultiplier: authoredDamage * multipliers.damage };
}
+13
View File
@@ -0,0 +1,13 @@
/** Separate from the source dungeon's Normal/Heroic creature variant. */
export function validBossDifficulty(value: unknown): value is number {
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 10;
}
export function bossDifficultyMultipliers(level: number) {
const difficulty = validBossDifficulty(level) ? level : 1;
return { health: 1 + (difficulty - 1) * 0.25, damage: 1 + (difficulty - 1) * 0.15 };
}
export function bossDifficultyLabel(level?: number): string {
return level ? `Difficulty ${level}${level === 1 ? " · Easy" : ""}` : "Legacy";
}
+12
View File
@@ -10,6 +10,18 @@ const party: readonly DungeonRunMember[] = [{ name: "Tester", classId: "rom-prie
beforeEach(() => { useDungeonRunStore.setState({ progress: null }); });
describe("dungeon completion and run timing", () => {
it("preserves the selected difficulty on resume and starts a new timer when it changes", () => {
const run = useDungeonRunStore.getState();
run.begin("deadmines", "normal", undefined, false, 7); run.start(1000, party);
const saved = normalizeDungeonRunProgress(JSON.parse(JSON.stringify(useDungeonRunStore.getState().progress)))!;
run.begin("deadmines", "normal", saved, false, 7);
expect(useDungeonRunStore.getState().progress).toEqual(saved);
run.begin("deadmines", "normal", saved, false, 8);
expect(useDungeonRunStore.getState().progress).toMatchObject({ bossDifficulty: 8, startedAt: null });
expect(useDungeonRunStore.getState().progress!.id).not.toBe(saved.id);
expect(normalizeDungeonRunProgress({ ...saved, bossDifficulty: 11 })).toBeNull();
expect(normalizeDungeonRunProgress({ ...saved, bossDifficulty: 1.5 })).toBeNull();
});
it("completes Barren Caves when Anglo dies, records its real spawn id, and survives checkpoint hydration", () => {
const dungeon = requireDungeonDefinition("barren-caves");
activateDungeonEncounterDefinitions(dungeon.id, dungeon.encounters ?? [], "normal");
+6 -4
View File
@@ -22,6 +22,7 @@ export function completedDungeonRun(progress: DungeonRunProgress): DungeonRunRec
const definition = dungeonDefinitionById(progress.dungeonId);
if (!definition || !progress.timed || progress.finishedAt === null || progress.durationMs === null) return null;
return { id: progress.id, dungeonId: progress.dungeonId, difficultyId: progress.difficultyId,
bossDifficulty: progress.bossDifficulty,
finishedAt: progress.finishedAt, durationMs: progress.durationMs, killedBossIds: progress.killedBossIds,
party: progress.party, fullClear: dungeonBossesForDifficulty(definition, progress.difficultyId)
.every((boss) => progress.killedBossIds.includes(boss.id)) };
@@ -29,7 +30,7 @@ export function completedDungeonRun(progress: DungeonRunProgress): DungeonRunRec
interface DungeonRunState {
readonly progress: DungeonRunProgress | null;
begin: (dungeonId: string, difficultyId: string, resume?: DungeonRunProgress, legacyResume?: boolean) => void;
begin: (dungeonId: string, difficultyId: string, resume?: DungeonRunProgress, legacyResume?: boolean, bossDifficulty?: number) => void;
start: (now: number, party: readonly DungeonRunMember[]) => void;
advance: (completedObjectiveIds: readonly string[], deadBossIds: readonly string[], now: number,
party: readonly DungeonRunMember[]) => void;
@@ -37,10 +38,11 @@ interface DungeonRunState {
export const useDungeonRunStore = create<DungeonRunState>((set, get) => ({
progress: null,
begin: (dungeonId, difficultyId, resume, legacyResume = false) => set({
progress: resume?.dungeonId === dungeonId && resume.difficultyId === difficultyId ? resume : {
begin: (dungeonId, difficultyId, resume, legacyResume = false, bossDifficulty = 1) => set({
progress: resume?.dungeonId === dungeonId && resume.difficultyId === difficultyId
&& resume.bossDifficulty === bossDifficulty ? resume : {
id: globalThis.crypto.randomUUID(), dungeonId, difficultyId, startedAt: null,
finishedAt: null, durationMs: null, killedBossIds: [], party: [], timed: !legacyResume,
finishedAt: null, durationMs: null, killedBossIds: [], party: [], timed: !legacyResume, bossDifficulty,
},
}),
start: (now, party) => {
+6
View File
@@ -1,3 +1,5 @@
import { validBossDifficulty } from "./dungeonDifficulty";
export interface DungeonRunMember {
readonly name: string;
readonly classId: string;
@@ -11,6 +13,7 @@ export interface DungeonRunProgress {
readonly id: string;
readonly dungeonId: string;
readonly difficultyId: string;
readonly bossDifficulty?: number;
readonly startedAt: number | null;
readonly finishedAt: number | null;
readonly durationMs: number | null;
@@ -23,6 +26,7 @@ export interface DungeonRunRecord {
readonly id: string;
readonly dungeonId: string;
readonly difficultyId: string;
readonly bossDifficulty?: number;
readonly durationMs: number;
readonly finishedAt: number;
readonly killedBossIds: readonly string[];
@@ -57,6 +61,7 @@ export function normalizeDungeonRunProgress(value: unknown): DungeonRunProgress
const text = (entry: unknown) => typeof entry === "string" && entry.length > 0 && entry.length <= 100;
const time = (entry: unknown) => entry === null || (typeof entry === "number" && Number.isFinite(entry) && entry >= 0);
if (!text(input.id) || !text(input.dungeonId) || !text(input.difficultyId)
|| (input.bossDifficulty !== undefined && !validBossDifficulty(input.bossDifficulty))
|| !time(input.startedAt) || !time(input.finishedAt) || !time(input.durationMs)
|| typeof input.timed !== "boolean" || !Array.isArray(input.killedBossIds)
|| input.killedBossIds.length > 100 || !input.killedBossIds.every(text)
@@ -70,6 +75,7 @@ export function normalizeDungeonRunProgress(value: unknown): DungeonRunProgress
|| (input.finishedAt !== null && (input.durationMs === null || input.party.length === 0
|| input.durationMs !== Math.max(1, Math.round(input.finishedAt - input.startedAt!))))) return null;
return { id: input.id, dungeonId: input.dungeonId, difficultyId: input.difficultyId,
...(input.bossDifficulty !== undefined ? { bossDifficulty: input.bossDifficulty } : {}),
startedAt: input.startedAt, finishedAt: input.finishedAt, durationMs: input.durationMs,
timed: input.timed, killedBossIds: [...new Set(input.killedBossIds)],
party: input.party.map((member) => ({ name: member.name, classId: member.classId,
+8 -1
View File
@@ -20,8 +20,10 @@ import type { DungeonEncounterSnapshot } from "./dungeonEncounterTypes";
import { dungeonContentIsUsable } from "../content/contentManager";
import { useDungeonRunStore } from "./dungeonRunStore";
import type { DungeonRunProgress } from "./dungeonRunTypes";
import { validBossDifficulty } from "./dungeonDifficulty";
export interface DungeonSessionOptions {
readonly bossDifficulty?: number;
readonly gameMode?: GameMode;
readonly spawn?: WorldSpawn;
readonly gmTestMode?: boolean;
@@ -48,12 +50,15 @@ export function activateDungeonSession(
if (!definition || !dungeonCanEnter(dungeonId) || !dungeonContentIsUsable(dungeonId)) {
return false;
}
if ((difficultyId !== undefined && !definition.difficultyVariants.some((variant) => variant.id === difficultyId))
|| (options.bossDifficulty !== undefined && !validBossDifficulty(options.bossDifficulty))) return false;
const previousDefinition = dungeonDefinitionById(useGameStore.getState().activeDungeonId);
const bossDifficulty = options.bossDifficulty ?? options.runProgress?.bossDifficulty ?? 1;
if (previousDefinition) releaseDungeonGltfCache(previousDefinition);
if (!options.preserveCharacter) {
useDungeonRunStore.getState().begin(dungeonId, difficultyId ?? definition.defaultDifficultyId,
options.runProgress, options.legacyResume);
options.runProgress, options.legacyResume, bossDifficulty);
}
activateDungeonEncounterDefinitions(
dungeonId,
@@ -103,6 +108,7 @@ export function activateDungeonSession(
spawn: shelvedDungeonSpawn(dungeonId, options.spawn),
gmTestMode: options.gmTestMode,
gmReviewTarget: options.gmReviewTarget,
bossDifficulty,
});
if (options.encounterSnapshots?.length) {
importDungeonEncounterSnapshots(dungeonId, options.encounterSnapshots, { authoritative: true });
@@ -124,6 +130,7 @@ export function restartActiveDungeonSession(): boolean {
gmTestMode: game.gmTestMode,
gmReviewTarget: game.activeGmReviewTarget,
preserveCharacter: true,
bossDifficulty: game.activeBossDifficulty,
encounterSnapshots,
});
}
+11 -1
View File
@@ -50,9 +50,18 @@ describe("dungeon session asset eviction", () => {
expect(clear).not.toHaveBeenCalled();
});
it("rejects invalid difficulty settings before changing the dungeon or evicting assets", () => {
const active = useGameStore.getState().activeDungeonId;
const clear = vi.spyOn(useGLTF, "clear").mockImplementation(() => undefined);
expect(activateDungeonSession("wailing-caverns", "missing")).toBe(false);
expect(activateDungeonSession("wailing-caverns", undefined, { bossDifficulty: 11 })).toBe(false);
expect(useGameStore.getState().activeDungeonId).toBe(active);
expect(clear).not.toHaveBeenCalled();
});
it("restarts the active dungeon in place while preserving its party and encounter state", () => {
const active = dungeonDefinitionById("wailing-caverns")!;
expect(activateDungeonSession(active.id)).toBe(true);
expect(activateDungeonSession(active.id, undefined, { bossDifficulty: 6 })).toBe(true);
usePartyStore.getState().initializeParty("retry-party", 20, 600, "healer");
const members = usePartyStore.getState().members.map((member) => member.id);
const current = dungeonEncounterSnapshot(WAILING_NARALEX_ENCOUNTER.id)!;
@@ -64,6 +73,7 @@ describe("dungeon session asset eviction", () => {
const clear = vi.spyOn(useGLTF, "clear").mockImplementation(() => undefined);
expect(restartActiveDungeonSession()).toBe(true);
expect(useGameStore.getState().activeBossDifficulty).toBe(6);
expect(clear.mock.calls.map(([url]) => url)).toEqual(dungeonGltfUrls(active));
expect(useGameStore.getState().sessionRevision).toBe(revision + 1);
@@ -1 +1 @@
{"schemaVersion":1,"classId":"barbarian","abilities":[{"id":"coa-tree-30762","classId":"barbarian","dbcSpellId":500918,"name":"Ancestral Roar","unlockLevel":1,"icon":"/assets/ui/spells/_d3threateningshout.png","sigil":"AR","description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":500918,"level":1,"description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}]}],"talentEntryId":30762},{"id":"coa-12-ancestral-spirit-47-705153","classId":"barbarian","dbcSpellId":705153,"name":"Ancestral Spirit","unlockLevel":1,"icon":"/assets/ui/spells/inv_misc_questionmark.png","sigil":"AS","description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705153,"level":1,"description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]},{"rank":2,"spellId":705154,"level":1,"description":"Ancestral SpiritRank 2Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 100%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705154:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705154:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]}]},{"id":"coa-tree-34279","classId":"barbarian","dbcSpellId":560456,"name":"Athleticism","unlockLevel":1,"icon":"/assets/ui/spells/5_run_border.png","sigil":"AT","descriptiLine truncated
{"schemaVersion":1,"classId":"barbarian","abilities":[{"id":"coa-tree-30762","classId":"barbarian","dbcSpellId":500918,"name":"Ancestral Roar","unlockLevel":1,"icon":"/assets/ui/spells/_d3threateningshout.png","sigil":"AR","description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":500918,"level":1,"description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}]}],"talentEntryId":30762},{"id":"coa-12-ancestral-spirit-47-705153","classId":"barbarian","dbcSpellId":705153,"name":"Ancestral Spirit","unlockLevel":1,"icon":"/assets/ui/spells/inv_misc_questionmark.png","sigil":"AS","description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705153,"level":1,"description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]},{"rank":2,"spellId":705154,"level":1,"description":"Ancestral SpiritRank 2Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 100%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705154:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705154:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]}]},{"id":"coa-tree-34279","classId":"barbarian","dbcSpellId":560456,"name":"Athleticism","unlockLevel":1,"icon":"/assets/ui/spells/5_run_border.png","sigil":"AT","descriptiLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"bloodmage","abilities":[{"id":"coa-tree-29871","classId":"bloodmage","dbcSpellId":504285,"name":"Alacrity","unlockLevel":1,"icon":"/assets/ui/spells/5_run_border.png","sigil":"AL","description":"Increases all primary stats by 4%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504285:effect:0:aura:137","name":"Alacrity (Aura 137)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"all-primary","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":137,"miscValue":-1,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":504285,"level":1,"description":"Increases all primary stats by 4%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504285:effect:0:aura:137","name":"Alacrity (Aura 137)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"all-primary","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":137,"miscValue":-1,"triggerSpellId":0}]},{"rank":2,"spellId":504893,"level":1,"description":"Increases all primary stats by 8%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504893:effect:0:aura:137","name":"Alacrity (Aura 137)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"all-primary","operation":"percent","value":0.08}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":137,"miscValue":-1,"triggerSpellId":0}]}],"talentEntryId":29871},{"id":"coa-20-atheranns-wickedness-73-704642","classId":"bloodmage","dbcSpellId":704642,"name":"Atherann's Wickedness","unlockLevel":1,"icon":"/assets/ui/spells/spell_shadow_destructivesoul.png","sigil":"AS","description":"Atherann's WickednessRank 1Increases your Shadow damage dealt by 4% and increases your hit chance by 3%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704642:effect:0:aura:79","name":"Atherann's Wickedness (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","school":"shadow","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":32,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:704642:effect:1:aura:333","name":"Atherann's Wickedness (Aura 333)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":333,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":704642,"level":1,"description":"Atherann's WickednessRank 1Increases your Shadow damage dealt by 4% and increases your hit chance by 3%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704642:effect:0:aura:79","name":"Atherann's Wickedness (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","school":"shadow","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":32,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:704642:effect:1:aura:333","name":"Atherann's Wickedness (Aura 333)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":333,"miscValue":0,"triggerSpellId":0}]},{"rank":2,"spellId":704643,"level":1,"description":"Atherann's WickednessRank 2Increases the damage of Atherann's Anguish by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704643:effect:0:aura:108","name":"Atherann's Wickedness (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}]}]},{"id":"coa-tree-8215","classId":"bloodmage","dbcSpellId":504627,"name":"Blood Bond","unlockLevel":1,"icon":"/assets/ui/spells/nhi_bloodsacrifice_border.png","sigil":"BB","description":"Bond yourself to an ally for 30 minutes, causing direct damage taken by tLine truncated
{"schemaVersion":1,"classId":"bloodmage","abilities":[{"id":"coa-tree-29871","classId":"bloodmage","dbcSpellId":504285,"name":"Alacrity","unlockLevel":1,"icon":"/assets/ui/spells/5_run_border.png","sigil":"AL","description":"Increases all primary stats by 4%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504285:effect:0:aura:137","name":"Alacrity (Aura 137)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"all-primary","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":137,"miscValue":-1,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":504285,"level":1,"description":"Increases all primary stats by 4%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504285:effect:0:aura:137","name":"Alacrity (Aura 137)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"all-primary","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":137,"miscValue":-1,"triggerSpellId":0}]},{"rank":2,"spellId":504893,"level":1,"description":"Increases all primary stats by 8%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504893:effect:0:aura:137","name":"Alacrity (Aura 137)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"all-primary","operation":"percent","value":0.08}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":137,"miscValue":-1,"triggerSpellId":0}]}],"talentEntryId":29871},{"id":"coa-20-atheranns-wickedness-73-704642","classId":"bloodmage","dbcSpellId":704642,"name":"Atherann's Wickedness","unlockLevel":1,"icon":"/assets/ui/spells/spell_shadow_destructivesoul.png","sigil":"AS","description":"Atherann's WickednessRank 1Increases your Shadow damage dealt by 4% and increases your hit chance by 3%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704642:effect:0:aura:79","name":"Atherann's Wickedness (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","school":"shadow","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":32,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:704642:effect:1:aura:333","name":"Atherann's Wickedness (Aura 333)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":333,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":704642,"level":1,"description":"Atherann's WickednessRank 1Increases your Shadow damage dealt by 4% and increases your hit chance by 3%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704642:effect:0:aura:79","name":"Atherann's Wickedness (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","school":"shadow","operation":"percent","value":0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":32,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:704642:effect:1:aura:333","name":"Atherann's Wickedness (Aura 333)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":333,"miscValue":0,"triggerSpellId":0}]},{"rank":2,"spellId":704643,"level":1,"description":"Atherann's WickednessRank 2Increases the damage of Atherann's Anguish by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704643:effect:0:aura:108","name":"Atherann's Wickedness (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}]}]},{"id":"coa-tree-8215","classId":"bloodmage","dbcSpellId":504627,"name":"Blood Bond","unlockLevel":1,"icon":"/assets/ui/spells/nhi_bloodsacrifice_border.png","sigil":"BB","description":"Bond yourself to an ally for 30 minutes, causing direct damage taken by tLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"chronomancer","abilities":[{"id":"coa-tree-30277","classId":"chronomancer","dbcSpellId":800857,"name":"Accelerated Recovery","unlockLevel":1,"icon":"/assets/ui/spells/spell_holy_healingfocus.png","sigil":"AR","description":"Accelerated RecoveryRank 118% of base mana Instant castAccelerates the bodies natural healing process, healing the target for (15*1000/3)*(12+0+Heal*0.23) over 15 sec. Periodic healing done by this scales with your spell haste.","target":"friendly","range":{"min":0,"max":40},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":18,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:800857:effect:0:aura:8","name":"Accelerated Recovery (Aura 8)","disposition":"buff","hideFromAuraStrip":true,"durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":6,"sourceAuraType":8,"miscValue":0,"triggerSpellId":0},{"kind":"hot","coefficient":0.24070173263549804,"basePoints":12,"dieSides":1,"pointsPerLevel":0.6052629947662354,"bonusPowerCoefficient":0,"sourceLevel":10,"maxScalingLevel":16,"ticks":5,"intervalMs":3000},{"kind":"apply-aura","aura":{"id":"coa:800857:effect:1:aura:283","name":"Accelerated Recovery (Aura 283)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":3,"sourceAuraType":283,"miscValue":0,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":800857,"level":1,"description":"Accelerated RecoveryRank 118% of base mana Instant castAccelerates the bodies natural healing process, healing the target for (15*1000/3)*(12+0+Heal*0.23) over 15 sec. Periodic healing done by this scales with your spell haste.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":18,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:800857:effect:0:aura:8","name":"Accelerated Recovery (Aura 8)","disposition":"buff","hideFromAuraStrip":true,"durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":6,"sourceAuraType":8,"miscValue":0,"triggerSpellId":0},{"kind":"hot","coefficient":0.24070173263549804,"basePoints":12,"dieSides":1,"pointsPerLevel":0.6052629947662354,"bonusPowerCoefficient":0,"sourceLevel":10,"maxScalingLevel":16,"ticks":5,"intervalMs":3000},{"kind":"apply-aura","aura":{"id":"coa:800857:effect:1:aura:283","name":"Accelerated Recovery (Aura 283)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":3,"sourceAuraType":283,"miscValue":0,"triggerSpellId":0}]}],"talentEntryId":30277},{"id":"coa-tree-4032","classId":"chronomancer","dbcSpellId":92119,"name":"Aeon of Resilience","unlockLevel":1,"icon":"/assets/ui/spells/inv_trinket_80_kultiras02a.png","sigil":"AO","description":"Level 10 Passive Teaches you Aeon of Resilience.Aeon of ResilienceReduces Epoch's cast time by -25% and it's mana cost by -10%, and healing done by it now reduces the target's damage taken by -5% for 6 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:92119:effect:0:aura:4","name":"Aeon of Resilience (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":92119,"level":1,"description":"Level 10 Passive Teaches you Aeon of Resilience.Aeon of ResilienceReduces Epoch's cast time by -25% and it's mana cost by -10%, and healing done by it now reduces the target's damage taken by -5% for 6 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:92119:effect:0:aura:4","name":"Aeon of Resilience (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0}]}],"talentEntryId":4032},{"id":"coa-tree-6214","classId":"chronomancer","dbcSpellId":560948,"name":"Ahead of the Game","unlockLevel":1,"icon":"/assets/ui/spells/achievement_bg_win_av_x_times.png","sigil":"AO","description":"Every 10th instance of your damage dealt or healing now gives you 60 increased spell power for 10 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:560948:effect:0:aura:42","name":"AheadLine truncated
{"schemaVersion":1,"classId":"chronomancer","abilities":[{"id":"coa-tree-30277","classId":"chronomancer","dbcSpellId":800857,"name":"Accelerated Recovery","unlockLevel":1,"icon":"/assets/ui/spells/spell_holy_healingfocus.png","sigil":"AR","description":"Accelerated RecoveryRank 118% of base mana Instant castAccelerates the bodies natural healing process, healing the target for (15*1000/3)*(12+0+Heal*0.23) over 15 sec. Periodic healing done by this scales with your spell haste.","target":"friendly","range":{"min":0,"max":40},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":18,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:800857:effect:0:aura:8","name":"Accelerated Recovery (Aura 8)","disposition":"buff","hideFromAuraStrip":true,"durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":6,"sourceAuraType":8,"miscValue":0,"triggerSpellId":0},{"kind":"hot","coefficient":0.24070173263549804,"basePoints":12,"dieSides":1,"pointsPerLevel":0.6052629947662354,"bonusPowerCoefficient":0,"sourceLevel":10,"maxScalingLevel":16,"ticks":5,"intervalMs":3000},{"kind":"apply-aura","aura":{"id":"coa:800857:effect:1:aura:283","name":"Accelerated Recovery (Aura 283)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":3,"sourceAuraType":283,"miscValue":0,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":800857,"level":1,"description":"Accelerated RecoveryRank 118% of base mana Instant castAccelerates the bodies natural healing process, healing the target for (15*1000/3)*(12+0+Heal*0.23) over 15 sec. Periodic healing done by this scales with your spell haste.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":18,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:800857:effect:0:aura:8","name":"Accelerated Recovery (Aura 8)","disposition":"buff","hideFromAuraStrip":true,"durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":6,"sourceAuraType":8,"miscValue":0,"triggerSpellId":0},{"kind":"hot","coefficient":0.24070173263549804,"basePoints":12,"dieSides":1,"pointsPerLevel":0.6052629947662354,"bonusPowerCoefficient":0,"sourceLevel":10,"maxScalingLevel":16,"ticks":5,"intervalMs":3000},{"kind":"apply-aura","aura":{"id":"coa:800857:effect:1:aura:283","name":"Accelerated Recovery (Aura 283)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"sourceEffectType":3,"sourceAuraType":283,"miscValue":0,"triggerSpellId":0}]}],"talentEntryId":30277},{"id":"coa-tree-4032","classId":"chronomancer","dbcSpellId":92119,"name":"Aeon of Resilience","unlockLevel":1,"icon":"/assets/ui/spells/inv_trinket_80_kultiras02a.png","sigil":"AO","description":"Level 10 Passive Teaches you Aeon of Resilience.Aeon of ResilienceReduces Epoch's cast time by -25% and it's mana cost by -10%, and healing done by it now reduces the target's damage taken by -5% for 6 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:92119:effect:0:aura:4","name":"Aeon of Resilience (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":92119,"level":1,"description":"Level 10 Passive Teaches you Aeon of Resilience.Aeon of ResilienceReduces Epoch's cast time by -25% and it's mana cost by -10%, and healing done by it now reduces the target's damage taken by -5% for 6 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:92119:effect:0:aura:4","name":"Aeon of Resilience (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0}]}],"talentEntryId":4032},{"id":"coa-tree-6214","classId":"chronomancer","dbcSpellId":560948,"name":"Ahead of the Game","unlockLevel":1,"icon":"/assets/ui/spells/achievement_bg_win_av_x_times.png","sigil":"AO","description":"Every 10th instance of your damage dealt or healing now gives you 60 increased spell power for 10 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:560948:effect:0:aura:42","name":"AheadLine truncated
+1 -1
View File
@@ -1 +1 @@
{"schemaVersion":1,"classId":"cultist","abilities":[{"id":"coa-25-abyssal-decay-89-500705","classId":"cultist","dbcSpellId":500705,"name":"Abyssal Decay","unlockLevel":1,"icon":"/assets/ui/spells/spell_priest_void_blast.png","sigil":"AD","description":"Abyssal DecayRank 19% of base mana Instant castApplies an Eldritch curse to an enemy, causing 9+(PL*0.6) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","target":"hostile","range":{"min":0,"max":30},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:500705:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.24166666716337204,"basePoints":9,"dieSides":5,"pointsPerLevel":0.6000000238418579,"bonusPowerCoefficient":0,"sourceLevel":1,"maxScalingLevel":9,"ticks":6,"intervalMs":3000,"tag":"spell-500705"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}],"passive":false,"source":"coa-progression","ranks":[{"rank":1,"spellId":500705,"level":1,"description":"Abyssal DecayRank 19% of base mana Instant castApplies an Eldritch curse to an enemy, causing 9+(PL*0.6) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:500705:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.24166666716337204,"basePoints":9,"dieSides":5,"pointsPerLevel":0.6000000238418579,"bonusPowerCoefficient":0,"sourceLevel":1,"maxScalingLevel":9,"ticks":6,"intervalMs":3000,"tag":"spell-500705"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}]},{"rank":2,"spellId":502144,"level":10,"description":"Abyssal DecayRank 29% of base mana Instant castApplies an Eldritch curse to an enemy, causing 17+(PL*1-10*1) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:502144:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.36066666603088376,"basePoints":17,"dieSides":1,"pointsPerLevel":1.0049999952316284,"bonusPowerCoefficient":0,"sourceLevel":10,"maxScalingLevel":18,"ticks":6,"intervalMs":3000,"tag":"spell-502144"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}]},{"rank":3,"spellId":502145,"level":19,"description":"Abyssal DecayRank 39% of base mana Instant castApplies an Eldritch curse to an enemy, causing 31+(PL*1.4-19*1.4) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:502145:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.5590245174426659,"basePoints":31,"dieSides":1,"pointsPerLevel":1.3695000410079956,"bonusPowerCoefficient":0,"sourceLevel":19,"maxScalingLevel":27,"ticks":6,"intervalMs":3000,"tag":"spell-502145"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}]},{"rank":4,"spellId":502146,"level":28,"description":"Abyssal DecayRank 49% of base mana Instant castApplies an Eldritch curse to an enemy, causing 55+(PL*1.7-28*1.7) Shadow damage every 3 sec for18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:502146:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellIdLine truncated
{"schemaVersion":1,"classId":"cultist","abilities":[{"id":"coa-25-abyssal-decay-89-500705","classId":"cultist","dbcSpellId":500705,"name":"Abyssal Decay","unlockLevel":1,"icon":"/assets/ui/spells/spell_priest_void_blast.png","sigil":"AD","description":"Abyssal DecayRank 19% of base mana Instant castApplies an Eldritch curse to an enemy, causing 9+(PL*0.6) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","target":"hostile","range":{"min":0,"max":30},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:500705:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.24166666716337204,"basePoints":9,"dieSides":5,"pointsPerLevel":0.6000000238418579,"bonusPowerCoefficient":0,"sourceLevel":1,"maxScalingLevel":9,"ticks":6,"intervalMs":3000,"tag":"spell-500705"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}],"passive":false,"source":"coa-progression","ranks":[{"rank":1,"spellId":500705,"level":1,"description":"Abyssal DecayRank 19% of base mana Instant castApplies an Eldritch curse to an enemy, causing 9+(PL*0.6) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:500705:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.24166666716337204,"basePoints":9,"dieSides":5,"pointsPerLevel":0.6000000238418579,"bonusPowerCoefficient":0,"sourceLevel":1,"maxScalingLevel":9,"ticks":6,"intervalMs":3000,"tag":"spell-500705"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}]},{"rank":2,"spellId":502144,"level":10,"description":"Abyssal DecayRank 29% of base mana Instant castApplies an Eldritch curse to an enemy, causing 17+(PL*1-10*1) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:502144:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.36066666603088376,"basePoints":17,"dieSides":1,"pointsPerLevel":1.0049999952316284,"bonusPowerCoefficient":0,"sourceLevel":10,"maxScalingLevel":18,"ticks":6,"intervalMs":3000,"tag":"spell-502144"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}]},{"rank":3,"spellId":502145,"level":19,"description":"Abyssal DecayRank 39% of base mana Instant castApplies an Eldritch curse to an enemy, causing 31+(PL*1.4-19*1.4) Shadow damage every 3 sec for 18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:502145:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellId":0},{"kind":"dot","coefficient":0.5590245174426659,"basePoints":31,"dieSides":1,"pointsPerLevel":1.3695000410079956,"bonusPowerCoefficient":0,"sourceLevel":19,"maxScalingLevel":27,"ticks":6,"intervalMs":3000,"tag":"spell-502145"},{"kind":"utility","action":"class-script","effectType":168,"auraType":0,"miscValue":120640,"triggerSpellId":0,"durationMs":18000}]},{"rank":4,"spellId":502146,"level":28,"description":"Abyssal DecayRank 49% of base mana Instant castApplies an Eldritch curse to an enemy, causing 55+(PL*1.7-28*1.7) Shadow damage every 3 sec for18 sec. Generates 5 Insanity.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":9,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:502146:effect:0:aura:3","name":"Abyssal Decay (Aura 3)","disposition":"debuff","hideFromAuraStrip":true,"durationMs":18000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse"},"sourceEffectType":6,"sourceAuraType":3,"miscValue":0,"triggerSpellIdLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"felsworn","abilities":[{"id":"coa-tree-29686","classId":"felsworn","dbcSpellId":803904,"name":"Annihilation","unlockLevel":1,"icon":"/assets/ui/spells/ability_boss_lordanthricystgreen.png","sigil":"AN","description":"Gorge on fel energy, guaranteeing your next direct instance of damage to critically strike, but causing it to consume 5% of your maximum health. Lasts for 5 attacks or 12 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:803904:effect:0:aura:290","name":"Annihilation (Aura 290)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:803904:effect:1:aura:42","name":"Annihilation (Aura 42)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:803904:proc:1:807961","triggers":["crit","hit"],"chance":1,"charges":5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":807961}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":807961}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":803904,"level":1,"description":"Gorge on fel energy, guaranteeing your next direct instance of damage to critically strike, but causing it to consume 5% of your maximum health. Lasts for 5 attacks or 12 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:803904:effect:0:aura:290","name":"Annihilation (Aura 290)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:803904:effect:1:aura:42","name":"Annihilation (Aura 42)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:803904:proc:1:807961","triggers":["crit","hit"],"chance":1,"charges":5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":807961}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":807961}]}],"talentEntryId":29686},{"id":"coa-tree-30301","classId":"felsworn","dbcSpellId":560822,"name":"Anti-Magic","unlockLevel":1,"icon":"/assets/ui/spells/spell_shadow_antimagicshell.png","sigil":"AM","description":"When Hateforged Barrier is removed from you, you now reduce -10% of all Magic damage taken for 8 seconds. In addition, Hateforged Barrier now heals for an additional 2% of your maximum health each tick.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:0:aura:4","name":"Anti-Magic (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:1:aura:107","name":"Anti-Magic (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.02}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":560822,"level":1,"description":"When Hateforged Barrier is removed from you, you now reduce -10% of all Magic damage taken for 8 seconds. In addition, Hateforged Barrier now heals for an additional 2% of your maximum health each tick.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:0:aura:4","name":"Anti-Magic (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:1:aura:107","name":"Anti-Magic (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.02}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}]}],"talentEntryId":30301},{"id":"coa-tree-33671","classId":"felsworn","dbcSpellId":706266,"namLine truncated
{"schemaVersion":1,"classId":"felsworn","abilities":[{"id":"coa-tree-29686","classId":"felsworn","dbcSpellId":803904,"name":"Annihilation","unlockLevel":1,"icon":"/assets/ui/spells/ability_boss_lordanthricystgreen.png","sigil":"AN","description":"Gorge on fel energy, guaranteeing your next direct instance of damage to critically strike, but causing it to consume 5% of your maximum health. Lasts for 5 attacks or 12 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:803904:effect:0:aura:290","name":"Annihilation (Aura 290)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:803904:effect:1:aura:42","name":"Annihilation (Aura 42)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:803904:proc:1:807961","triggers":["crit","hit"],"chance":1,"charges":5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":807961}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":807961}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":803904,"level":1,"description":"Gorge on fel energy, guaranteeing your next direct instance of damage to critically strike, but causing it to consume 5% of your maximum health. Lasts for 5 attacks or 12 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:803904:effect:0:aura:290","name":"Annihilation (Aura 290)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:803904:effect:1:aura:42","name":"Annihilation (Aura 42)","disposition":"buff","durationMs":12000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:803904:proc:1:807961","triggers":["crit","hit"],"chance":1,"charges":5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":807961}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":807961}]}],"talentEntryId":29686},{"id":"coa-tree-30301","classId":"felsworn","dbcSpellId":560822,"name":"Anti-Magic","unlockLevel":1,"icon":"/assets/ui/spells/spell_shadow_antimagicshell.png","sigil":"AM","description":"When Hateforged Barrier is removed from you, you now reduce -10% of all Magic damage taken for 8 seconds. In addition, Hateforged Barrier now heals for an additional 2% of your maximum health each tick.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:0:aura:4","name":"Anti-Magic (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:1:aura:107","name":"Anti-Magic (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.02}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":560822,"level":1,"description":"When Hateforged Barrier is removed from you, you now reduce -10% of all Magic damage taken for 8 seconds. In addition, Hateforged Barrier now heals for an additional 2% of your maximum health each tick.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:0:aura:4","name":"Anti-Magic (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560822:effect:1:aura:107","name":"Anti-Magic (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.02}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}]}],"talentEntryId":30301},{"id":"coa-tree-33671","classId":"felsworn","dbcSpellId":706266,"namLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"guardian","abilities":[{"id":"coa-18-banner-boy-68-705358","classId":"guardian","dbcSpellId":705358,"name":"Banner Boy","unlockLevel":1,"icon":"/assets/ui/spells/achievement_bg_captureflag_wsg.png","sigil":"BB","description":"Banner BoyRank 1Reduces the Energy cost of Banners by 10.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705358:effect:0:aura:107","name":"Banner Boy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:1:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:2:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":3,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705358,"level":1,"description":"Banner BoyRank 1Reduces the Energy cost of Banners by 10.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705358:effect:0:aura:107","name":"Banner Boy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:1:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:2:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":3,"triggerSpellId":0}]}]},{"id":"coa-tree-11797","classId":"guardian","dbcSpellId":803683,"name":"Battle Drums","unlockLevel":1,"icon":"/assets/ui/spells/inv_archaeology_70_tauren_drum.png","sigil":"BD","description":"Place down 3 Battle Drums around you for 1 minute. Allies may click on the drums to increase their critical strike chance, haste, damage, and healing done by 10% and causes their damage dealt to trigger a Sound of War for their next 5 instances of damage or 30 seconds.","target":"hostile","range":{"min":0,"max":0},"radius":3,"castMode":"instant","castTimeMs":0,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"energy","amount":50},"effects":[{"kind":"damage","coefficient":1},{"kind":"heal","coefficient":1},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":803683,"level":1,"description":"Place down 3 Battle Drums around you for 1 minute. Allies may click on the drums to increase their critical strike chance, haste, damage, and healing done by 10% and causes their damage dealt to trigger a Sound of War for their next 5 instances of damage or 30 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"energy","amount":50},"effects":[{"kind":"damage","coefficient":1},{"kind":"heal","coefficient":1},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000}]}],"talentEntryId":11797},{"id":"guardian-battle-rush","classId":"guardian","dbcSpellId":802197,"name":"Battle Rush","unlockLevel":1,"icon":"/assets/ui/spells/warrior_talent_icon_skirmisher.png","sigil":"BR","description":"Battle RushRank 1Instant cast30 sec cooldownCharge an enemy, dealing 16+0+AP*0.09996 Physical damage and stunnLine truncated
{"schemaVersion":1,"classId":"guardian","abilities":[{"id":"coa-18-banner-boy-68-705358","classId":"guardian","dbcSpellId":705358,"name":"Banner Boy","unlockLevel":1,"icon":"/assets/ui/spells/achievement_bg_captureflag_wsg.png","sigil":"BB","description":"Banner BoyRank 1Reduces the Energy cost of Banners by 10.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705358:effect:0:aura:107","name":"Banner Boy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:1:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:2:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":3,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705358,"level":1,"description":"Banner BoyRank 1Reduces the Energy cost of Banners by 10.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705358:effect:0:aura:107","name":"Banner Boy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:1:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705358:effect:2:aura:4","name":"Banner Boy (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":3,"triggerSpellId":0}]}]},{"id":"coa-tree-11797","classId":"guardian","dbcSpellId":803683,"name":"Battle Drums","unlockLevel":1,"icon":"/assets/ui/spells/inv_archaeology_70_tauren_drum.png","sigil":"BD","description":"Place down 3 Battle Drums around you for 1 minute. Allies may click on the drums to increase their critical strike chance, haste, damage, and healing done by 10% and causes their damage dealt to trigger a Sound of War for their next 5 instances of damage or 30 seconds.","target":"hostile","range":{"min":0,"max":0},"radius":3,"castMode":"instant","castTimeMs":0,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"energy","amount":50},"effects":[{"kind":"damage","coefficient":1},{"kind":"heal","coefficient":1},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":803683,"level":1,"description":"Place down 3 Battle Drums around you for 1 minute. Allies may click on the drums to increase their critical strike chance, haste, damage, and healing done by 10% and causes their damage dealt to trigger a Sound of War for their next 5 instances of damage or 30 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"energy","amount":50},"effects":[{"kind":"damage","coefficient":1},{"kind":"heal","coefficient":1},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000},{"kind":"utility","action":"portal","effectType":50,"auraType":0,"miscValue":9000117,"triggerSpellId":0,"durationMs":60000}]}],"talentEntryId":11797},{"id":"guardian-battle-rush","classId":"guardian","dbcSpellId":802197,"name":"Battle Rush","unlockLevel":1,"icon":"/assets/ui/spells/warrior_talent_icon_skirmisher.png","sigil":"BR","description":"Battle RushRank 1Instant cast30 sec cooldownCharge an enemy, dealing 16+0+AP*0.09996 Physical damage and stunnLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"knight-of-xoroth","abilities":[{"id":"coa-tree-30701","classId":"knight-of-xoroth","dbcSpellId":805679,"name":"Black Shield","unlockLevel":1,"icon":"/assets/ui/spells/spell_warlock_soulburn_haunt.png","sigil":"BS","description":"Consume all of your Demon's Blood stacks to create a demonic shield that absorbs 860 damage, increased by 20% per Demon's Blood stack, for 30 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"shield","coefficient":1,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":0,"triggerSpellId":0,"durationMs":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":805679,"level":1,"description":"Consume all of your Demon's Blood stacks to create a demonic shield that absorbs 860 damage, increased by 20% per Demon's Blood stack, for 30 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"shield","coefficient":1,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":0,"triggerSpellId":0,"durationMs":0}]}],"talentEntryId":30701},{"id":"coa-tree-34064","classId":"knight-of-xoroth","dbcSpellId":300395,"name":"Boiling Blood","unlockLevel":1,"icon":"/assets/ui/spells/nhi_bloodboil_border.png","sigil":"BB","description":"Casting Suffuse now increases your healing received by 25% for the first 6 seconds of it's duration.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:300395:effect:0:aura:42","name":"Boiling Blood (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:300395:proc:0:300394","triggers":["cast","heal"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":300394}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":300394}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":300395,"level":1,"description":"Casting Suffuse now increases your healing received by 25% for the first 6 seconds of it's duration.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:300395:effect:0:aura:42","name":"Boiling Blood (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:300395:proc:0:300394","triggers":["cast","heal"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":300394}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":300394}]}],"talentEntryId":34064},{"id":"coa-tree-4018","classId":"knight-of-xoroth","dbcSpellId":92104,"name":"Brimstone Buckler","unlockLevel":1,"icon":"/assets/ui/spells/ability_warlock_improveddemonictactics.png","sigil":"BB","description":"Level 10 Passive Successful blocks now have a 30% chance to summon 1 Hellfire Imp to aid you in battle for 12 seconds. Can only occur once every 3 sec.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92104:effect:0:aura:23","name":"Brimstone Buckler (Aura 23)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92104:proc:0:562029","triggers":["periodic"],"chance":0.3,"internalCooldownMs":3000,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":562029}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":23,"miscValue":0,"triggerSpellId":562029},{"kind":"apply-aura","aura":{"id":"coa:92104:effect:1:aura:42","name":"Brimstone Buckler (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92104:proc:1:805966","triggers":["block"],"chance":0.3,"internalCooldownMs":3000,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":805966}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":805966}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":92104,"level":1,"description":"Level 10 Passive Successful blocks now have a 30% chance to summon 1 Hellfire Imp to aid you in battle for 12 seconds. Can only occur once every 3 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92104:effect:0:aura:23","name":"Brimstone Buckler (Aura 23)","disposition":"buff","durationMs":null,"maxSLine truncated
{"schemaVersion":1,"classId":"knight-of-xoroth","abilities":[{"id":"coa-tree-30701","classId":"knight-of-xoroth","dbcSpellId":805679,"name":"Black Shield","unlockLevel":1,"icon":"/assets/ui/spells/spell_warlock_soulburn_haunt.png","sigil":"BS","description":"Consume all of your Demon's Blood stacks to create a demonic shield that absorbs 860 damage, increased by 20% per Demon's Blood stack, for 30 seconds.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"shield","coefficient":1,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":0,"triggerSpellId":0,"durationMs":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":805679,"level":1,"description":"Consume all of your Demon's Blood stacks to create a demonic shield that absorbs 860 damage, increased by 20% per Demon's Blood stack, for 30 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"shield","coefficient":1,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":0,"triggerSpellId":0,"durationMs":0}]}],"talentEntryId":30701},{"id":"coa-tree-34064","classId":"knight-of-xoroth","dbcSpellId":300395,"name":"Boiling Blood","unlockLevel":1,"icon":"/assets/ui/spells/nhi_bloodboil_border.png","sigil":"BB","description":"Casting Suffuse now increases your healing received by 25% for the first 6 seconds of it's duration.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:300395:effect:0:aura:42","name":"Boiling Blood (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:300395:proc:0:300394","triggers":["cast","heal"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":300394}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":300394}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":300395,"level":1,"description":"Casting Suffuse now increases your healing received by 25% for the first 6 seconds of it's duration.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:300395:effect:0:aura:42","name":"Boiling Blood (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:300395:proc:0:300394","triggers":["cast","heal"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":300394}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":300394}]}],"talentEntryId":34064},{"id":"coa-tree-4018","classId":"knight-of-xoroth","dbcSpellId":92104,"name":"Brimstone Buckler","unlockLevel":1,"icon":"/assets/ui/spells/ability_warlock_improveddemonictactics.png","sigil":"BB","description":"Level 10 Passive Successful blocks now have a 30% chance to summon 1 Hellfire Imp to aid you in battle for 12 seconds. Can only occur once every 3 sec.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92104:effect:0:aura:23","name":"Brimstone Buckler (Aura 23)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92104:proc:0:562029","triggers":["periodic"],"chance":0.3,"internalCooldownMs":3000,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":562029}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":23,"miscValue":0,"triggerSpellId":562029},{"kind":"apply-aura","aura":{"id":"coa:92104:effect:1:aura:42","name":"Brimstone Buckler (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92104:proc:1:805966","triggers":["block"],"chance":0.3,"internalCooldownMs":3000,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":805966}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":805966}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":92104,"level":1,"description":"Level 10 Passive Successful blocks now have a 30% chance to summon 1 Hellfire Imp to aid you in battle for 12 seconds. Can only occur once every 3 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92104:effect:0:aura:23","name":"Brimstone Buckler (Aura 23)","disposition":"buff","durationMs":null,"maxSLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"necromancer","abilities":[{"id":"coa-tree-30600","classId":"necromancer","dbcSpellId":805428,"name":"Animate: Frost Wyrm","unlockLevel":1,"icon":"/assets/ui/spells/5_dragoncoldbreath_border.png","sigil":"AF","description":"Animate a Frost Wyrm that flies behind the Necromancer that blasts nearby enemies every 2 sec for 30 seconds, dealing 1500 + 14.88% frost SP + 14.88% Intellect Frost damage.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"mana","amount":31,"percentage":true},"effects":[{"kind":"summon","creatureId":50177,"coefficient":0.08,"durationMs":30000}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":805428,"level":1,"description":"Animate a Frost Wyrm that flies behind the Necromancer that blasts nearby enemies every 2 sec for 30 seconds, dealing 1500 + 14.88% frost SP + 14.88% Intellect Frost damage.","castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"mana","amount":31,"percentage":true},"effects":[{"kind":"summon","creatureId":50177,"coefficient":0.08,"durationMs":30000}]}],"talentEntryId":30600},{"id":"coa-23-animate-zombies-84-504315","classId":"necromancer","dbcSpellId":504315,"name":"Animate: Zombies","unlockLevel":1,"icon":"/assets/ui/spells/zombiewc3.png","sigil":"AZ","description":"Animate: ZombiesRank 121% of base mana 3 sec cast15 sec cooldownAnimate 2 Zombies to aid you in combat for 15 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","target":"hostile","range":{"min":0,"max":0},"radius":3,"castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":21,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"withValue":2},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}],"passive":false,"source":"coa-progression","ranks":[{"rank":1,"spellId":504315,"level":1,"description":"Animate: ZombiesRank 121% of base mana 3 sec cast15 sec cooldownAnimate 2 Zombies to aid you in combat for 15 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":21,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"withValue":2},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}]},{"rank":2,"spellId":525378,"level":30,"description":"Animate: ZombiesRank 223% of base mana 3 sec cast15 sec cooldownAnimate 3 Zombies to aid you in combat for 15 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":23,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"withValue":3},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}]},{"rank":3,"spellId":525381,"level":51,"description":"Animate: ZombiesRank 324% of base mana 3 sec cast15 sec cooldownAnimate 4 Zombies to aid you in combat for 10 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":24,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"withValue":4},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}]}]},{"id":"coa-tree-29774","classId":"necromancer","dbcSpellId":802121,"name":"Bone Tithe","unlockLevel":1,"icon":"/assets/ui/spells/ossuary_bond.png","sigil":"BT","description":"Siphon life from your undead minions, sacrificing 40% of their health to grant yourself an absorb shield equal to half of the health stolen for 20 seconds. Usable while stunned.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"mana","amount":25,"percentage":true},"effects":[{"kind":"shield","coefficient":1,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":77,"auraType":0,"miscValue":0,"triggerSpellId"Line truncated
{"schemaVersion":1,"classId":"necromancer","abilities":[{"id":"coa-tree-30600","classId":"necromancer","dbcSpellId":805428,"name":"Animate: Frost Wyrm","unlockLevel":1,"icon":"/assets/ui/spells/5_dragoncoldbreath_border.png","sigil":"AF","description":"Animate a Frost Wyrm that flies behind the Necromancer that blasts nearby enemies every 2 sec for 30 seconds, dealing 1500 + 14.88% frost SP + 14.88% Intellect Frost damage.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"mana","amount":31,"percentage":true},"effects":[{"kind":"summon","creatureId":50177,"coefficient":0.08,"durationMs":30000}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":805428,"level":1,"description":"Animate a Frost Wyrm that flies behind the Necromancer that blasts nearby enemies every 2 sec for 30 seconds, dealing 1500 + 14.88% frost SP + 14.88% Intellect Frost damage.","castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"mana","amount":31,"percentage":true},"effects":[{"kind":"summon","creatureId":50177,"coefficient":0.08,"durationMs":30000}]}],"talentEntryId":30600},{"id":"coa-23-animate-zombies-84-504315","classId":"necromancer","dbcSpellId":504315,"name":"Animate: Zombies","unlockLevel":1,"icon":"/assets/ui/spells/zombiewc3.png","sigil":"AZ","description":"Animate: ZombiesRank 121% of base mana 3 sec cast15 sec cooldownAnimate 2 Zombies to aid you in combat for 15 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","target":"hostile","range":{"min":0,"max":0},"radius":3,"castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":21,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"expanded":true,"withValue":2},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}],"passive":false,"source":"coa-progression","ranks":[{"rank":1,"spellId":504315,"level":1,"description":"Animate: ZombiesRank 121% of base mana 3 sec cast15 sec cooldownAnimate 2 Zombies to aid you in combat for 15 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":21,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"expanded":true,"withValue":2},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}]},{"rank":2,"spellId":525378,"level":30,"description":"Animate: ZombiesRank 223% of base mana 3 sec cast15 sec cooldownAnimate 3 Zombies to aid you in combat for 15 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":23,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"expanded":true,"withValue":3},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}]},{"rank":3,"spellId":525381,"level":51,"description":"Animate: ZombiesRank 324% of base mana 3 sec cast15 sec cooldownAnimate 4 Zombies to aid you in combat for 10 sec. Every 3 sec, Zombies emit Zombie Plague, dealing 79+1.0 Points Per Level+SP*0.1 Plague Damage to nearby enemies.","castMode":"cast","castTimeMs":3000,"cooldownMs":15000,"gcdMs":1000,"cost":{"resource":"mana","amount":24,"percentage":true},"effects":[{"kind":"trigger-spell","spellId":525379,"expanded":true,"withValue":4},{"kind":"damage","coefficient":1},{"kind":"summon","creatureId":503031,"coefficient":0.08,"durationMs":15000},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":524287,"triggerSpellId":500991,"durationMs":100}]}]},{"id":"coa-tree-29774","classId":"necromancer","dbcSpellId":802121,"name":"Bone Tithe","unlockLevel":1,"icon":"/assets/ui/spells/ossuary_bond.png","sigil":"BT","description":"Siphon life from your undead minions, sacrificing 40% of their health to grant yourself an absorb shield equal to half of the health stolen for 20 seconds. Usable while stunned.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":120000,"gcdMs":1500,"cost":{"resource":"mana","amount":25,"percentage":true},"effects":[{"kind":"shield","coefficient":1,"durationMs":15000},{"kind":"utility","action":"class-scrLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"primalist","abilities":[{"id":"coa-tree-29362","classId":"primalist","dbcSpellId":800094,"name":"Bearskin","unlockLevel":1,"icon":"/assets/ui/spells/spell_druid_primaltenacity.png","sigil":"BE","description":"Reduces all damage taken by -60% and reduces the duration of root, stun, and incapacitate effects on you by -30% for 10 seconds.","target":"hostile","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":300000,"gcdMs":1500,"cost":{"resource":"mana","amount":24,"percentage":true},"effects":[{"kind":"status","status":"sleep","durationMs":10000},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:0:aura:87","name":"Bearskin (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.6}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:1:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":5,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:2:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":12,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":800094,"level":1,"description":"Reduces all damage taken by -60% and reduces the duration of root, stun, and incapacitate effects on you by -30% for 10 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":300000,"gcdMs":1500,"cost":{"resource":"mana","amount":24,"percentage":true},"effects":[{"kind":"status","status":"sleep","durationMs":10000},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:0:aura:87","name":"Bearskin (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.6}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:1:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":5,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:2:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":12,"triggerSpellId":0}]}],"talentEntryId":29362},{"id":"coa-tree-29252","classId":"primalist","dbcSpellId":500692,"name":"Boulder Dash","unlockLevel":1,"icon":"/assets/ui/spells/custom_elementl(earth)_b_01_border.png","sigil":"BD","description":"Raise a boulder out of the ground and encase yourself within it, preventing you from attacking or casting spells. For 10 seconds, you roll forward at 70% increased movement speed, dealing 1 + 50% AP + 100% SP Physical damage to enemies you roll over, and you are immune to crowd control effects.","target":"hostile","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":180000,"gcdMs":1250,"cost":{"resource":"mana","amount":35,"percentage":true},"effects":[{"kind":"damage","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:500692:effect:0:aura:23","name":"Boulder Dash (Aura 23)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:500692:proc:0:500693","triggers":["periodic"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":500693}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":23,"miscValue":0,"triggerSpellId":500693},{"kind":"apply-aura","aura":{"id":"coa:500692:effect:1:aura:31","name":"Boulder Dash (Aura 31)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"movement-speed","operation":"percent","value":0.7}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":31,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:500692:effect:2:aura:241","name":"Boulder Dash (Aura 241)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":241,"miscValue":0,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":500692,"level":1,"description":"Raise a boulder out of the ground aLine truncated
{"schemaVersion":1,"classId":"primalist","abilities":[{"id":"coa-tree-29362","classId":"primalist","dbcSpellId":800094,"name":"Bearskin","unlockLevel":1,"icon":"/assets/ui/spells/spell_druid_primaltenacity.png","sigil":"BE","description":"Reduces all damage taken by -60% and reduces the duration of root, stun, and incapacitate effects on you by -30% for 10 seconds.","target":"hostile","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":300000,"gcdMs":1500,"cost":{"resource":"mana","amount":24,"percentage":true},"effects":[{"kind":"status","status":"sleep","durationMs":10000},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:0:aura:87","name":"Bearskin (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.6}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:1:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":5,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:2:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":12,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":800094,"level":1,"description":"Reduces all damage taken by -60% and reduces the duration of root, stun, and incapacitate effects on you by -30% for 10 seconds.","castMode":"instant","castTimeMs":0,"cooldownMs":300000,"gcdMs":1500,"cost":{"resource":"mana","amount":24,"percentage":true},"effects":[{"kind":"status","status":"sleep","durationMs":10000},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:0:aura:87","name":"Bearskin (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.6}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:1:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":5,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:800094:effect:2:aura:232","name":"Bearskin (Aura 232)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":232,"miscValue":12,"triggerSpellId":0}]}],"talentEntryId":29362},{"id":"coa-tree-29252","classId":"primalist","dbcSpellId":500692,"name":"Boulder Dash","unlockLevel":1,"icon":"/assets/ui/spells/custom_elementl(earth)_b_01_border.png","sigil":"BD","description":"Raise a boulder out of the ground and encase yourself within it, preventing you from attacking or casting spells. For 10 seconds, you roll forward at 70% increased movement speed, dealing 1 + 50% AP + 100% SP Physical damage to enemies you roll over, and you are immune to crowd control effects.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":180000,"gcdMs":1250,"cost":{"resource":"mana","amount":35,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:500692:effect:0:aura:23","name":"Boulder Dash (Aura 23)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:500692:proc:0:500693","triggers":["periodic"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":500693}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":23,"miscValue":0,"triggerSpellId":500693},{"kind":"apply-aura","aura":{"id":"coa:500692:effect:1:aura:31","name":"Boulder Dash (Aura 31)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"movement-speed","operation":"percent","value":0.7}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":31,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:500692:effect:2:aura:241","name":"Boulder Dash (Aura 241)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":241,"miscValue":0,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":500692,"level":1,"description":"Raise a boulder out of the ground and encase yourself within it, preventLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"pyromancer","abilities":[{"id":"coa-tree-33843","classId":"pyromancer","dbcSpellId":300921,"name":"Al Dente","unlockLevel":1,"icon":"/assets/ui/spells/achievement_cooking_masteroftheoven.png","sigil":"AD","description":"Targets affected by Gaze of Ysera now take 15% increased Fire damage.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:300921:effect:0:aura:107","name":"Al Dente (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.15}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":300921,"level":1,"description":"Targets affected by Gaze of Ysera now take 15% increased Fire damage.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:300921:effect:0:aura:107","name":"Al Dente (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.15}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}]}],"talentEntryId":33843},{"id":"coa-tree-33882","classId":"pyromancer","dbcSpellId":504397,"name":"Blessing of the Firelands","unlockLevel":1,"icon":"/assets/ui/spells/nhi_fire_soul_border.png","sigil":"BO","description":"Each stack of Heat now increases the damage dealt by Dragon Leap by 6%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504397:effect:0:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.06}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":12,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:504397:effect:1:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":504397,"level":1,"description":"Each stack of Heat now increases the damage dealt by Dragon Leap by 6%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504397:effect:0:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.06}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":12,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:504397:effect:1:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}]}],"talentEntryId":33882},{"id":"coa-tree-32499","classId":"pyromancer","dbcSpellId":300759,"name":"Bright Flames","unlockLevel":1,"icon":"/assets/ui/spells/spell_frost_fireresistancetotem.png","sigil":"BF","description":"Increases the amount absorbed by Inferno Barrier by 10% and the damage it deals by 15%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:300759:effect:0:aura:317","name":"Bright Flames (Aura 317)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":317,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:300759:effect:1:aura:108","name":"Bright Flames (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.15}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":300759,"level":1,"description":"Increases the amount absorbed by Inferno Barrier by 10% and the damage it dLine truncated
{"schemaVersion":1,"classId":"pyromancer","abilities":[{"id":"coa-tree-33843","classId":"pyromancer","dbcSpellId":300921,"name":"Al Dente","unlockLevel":1,"icon":"/assets/ui/spells/achievement_cooking_masteroftheoven.png","sigil":"AD","description":"Targets affected by Gaze of Ysera now take 15% increased Fire damage.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:300921:effect:0:aura:107","name":"Al Dente (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.15}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":300921,"level":1,"description":"Targets affected by Gaze of Ysera now take 15% increased Fire damage.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:300921:effect:0:aura:107","name":"Al Dente (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.15}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}]}],"talentEntryId":33843},{"id":"coa-tree-33882","classId":"pyromancer","dbcSpellId":504397,"name":"Blessing of the Firelands","unlockLevel":1,"icon":"/assets/ui/spells/nhi_fire_soul_border.png","sigil":"BO","description":"Each stack of Heat now increases the damage dealt by Dragon Leap by 6%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504397:effect:0:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.06}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":12,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:504397:effect:1:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":504397,"level":1,"description":"Each stack of Heat now increases the damage dealt by Dragon Leap by 6%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:504397:effect:0:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.06}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":12,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:504397:effect:1:aura:107","name":"Blessing of the Firelands (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":23,"triggerSpellId":0}]}],"talentEntryId":33882},{"id":"coa-tree-32499","classId":"pyromancer","dbcSpellId":300759,"name":"Bright Flames","unlockLevel":1,"icon":"/assets/ui/spells/spell_frost_fireresistancetotem.png","sigil":"BF","description":"Increases the amount absorbed by Inferno Barrier by 10% and the damage it deals by 15%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:300759:effect:0:aura:317","name":"Bright Flames (Aura 317)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":317,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:300759:effect:1:aura:108","name":"Bright Flames (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.15}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":300759,"level":1,"description":"Increases the amount absorbed by Inferno Barrier by 10% and the damage it dLine truncated
+1 -1
View File
@@ -1 +1 @@
{"schemaVersion":1,"classId":"ranger","abilities":[{"id":"coa-21-agile-none-560796","classId":"ranger","dbcSpellId":560796,"name":"Agile","unlockLevel":1,"icon":"/assets/ui/spells/inv_sword_38.png","sigil":"AG","description":"AgileRank 2Increases the damage of Wild Strike, Whipvine Arrow, and Ravage by 10%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560796:effect:0:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560796:effect:1:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":22,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":2,"spellId":560796,"level":1,"description":"AgileRank 2Increases the damage of Wild Strike, Whipvine Arrow, and Ravage by 10%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560796:effect:0:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560796:effect:1:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":22,"triggerSpellId":0}]}]},{"id":"coa-21-archery-training-76-705036","classId":"ranger","dbcSpellId":705036,"name":"Archery Training","unlockLevel":1,"icon":"/assets/ui/spells/inv_bow_1h_draenorcrafted_d_01_a_horde.png","sigil":"AT","description":"Archery TrainingRank 1Increases the damage of Skullpiercer by 3% and your critical strike chance by 1%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705036:effect:0:aura:290","name":"Archery Training (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705036:effect:1:aura:108","name":"Archery Training (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.03}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705036,"level":1,"description":"Archery TrainingRank 1Increases the damage of Skullpiercer by 3% and your critical strike chance by 1%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705036:effect:0:aura:290","name":"Archery Training (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705036:effect:1:aura:108","name":"Archery Training (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.03}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}]},{"rank":2,"spellId":705037,"level":1,"description":"Archery TrainingRank 2Increases the damage of Skullpiercer by 6% and your critical strike chance by 2%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705037:effect:0:aura:290","name":"Archery Training (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705037:effect:1:aura:108","name":"Archery Training (Aura 108)","disposition":"buff","dLine truncated
{"schemaVersion":1,"classId":"ranger","abilities":[{"id":"coa-21-agile-none-560796","classId":"ranger","dbcSpellId":560796,"name":"Agile","unlockLevel":1,"icon":"/assets/ui/spells/inv_sword_38.png","sigil":"AG","description":"AgileRank 2Increases the damage of Wild Strike, Whipvine Arrow, and Ravage by 10%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560796:effect:0:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560796:effect:1:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":22,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":2,"spellId":560796,"level":1,"description":"AgileRank 2Increases the damage of Wild Strike, Whipvine Arrow, and Ravage by 10%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560796:effect:0:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:560796:effect:1:aura:108","name":"Agile (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":22,"triggerSpellId":0}]}]},{"id":"coa-21-archery-training-76-705036","classId":"ranger","dbcSpellId":705036,"name":"Archery Training","unlockLevel":1,"icon":"/assets/ui/spells/inv_bow_1h_draenorcrafted_d_01_a_horde.png","sigil":"AT","description":"Archery TrainingRank 1Increases the damage of Skullpiercer by 3% and your critical strike chance by 1%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705036:effect:0:aura:290","name":"Archery Training (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705036:effect:1:aura:108","name":"Archery Training (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.03}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705036,"level":1,"description":"Archery TrainingRank 1Increases the damage of Skullpiercer by 3% and your critical strike chance by 1%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705036:effect:0:aura:290","name":"Archery Training (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705036:effect:1:aura:108","name":"Archery Training (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.03}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}]},{"rank":2,"spellId":705037,"level":1,"description":"Archery TrainingRank 2Increases the damage of Skullpiercer by 6% and your critical strike chance by 2%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705037:effect:0:aura:290","name":"Archery Training (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705037:effect:1:aura:108","name":"Archery Training (Aura 108)","disposition":"buff","dLine truncated
+1 -1
View File
@@ -1 +1 @@
{"schemaVersion":1,"classId":"reaper","abilities":[{"id":"coa-tree-6708","classId":"reaper","dbcSpellId":706790,"name":"Backswing","unlockLevel":1,"icon":"/assets/ui/spells/novart_magicspell_(32)_border.png","sigil":"BA","description":"Increases the Runic Power generated by Reap by 5.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706790:effect:0:aura:107","name":"Backswing (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.5}]},"sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":706790,"level":1,"description":"Increases the Runic Power generated by Reap by 5.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706790:effect:0:aura:107","name":"Backswing (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.5}]},"sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}]}],"talentEntryId":6708},{"id":"coa-tree-34500","classId":"reaper","dbcSpellId":560412,"name":"Between Shadows","unlockLevel":1,"icon":"/assets/ui/spells/5_shadowworld_border.png","sigil":"BS","description":"Casting Spectre Stride now generates 1 Reaped Soul.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560412:effect:0:aura:42","name":"Between Shadows (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:560412:proc:0:504390","triggers":["cast"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":504390}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":504390}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":560412,"level":1,"description":"Casting Spectre Stride now generates 1 Reaped Soul.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560412:effect:0:aura:42","name":"Between Shadows (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:560412:proc:0:504390","triggers":["cast"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":504390}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":504390}]}],"talentEntryId":34500},{"id":"coa-tree-31289","classId":"reaper","dbcSpellId":680337,"name":"Bolstered Form","unlockLevel":1,"icon":"/assets/ui/spells/achievement_raid_torghast_shadowscourge_prisonofnerzhul.png","sigil":"BF","description":"Assume a bolstered form for 15 seconds, generating 30 Runic Power, increasing your Armor and your parry chance by 30%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:680337:effect:0:aura:101","name":"Bolstered Form (Aura 101)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"resistance:physical","operation":"percent","value":0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":101,"miscValue":1,"triggerSpellId":0},{"kind":"trigger-spell","spellId":359505},{"kind":"resource","amount":300},{"kind":"apply-aura","aura":{"id":"coa:680337:effect:2:aura:47","name":"Bolstered Form (Aura 47)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"parry","operation":"percent","value":0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":47,"miscValue":127,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":680337,"level":1,"description":"Assume a bolstered form for 15 seconds, generating 30 Runic Power, increasing your Armor and your parry chance by 30%.","castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:680337:effect:0:aura:101","name":"Bolstered Form (Aura 101)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"resistance:physical","operation":"percent","value":0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":1Line truncated
{"schemaVersion":1,"classId":"reaper","abilities":[{"id":"coa-tree-6708","classId":"reaper","dbcSpellId":706790,"name":"Backswing","unlockLevel":1,"icon":"/assets/ui/spells/novart_magicspell_(32)_border.png","sigil":"BA","description":"Increases the Runic Power generated by Reap by 5.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706790:effect:0:aura:107","name":"Backswing (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.5}]},"sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":706790,"level":1,"description":"Increases the Runic Power generated by Reap by 5.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706790:effect:0:aura:107","name":"Backswing (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.5}]},"sourceEffectType":6,"sourceAuraType":107,"miscValue":3,"triggerSpellId":0}]}],"talentEntryId":6708},{"id":"coa-tree-34500","classId":"reaper","dbcSpellId":560412,"name":"Between Shadows","unlockLevel":1,"icon":"/assets/ui/spells/5_shadowworld_border.png","sigil":"BS","description":"Casting Spectre Stride now generates 1 Reaped Soul.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560412:effect:0:aura:42","name":"Between Shadows (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:560412:proc:0:504390","triggers":["cast"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":504390}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":504390}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":560412,"level":1,"description":"Casting Spectre Stride now generates 1 Reaped Soul.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:560412:effect:0:aura:42","name":"Between Shadows (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:560412:proc:0:504390","triggers":["cast"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":504390}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":504390}]}],"talentEntryId":34500},{"id":"coa-tree-31289","classId":"reaper","dbcSpellId":680337,"name":"Bolstered Form","unlockLevel":1,"icon":"/assets/ui/spells/achievement_raid_torghast_shadowscourge_prisonofnerzhul.png","sigil":"BF","description":"Assume a bolstered form for 15 seconds, generating 30 Runic Power, increasing your Armor and your parry chance by 30%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:680337:effect:0:aura:101","name":"Bolstered Form (Aura 101)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"resistance:physical","operation":"percent","value":0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":101,"miscValue":1,"triggerSpellId":0},{"kind":"trigger-spell","spellId":359505,"expanded":true},{"kind":"resource","amount":300},{"kind":"apply-aura","aura":{"id":"coa:680337:effect:2:aura:47","name":"Bolstered Form (Aura 47)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"parry","operation":"percent","value":0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":47,"miscValue":127,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":680337,"level":1,"description":"Assume a bolstered form for 15 seconds, generating 30 Runic Power, increasing your Armor and your parry chance by 30%.","castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:680337:effect:0:aura:101","name":"Bolstered Form (Aura 101)","disposition":"buff","durationMs":15000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"stat","stat":"resistance:physical","operation":"percent","value":0.25}]},"recipient":"caster","sourceEffectType":6,"sLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"runemaster","abilities":[{"id":"coa-32-ancient-carvings-117-705616","classId":"runemaster","dbcSpellId":705616,"name":"Ancient Carvings","unlockLevel":1,"icon":"/assets/ui/spells/inv_relics_6orunestone_ogremissive.png","sigil":"AC","description":"Ancient CarvingsRank 2InstantReduces the cooldown of Words by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705616:effect:0:aura:108","name":"Ancient Carvings (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.2}]},"recipient":"caster","sourceEffectType":3,"sourceAuraType":108,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:1:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:2:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":34,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":2,"spellId":705616,"level":1,"description":"Ancient CarvingsRank 2InstantReduces the cooldown of Words by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705616:effect:0:aura:108","name":"Ancient Carvings (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.2}]},"recipient":"caster","sourceEffectType":3,"sourceAuraType":108,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:1:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:2:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":34,"triggerSpellId":0}]}]},{"id":"coa-tree-29226","classId":"runemaster","dbcSpellId":806797,"name":"Ancient Teachings","unlockLevel":1,"icon":"/assets/ui/spells/ability_mage_potentspirit.png","sigil":"AT","description":"Increases the effectiveness of Etching of the Dextrous by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:806797:effect:0:aura:216","name":"Ancient Teachings (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":126,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806797:effect:1:aura:192","name":"Ancient Teachings (Aura 192)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":192,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806797:effect:2:aura:108","name":"Ancient Teachings (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":8,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":806797,"level":1,"description":"Increases the effectiveness of Etching of the Dextrous by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:806797:effect:0:aura:216","name":"Ancient Teachings (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":126,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806797:effect:1:aura:192","name":"Ancient Teachings (Aura 192)","disposition":Line truncated
{"schemaVersion":1,"classId":"runemaster","abilities":[{"id":"coa-32-ancient-carvings-117-705616","classId":"runemaster","dbcSpellId":705616,"name":"Ancient Carvings","unlockLevel":1,"icon":"/assets/ui/spells/inv_relics_6orunestone_ogremissive.png","sigil":"AC","description":"Ancient CarvingsRank 2InstantReduces the cooldown of Words by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705616:effect:0:aura:108","name":"Ancient Carvings (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.2}]},"recipient":"caster","sourceEffectType":3,"sourceAuraType":108,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:1:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:2:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":34,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":2,"spellId":705616,"level":1,"description":"Ancient CarvingsRank 2InstantReduces the cooldown of Words by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705616:effect:0:aura:108","name":"Ancient Carvings (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.2}]},"recipient":"caster","sourceEffectType":3,"sourceAuraType":108,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:1:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705616:effect:2:aura:4","name":"Ancient Carvings (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":34,"triggerSpellId":0}]}]},{"id":"coa-tree-29226","classId":"runemaster","dbcSpellId":806797,"name":"Ancient Teachings","unlockLevel":1,"icon":"/assets/ui/spells/ability_mage_potentspirit.png","sigil":"AT","description":"Increases the effectiveness of Etching of the Dextrous by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:806797:effect:0:aura:216","name":"Ancient Teachings (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":126,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806797:effect:1:aura:192","name":"Ancient Teachings (Aura 192)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":192,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806797:effect:2:aura:108","name":"Ancient Teachings (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":8,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":806797,"level":1,"description":"Increases the effectiveness of Etching of the Dextrous by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:806797:effect:0:aura:216","name":"Ancient Teachings (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":126,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806797:effect:1:aura:192","name":"Ancient Teachings (Aura 192)","disposition":Line truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"starcaller","abilities":[{"id":"coa-26-arrows-of-starlight-93-704733","classId":"starcaller","dbcSpellId":704733,"name":"Arrows of Starlight","unlockLevel":1,"icon":"/assets/ui/spells/ability_ironmaidens_ironshot.png","sigil":"AO","description":"Arrows of StarlightRank 1Increases the damage of Moon Arrow by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704733:effect:0:aura:108","name":"Arrows of Starlight (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":704733,"level":1,"description":"Arrows of StarlightRank 1Increases the damage of Moon Arrow by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704733:effect:0:aura:108","name":"Arrows of Starlight (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}]}]},{"id":"coa-tree-30838","classId":"starcaller","dbcSpellId":806155,"name":"Astral Aegis","unlockLevel":1,"icon":"/assets/ui/spells/ability_bastion_monk.png","sigil":"AA","description":"Drains 30% Maximum Mana For 10 seconds, direct Magic damage taken will silence the attacker for 1 seconds and deal 57 + 18% arcane SP Arcane damage to them.","target":"hostile","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":30000,"gcdMs":1500,"cost":{"resource":"mana","amount":19,"percentage":true},"effects":[{"kind":"damage","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:806155:effect:0:aura:87","name":"Astral Aegis (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806155:effect:1:aura:42","name":"Astral Aegis (Aura 42)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:806155:proc:1:806453","triggers":["damage-taken","hit"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":806453}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":806453}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":806155,"level":1,"description":"Drains 30% Maximum Mana For 10 seconds, direct Magic damage taken will silence the attacker for 1 seconds and deal 57 + 18% arcane SP Arcane damage to them.","castMode":"instant","castTimeMs":0,"cooldownMs":30000,"gcdMs":1500,"cost":{"resource":"mana","amount":19,"percentage":true},"effects":[{"kind":"damage","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:806155:effect:0:aura:87","name":"Astral Aegis (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806155:effect:1:aura:42","name":"Astral Aegis (Aura 42)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:806155:proc:1:806453","triggers":["damage-taken","hit"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":806453}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":806453}]}],"talentEntryId":30838},{"id":"starcaller-astral-flare","classId":"starcaller","dbcSpellId":800499,"name":"Astral Flare","unlockLevel":1,"icon":"/assets/ui/spells/spell_shadow_manaburn.png","sigil":"AF","description":"Astral FlareRank 12 sec castYou call an Astral Flare down from the sky, dealing 1 Arcane Damage to an enemy and regenerating 5% of your Maximum Mana.","target":"hostile","range":{"min":0,"max":40},"castMode":"cast","castTimeMs":2000,"cooldownMs":0,"gcdMs":1250,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"trigger-spell","spellId":800507,"withValue":10},{"kind":"damage","coefficient":0.08,"basePoints":1,"dieSides":1,"pointsPerLevel":0,"bonusPowerCoefficient":0,"sourceLevel":6},{"kind":"trigger-spell","spellId":804096,"withValLine truncated
{"schemaVersion":1,"classId":"starcaller","abilities":[{"id":"coa-26-arrows-of-starlight-93-704733","classId":"starcaller","dbcSpellId":704733,"name":"Arrows of Starlight","unlockLevel":1,"icon":"/assets/ui/spells/ability_ironmaidens_ironshot.png","sigil":"AO","description":"Arrows of StarlightRank 1Increases the damage of Moon Arrow by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704733:effect:0:aura:108","name":"Arrows of Starlight (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":704733,"level":1,"description":"Arrows of StarlightRank 1Increases the damage of Moon Arrow by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704733:effect:0:aura:108","name":"Arrows of Starlight (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":0,"triggerSpellId":0}]}]},{"id":"coa-tree-30838","classId":"starcaller","dbcSpellId":806155,"name":"Astral Aegis","unlockLevel":1,"icon":"/assets/ui/spells/ability_bastion_monk.png","sigil":"AA","description":"Drains 30% Maximum Mana For 10 seconds, direct Magic damage taken will silence the attacker for 1 seconds and deal 57 + 18% arcane SP Arcane damage to them.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":30000,"gcdMs":1500,"cost":{"resource":"mana","amount":19,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:806155:effect:0:aura:87","name":"Astral Aegis (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806155:effect:1:aura:42","name":"Astral Aegis (Aura 42)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:806155:proc:1:806453","triggers":["damage-taken","hit"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":806453}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":806453}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":806155,"level":1,"description":"Drains 30% Maximum Mana For 10 seconds, direct Magic damage taken will silence the attacker for 1 seconds and deal 57 + 18% arcane SP Arcane damage to them.","castMode":"instant","castTimeMs":0,"cooldownMs":30000,"gcdMs":1500,"cost":{"resource":"mana","amount":19,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:806155:effect:0:aura:87","name":"Astral Aegis (Aura 87)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:806155:effect:1:aura:42","name":"Astral Aegis (Aura 42)","disposition":"buff","durationMs":10000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:806155:proc:1:806453","triggers":["damage-taken","hit"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":806453}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":806453}]}],"talentEntryId":30838},{"id":"starcaller-astral-flare","classId":"starcaller","dbcSpellId":800499,"name":"Astral Flare","unlockLevel":1,"icon":"/assets/ui/spells/spell_shadow_manaburn.png","sigil":"AF","description":"Astral FlareRank 12 sec castYou call an Astral Flare down from the sky, dealing 1 Arcane Damage to an enemy and regenerating 5% of your Maximum Mana.","target":"hostile","range":{"min":0,"max":40},"castMode":"cast","castTimeMs":2000,"cooldownMs":0,"gcdMs":1250,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"trigger-spell","spellId":800507,"expanded":true,"withValue":10},{"kind":"damage","coefficient":0.08,"basePoints":1,"dieSides":1,"pointsPerLevel":0,"bonusPowerCoefficient":0,"sourceLevel":6},{"kind":"trigger-spell","spellId":804096,"expanded":true,"withValue":5},{"kind":"resource","amount":2,"pLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"stormbringer","abilities":[{"id":"coa-tree-34916","classId":"stormbringer","dbcSpellId":807462,"name":"Aether Mastery","unlockLevel":1,"icon":"/assets/ui/spells/achievement_zone_netherstorm_01.png","sigil":"AM","description":"Allows 30% of your mana regeneration to continue while casting and increases your critical strike chance by 2%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:807462:effect:0:aura:134","name":"Aether Mastery (Aura 134)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"resource","resource":"mana","property":"regeneration","operation":"percent","value":0.3}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":134,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:807462:effect:1:aura:290","name":"Aether Mastery (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":807462,"level":1,"description":"Allows 30% of your mana regeneration to continue while casting and increases your critical strike chance by 2%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:807462:effect:0:aura:134","name":"Aether Mastery (Aura 134)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"resource","resource":"mana","property":"regeneration","operation":"percent","value":0.3}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":134,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:807462:effect:1:aura:290","name":"Aether Mastery (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0}]},{"rank":2,"spellId":807887,"level":1,"description":"Allows 60% of your mana regeneration to continue while casting and increases your critical strike chance by 4%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:807887:effect:0:aura:134","name":"Aether Mastery (Aura 134)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"resource","resource":"mana","property":"regeneration","operation":"percent","value":0.6}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":134,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:807887:effect:1:aura:290","name":"Aether Mastery (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0}]}],"talentEntryId":34916},{"id":"coa-16-aethermancy-62-705690","classId":"stormbringer","dbcSpellId":705690,"name":"Aethermancy","unlockLevel":1,"icon":"/assets/ui/spells/spell_shaman_improvedreincarnation.png","sigil":"AE","description":"AethermancyRank 1Increases the critical strike chance of your Invigorating Surge by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705690:effect:0:aura:107","name":"Aethermancy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":7,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705690:effect:1:aura:107","name":"Aethermancy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":1}]},"recipient":"caster","sourceEffectType":3,"sourceAuraType":107,"miscValue":7,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705690,"level":1,"description":"AethermancyRank 1Increases the critical strike chance of your Invigorating Surge by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705690:effect:0:aura:107","name":"Aethermancy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":7,"triggerSpellId":0},{"kinLine truncated
{"schemaVersion":1,"classId":"stormbringer","abilities":[{"id":"coa-tree-34916","classId":"stormbringer","dbcSpellId":807462,"name":"Aether Mastery","unlockLevel":1,"icon":"/assets/ui/spells/achievement_zone_netherstorm_01.png","sigil":"AM","description":"Allows 30% of your mana regeneration to continue while casting and increases your critical strike chance by 2%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:807462:effect:0:aura:134","name":"Aether Mastery (Aura 134)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"resource","resource":"mana","property":"regeneration","operation":"percent","value":0.3}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":134,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:807462:effect:1:aura:290","name":"Aether Mastery (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":807462,"level":1,"description":"Allows 30% of your mana regeneration to continue while casting and increases your critical strike chance by 2%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:807462:effect:0:aura:134","name":"Aether Mastery (Aura 134)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"resource","resource":"mana","property":"regeneration","operation":"percent","value":0.3}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":134,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:807462:effect:1:aura:290","name":"Aether Mastery (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0}]},{"rank":2,"spellId":807887,"level":1,"description":"Allows 60% of your mana regeneration to continue while casting and increases your critical strike chance by 4%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:807887:effect:0:aura:134","name":"Aether Mastery (Aura 134)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"resource","resource":"mana","property":"regeneration","operation":"percent","value":0.6}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":134,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:807887:effect:1:aura:290","name":"Aether Mastery (Aura 290)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh"},"recipient":"caster","sourceEffectType":6,"sourceAuraType":290,"miscValue":0,"triggerSpellId":0}]}],"talentEntryId":34916},{"id":"coa-16-aethermancy-62-705690","classId":"stormbringer","dbcSpellId":705690,"name":"Aethermancy","unlockLevel":1,"icon":"/assets/ui/spells/spell_shaman_improvedreincarnation.png","sigil":"AE","description":"AethermancyRank 1Increases the critical strike chance of your Invigorating Surge by 20%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705690:effect:0:aura:107","name":"Aethermancy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":7,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705690:effect:1:aura:107","name":"Aethermancy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":1}]},"recipient":"caster","sourceEffectType":3,"sourceAuraType":107,"miscValue":7,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705690,"level":1,"description":"AethermancyRank 1Increases the critical strike chance of your Invigorating Surge by 20%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705690:effect:0:aura:107","name":"Aethermancy (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.2}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":7,"triggerSpellId":0},{"kinLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"sun-cleric","abilities":[{"id":"coa-tree-4048","classId":"sun-cleric","dbcSpellId":92137,"name":"Angelic Presence","unlockLevel":1,"icon":"/assets/ui/spells/ability_paladin_conviction.png","sigil":"AP","description":"Level 10 Passive Avoiding an attack now has a 20% chance to grant you Angelic Presence.Angelic PresenceYour next Illumination within 15 seconds is instant cast and free of cost.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92137:effect:0:aura:42","name":"Angelic Presence (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92137:proc:0:800722","triggers":["cast","hit"],"chance":0.2,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":800722}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":800722},{"kind":"apply-aura","aura":{"id":"coa:92137:effect:1:aura:79","name":"Angelic Presence (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":127,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":92137,"level":1,"description":"Level 10 Passive Avoiding an attack now has a 20% chance to grant you Angelic Presence.Angelic PresenceYour next Illumination within 15 seconds is instant cast and free of cost.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92137:effect:0:aura:42","name":"Angelic Presence (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92137:proc:0:800722","triggers":["cast","hit"],"chance":0.2,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":800722}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":800722},{"kind":"apply-aura","aura":{"id":"coa:92137:effect:1:aura:79","name":"Angelic Presence (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":127,"triggerSpellId":0}]}],"talentEntryId":4048},{"id":"coa-27-bastion-of-vengeance-97-704925","classId":"sun-cleric","dbcSpellId":704925,"name":"Bastion of Vengeance","unlockLevel":1,"icon":"/assets/ui/spells/inv_shield_1h_artifactnorgannon_d_06.png","sigil":"BO","description":"Bastion of VengeanceRank 1Increases your block chance by 2% and gives successful blocks a 50% chance to reduce the remaining cooldown of Vengeful Slam by 0.01 sec.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704925:effect:0:aura:42","name":"Bastion of Vengeance (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:704925:proc:0:704926","triggers":["block"],"chance":0.5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":704926}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":704926},{"kind":"apply-aura","aura":{"id":"coa:704925:effect:1:aura:51","name":"Bastion of Vengeance (Aura 51)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"block","operation":"percent","value":0.02}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":51,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":704925,"level":1,"description":"Bastion of VengeanceRank 1Increases your block chance by 2% and gives successful blocks a 50% chance to reduce the remaining cooldown of Vengeful Slam by 0.01 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704925:effect:0:aura:42","name":"Bastion of Vengeance (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:704925:proc:0:704926","triggers":["block"],"chance":0.5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":704926}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":704926},{"kind":"apply-aura","aura":{"id":"coa:704925:effect:1:aura:51","name":"Bastion of Vengeance (Aura 51)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","statLine truncated
{"schemaVersion":1,"classId":"sun-cleric","abilities":[{"id":"coa-tree-4048","classId":"sun-cleric","dbcSpellId":92137,"name":"Angelic Presence","unlockLevel":1,"icon":"/assets/ui/spells/ability_paladin_conviction.png","sigil":"AP","description":"Level 10 Passive Avoiding an attack now has a 20% chance to grant you Angelic Presence.Angelic PresenceYour next Illumination within 15 seconds is instant cast and free of cost.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92137:effect:0:aura:42","name":"Angelic Presence (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92137:proc:0:800722","triggers":["cast","hit"],"chance":0.2,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":800722}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":800722},{"kind":"apply-aura","aura":{"id":"coa:92137:effect:1:aura:79","name":"Angelic Presence (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":127,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":92137,"level":1,"description":"Level 10 Passive Avoiding an attack now has a 20% chance to grant you Angelic Presence.Angelic PresenceYour next Illumination within 15 seconds is instant cast and free of cost.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:92137:effect:0:aura:42","name":"Angelic Presence (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:92137:proc:0:800722","triggers":["cast","hit"],"chance":0.2,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":800722}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":800722},{"kind":"apply-aura","aura":{"id":"coa:92137:effect:1:aura:79","name":"Angelic Presence (Aura 79)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"dealt","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":79,"miscValue":127,"triggerSpellId":0}]}],"talentEntryId":4048},{"id":"coa-27-bastion-of-vengeance-97-704925","classId":"sun-cleric","dbcSpellId":704925,"name":"Bastion of Vengeance","unlockLevel":1,"icon":"/assets/ui/spells/inv_shield_1h_artifactnorgannon_d_06.png","sigil":"BO","description":"Bastion of VengeanceRank 1Increases your block chance by 2% and gives successful blocks a 50% chance to reduce the remaining cooldown of Vengeful Slam by 0.01 sec.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704925:effect:0:aura:42","name":"Bastion of Vengeance (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:704925:proc:0:704926","triggers":["block"],"chance":0.5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":704926}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":704926},{"kind":"apply-aura","aura":{"id":"coa:704925:effect:1:aura:51","name":"Bastion of Vengeance (Aura 51)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"block","operation":"percent","value":0.02}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":51,"miscValue":0,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":704925,"level":1,"description":"Bastion of VengeanceRank 1Increases your block chance by 2% and gives successful blocks a 50% chance to reduce the remaining cooldown of Vengeful Slam by 0.01 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:704925:effect:0:aura:42","name":"Bastion of Vengeance (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:704925:proc:0:704926","triggers":["block"],"chance":0.5,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":704926}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":704926},{"kind":"apply-aura","aura":{"id":"coa:704925:effect:1:aura:51","name":"Bastion of Vengeance (Aura 51)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","statLine truncated
+1 -1
View File
@@ -1 +1 @@
{"schemaVersion":1,"classId":"templar","abilities":[{"id":"coa-19-alertness-71-706321","classId":"templar","dbcSpellId":706321,"name":"Alertness","unlockLevel":1,"icon":"/assets/ui/spells/spell_holy_powerinfusion.png","sigil":"AL","description":"AlertnessRank 1Reduces damage taken by 5%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706321:effect:0:aura:87","name":"Alertness (Aura 87)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:706321:effect:1:aura:107","name":"Alertness (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":5,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":706321,"level":1,"description":"AlertnessRank 1Reduces damage taken by 5%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706321:effect:0:aura:87","name":"Alertness (Aura 87)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:706321:effect:1:aura:107","name":"Alertness (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":5,"triggerSpellId":0}]},{"rank":2,"spellId":706322,"level":1,"description":"AlertnessRank 2Reduces Physical Damage taken by 4% and increases the range of Benediction by 10 yds.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706322:effect:0:aura:87","name":"Alertness (Aura 87)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:706322:effect:1:aura:107","name":"Alertness (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":5,"triggerSpellId":0}]}]},{"id":"coa-tree-34375","classId":"templar","dbcSpellId":801457,"name":"Binding Scripture","unlockLevel":1,"icon":"/assets/ui/spells/_d3breathofheaven.png","sigil":"BS","description":"Healing an ally now redirects 10% of their damage taken to you and reduces your damage taken by -5% for 10 seconds, stacking 3 times.","target":"hostile","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"damage","coefficient":1},{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:801457:effect:0:aura:42","name":"Binding Scripture (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:801457:proc:0:705309","triggers":["heal","damage-taken"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":705309}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":705309}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":801457,"level":1,"description":"Healing an ally now redirects 10% of their damage taken to you and reduces your damage taken by -5% for 10 seconds, stacking 3 times.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"damage","coefficient":1},{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:801457:effect:0:aura:42","name":"Binding Scripture (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:801457:proc:0:705309","triggers":["heal","damage-taken"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":705309}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":705309}]}],"taleLine truncated
{"schemaVersion":1,"classId":"templar","abilities":[{"id":"coa-19-alertness-71-706321","classId":"templar","dbcSpellId":706321,"name":"Alertness","unlockLevel":1,"icon":"/assets/ui/spells/spell_holy_powerinfusion.png","sigil":"AL","description":"AlertnessRank 1Reduces damage taken by 5%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706321:effect:0:aura:87","name":"Alertness (Aura 87)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:706321:effect:1:aura:107","name":"Alertness (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":5,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":706321,"level":1,"description":"AlertnessRank 1Reduces damage taken by 5%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706321:effect:0:aura:87","name":"Alertness (Aura 87)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:706321:effect:1:aura:107","name":"Alertness (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":5,"triggerSpellId":0}]},{"rank":2,"spellId":706322,"level":1,"description":"AlertnessRank 2Reduces Physical Damage taken by 4% and increases the range of Benediction by 10 yds.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:706322:effect:0:aura:87","name":"Alertness (Aura 87)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"damage","direction":"taken","operation":"percent","value":-0.04}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":87,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:706322:effect:1:aura:107","name":"Alertness (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":5,"triggerSpellId":0}]}]},{"id":"coa-tree-34375","classId":"templar","dbcSpellId":801457,"name":"Binding Scripture","unlockLevel":1,"icon":"/assets/ui/spells/_d3breathofheaven.png","sigil":"BS","description":"Healing an ally now redirects 10% of their damage taken to you and reduces your damage taken by -5% for 10 seconds, stacking 3 times.","target":"friendly","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:801457:effect:0:aura:42","name":"Binding Scripture (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:801457:proc:0:705309","triggers":["heal","damage-taken"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":705309}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":705309}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":801457,"level":1,"description":"Healing an ally now redirects 10% of their damage taken to you and reduces your damage taken by -5% for 10 seconds, stacking 3 times.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:801457:effect:0:aura:42","name":"Binding Scripture (Aura 42)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","procs":[{"id":"coa:801457:proc:0:705309","triggers":["heal","damage-taken"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":705309}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":705309}]}],"talentEntryId":34375},{"id":"coa-tree-29704","classId":"templar","dbcSpLine truncated
+1 -1
View File
@@ -1 +1 @@
{"schemaVersion":1,"classId":"tinker","abilities":[{"id":"coa-tree-29440","classId":"tinker","dbcSpellId":801744,"name":"Air Strike","unlockLevel":1,"icon":"/assets/ui/spells/ability_mount_gyrocoptor.png","sigil":"AS","description":"Mark the target location for an Air Strike. After 7 seconds, it deals 1250 Fire damage to up to 12 enemies caught within the blast. This ability always critically strikes.","target":"hostile","range":{"min":0,"max":60},"radius":20,"castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":25,"percentage":true},"effects":[{"kind":"damage","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:801744:effect:0:aura:23","name":"Air Strike (Aura 23)","disposition":"debuff","durationMs":7000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:801744:proc:0:801745","triggers":["periodic"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":801745}}}]},"sourceEffectType":27,"sourceAuraType":23,"miscValue":0,"triggerSpellId":801745}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":801744,"level":1,"description":"Mark the target location for an Air Strike. After 7 seconds, it deals 1250 Fire damage to up to 12 enemies caught within the blast. This ability always critically strikes.","castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":25,"percentage":true},"effects":[{"kind":"damage","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:801744:effect:0:aura:23","name":"Air Strike (Aura 23)","disposition":"debuff","durationMs":7000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:801744:proc:0:801745","triggers":["periodic"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":801745}}}]},"sourceEffectType":27,"sourceAuraType":23,"miscValue":0,"triggerSpellId":801745}]}],"talentEntryId":29440},{"id":"coa-tree-5997","classId":"tinker","dbcSpellId":520445,"name":"Auto Resuscitation Device","unlockLevel":1,"icon":"/assets/ui/spells/inv_misc_enggizmos_15.png","sigil":"AR","description":"Attach a resuscitation device to your target ally for 20 seconds. When the target would otherwise die, they are instead healed for 50% of their maximum health.","target":"friendly","range":{"min":0,"max":20},"castMode":"cast","castTimeMs":1500,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"mana","amount":40,"percentage":true},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:520445:effect:0:aura:69","name":"Auto Resuscitation Device (Aura 69)","disposition":"buff","durationMs":20000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","absorbs":[{"id":"coa:520445:absorb:0","amount":20,"perStack":false}]},"sourceEffectType":6,"sourceAuraType":69,"miscValue":127,"triggerSpellId":524780}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":520445,"level":1,"description":"Attach a resuscitation device to your target ally for 20 seconds. When the target would otherwise die, they are instead healed for 50% of their maximum health.","castMode":"cast","castTimeMs":1500,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"mana","amount":40,"percentage":true},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:520445:effect:0:aura:69","name":"Auto Resuscitation Device (Aura 69)","disposition":"buff","durationMs":20000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","absorbs":[{"id":"coa:520445:absorb:0","amount":20,"perStack":false}]},"sourceEffectType":6,"sourceAuraType":69,"miscValue":127,"triggerSpellId":524780}]}],"talentEntryId":5997},{"id":"coa-28-blasting-barrels-99-705835","classId":"tinker","dbcSpellId":705835,"name":"Blasting Barrels","unlockLevel":1,"icon":"/assets/ui/spells/5_gunshot_(3)_border.png","sigil":"BB","description":"Blasting BarrelsRank 1InstantIncreases critical strike damage by 0% and increases damage dealt by Rounds by 0%.","target":"hostile","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"damage","coefficient":1}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705835,"level":1,"description":"Blasting BarrelsRank 1InstantIncreases critical strike damage by 0% and increases damage dealt by Rounds by 0%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"damage","coefficient":1}]}]},{"id":"coa-tree-30583","classId":"tinker","dbcSpellId":560754,"name":"Build: Alarm Beacon","unlockLevel":1,"icon":"/assets/ui/spells/inv_lightforgedmechsuit.png","sigil":"BA","description":"3 Charges, 15 sec recharge Throw down an alarm beacon for 10 seconds, removing fear, charm and sleep effects from up to 1 ally within 20 yds every 1 sec.","target":"hostile","range":{"min":0,Line truncated
{"schemaVersion":1,"classId":"tinker","abilities":[{"id":"coa-tree-29440","classId":"tinker","dbcSpellId":801744,"name":"Air Strike","unlockLevel":1,"icon":"/assets/ui/spells/ability_mount_gyrocoptor.png","sigil":"AS","description":"Mark the target location for an Air Strike. After 7 seconds, it deals 1250 Fire damage to up to 12 enemies caught within the blast. This ability always critically strikes.","target":"hostile","range":{"min":0,"max":60},"radius":20,"castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":25,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:801744:effect:0:aura:23","name":"Air Strike (Aura 23)","disposition":"debuff","durationMs":7000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:801744:proc:0:801745","triggers":["periodic"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":801745}}}]},"sourceEffectType":27,"sourceAuraType":23,"miscValue":0,"triggerSpellId":801745}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":801744,"level":1,"description":"Mark the target location for an Air Strike. After 7 seconds, it deals 1250 Fire damage to up to 12 enemies caught within the blast. This ability always critically strikes.","castMode":"instant","castTimeMs":0,"cooldownMs":60000,"gcdMs":1500,"cost":{"resource":"mana","amount":25,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:801744:effect:0:aura:23","name":"Air Strike (Aura 23)","disposition":"debuff","durationMs":7000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","procs":[{"id":"coa:801744:proc:0:801745","triggers":["periodic"],"chance":1,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":801745}}}]},"sourceEffectType":27,"sourceAuraType":23,"miscValue":0,"triggerSpellId":801745}]}],"talentEntryId":29440},{"id":"coa-tree-5997","classId":"tinker","dbcSpellId":520445,"name":"Auto Resuscitation Device","unlockLevel":1,"icon":"/assets/ui/spells/inv_misc_enggizmos_15.png","sigil":"AR","description":"Attach a resuscitation device to your target ally for 20 seconds. When the target would otherwise die, they are instead healed for 50% of their maximum health.","target":"friendly","range":{"min":0,"max":20},"castMode":"cast","castTimeMs":1500,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"mana","amount":40,"percentage":true},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:520445:effect:0:aura:69","name":"Auto Resuscitation Device (Aura 69)","disposition":"buff","durationMs":20000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","absorbs":[{"id":"coa:520445:absorb:0","amount":20,"perStack":false}]},"sourceEffectType":6,"sourceAuraType":69,"miscValue":127,"triggerSpellId":524780}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":520445,"level":1,"description":"Attach a resuscitation device to your target ally for 20 seconds. When the target would otherwise die, they are instead healed for 50% of their maximum health.","castMode":"cast","castTimeMs":1500,"cooldownMs":180000,"gcdMs":1500,"cost":{"resource":"mana","amount":40,"percentage":true},"effects":[{"kind":"heal","coefficient":1},{"kind":"apply-aura","aura":{"id":"coa:520445:effect:0:aura:69","name":"Auto Resuscitation Device (Aura 69)","disposition":"buff","durationMs":20000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"magic","absorbs":[{"id":"coa:520445:absorb:0","amount":20,"perStack":false}]},"sourceEffectType":6,"sourceAuraType":69,"miscValue":127,"triggerSpellId":524780}]}],"talentEntryId":5997},{"id":"coa-28-blasting-barrels-99-705835","classId":"tinker","dbcSpellId":705835,"name":"Blasting Barrels","unlockLevel":1,"icon":"/assets/ui/spells/5_gunshot_(3)_border.png","sigil":"BB","description":"Blasting BarrelsRank 1InstantIncreases critical strike damage by 0% and increases damage dealt by Rounds by 0%.","target":"hostile","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"damage","coefficient":1}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705835,"level":1,"description":"Blasting BarrelsRank 1InstantIncreases critical strike damage by 0% and increases damage dealt by Rounds by 0%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"damage","coefficient":1}]}]},{"id":"coa-tree-30583","classId":"tinker","dbcSpellId":560754,"name":"Build: Alarm Beacon","unlockLevel":1,"icon":"/assets/ui/spells/inv_lightforgedmechsuit.png","sigil":"BA","description":"3 Charges, 15 sec recharge Throw down an alarm beacon for 10 seconds, removing fear, charm and sleep effects from up to 1 ally within 20 yds every 1 sec.","target":"hostile","range":{"min":0,"max":20},"radius":5,"castMode":"instant","castTimeMs":0,"cooldownMsLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"venomancer","abilities":[{"id":"coa-29-acceleration-103-705960","classId":"venomancer","dbcSpellId":705960,"name":"Acceleration","unlockLevel":1,"icon":"/assets/ui/spells/_meat_rotten.png","sigil":"AC","description":"AccelerationRank 2Increases the tick rate of Wilt and Shadra's Vigil by 10%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705960:effect:0:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705960:effect:1:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":2,"spellId":705960,"level":1,"description":"AccelerationRank 2Increases the tick rate of Wilt and Shadra's Vigil by 10%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705960:effect:0:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705960:effect:1:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0}]}]},{"id":"coa-tree-6086","classId":"venomancer","dbcSpellId":805775,"name":"Adrenal Venom","unlockLevel":1,"icon":"/assets/ui/spells/trade_alchemy_dpotion_a26.png","sigil":"AV","description":"Activate Adrenal Venom for 120 minutes, giving your casts a 25% chance to increase your haste by 6% for 6 seconds, stacking 3 times. You can have a maximum of 2 unique Venoms active at a time.","target":"self","range":{"min":0,"max":0},"castMode":"cast","castTimeMs":1000,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":20,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:805775:effect:0:aura:42","name":"Adrenal Venom (Aura 42)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","procs":[{"id":"coa:805775:proc:0:805894","triggers":["cast"],"chance":0.25,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":805894}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":805894},{"kind":"apply-aura","aura":{"id":"coa:805775:effect:1:aura:107","name":"Adrenal Venom (Aura 107)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":17,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":805775,"level":1,"description":"Activate Adrenal Venom for 120 minutes, giving your casts a 25% chance to increase your haste by 6% for 6 seconds, stacking 3 times. You can have a maximum of 2 unique Venoms active at a time.","castMode":"cast","castTimeMs":1000,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":20,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:805775:effect:0:aura:42","name":"Adrenal Venom (Aura 42)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","procs":[{"id":"coa:805775:proc:0:805894","triggers":["cast"],"chance":0.25,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":805894}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":805894},{"kind":"apply-aura","aura":{"id":"coa:805775:effect:1:aura:107","name":"Adrenal Venom (Aura 107)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":17,"triggerSpellId":0}]}],"talentEntryId":6086},{"id":"coa-tree-29574"Line truncated
{"schemaVersion":1,"classId":"venomancer","abilities":[{"id":"coa-29-acceleration-103-705960","classId":"venomancer","dbcSpellId":705960,"name":"Acceleration","unlockLevel":1,"icon":"/assets/ui/spells/_meat_rotten.png","sigil":"AC","description":"AccelerationRank 2Increases the tick rate of Wilt and Shadra's Vigil by 10%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705960:effect:0:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705960:effect:1:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":2,"spellId":705960,"level":1,"description":"AccelerationRank 2Increases the tick rate of Wilt and Shadra's Vigil by 10%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705960:effect:0:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705960:effect:1:aura:108","name":"Acceleration (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":19,"triggerSpellId":0}]}]},{"id":"coa-tree-6086","classId":"venomancer","dbcSpellId":805775,"name":"Adrenal Venom","unlockLevel":1,"icon":"/assets/ui/spells/trade_alchemy_dpotion_a26.png","sigil":"AV","description":"Activate Adrenal Venom for 120 minutes, giving your casts a 25% chance to increase your haste by 6% for 6 seconds, stacking 3 times. You can have a maximum of 2 unique Venoms active at a time.","target":"self","range":{"min":0,"max":0},"castMode":"cast","castTimeMs":1000,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":20,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:805775:effect:0:aura:42","name":"Adrenal Venom (Aura 42)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","procs":[{"id":"coa:805775:proc:0:805894","triggers":["cast"],"chance":0.25,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":805894}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":805894},{"kind":"apply-aura","aura":{"id":"coa:805775:effect:1:aura:107","name":"Adrenal Venom (Aura 107)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":17,"triggerSpellId":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":805775,"level":1,"description":"Activate Adrenal Venom for 120 minutes, giving your casts a 25% chance to increase your haste by 6% for 6 seconds, stacking 3 times. You can have a maximum of 2 unique Venoms active at a time.","castMode":"cast","castTimeMs":1000,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":20,"percentage":true},"effects":[{"kind":"apply-aura","aura":{"id":"coa:805775:effect:0:aura:42","name":"Adrenal Venom (Aura 42)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","procs":[{"id":"coa:805775:proc:0:805894","triggers":["cast"],"chance":0.25,"action":{"kind":"custom","id":"wow335-trigger-spell","data":{"spellId":805894}}}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":42,"miscValue":0,"triggerSpellId":805894},{"kind":"apply-aura","aura":{"id":"coa:805775:effect:1:aura:107","name":"Adrenal Venom (Aura 107)","disposition":"buff","durationMs":7200000,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"poison","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":17,"triggerSpellId":0}]}],"talentEntryId":6086},{"id":"coa-tree-29574"Line truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"witch-doctor","abilities":[{"id":"coa-tree-30147","classId":"witch-doctor","dbcSpellId":705921,"name":"Alchemical Enhancement","unlockLevel":1,"icon":"/assets/ui/spells/inv_alchemy_71_potion4.png","sigil":"AE","description":"Increases your haste by 5%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705921:effect:0:aura:216","name":"Alchemical Enhancement (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705921:effect:1:aura:192","name":"Alchemical Enhancement (Aura 192)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":192,"miscValue":127,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":705921,"level":1,"description":"Increases your haste by 5%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705921:effect:0:aura:216","name":"Alchemical Enhancement (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705921:effect:1:aura:192","name":"Alchemical Enhancement (Aura 192)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":192,"miscValue":127,"triggerSpellId":0}]}],"talentEntryId":30147},{"id":"coa-tree-11323","classId":"witch-doctor","dbcSpellId":301297,"name":"Blatant Curse","unlockLevel":1,"icon":"/assets/ui/spells/spell_nature_removecurse.png","sigil":"BC","description":"Reduces the mana cost of your Jinxes by -25%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:301297:effect:0:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":8,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:301297:effect:1:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":301297,"level":1,"description":"Reduces the mana cost of your Jinxes by -25%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:301297:effect:0:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":8,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:301297:effect:1:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0}]}],"talentEntryId":11323},{"id":"coa-tree-12048","classId":"witch-doctor","dbcSpellId":572870,"name":"Blessing of Hir'eek","unlockLevel":1,"icon":"/assets/ui/spells/trade_archaeology_trollbatidol.png","sigil":"BO","description":"Your Hexbreak now removes an additional curse effect.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:572870:effect:0:aura:107","name":"Blessing of Hir'eek (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"sLine truncated
{"schemaVersion":1,"classId":"witch-doctor","abilities":[{"id":"coa-tree-30147","classId":"witch-doctor","dbcSpellId":705921,"name":"Alchemical Enhancement","unlockLevel":1,"icon":"/assets/ui/spells/inv_alchemy_71_potion4.png","sigil":"AE","description":"Increases your haste by 5%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705921:effect:0:aura:216","name":"Alchemical Enhancement (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705921:effect:1:aura:192","name":"Alchemical Enhancement (Aura 192)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":192,"miscValue":127,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":705921,"level":1,"description":"Increases your haste by 5%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705921:effect:0:aura:216","name":"Alchemical Enhancement (Aura 216)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":216,"miscValue":0,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705921:effect:1:aura:192","name":"Alchemical Enhancement (Aura 192)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"haste","operation":"percent","value":0.05}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":192,"miscValue":127,"triggerSpellId":0}]}],"talentEntryId":30147},{"id":"coa-tree-11323","classId":"witch-doctor","dbcSpellId":301297,"name":"Blatant Curse","unlockLevel":1,"icon":"/assets/ui/spells/spell_nature_removecurse.png","sigil":"BC","description":"Reduces the mana cost of your Jinxes by -25%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:301297:effect:0:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":8,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:301297:effect:1:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0}],"passive":true,"source":"coa-tree","ranks":[{"rank":1,"spellId":301297,"level":1,"description":"Reduces the mana cost of your Jinxes by -25%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:301297:effect:0:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":8,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:301297:effect:1:aura:108","name":"Blatant Curse (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","dispelCategory":"curse","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.25}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0}]}],"talentEntryId":11323},{"id":"coa-tree-12048","classId":"witch-doctor","dbcSpellId":572870,"name":"Blessing of Hir'eek","unlockLevel":1,"icon":"/assets/ui/spells/trade_archaeology_trollbatidol.png","sigil":"BO","description":"Your Hexbreak now removes an additional curse effect.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"mana","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:572870:effect:0:aura:107","name":"Blessing of Hir'eek (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"sLine truncated
@@ -1 +1 @@
{"schemaVersion":1,"classId":"witch-hunter","abilities":[{"id":"coa-15-agile-steps-58-705521","classId":"witch-hunter","dbcSpellId":705521,"name":"Agile Steps","unlockLevel":1,"icon":"/assets/ui/spells/inv_boot_cloth_nzothraidmythic_d_01.png","sigil":"AS","description":"Agile StepsRank 1Reduces the cooldown of Vault by 2 sec.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705521:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-20}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":1,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705521,"level":1,"description":"Agile StepsRank 1Reduces the cooldown of Vault by 2 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705521:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-20}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":1,"triggerSpellId":0}]},{"rank":2,"spellId":705522,"level":1,"description":"Agile StepsRank 2Reduces the cooldown of Vault by 4 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705522:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705522:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-40}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705522:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":1,"triggerSpellId":0}]},{"rank":3,"spellId":705523,"level":1,"description":"Agile StepsRank 3InstantReduces the cooldown of Vault by 3 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705523:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705523:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-30}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705523:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceALine truncated
{"schemaVersion":1,"classId":"witch-hunter","abilities":[{"id":"coa-15-agile-steps-58-705521","classId":"witch-hunter","dbcSpellId":705521,"name":"Agile Steps","unlockLevel":1,"icon":"/assets/ui/spells/inv_boot_cloth_nzothraidmythic_d_01.png","sigil":"AS","description":"Agile StepsRank 1Reduces the cooldown of Vault by 2 sec.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705521:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-20}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":1,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705521,"level":1,"description":"Agile StepsRank 1Reduces the cooldown of Vault by 2 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705521:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-20}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705521:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":1,"triggerSpellId":0}]},{"rank":2,"spellId":705522,"level":1,"description":"Agile StepsRank 2Reduces the cooldown of Vault by 4 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705522:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705522:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-40}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705522:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":1,"triggerSpellId":0}]},{"rank":3,"spellId":705523,"level":1,"description":"Agile StepsRank 3InstantReduces the cooldown of Vault by 3 sec.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"rage","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705523:effect:0:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":4,"miscValue":127,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705523:effect:1:aura:107","name":"Agile Steps (Aura 107)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"attack-power","operation":"percent","value":-30}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":107,"miscValue":11,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705523:effect:2:aura:4","name":"Agile Steps (Aura 4)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","utilityTags":["coa-aura:4"]},"recipient":"caster","sourceEffectType":6,"sourceALine truncated
@@ -1 +1 @@
{"schemaVersion":1,"abilitiesByClass":{"barbarian":[{"id":"coa-tree-30762","classId":"barbarian","dbcSpellId":500918,"name":"Ancestral Roar","unlockLevel":1,"icon":"/assets/ui/spells/_d3threateningshout.png","sigil":"AR","description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":500918,"level":1,"description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}]}],"talentEntryId":30762},{"id":"coa-12-ancestral-spirit-47-705153","classId":"barbarian","dbcSpellId":705153,"name":"Ancestral Spirit","unlockLevel":1,"icon":"/assets/ui/spells/inv_misc_questionmark.png","sigil":"AS","description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705153,"level":1,"description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]},{"rank":2,"spellId":705154,"level":1,"description":"Ancestral SpiritRank 2Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 100%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705154:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705154:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]}]},{"id":"coa-tree-34279","classId":"barbarian","dbcSpellId":560456,"name":"Athleticism","unlockLevel":1,"icon":"/assets/ui/spells/5_run_border.png","sigil":"AT","descriptionLine truncated
{"schemaVersion":1,"abilitiesByClass":{"barbarian":[{"id":"coa-tree-30762","classId":"barbarian","dbcSpellId":500918,"name":"Ancestral Roar","unlockLevel":1,"icon":"/assets/ui/spells/_d3threateningshout.png","sigil":"AR","description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}],"passive":false,"source":"coa-tree","ranks":[{"rank":1,"spellId":500918,"level":1,"description":"Ancestral RoarRank 1Instant cast25 sec cooldownRequires Enraged Roar with ancestral fervor, healing you for 100+0+AP*0.5.","castMode":"instant","castTimeMs":0,"cooldownMs":25000,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"heal","coefficient":1.6580645243326824,"basePoints":100,"dieSides":7,"pointsPerLevel":3.200000047683716,"bonusPowerCoefficient":0,"sourceLevel":16,"maxScalingLevel":22},{"kind":"utility","action":"class-script","effectType":3,"auraType":0,"miscValue":3,"triggerSpellId":0,"durationMs":0}]}],"talentEntryId":30762},{"id":"coa-12-ancestral-spirit-47-705153","classId":"barbarian","dbcSpellId":705153,"name":"Ancestral Spirit","unlockLevel":1,"icon":"/assets/ui/spells/inv_misc_questionmark.png","sigil":"AS","description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","target":"self","range":{"min":0,"max":0},"castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}],"passive":true,"source":"coa-progression","ranks":[{"rank":1,"spellId":705153,"level":1,"description":"Ancestral SpiritRank 1Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 50%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705153:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705153:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":0.5}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]},{"rank":2,"spellId":705154,"level":1,"description":"Ancestral SpiritRank 2Reduces the Energy cost of your Spirit spells and increases the duration of your Shouts by 100%.","castMode":"instant","castTimeMs":0,"cooldownMs":0,"gcdMs":1500,"cost":{"resource":"energy","amount":0},"effects":[{"kind":"apply-aura","aura":{"id":"coa:705154:effect:0:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":-1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":14,"triggerSpellId":0},{"kind":"apply-aura","aura":{"id":"coa:705154:effect:1:aura:108","name":"Ancestral Spirit (Aura 108)","disposition":"buff","durationMs":null,"maxStacks":1,"stackBehavior":"refresh","modifiers":[{"kind":"stat","stat":"ranged-attack-power","operation":"percent","value":1}]},"recipient":"caster","sourceEffectType":6,"sourceAuraType":108,"miscValue":1,"triggerSpellId":0}]}]},{"id":"coa-tree-34279","classId":"barbarian","dbcSpellId":560456,"name":"Athleticism","unlockLevel":1,"icon":"/assets/ui/spells/5_run_border.png","sigil":"AT","descriptionLine truncated
File diff suppressed because it is too large. Load diff
+11 -7
View File
@@ -30,14 +30,14 @@ describe("SQL-generated boss loot catalog", () => {
});
it("rolls recognizable boss items while setting item level from the player", () => {
const first = rollBossLoot("lady-anacondra", 37, { random: () => 0, now: 12_345 });
const last = rollBossLoot("lady-anacondra", 37, { random: () => 0.999, now: 12_346 });
const first = rollBossLoot("lady-anacondra", 80, { random: () => 0, now: 12_345 });
const last = rollBossLoot("lady-anacondra", 80, { random: () => 0.999, now: 12_346 });
expect(first).toHaveLength(1);
expect(first[0]).toMatchObject({
itemId: 5404,
name: "Serpent's Shoulders",
itemLevel: 37,
itemLevel: 85,
sourceItemLevel: 23,
sourceBossKey: "lady-anacondra",
acquiredAt: 12_345,
@@ -45,7 +45,7 @@ describe("SQL-generated boss loot catalog", () => {
expect(last[0]).toMatchObject({
itemId: 10412,
name: "Belt of the Fang",
itemLevel: 37,
itemLevel: 85,
sourceItemLevel: 21,
});
expect(first[0].stats.agility).toBeGreaterThan(0);
@@ -62,16 +62,16 @@ describe("SQL-generated boss loot catalog", () => {
});
it("adds at most one bonus weighted item without changing normal rolls", () => {
const normal = rollBossLoot("lady-anacondra", 20, {
const normal = rollBossLoot("lady-anacondra", 80, {
random: () => 0,
now: 20_000,
});
const guaranteedBonus = rollBossLoot("lady-anacondra", 20, {
const guaranteedBonus = rollBossLoot("lady-anacondra", 80, {
random: () => 0,
now: 20_001,
bonusItemChance: 1,
});
const failedBonus = rollBossLoot("lady-anacondra", 20, {
const failedBonus = rollBossLoot("lady-anacondra", 80, {
random: () => 0.999,
now: 20_002,
bonusItemChance: 0.5,
@@ -83,4 +83,8 @@ describe("SQL-generated boss loot catalog", () => {
expect(new Set(guaranteedBonus.map((item) => item.instanceId)).size).toBe(2);
expect(guaranteedBonus.every((item) => item.sourceBossKey === "lady-anacondra")).toBe(true);
});
it.each([1, 37, 79])("suppresses equipment and bonus equipment at level %i", (level) => {
expect(rollBossLoot("lady-anacondra", level, { random: () => 0, bonusItemChance: 1 })).toEqual([]);
});
});
+2 -1
View File
@@ -6,6 +6,7 @@ import {
} from "./itemStats";
import type { InventoryItem, ItemQuality } from "./lootTypes";
import { rollRunewakerBossLoot, runewakerBossHasLoot } from "./runewakerLootCatalog";
import { allowedLootDrops } from "./lootPolicy";
export interface LootCatalogItem {
readonly itemId: number;
@@ -153,5 +154,5 @@ export function rollBossLoot(
addWeightedDrop();
}
return drops;
return allowedLootDrops(drops, playerLevel);
}
+9
View File
@@ -0,0 +1,9 @@
import { equipmentSlotForItem } from "./equipment";
import type { InventoryItem } from "./lootTypes";
/** Heirlooms cover leveling gear. Keep authored non-equipment rewards at every level. */
export function allowedLootDrops(drops: readonly InventoryItem[], playerLevel: number): readonly InventoryItem[] {
return Number.isFinite(playerLevel) && playerLevel >= 80
? drops
: drops.filter((item) => equipmentSlotForItem(item) === null);
}
+6 -5
View File
@@ -14,7 +14,7 @@ describe("Manastorm corpse loot", () => {
useManastormStore.getState().resetRun();
});
it("guarantees Kresh's normal item but waits for an explicit reward claim", () => {
it("guarantees Kresh's Normal card but waits for an explicit reward claim", () => {
const kresh = MANASTORM_ENCOUNTERS.find((encounter) => encounter.id === "kresh")!;
useGameStore.getState().activateDungeon(kresh.dungeonId, undefined, {
gameMode: "manastorm",
@@ -34,13 +34,14 @@ describe("Manastorm corpse loot", () => {
useCombatStore.getState().damageMob(kresh.bossRuntimeId, 1, 10_000);
const corpse = useCombatStore.getState().mobs[kresh.bossRuntimeId];
expect(corpse.pendingLoot).toHaveLength(1);
expect(corpse.pendingLoot[0]?.sourceBossKey).toBe("kresh");
expect(corpse.pendingLoot).toEqual([]);
expect(corpse.bossCardDrop?.rarities).toContain("normal");
expect(useCombatStore.getState().inventory).toEqual([]);
expect(useCombatStore.getState().mobs[kresh.bossRuntimeId]?.looted).toBe(false);
expect(lootCurrentManastormBoss(10_100)).toBe(true);
expect(useCombatStore.getState().inventory).toEqual(corpse.pendingLoot);
expect(useCombatStore.getState().mobs[kresh.bossRuntimeId]?.looted).toBe(true);
expect(useCombatStore.getState().bossCards.counts["wow:kresh"]?.normal).toBe(1);
expect(useCombatStore.getState().bossLootRewards[0]).toMatchObject({
bossId: kresh.bossRuntimeId,
bossName: kresh.bossName,
@@ -52,7 +53,7 @@ describe("Manastorm corpse loot", () => {
it("opens a cache into concrete loot scaled to the character level", () => {
useCombatStore.getState().initializeCharacter({
classId: "priest",
level: 37,
level: 80,
xp: 0,
inventory: [],
});
@@ -77,7 +78,7 @@ describe("Manastorm corpse loot", () => {
expect(useManastormStore.getState().rewardCache).not.toContainEqual(cache);
expect(useCombatStore.getState().inventory).toEqual([
expect.objectContaining({
itemLevel: 37,
itemLevel: 85,
acquiredAt: 12_345,
}),
]);
+2 -2
View File
@@ -984,7 +984,7 @@ function executePartyAbility(
} else if (effect.kind === "execute") {
for (const hostileTargetId of hostileTargets) {
const target = useCombatStore.getState().mobs[hostileTargetId];
if (target && target.health / Math.max(1, target.maxHealth) <= 0.2) {
if (target && !target.boss && target.health / Math.max(1, target.maxHealth) <= 0.2) {
effectiveAmount += combat.damageMob(
hostileTargetId,
Math.max(target.health, partyAbilityAmount(runtimeMember, ability, effect)),
@@ -1078,7 +1078,7 @@ function executePartyAbility(
resourcePools,
resource: resource === runtimeMember.resourceType ? resourcePools[resource] ?? runtimeMember.resource : runtimeMember.resource,
};
} else if (effect.kind === "trigger-spell" && depth < 2) {
} else if (effect.kind === "trigger-spell" && !effect.expanded && depth < 2) {
const triggered = abilitiesForClass(member.classId).find((candidate) => candidate.dbcSpellId === effect.spellId)
?? triggeredAbilityBySpellId(effect.spellId);
if (triggered && triggered.id !== ability.id) {
+1
View File
@@ -53,6 +53,7 @@ export interface PartyMember {
readonly gender: GenderId;
readonly appearance: CharacterAppearance;
readonly classId: ClassId;
readonly secondaryClassId?: ClassId | null;
readonly specialization: string;
readonly specializationId: string | null;
readonly talentTreeId: string;
+2 -1
View File
@@ -1,4 +1,5 @@
import generatedCatalog from "./generated/runewakerLootCatalog.json";
import { allowedLootDrops } from "./lootPolicy";
import { EMPTY_ITEM_STATS } from "./itemStats";
import type { InventoryItem } from "./lootTypes";
@@ -142,5 +143,5 @@ export function rollRunewakerBossLoot(
const item = rollSourceSlot(boss, bonusRoll, playerLevel, levelDelta, acquiredAt, random);
if (item) drops.push(item);
}
return drops;
return allowedLootDrops(drops, playerLevel);
}
+6 -1
View File
@@ -4,11 +4,12 @@ import { DEFAULT_DUNGEON_ID, requireDungeonDefinition, type DungeonId } from "./
import type { Vector3Tuple, WorldSpawn } from "./dungeonTypes";
import type { ActionBindingLayer } from "./actionBindings";
import type { GmReviewTarget } from "./gmContentReview";
import { validBossDifficulty } from "./dungeonDifficulty";
export type AssetStatus = "checking" | "loading" | "ready" | "proxy" | "error";
export type InputMode = "keyboard" | "gamepad";
export type GameMode = "dungeon" | "manastorm";
export type GameOverlay = "pause" | "report-issue" | "party" | "inventory" | "map" | "boss-guide" | "spellbook" | "talents" | "bindings" | "options" | "ui-layout" | "keybinds" | "gm" | "dungeon-results" | null;
export type GameOverlay = "pause" | "report-issue" | "party" | "inventory" | "boss-cards" | "map" | "boss-guide" | "spellbook" | "talents" | "bindings" | "options" | "ui-layout" | "keybinds" | "gm" | "dungeon-results" | null;
interface PlayerSnapshot {
position: Vector3Tuple;
@@ -20,6 +21,7 @@ interface PlayerSnapshot {
export interface GameState {
activeDungeonId: DungeonId;
activeDifficultyId: string;
activeBossDifficulty: number;
gameMode: GameMode;
gmTestMode: boolean;
activeGmReviewTarget: GmReviewTarget | null;
@@ -54,6 +56,7 @@ export interface GameState {
readonly spawn?: WorldSpawn;
readonly gmTestMode?: boolean;
readonly gmReviewTarget?: GmReviewTarget | null;
readonly bossDifficulty?: number;
},
) => void;
openOverlay: (overlay: Exclude<GameOverlay, null>) => void;
@@ -82,6 +85,7 @@ const entrance = initialDungeon.entrance;
export const useGameStore = create<GameState>((set) => ({
activeDungeonId: DEFAULT_DUNGEON_ID,
activeDifficultyId: initialDungeon.defaultDifficultyId,
activeBossDifficulty: 1,
gameMode: "dungeon",
gmTestMode: false,
activeGmReviewTarget: null,
@@ -118,6 +122,7 @@ export const useGameStore = create<GameState>((set) => ({
return {
activeDungeonId,
activeDifficultyId,
activeBossDifficulty: validBossDifficulty(options?.bossDifficulty) ? options.bossDifficulty : 1,
gameMode: options?.gameMode ?? "dungeon",
gmTestMode: options?.gmTestMode ?? false,
activeGmReviewTarget: options?.gmReviewTarget ?? null,
+8
View File
@@ -66,4 +66,12 @@ describe("talent runtime modifiers", () => {
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);
});
});
+3
View File
@@ -6,6 +6,7 @@ import {
export type TalentModifierKind =
| "damage-percent"
| "critical-damage-percent"
| "healing-percent"
| "damage-taken-percent"
| "max-health-percent"
@@ -70,6 +71,8 @@ export function parseTalentModifiers(description: string): readonly ParsedModifi
if (/cooldown/.test(lower)) add({ kind: "cooldown-percent", amount, unit: "percent", scope });
if (/damage (?:done )?to you|damage you (?:take|suffer)|damage taken/.test(lower)) {
add({ kind: "damage-taken-percent", amount, unit: "percent", scope });
} else if (/\bcritical damage\b/.test(lower)) {
add({ kind: "critical-damage-percent", amount, unit: "percent", scope });
} else if (/\bdamage\b/.test(lower)) {
add({ kind: "damage-percent", amount, unit: "percent", scope });
}
+84
View File
@@ -0,0 +1,84 @@
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
import { DUNGEON_DEFINITIONS, requireDungeonDefinition } from "./dungeonRegistry";
import { wowDungeonMapFor, wowMapContains, wowMapFloorFor, wowMapHeading, wowMapPoint, wowMapWorldPosition, type WowDungeonMap } from "./wowDungeonMap";
function mapFor(id: string) {
const map = wowDungeonMapFor(requireDungeonDefinition(id));
expect(map, id).not.toBeNull();
return map!;
}
describe("original WoW dungeon map coordinates", () => {
it("maps WoW west/north to the top-left, east/south to the bottom-right", () => {
const map: WowDungeonMap = { mapId: 1, coordinateTransform: "test", runtimeToWow: [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0],
floors: [{ level: 1, name: "Test", bounds: [0, 100, 0, 150], image: "test", checksum: "test" }] };
expect(wowMapPoint(map, map.floors[0], [100, 0, 150])).toEqual([0, 0]);
expect(wowMapPoint(map, map.floors[0], [0, 0, 0])).toEqual([1002, 668]);
expect(wowMapPoint(map, map.floors[0], [50, 99, 75])).toEqual([501, 334]);
expect(wowMapContains(map, map.floors[0], [101, 0, 150])).toBe(false);
});
it("uses authored Wailing Caverns coordinates rather than stretching its world bounds", () => {
const dungeon = requireDungeonDefinition("wailing-caverns"), map = mapFor(dungeon.id);
const source = wowMapWorldPosition(map, dungeon.entrance.footPosition);
expect(source[0]).toBeCloseTo(-dungeon.entrance.footPosition[0], 5);
expect(source[1]).toBeCloseTo(dungeon.entrance.footPosition[2], 5);
expect(wowMapContains(map, wowMapFloorFor(map, dungeon.entrance.footPosition), dungeon.entrance.footPosition)).toBe(true);
});
it("inverts the shifted Deadmines ADT basis", () => {
const dungeon = requireDungeonDefinition("deadmines"), map = mapFor(dungeon.id);
const source = wowMapWorldPosition(map, dungeon.entrance.footPosition);
expect(source[0]).toBeCloseTo(-16.4, 1);
expect(source[1]).toBeCloseTo(-383.07, 1);
expect(source[2]).toBeCloseTo(61.78, 1);
});
it("aligns the event-driven Trial of the Champion arena entrance", () => {
const dungeon = requireDungeonDefinition("trial-of-the-champion"), map = mapFor(dungeon.id);
expect(wowMapWorldPosition(map, dungeon.entrance.footPosition)).toEqual([805.227, 618.038, 412.393]);
expect(wowMapContains(map, wowMapFloorFor(map, dungeon.entrance.footPosition), dungeon.entrance.footPosition)).toBe(true);
});
it.each(["hellfire-ramparts", "razorfen-kraul", "scholomance", "dire-maul"])("aligns the rotated %s environment", (id) => {
const dungeon = requireDungeonDefinition(id), map = mapFor(id);
const floor = wowMapFloorFor(map, dungeon.entrance.footPosition);
expect(wowMapContains(map, floor, dungeon.entrance.footPosition)).toBe(true);
const heading = wowMapHeading(map, floor, dungeon.entrance.footPosition, 0.7);
expect(Math.hypot(...heading)).toBeCloseTo(23, 5);
});
it("allows explicitly selecting the other Deadmines floor", () => {
const dungeon = requireDungeonDefinition("deadmines"), map = mapFor(dungeon.id);
expect(wowMapFloorFor(map, dungeon.entrance.footPosition, 2).level).toBe(2);
expect(wowMapFloorFor(map, dungeon.entrance.footPosition, 999).level).not.toBe(999);
});
it("falls back for non-WoW maps and replaced environments", () => {
expect(wowDungeonMapFor(requireDungeonDefinition("forsaken-abbey"))).toBeNull();
const dungeon = requireDungeonDefinition("wailing-caverns");
expect(wowDungeonMapFor({ ...dungeon, provenance: { ...dungeon.provenance, coordinateTransform: "changed" } })).toBeNull();
});
it("packages complete, checksummed PNG floors with each available map", () => {
let count = 0;
for (const dungeon of DUNGEON_DEFINITIONS) {
const map = wowDungeonMapFor(dungeon);
if (!map) continue;
count += 1;
expect(map.runtimeToWow).toHaveLength(12);
expect(map.runtimeToWow.every(Number.isFinite)).toBe(true);
expect(new Set(map.floors.map((floor) => floor.level)).size).toBe(map.floors.length);
for (const floor of map.floors) {
const png = readFileSync(`public${floor.image}`);
expect(png.toString("ascii", 1, 4)).toBe("PNG");
expect([png.readUInt32BE(16), png.readUInt32BE(20)]).toEqual([1002, 668]);
expect(createHash("sha256").update(png).digest("hex")).toBe(floor.checksum);
expect(floor.bounds.every(Number.isFinite)).toBe(true);
}
}
expect(count).toBeGreaterThanOrEqual(50);
});
});
+64
View File
@@ -0,0 +1,64 @@
import catalog from "./generated/wowDungeonMaps.generated.json";
import type { DungeonDefinition, Vector3Tuple } from "./dungeonTypes";
export interface WowMapFloor {
readonly level: number;
readonly name: string;
/** World MinX, MaxX, MinY, MaxY; X points north and Y points west. */
readonly bounds: readonly [number, number, number, number];
readonly image: string;
readonly checksum: string;
}
export interface WowDungeonMap {
readonly mapId: number;
readonly coordinateTransform: string;
readonly visualChecksum?: string;
/** Three row-major affine rows converting package position to WoW XYZ. */
readonly runtimeToWow: readonly number[];
readonly floors: readonly WowMapFloor[];
}
const maps = catalog.dungeons as unknown as Readonly<Record<string, WowDungeonMap>>;
export function wowDungeonMapFor(dungeon: DungeonDefinition): WowDungeonMap | null {
const map = maps[dungeon.id];
// A replacement environment must be reimported, never silently misaligned.
return map?.mapId === dungeon.mapId
&& map.coordinateTransform === dungeon.provenance.coordinateTransform
&& map.visualChecksum === dungeon.assets.visual[0]?.checksum ? map : null;
}
export function wowMapWorldPosition(map: WowDungeonMap, position: Vector3Tuple): Vector3Tuple {
return [0, 1, 2].map((row) => {
const i = row * 4;
return map.runtimeToWow[i] * position[0] + map.runtimeToWow[i + 1] * position[1]
+ map.runtimeToWow[i + 2] * position[2] + map.runtimeToWow[i + 3];
}) as unknown as Vector3Tuple;
}
export function wowMapPoint(map: WowDungeonMap, floor: WowMapFloor, position: Vector3Tuple): readonly [number, number] {
const [x, y] = wowMapWorldPosition(map, position);
const [minX, maxX, minY, maxY] = floor.bounds;
return [(maxY - y) / (maxY - minY) * 1002, (maxX - x) / (maxX - minX) * 668];
}
export function wowMapContains(map: WowDungeonMap, floor: WowMapFloor, position: Vector3Tuple): boolean {
const [x, y] = wowMapPoint(map, floor, position);
return Number.isFinite(x) && Number.isFinite(y) && x >= 0 && x <= 1002 && y >= 0 && y <= 668;
}
/** Smallest containing floor wins; stacked rooms can be selected explicitly in the map panel. */
export function wowMapFloorFor(map: WowDungeonMap, position: Vector3Tuple, level?: number | null): WowMapFloor {
const explicit = map.floors.find((floor) => floor.level === level);
if (explicit) return explicit;
const containing = map.floors.filter((floor) => floor.level !== 0 && wowMapContains(map, floor, position));
const size = (floor: WowMapFloor) => (floor.bounds[1] - floor.bounds[0]) * (floor.bounds[3] - floor.bounds[2]);
return containing.sort((a, b) => size(a) - size(b) || a.level - b.level)[0]
?? map.floors.find((floor) => floor.level === 0) ?? map.floors[0];
}
export function wowMapHeading(map: WowDungeonMap, floor: WowMapFloor, position: Vector3Tuple, yaw: number): readonly [number, number] {
const [x, y] = wowMapPoint(map, floor, position);
const [targetX, targetY] = wowMapPoint(map, floor, [position[0] + Math.sin(yaw), position[1], position[2] + Math.cos(yaw)]);
const length = Math.hypot(targetX - x, targetY - y) || 1;
return [(targetX - x) / length * 23, (targetY - y) / length * 23];
}