Release v0.1.4 2026-07-12

This commit is contained in:
Warren H
2026-07-12 13:49:46 -04:00
parent b48b3a4f8f
commit bef71d391a
803 changed files with 3800 additions and 358322 deletions
+36 -24
View File
@@ -1,15 +1,9 @@
import type { BossCollection, GameModeId, GameSettings, HunterSave, SaveSlotId } from "./types";
import { BOSS_DEFINITIONS, BOSS_ORDER } from "../game/bossCatalog";
import type { BossGroupCollection, GameModeId, GameSettings, HunterSave, SaveSlotId } from "./types";
import { AVAILABLE_BOSS_IDS, BOSS_DEFINITIONS, BOSS_GROUPS } from "../game/bossCatalog";
import { createClassInventory } from "../game/healers";
import type { BossId } from "../game/types";
import { createDefaultGearProgress } from "../game/progression/gear";
import {
BOSS_DROP_TABLES,
createEmptyCollectionLog,
type CollectionLog,
type LootRarity,
type MaterialStack,
} from "../game/progression/loot";
import { BOSS_PET_DROPS, GROUP_DROP_TABLES, createEmptyCollectionLog, type CollectionLog, type LootRarity, type MaterialStack } from "../game/progression/loot";
export const DEFAULT_SETTINGS: GameSettings = {
masterVolume: 80,
@@ -18,7 +12,7 @@ export const DEFAULT_SETTINGS: GameSettings = {
largeText: false,
};
const RARITY_LABELS: Record<LootRarity, BossCollection["drops"][number]["rarity"]> = {
const RARITY_LABELS: Record<LootRarity, BossGroupCollection["drops"][number]["rarity"]> = {
common: "Common",
uncommon: "Uncommon",
rare: "Rare",
@@ -26,31 +20,49 @@ const RARITY_LABELS: Record<LootRarity, BossCollection["drops"][number]["rarity"
legendary: "Legendary",
};
export function buildCollections(collectionLog: CollectionLog, bossKills: Record<string, number>): BossCollection[] {
return BOSS_ORDER.map((bossId) => {
const table = BOSS_DROP_TABLES[bossId];
export function buildCollections(collectionLog: CollectionLog, bossKills: Record<string, number>): BossGroupCollection[] {
return BOSS_GROUPS.map((group) => {
const table = GROUP_DROP_TABLES[group.id];
const bosses = group.bossIds.map((bossId) => {
const pet = BOSS_PET_DROPS[bossId];
return {
bossId,
bossName: BOSS_DEFINITIONS[bossId].name,
kills: bossKills[bossId] ?? 0,
pet: {
id: pet.id,
name: pet.name,
icon: pet.glyph,
rarity: RARITY_LABELS[pet.rarity],
count: collectionLog.petsFound[pet.id] ?? 0,
chance: pet.chanceLabel,
kind: pet.kind,
},
};
});
return {
bossId,
bossName: BOSS_DEFINITIONS[bossId].name,
defeated: (bossKills[bossId] ?? 0) > 0,
groupId: group.id,
groupLetter: group.letter,
groupName: group.name,
coreMechanic: group.coreMechanic,
defeated: bosses.some((boss) => boss.kills > 0),
drops: table.entries.map((drop) => ({
id: drop.id,
name: drop.name,
icon: drop.glyph,
rarity: RARITY_LABELS[drop.rarity],
count: drop.kind === "coin"
? collectionLog.dropsFound[drop.id] ?? 0
: collectionLog.petsFound[drop.id] ?? 0,
count: collectionLog.dropsFound[drop.id] ?? 0,
chance: drop.chanceLabel,
itemLevel: drop.kind === "coin" ? drop.itemLevel : undefined,
itemLevel: drop.itemLevel,
kind: drop.kind,
})),
bosses,
};
});
}
export const DEFAULT_COLLECTION_LOG: CollectionLog = createEmptyCollectionLog();
export const DEFAULT_COLLECTIONS: BossCollection[] = buildCollections(DEFAULT_COLLECTION_LOG, {});
export const DEFAULT_COLLECTIONS: BossGroupCollection[] = buildCollections(DEFAULT_COLLECTION_LOG, {});
export const MODE_COPY: Record<GameModeId, { eyebrow: string; title: string; description: string; detail: string; status: string }> = {
"roguelike-pve": {
@@ -64,7 +76,7 @@ export const MODE_COPY: Record<GameModeId, { eyebrow: string; title: string; des
eyebrow: "14 hunters · chosen encounter",
title: "Dungeons",
description: "Choose a guardian, review its mechanics, and bring a prepared healing loadout into a focused encounter.",
detail: "Ten prototype guardians available",
detail: `${AVAILABLE_BOSS_IDS.length} animated guardians available`,
status: "Playable now",
},
"roguelike-pvp": {
@@ -84,7 +96,7 @@ export const MODE_COPY: Record<GameModeId, { eyebrow: string; title: string; des
};
export function selectRandomBoss(random: () => number = Math.random): BossId {
return BOSS_ORDER[Math.floor(random() * BOSS_ORDER.length)] ?? BOSS_ORDER[0];
return AVAILABLE_BOSS_IDS[Math.floor(random() * AVAILABLE_BOSS_IDS.length)] ?? AVAILABLE_BOSS_IDS[0];
}
export const MAX_HUNTER_NAME_LENGTH = 20;
@@ -101,7 +113,7 @@ export function createHunterSave(slotId: SaveSlotId, now: string, hunterName: st
const normalizedName = normalizeHunterName(hunterName);
if (!normalizedName) throw new Error("Hunter name is required.");
return {
schemaVersion: 4,
schemaVersion: 5,
slotId,
hunterName: normalizedName,
activeClassId: "priest",