Files
healer-man/src/game/lootCatalog.test.ts
T
2026-09-13 13:21:27 -04:00

91 lines
3.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { WAILING_CAVERNS_ENTITIES } from "./mobPopulation";
import {
LOOT_CATALOG,
bossHasLoot,
bossLootTable,
rollBossLoot,
scaledLootItemLevel,
} from "./lootCatalog";
describe("SQL-generated boss loot catalog", () => {
it("covers every authored Wailing Caverns boss with queryable item templates", () => {
const bossKeys = Object.values(WAILING_CAVERNS_ENTITIES)
.filter((entity) => entity.kind === "boss")
.map((entity) => entity.id)
.sort();
const catalogKeys = LOOT_CATALOG.bosses
.filter((boss) => boss.dungeonId === "wailing-caverns")
.map((boss) => boss.bossKey)
.sort();
expect(catalogKeys).toEqual(bossKeys);
expect(LOOT_CATALOG.bosses).toHaveLength(9);
expect(LOOT_CATALOG.bosses.flatMap((boss) => boss.items)).toHaveLength(23);
for (const boss of LOOT_CATALOG.bosses) {
expect(boss.items.length).toBeGreaterThan(0);
expect(boss.items.every((item) => item.weight > 0)).toBe(true);
expect(bossHasLoot(boss.bossKey)).toBe(true);
}
});
it("rolls recognizable boss items while setting item level from the player", () => {
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: 85,
sourceItemLevel: 23,
sourceBossKey: "lady-anacondra",
acquiredAt: 12_345,
});
expect(last[0]).toMatchObject({
itemId: 10412,
name: "Belt of the Fang",
itemLevel: 85,
sourceItemLevel: 21,
});
expect(first[0].stats.agility).toBeGreaterThan(0);
expect(first[0].stats.strength).toBe(0);
expect(first[0].stats.armor).toBeGreaterThan(0);
expect(bossLootTable("lady-anacondra")?.lootTableId).toBe("wc-lady-anacondra");
});
it("clamps generated item levels to the supported character range", () => {
expect(scaledLootItemLevel(-10)).toBe(1);
expect(scaledLootItemLevel(42.9)).toBe(42);
expect(scaledLootItemLevel(900)).toBe(85);
expect(rollBossLoot("not-a-boss", 20)).toEqual([]);
});
it("adds at most one bonus weighted item without changing normal rolls", () => {
const normal = rollBossLoot("lady-anacondra", 80, {
random: () => 0,
now: 20_000,
});
const guaranteedBonus = rollBossLoot("lady-anacondra", 80, {
random: () => 0,
now: 20_001,
bonusItemChance: 1,
});
const failedBonus = rollBossLoot("lady-anacondra", 80, {
random: () => 0.999,
now: 20_002,
bonusItemChance: 0.5,
});
expect(normal).toHaveLength(1);
expect(guaranteedBonus).toHaveLength(2);
expect(failedBonus).toHaveLength(1);
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([]);
});
});