Release Healer Man 0.1.43

This commit is contained in:
phenom committed 2026-09-14 13:20:20 -04:00
1 parent c7e8163790
commit ccc01396cd
86 files changed
+2951 -198

No files matched your search

+18 -2
View File
@@ -6,7 +6,7 @@ export const UI_DEVICES: readonly UiDevice[] = ["mobile", "pc"];
export const BAR_COLUMNS = [1, 2, 3, 4, 6, 12] as const;
export const HUD_ELEMENTS = {
party: "Party frames", summons: "Pet and summon frames", minimap: "Minimap",
player: "Player status", timeline: "Encounter timeline", target: "Enemy target",
player: "Buffs and debuffs", timeline: "Encounter timeline", target: "Enemy target",
friendly: "Friendly target", threat: "Threat meter", dps: "DPS meter", cast: "Cast bar",
hints: "Control hints", actions: "Controller action bar", experience: "Experience bar",
reticle: "Crosshair", loot: "Loot notifications", interaction: "Interaction prompt",
@@ -16,8 +16,10 @@ export const HUD_ELEMENTS = {
"bar-4": "Action bar 4", "bar-5": "Action bar 5",
} as const;
export type HudElementId = keyof typeof HUD_ELEMENTS;
export type HudScreen = "auto" | "top" | "bottom" | "hidden";
export interface HudElementLayout {
visible: boolean;
screen?: HudScreen;
position: NormalizedHudPosition | null;
width: number | null;
}
@@ -87,6 +89,7 @@ export function normalizeUiLayout(value: unknown): UiLayout {
const element = record(elements[id]);
defaults.elements[id] = {
visible: element.visible !== false,
...(["auto", "top", "bottom", "hidden"].includes(String(element.screen)) ? { screen: element.screen as HudScreen } : {}),
position: element.position ? normalizeHudPosition(element.position, { x: 0.5, y: 0.5 }) : null,
width: typeof element.width === "number" ? bounded(element.width, 200, 20, 2000) : null,
};
@@ -114,8 +117,21 @@ export function normalizeUiLayout(value: unknown): UiLayout {
}
export function resolveDpsMeterDisplay(layout: UiLayout, dualScreen: boolean): "main" | "companion" {
const screen = layout.elements.dps.screen;
if (screen === "top" || screen === "bottom") return !dualScreen || screen === "top" ? "main" : "companion";
return layout.dpsMeterDisplay === "auto" ? dualScreen ? "companion" : "main" : layout.dpsMeterDisplay;
}
/** One owner per widget; single-display layouts keep all visible widgets available. */
export function resolveHudScreen(id: HudElementId, layout: UiLayout, dualScreen: boolean): "top" | "bottom" | "hidden" {
const element = layout.elements[id];
if (!element.visible || element.screen === "hidden") return "hidden";
if (!dualScreen) return "top";
if (element.screen === "top" || element.screen === "bottom") return element.screen;
if (id === "dps") return resolveDpsMeterDisplay(layout, true) === "main" ? "top" : "bottom";
if (["player", "actions", "cast", "experience", "bar-1", "bar-2", "bar-3", "bar-4", "bar-5"].includes(id)) return "bottom";
if (id === "hints") return "hidden";
return "top";
}
export function normalizeUiPreferences(value: unknown): UiPreferences {
const source = record(value);
const current = record(source.current);
@@ -174,7 +190,7 @@ export function importUiPreferences(text: string): UiPreferences {
if (id === "dps" && record(layout.elements)[id] === undefined) continue;
const element = record(record(layout.elements)[id]);
const position = record(element.position);
if (typeof element.visible !== "boolean" || (element.position !== null && [position.x, position.y].some((v) => typeof v !== "number" || !Number.isFinite(v) || v < 0 || v > 1))
if ((element.screen !== undefined && !["auto", "top", "bottom", "hidden"].includes(String(element.screen))) || typeof element.visible !== "boolean" || (element.position !== null && [position.x, position.y].some((v) => typeof v !== "number" || !Number.isFinite(v) || v < 0 || v > 1))
|| (element.width !== null && (typeof element.width !== "number" || !Number.isFinite(element.width) || element.width < 20 || element.width > 2000))) throw new Error("Invalid HUD position or visibility.");
}
const keys = new Set<string>();