Update Healer Man server
This commit is contained in:
1 parent
6114a2295f
commit
69809f7228
593 files changed
+903643
-40774
No files matched your search
@@ -0,0 +1,104 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
enemyNpcSourceSpellBlockMetadata,
|
||||
SPELL_ATTR0_CU_DIRECT_DAMAGE,
|
||||
SPELL_ATTR3_ALWAYS_HIT,
|
||||
SPELL_DAMAGE_CLASS_MELEE,
|
||||
SPELL_SCHOOL_MASK_NORMAL,
|
||||
} from "./enemyBlocking";
|
||||
import {
|
||||
enemyUtilityEffectsAfterBlock,
|
||||
enemyUtilitySpellBlockDisposition,
|
||||
enemyUtilitySpellBlockSourceContract,
|
||||
} from "./enemyUtilitySpellBlocking";
|
||||
|
||||
const sourceSpell = enemyNpcSourceSpellBlockMetadata(72, "wow335")!;
|
||||
const utilityEffects = [
|
||||
{ kind: "interrupt", lockoutMs: 6_000 },
|
||||
{ kind: "apply-aura", spellId: 29_703 },
|
||||
{ kind: "status", status: "silence", durationMs: 6_000 },
|
||||
] as const;
|
||||
|
||||
const baseInput = {
|
||||
spellId: 72,
|
||||
sourceProfile: "wow335" as const,
|
||||
spellDefense: sourceSpell,
|
||||
casterKind: "player" as const,
|
||||
targetKind: "ordinary-npc" as const,
|
||||
};
|
||||
|
||||
describe("ordinary NPC utility spell full-hit blocking", () => {
|
||||
it("publishes the exact Shield Bash 72 signature and block-relevant metadata", () => {
|
||||
expect(enemyUtilitySpellBlockSourceContract(72, "wow335")).toMatchObject({
|
||||
spellId: 72,
|
||||
sourceProfile: "wow335",
|
||||
spellDefense: {
|
||||
damageClass: SPELL_DAMAGE_CLASS_MELEE,
|
||||
schoolMask: SPELL_SCHOOL_MASK_NORMAL,
|
||||
attributes0: 327696,
|
||||
attributes3: 8,
|
||||
directDamageFromEffects: false,
|
||||
sourceProfile: "wow335",
|
||||
customAttributeEvidence: { knownMask: 131_328, value: 0 },
|
||||
},
|
||||
dbcEffects: [
|
||||
{ index: 0, effectType: 68, mechanic: 26, targetA: 6, triggerSpellId: 0 },
|
||||
{ index: 1, effectType: 64, mechanic: 0, targetA: 6, triggerSpellId: 29_703 },
|
||||
],
|
||||
});
|
||||
expect(enemyUtilitySpellBlockSourceContract(72, "ascension")).toBeUndefined();
|
||||
expect(enemyUtilitySpellBlockSourceContract(1_671, "wow335")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("suppresses every utility effect after a resolved full block", () => {
|
||||
const disposition = enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block" });
|
||||
const effectsToApply = enemyUtilityEffectsAfterBlock(utilityEffects, disposition);
|
||||
const sideEffects: string[] = [];
|
||||
for (const effect of effectsToApply) sideEffects.push(effect.kind);
|
||||
|
||||
expect(disposition).toBe("blocked");
|
||||
expect(effectsToApply).toEqual([]);
|
||||
expect(sideEffects).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps landed utility effects and suppresses ordinary unsuccessful hit-table outcomes", () => {
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "hit" })).toBe("apply");
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "crit" })).toBe("apply");
|
||||
for (const outcome of ["miss", "dodge", "parry", "resist"] as const) {
|
||||
const disposition = enemyUtilitySpellBlockDisposition({ ...baseInput, outcome });
|
||||
expect(disposition).toBe("avoided");
|
||||
expect(enemyUtilityEffectsAfterBlock(utilityEffects, disposition)).toEqual([]);
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves the existing fallback for missing source, rank, profile, or signature", () => {
|
||||
const missingProof = { ...sourceSpell };
|
||||
delete (missingProof as { customAttributeEvidence?: unknown }).customAttributeEvidence;
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", spellDefense: missingProof })).toBe("fallback");
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", spellId: undefined })).toBe("fallback");
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", spellId: 1_671 })).toBe("fallback");
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", sourceProfile: "ascension" })).toBe("fallback");
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: undefined })).toBe("fallback");
|
||||
expect(enemyUtilityEffectsAfterBlock(utilityEffects, "fallback")).toBe(utilityEffects);
|
||||
});
|
||||
|
||||
it("rejects signatures whose source hit-table attributes disable or redirect the block phase", () => {
|
||||
for (const spellDefense of [
|
||||
{ ...sourceSpell, attributes3: sourceSpell.attributes3 | SPELL_ATTR3_ALWAYS_HIT },
|
||||
{ ...sourceSpell, customAttributes: SPELL_ATTR0_CU_DIRECT_DAMAGE },
|
||||
{ ...sourceSpell, damageClass: 1 },
|
||||
{ ...sourceSpell, schoolMask: 0x10 },
|
||||
{ ...sourceSpell, attributes3: 0 },
|
||||
]) {
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", spellDefense })).toBe("fallback");
|
||||
}
|
||||
});
|
||||
|
||||
it("excludes NPC outbound, native, character, summon, and unknown target paths", () => {
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", casterKind: "enemy-npc" })).toBe("fallback");
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", casterKind: "rom-native" })).toBe("fallback");
|
||||
for (const targetKind of ["character", "native-rom", "summon", "unknown"] as const) {
|
||||
expect(enemyUtilitySpellBlockDisposition({ ...baseInput, outcome: "block", targetKind })).toBe("fallback");
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user