Update Healer Man server
This commit is contained in:
1 parent
4c768fbec6
commit
b16821e92e
330 files changed
+35406
-1760
No files matched your search
@@ -0,0 +1,110 @@
|
||||
import type { TalentModifier } from "./talentModifiers";
|
||||
import { WOW335_TALENT_NODES } from "./wow335Talents.generated";
|
||||
|
||||
export const WOW335_DRUID_MASTER_SHAPESHIFTER_TALENT_ID = "talent-1915";
|
||||
|
||||
export type Wow335DruidShapeshiftForm = "bear" | "cat" | "moonkin" | "tree-of-life";
|
||||
|
||||
const masterShapeshifterTalent = WOW335_TALENT_NODES.find(
|
||||
(talent) => talent.id === WOW335_DRUID_MASTER_SHAPESHIFTER_TALENT_ID,
|
||||
) ?? (() => {
|
||||
throw new Error(`Generated Druid talent ${WOW335_DRUID_MASTER_SHAPESHIFTER_TALENT_ID} is missing`);
|
||||
})();
|
||||
|
||||
function normalizedRank(rank: number): number {
|
||||
return Number.isFinite(rank)
|
||||
? Math.max(0, Math.min(masterShapeshifterTalent.rankDescriptions.length, Math.trunc(rank)))
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The generated rank tooltip has a separate bonus for each shapeshift form.
|
||||
* Return only the active form's modifier so the clauses cannot leak globally.
|
||||
*/
|
||||
export function wow335DruidMasterShapeshifterModifiersForForm(
|
||||
rank: number,
|
||||
form: Wow335DruidShapeshiftForm | null,
|
||||
): readonly TalentModifier[] {
|
||||
const normalized = normalizedRank(rank);
|
||||
if (normalized <= 0 || !form) return [];
|
||||
const description = masterShapeshifterTalent.rankDescriptions[normalized - 1] ?? "";
|
||||
const clauses = {
|
||||
bear: {
|
||||
pattern: /Bear Form\s*-\s*Increases physical damage by\s+(\d+(?:\.\d+)?)%/i,
|
||||
kind: "damage-percent" as const,
|
||||
scope: "physical damage",
|
||||
},
|
||||
cat: {
|
||||
pattern: /Cat Form\s*-\s*Increases melee critical strike chance by\s+(\d+(?:\.\d+)?)%/i,
|
||||
kind: "critical-chance-percent" as const,
|
||||
scope: "melee critical strike chance",
|
||||
},
|
||||
moonkin: {
|
||||
pattern: /Moonkin Form\s*-\s*Increases Arcane and Nature damage by\s+(\d+(?:\.\d+)?)%/i,
|
||||
kind: "damage-percent" as const,
|
||||
scope: "Arcane and Nature damage",
|
||||
},
|
||||
"tree-of-life": {
|
||||
pattern: /Tree of Life Form\s*-\s*Increases healing by\s+(\d+(?:\.\d+)?)%/i,
|
||||
kind: "healing-percent" as const,
|
||||
scope: "healing",
|
||||
},
|
||||
} as const;
|
||||
const clause = clauses[form];
|
||||
const amount = Number(description.match(clause.pattern)?.[1] ?? 0);
|
||||
if (!Number.isFinite(amount) || amount <= 0) return [];
|
||||
|
||||
return [{
|
||||
kind: clause.kind,
|
||||
amount,
|
||||
unit: "percent",
|
||||
scope: clause.scope,
|
||||
sourceTalentId: WOW335_DRUID_MASTER_SHAPESHIFTER_TALENT_ID,
|
||||
sourceTalentName: "Master Shapeshifter",
|
||||
rank: normalized,
|
||||
description,
|
||||
}];
|
||||
}
|
||||
|
||||
/** Resolve the stock WoW shapeshift spell IDs used by the active aura runtime. */
|
||||
export function wow335DruidShapeshiftFormForSpellId(spellId: number): Wow335DruidShapeshiftForm | null {
|
||||
switch (spellId) {
|
||||
case 5487: // Bear Form
|
||||
case 9634: // Dire Bear Form
|
||||
return "bear";
|
||||
case 768: // Cat Form
|
||||
return "cat";
|
||||
case 24858: // Moonkin Form
|
||||
return "moonkin";
|
||||
case 33891: // Tree of Life
|
||||
case 65139: // Generated Tree of Life form row
|
||||
return "tree-of-life";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Extract a form from the canonical aura IDs written by generated WoW forms. */
|
||||
export function wow335DruidShapeshiftFormForAuraId(auraId: string): Wow335DruidShapeshiftForm | null {
|
||||
const spellId = auraId.match(/^wow335:(\d+):/)?.[1];
|
||||
return spellId === undefined ? null : wow335DruidShapeshiftFormForSpellId(Number(spellId));
|
||||
}
|
||||
|
||||
/** Find an active generated shapeshift aura on the requested actor. */
|
||||
export function wow335DruidShapeshiftFormForAuras(
|
||||
auras: readonly {
|
||||
readonly definition: { readonly id: string };
|
||||
readonly targetId: string;
|
||||
readonly expiresAt: number | null;
|
||||
}[],
|
||||
actorId: string,
|
||||
now: number,
|
||||
): Wow335DruidShapeshiftForm | null {
|
||||
const matching = auras
|
||||
.filter((aura) => aura.targetId === actorId && (aura.expiresAt === null || aura.expiresAt > now))
|
||||
.map((aura) => wow335DruidShapeshiftFormForAuraId(aura.definition.id))
|
||||
.filter((form): form is Wow335DruidShapeshiftForm => form !== null);
|
||||
// Normally the aura system removes the previous form. Taking the most recent
|
||||
// active form also makes stale imported form auras deterministic.
|
||||
return matching.at(-1) ?? null;
|
||||
}
|
||||
Reference in new issue
Block a user