Update Healer Man server
This commit is contained in:
1 parent
69809f7228
commit
ff20ab8779
101 files changed
+16713
-945
No files matched your search
@@ -9,9 +9,12 @@ import {
|
||||
purgeNamedEnemyControlShoutAuras,
|
||||
} from "./enemyControlImmunityPurge";
|
||||
|
||||
function selectedAbility(spellId: number) {
|
||||
const base = WOW335_ABILITIES_BY_CLASS.warrior.find((ability) => ability.dbcSpellId === spellId);
|
||||
if (!base) throw new Error(`Missing generated Warrior ability ${spellId}`);
|
||||
function selectedAbility(
|
||||
spellId: number,
|
||||
classId: keyof typeof WOW335_ABILITIES_BY_CLASS = "warrior",
|
||||
) {
|
||||
const base = WOW335_ABILITIES_BY_CLASS[classId].find((ability) => ability.dbcSpellId === spellId);
|
||||
if (!base) throw new Error(`Missing generated ${classId} ability ${spellId}`);
|
||||
return abilityAtLevel(base, 80);
|
||||
}
|
||||
|
||||
@@ -40,6 +43,7 @@ describe("source-proven enemy control immunity purge", () => {
|
||||
grantsMechanics: ["fear"],
|
||||
purgesNamedShoutSpellMechanics: ["fear"],
|
||||
usableWhileControlledBy: ["fear"],
|
||||
directCastBypasses: [],
|
||||
});
|
||||
expect(enemyControlAbilityUsableWhileControlled(berserkerRage, "fear")).toBe(true);
|
||||
expect(enemyControlAbilityUsableWhileControlled(berserkerRage, "stun")).toBe(false);
|
||||
@@ -55,11 +59,70 @@ describe("source-proven enemy control immunity purge", () => {
|
||||
grantsMechanics: ["fear", "stun"],
|
||||
purgesNamedShoutSpellMechanics: ["fear"],
|
||||
usableWhileControlledBy: [],
|
||||
directCastBypasses: [],
|
||||
});
|
||||
expect(enemyControlAbilityUsableWhileControlled(bladestorm, "fear")).toBe(false);
|
||||
expect(enemyControlAbilityUsableWhileControlled(bladestorm, "stun")).toBe(false);
|
||||
});
|
||||
|
||||
it("proves Lichborne's exact Charm/Fear/Sleep purge and its separate cast-state flags", () => {
|
||||
const lichborne = selectedAbility(49039, "death-knight");
|
||||
const proof = enemyControlImmunityPurgeProofForAbility(lichborne);
|
||||
|
||||
expect(lichborne).toMatchObject({
|
||||
id: "wow335-death-knight-lichborne",
|
||||
name: "Lichborne",
|
||||
classId: "death-knight",
|
||||
source: "wow335-progression",
|
||||
dbcSpellId: 49039,
|
||||
wowSpellDefense: {
|
||||
sourceProfile: "wow335",
|
||||
damageClass: 0,
|
||||
schoolMask: 32,
|
||||
attributes0: 262144,
|
||||
attributes1: 163872,
|
||||
attributes3: 0,
|
||||
attributes5: 393224,
|
||||
directDamageFromEffects: false,
|
||||
},
|
||||
});
|
||||
expect(lichborne.effects).toHaveLength(3);
|
||||
const expectedEffects = [
|
||||
{ miscValue: 1, sourceBasePoints: 0, sourceDieSides: 1, immunity: undefined },
|
||||
{ miscValue: 5, sourceBasePoints: 0, sourceDieSides: 0, immunity: "fear" },
|
||||
{ miscValue: 10, sourceBasePoints: 0, sourceDieSides: 0, immunity: "sleep" },
|
||||
] as const;
|
||||
lichborne.effects.forEach((effect, index) => {
|
||||
const expected = expectedEffects[index];
|
||||
expect(effect.kind).toBe("apply-aura");
|
||||
if (effect.kind !== "apply-aura") throw new Error("Expected selected Lichborne immunity aura");
|
||||
expect(effect).toMatchObject({
|
||||
sourceEffectType: 6,
|
||||
sourceAuraType: 77,
|
||||
sourceBasePoints: expected.sourceBasePoints,
|
||||
sourceDieSides: expected.sourceDieSides,
|
||||
sourcePointsPerLevel: 0,
|
||||
miscValue: expected.miscValue,
|
||||
recipient: "caster",
|
||||
});
|
||||
if (expected.immunity) expect(effect.aura.controlImmunities).toContain(expected.immunity);
|
||||
expect(effect.aura.id).toBe(`wow335:49039:effect:${index}:aura:77`);
|
||||
});
|
||||
expect(proof).toMatchObject({
|
||||
sourceProfile: "wow335",
|
||||
sourceSpellId: 49039,
|
||||
grantsMechanics: ["charm", "fear", "sleep"],
|
||||
purgesNamedShoutSpellMechanics: ["fear"],
|
||||
usableWhileControlledBy: ["fear", "stun", "confuse"],
|
||||
directCastBypasses: ["fear", "stun", "confuse"],
|
||||
});
|
||||
expect(enemyControlAbilityUsableWhileControlled(lichborne, "fear")).toBe(true);
|
||||
expect(enemyControlAbilityUsableWhileControlled(lichborne, "stun")).toBe(true);
|
||||
expect(enemyControlAbilityUsableWhileControlled(lichborne, "confuse")).toBe(true);
|
||||
expect(enemyControlAbilityUsableWhileControlled(lichborne, "charm")).toBe(false);
|
||||
expect(enemyControlAbilityUsableWhileControlled(lichborne, "sleep")).toBe(false);
|
||||
});
|
||||
|
||||
it("fails closed for a changed profile, missing or changed raw flags, and changed aura scalars", () => {
|
||||
const berserkerRage = selectedAbility(18499);
|
||||
const defense = berserkerRage.wowSpellDefense!;
|
||||
@@ -89,6 +152,35 @@ describe("source-proven enemy control immunity purge", () => {
|
||||
})).toBeUndefined();
|
||||
});
|
||||
|
||||
it("fails closed for Lichborne when its selected WoW profile, full flags, or effect scalars change", () => {
|
||||
const lichborne = selectedAbility(49039, "death-knight");
|
||||
const defense = lichborne.wowSpellDefense!;
|
||||
const fearIndex = lichborne.effects.findIndex((effect) => (
|
||||
effect.kind === "apply-aura" && effect.sourceAuraType === 77 && effect.miscValue === 5
|
||||
));
|
||||
const fearAura = lichborne.effects[fearIndex];
|
||||
if (fearAura.kind !== "apply-aura") throw new Error("Expected selected Lichborne fear immunity aura");
|
||||
|
||||
expect(enemyControlImmunityPurgeProofForAbility({
|
||||
...lichborne,
|
||||
wowSpellDefense: { ...defense, sourceProfile: "ascension" },
|
||||
})).toBeUndefined();
|
||||
expect(enemyControlImmunityPurgeProofForAbility({
|
||||
...lichborne,
|
||||
wowSpellDefense: { ...defense, attributes1: undefined },
|
||||
})).toBeUndefined();
|
||||
expect(enemyControlImmunityPurgeProofForAbility({
|
||||
...lichborne,
|
||||
wowSpellDefense: { ...defense, attributes5: defense.attributes5! ^ 0x00020000 },
|
||||
})).toBeUndefined();
|
||||
expect(enemyControlImmunityPurgeProofForAbility({
|
||||
...lichborne,
|
||||
effects: lichborne.effects.map((effect, index) => index === fearIndex
|
||||
? { ...fearAura, sourceDieSides: 1 }
|
||||
: effect),
|
||||
})).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not infer active purge from Icebound Fortitude's stun-immunity row", () => {
|
||||
const base = WOW335_ABILITIES_BY_CLASS["death-knight"].find((ability) => ability.dbcSpellId === 48792);
|
||||
if (!base) throw new Error("Missing generated Death Knight ability 48792");
|
||||
@@ -128,6 +220,7 @@ describe("source-proven enemy control immunity purge", () => {
|
||||
grantsMechanics: ["fear"],
|
||||
purgesNamedShoutSpellMechanics: ["fear"],
|
||||
usableWhileControlledBy: ["fear"],
|
||||
directCastBypasses: [],
|
||||
} as const;
|
||||
|
||||
expect(purgeNamedEnemyControlShoutAuras([aura], "party-warrior", forged, 0)).toEqual({
|
||||
@@ -155,4 +248,54 @@ describe("source-proven enemy control immunity purge", () => {
|
||||
berserkerRage, "stun", [sourceFear], "party-warrior", 100,
|
||||
)).toBe(false);
|
||||
});
|
||||
|
||||
it("does not let Bladestorm borrow its purge grant as a control cast bypass", () => {
|
||||
const bladestorm = selectedAbility(46924);
|
||||
const sourceFear = activeAura("enemy-control:source-spell-5246", "party-warrior");
|
||||
const sourceChildStun = activeAura("enemy-control:source-spell-20511", "party-warrior");
|
||||
|
||||
expect(enemyControlAbilityCanEscapeAuras(
|
||||
bladestorm, "fear", [sourceFear], "party-warrior", 100,
|
||||
)).toBe(false);
|
||||
expect(enemyControlAbilityCanEscapeAuras(
|
||||
bladestorm, "stun", [sourceChildStun], "party-warrior", 100,
|
||||
)).toBe(false);
|
||||
});
|
||||
|
||||
it("allows Lichborne through sourced or directly supported control and retains unrelated auras", () => {
|
||||
const lichborne = selectedAbility(49039, "death-knight");
|
||||
const proof = enemyControlImmunityPurgeProofForAbility(lichborne);
|
||||
const sourceChildStun = activeAura("enemy-control:source-spell-20511", "party-death-knight");
|
||||
const genericStun = activeAura("enemy-control:another-caster:another-spell:stun", "party-death-knight");
|
||||
const genericConfuse = activeAura("enemy-control:another-caster:another-spell:confuse", "party-death-knight");
|
||||
const genericFear = activeAura("enemy-control:another-caster:another-spell:fear", "party-death-knight");
|
||||
|
||||
expect(enemyControlAbilityCanEscapeAuras(
|
||||
lichborne, "stun", [sourceChildStun], "party-death-knight", 100,
|
||||
)).toBe(true);
|
||||
expect(enemyControlAbilityCanEscapeAuras(
|
||||
lichborne, "stun", [genericStun], "party-death-knight", 100,
|
||||
)).toBe(true);
|
||||
expect(enemyControlAbilityCanEscapeAuras(
|
||||
lichborne, "confuse", [genericConfuse], "party-death-knight", 100,
|
||||
)).toBe(true);
|
||||
expect(enemyControlAbilityCanEscapeAuras(
|
||||
lichborne, "fear", [genericFear], "party-death-knight", 100,
|
||||
)).toBe(true);
|
||||
expect(enemyControlAbilityCanEscapeAuras(
|
||||
selectedAbility(18499), "fear", [genericFear], "party-death-knight", 100,
|
||||
)).toBe(false);
|
||||
const mixedFear = purgeNamedEnemyControlShoutAuras(
|
||||
[genericFear, activeAura("enemy-control:source-spell-19134", "party-death-knight")],
|
||||
"party-death-knight", proof, 100,
|
||||
);
|
||||
expect(mixedFear.removed.map((aura) => aura.definition.id)).toEqual(["enemy-control:source-spell-19134"]);
|
||||
expect(mixedFear.auras).toEqual([genericFear]);
|
||||
expect(purgeNamedEnemyControlShoutAuras(
|
||||
[genericStun, genericConfuse], "party-death-knight", proof, 100,
|
||||
)).toEqual({
|
||||
auras: [genericStun, genericConfuse],
|
||||
removed: [],
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user