Release Healer Man 0.1.21

This commit is contained in:
phenom committed 2026-09-08 10:40:26 -04:00
1 parent 699fc858c9
commit f6f2375145
210 files changed
+976039 -6247

No files matched your search

+35 -5
View File
@@ -27,6 +27,10 @@ import {
normalizeSpecializationId,
specializationById,
} from "../game/specializationCatalog";
import {
normalizeDungeonRunCheckpoint,
type DungeonRunCheckpoint,
} from "../game/dungeonRunCheckpoint";
const DATABASE_KEY = "healer-man.profile-database.v1";
const SESSION_KEY = "healer-man.session.v1";
@@ -56,7 +60,7 @@ interface LocalAccount {
}
interface ProfileDatabase {
version: 4;
version: 5;
accounts: LocalAccount[];
rosters: Record<string, CharacterProfile[]>;
presentationSettingsByOwner: Record<string, CombatPresentationSettings>;
@@ -98,7 +102,7 @@ function browserSessionStorage(): StorageLike | null {
}
function emptyDatabase(): ProfileDatabase {
return { version: 4, accounts: [], rosters: {}, presentationSettingsByOwner: {} };
return { version: 5, accounts: [], rosters: {}, presentationSettingsByOwner: {} };
}
function isCharacterProfile(value: unknown): value is CharacterProfile {
@@ -126,6 +130,7 @@ function normalizeCharacterProfile(value: CharacterProfile): CharacterProfile {
secondaryClassId?: unknown;
actionLoadouts?: unknown;
specializationId?: unknown;
dungeonRunCheckpoint?: unknown;
};
const level = typeof legacy.level === "number" && Number.isFinite(legacy.level)
? Math.max(1, Math.min(80, Math.floor(legacy.level)))
@@ -170,6 +175,7 @@ function normalizeCharacterProfile(value: CharacterProfile): CharacterProfile {
const settings = legacy.settings && typeof legacy.settings === "object" && !Array.isArray(legacy.settings)
? { ...(legacy.settings as Partial<GameplaySettings>) }
: undefined;
const dungeonRunCheckpoint = normalizeDungeonRunCheckpoint(legacy.dungeonRunCheckpoint);
return {
...value,
level,
@@ -183,6 +189,7 @@ function normalizeCharacterProfile(value: CharacterProfile): CharacterProfile {
inventory,
equipment,
manastormProgress,
dungeonRunCheckpoint,
settings,
};
}
@@ -196,7 +203,7 @@ function readDatabase(storage: StorageLike | null = browserLocalStorage()): Prof
rosters?: unknown;
presentationSettingsByOwner?: unknown;
}) | null;
if (!parsed || ![1, 2, 3, 4].includes(parsed.version ?? 0) || !Array.isArray(parsed.accounts) || !parsed.rosters || typeof parsed.rosters !== "object") {
if (!parsed || ![1, 2, 3, 4, 5].includes(parsed.version ?? 0) || !Array.isArray(parsed.accounts) || !parsed.rosters || typeof parsed.rosters !== "object") {
return emptyDatabase();
}
const accounts = parsed.accounts.filter((account): account is LocalAccount => Boolean(
@@ -236,8 +243,8 @@ function readDatabase(storage: StorageLike | null = browserLocalStorage()): Prof
return [ownerId, normalized];
}),
);
const database: ProfileDatabase = { version: 4, accounts, rosters, presentationSettingsByOwner };
if (parsed.version !== 4 || presentationSettingsMigrated) writeDatabase(database, storage);
const database: ProfileDatabase = { version: 5, accounts, rosters, presentationSettingsByOwner };
if (parsed.version !== 5 || presentationSettingsMigrated) writeDatabase(database, storage);
return database;
} catch {
return emptyDatabase();
@@ -762,6 +769,29 @@ export function updateCharacterManastormProgress(
return updated;
}
export function updateCharacterDungeonRunCheckpoint(
ownerId: string,
characterId: string,
checkpoint: DungeonRunCheckpoint | null,
storage: StorageLike | null = browserLocalStorage(),
): CharacterProfile | null {
if (!storage) return null;
const database = readDatabase(storage);
const normalized = checkpoint === null ? null : normalizeDungeonRunCheckpoint(checkpoint);
if (checkpoint !== null && !normalized) return null;
let updated: CharacterProfile | null = null;
database.rosters[ownerId] = (database.rosters[ownerId] ?? []).map((character) => {
if (character.id !== characterId) return character;
updated = normalizeCharacterProfile({
...character,
dungeonRunCheckpoint: normalized,
});
return updated;
});
if (updated) writeDatabase(database, storage);
return updated;
}
export function deleteCharacter(
ownerId: string,
characterId: string,