Release Healer Man 0.1.28
This commit is contained in:
1 parent
ed8b9e3719
commit
8c9809d3e0
23 files changed
+975
-55
No files matched your search
+45
-32
@@ -32,6 +32,9 @@ import { AuraStrip } from "./AuraStrip";
|
||||
import { ManastormStatus } from "./ManastormStatus";
|
||||
import { ThreatMeterWidget } from "./ThreatMeterWidget";
|
||||
import { BossLootWindow } from "./BossLootWindow";
|
||||
import { EditableHudElement } from "./EditableHudElement";
|
||||
import { DesktopActionBars } from "./DesktopActionBars";
|
||||
import { currentUiDevice, useUiLayoutStore } from "../game/uiLayoutStore";
|
||||
import { SummonFrames } from "./SummonFrames";
|
||||
import { useOnlineSessionStore } from "../app/onlineSessionStore";
|
||||
import { onlineAccountIdFromActor, onlinePlayerActorId } from "../game/onlineSessionRuntime";
|
||||
@@ -139,6 +142,8 @@ export function DungeonCompletePrompt({
|
||||
}
|
||||
|
||||
export function Hud() {
|
||||
const ui = useUiLayoutStore();
|
||||
const desktopBars = currentUiDevice() === "pc" && (ui.draft ?? ui.preferences.current.pc).wowBars;
|
||||
const character = useShellStore((state) => state.activeCharacter);
|
||||
const gameMode = useGameStore((state) => state.gameMode);
|
||||
const areaName = useGameStore((state) => state.areaName);
|
||||
@@ -216,10 +221,12 @@ export function Hud() {
|
||||
|
||||
const classColor = classById(classId).color;
|
||||
const resourceTone = resourceProfileForClass(classId).type;
|
||||
const actionItems = useMemo<ActionBarItems>(() => Object.fromEntries(ACTION_CONTROLS.map((control) => {
|
||||
const abilityId = actionBindings[actionBindingId(actionLayer, control)];
|
||||
const catalogAbility = abilityId ? abilities.find((candidate) => candidate.id === abilityId) ?? null : null;
|
||||
if (!catalogAbility) return [control, null];
|
||||
const assignedAbilities = useMemo(() => {
|
||||
const used = new Set(Object.values(actionBindings));
|
||||
if (desktopBars) for (const bar of (ui.draft ?? ui.preferences.current.pc).bars) for (const slot of bar.slots) used.add(slot.abilityId);
|
||||
return abilities.filter((ability) => used.has(ability.id));
|
||||
}, [abilities, actionBindings, desktopBars, ui.draft, ui.preferences]);
|
||||
const abilityItems = useMemo<Record<string, ActionBarItem>>(() => Object.fromEntries(assignedAbilities.map((catalogAbility) => {
|
||||
const learnedTalentRank = catalogAbility.talentEntryId === undefined
|
||||
? undefined
|
||||
: talentRanks[`coa-entry-${catalogAbility.talentEntryId}`] ?? 0;
|
||||
@@ -254,8 +261,11 @@ export function Hud() {
|
||||
lockedUntilLevel: level < ability.unlockLevel ? ability.unlockLevel : undefined,
|
||||
target: ability.target,
|
||||
};
|
||||
return [control, item];
|
||||
})) as ActionBarItems, [abilities, actionBindings, actionLayer, activeCast, auras, classColor, classId, clock, cooldowns, globalCooldownEndsAt, health, level, maxHealth, maxResource, maxResourcePools, resource, resourceName, resourcePools, resourceTone, talentModifiers, talentRanks]);
|
||||
return [catalogAbility.id, item];
|
||||
})), [assignedAbilities, activeCast, auras, classColor, classId, clock, cooldowns, globalCooldownEndsAt, health, level, maxHealth, maxResource, maxResourcePools, resource, resourceName, resourcePools, resourceTone, talentModifiers, talentRanks]);
|
||||
const actionItems = Object.fromEntries(ACTION_CONTROLS.map((control) => [control,
|
||||
abilityItems[actionBindings[actionBindingId(actionLayer, control)] ?? ""] ?? null,
|
||||
])) as ActionBarItems;
|
||||
|
||||
const castBinding = (control: (typeof ACTION_CONTROLS)[number]) => useCombatStore.getState().castActionBinding(
|
||||
useGameStore.getState().actionLayer,
|
||||
@@ -362,17 +372,17 @@ export function Hud() {
|
||||
<div className="hud" style={{ "--game-ui-scale": settings.uiScale } as CSSProperties}>
|
||||
<ManastormStatus />
|
||||
<BossLootWindow />
|
||||
{dungeonComplete && health > 0 ? (
|
||||
<EditableHudElement id="completion">{dungeonComplete && health > 0 ? (
|
||||
<DungeonCompletePrompt dungeonTitle={dungeon.title} onFinish={finishDungeon} />
|
||||
) : null}
|
||||
{feedback?.kind === "loot" ? (
|
||||
) : null}</EditableHudElement>
|
||||
<EditableHudElement id="loot">{feedback?.kind === "loot" ? (
|
||||
<section className="loot-reward" role="status" aria-live="polite">
|
||||
<span aria-hidden="true">◆</span>
|
||||
<p><strong>Loot acquired</strong><small>{feedback.message}</small><em>Press I to inspect and equip</em></p>
|
||||
</section>
|
||||
) : null}
|
||||
<PartyFrames />
|
||||
<SummonFrames now={clock} />
|
||||
) : null}</EditableHudElement>
|
||||
<EditableHudElement id="party"><PartyFrames /></EditableHudElement>
|
||||
<EditableHudElement id="summons"><SummonFrames now={clock} /></EditableHudElement>
|
||||
|
||||
{pendingGroundTarget ? (
|
||||
<section className="ground-target-reticle" role="status" aria-live="polite">
|
||||
@@ -391,19 +401,19 @@ export function Hud() {
|
||||
) : null}
|
||||
|
||||
<div className="hud-top-right">
|
||||
<Minimap
|
||||
<EditableHudElement id="minimap"><Minimap
|
||||
position={playerPosition}
|
||||
yaw={cameraYaw}
|
||||
areaName={stagePresentation.areaName}
|
||||
distanceTravelled={distance}
|
||||
rotationMode={settings.minimapRotation}
|
||||
onOpenMap={toggleMap}
|
||||
/>
|
||||
<PlayerStatusPanel now={clock} />
|
||||
<EncounterTimeline now={clock} />
|
||||
/></EditableHudElement>
|
||||
<EditableHudElement id="player"><PlayerStatusPanel now={clock} /></EditableHudElement>
|
||||
<EditableHudElement id="timeline"><EncounterTimeline now={clock} /></EditableHudElement>
|
||||
</div>
|
||||
|
||||
{target && settings.showTargetFrame && (
|
||||
<EditableHudElement id="target">{target && settings.showTargetFrame && (
|
||||
<section className={`target-frame ${target.boss ? "target-frame--boss" : ""}`} aria-label={`Target ${target.name}`}>
|
||||
<header><strong>{target.name}</strong><span>{target.boss ? "Boss" : `Level ${target.level}`}</span></header>
|
||||
<div className="target-frame__track"><span style={{ width: `${targetPercent}%` }} /></div>
|
||||
@@ -420,18 +430,18 @@ export function Hud() {
|
||||
<AuraStrip targetId={target.id} className="aura-strip--target" />
|
||||
<small>{Math.ceil(target.health)} / {target.maxHealth}</small>
|
||||
</section>
|
||||
)}
|
||||
)}</EditableHudElement>
|
||||
|
||||
{target && settings.showThreatMeter && threatRows.length > 0 && (
|
||||
<EditableHudElement id="threat">{target && settings.showThreatMeter && threatRows.length > 0 && (
|
||||
<ThreatMeterWidget
|
||||
targetName={target.name}
|
||||
rows={threatRows}
|
||||
position={settings.threatMeterPosition}
|
||||
onPositionChange={updateThreatMeterPosition}
|
||||
/>
|
||||
)}
|
||||
)}</EditableHudElement>
|
||||
|
||||
{selectedFriendly && settings.showTargetFrame && (
|
||||
<EditableHudElement id="friendly">{selectedFriendly && settings.showTargetFrame && (
|
||||
<section className="target-frame target-frame--friendly" aria-label={`Friendly target ${selectedFriendly.name}${selectedFriendly.self ? ", self" : ""}`}>
|
||||
<header>
|
||||
<strong>{selectedFriendly.name}</strong>
|
||||
@@ -448,10 +458,10 @@ export function Hud() {
|
||||
/>
|
||||
<small>{Math.ceil(selectedFriendly.health)} / {selectedFriendly.maxHealth}</small>
|
||||
</section>
|
||||
)}
|
||||
)}</EditableHudElement>
|
||||
|
||||
<div className="hud-bottom-stack">
|
||||
{activeCast && castingAbility && (
|
||||
<EditableHudElement id="cast">{activeCast && castingAbility && (
|
||||
<section className={`cast-bar cast-bar--${activeCast.mode}`} aria-label={`${activeCast.mode === "channel" ? "Channeling" : "Casting"} ${castingAbility.name}`}>
|
||||
<header><strong>{castingAbility.name}</strong><span>{castRemaining.toFixed(1)}s</span></header>
|
||||
<div className="cast-bar__track">
|
||||
@@ -459,9 +469,9 @@ export function Hud() {
|
||||
</div>
|
||||
<small>{activeCast.mode === "channel" ? "Channeling" : "Casting"}</small>
|
||||
</section>
|
||||
)}
|
||||
)}</EditableHudElement>
|
||||
|
||||
{!activeCast && (
|
||||
<EditableHudElement id="hints">{!activeCast && (
|
||||
<div className={`control-hint ${hasMoved && cameraLookActive ? "control-hint--settled" : ""}`}>
|
||||
{inputMode === "gamepad"
|
||||
? "Left stick move | L1 / L2 layers | Face / R1 / R2 / D-pad abilities | R3 target | Start pause"
|
||||
@@ -469,21 +479,24 @@ export function Hud() {
|
||||
? "Release right mouse for cursor | WASD move | Arrow keys look | 1-8 abilities | Shift / Alt layers"
|
||||
: "Right mouse / Arrow keys look | Click party frames to target | WASD move | Tab enemy"}
|
||||
</div>
|
||||
)}
|
||||
)}</EditableHudElement>
|
||||
|
||||
<ActionBar
|
||||
{!desktopBars && <EditableHudElement id="actions"><ActionBar
|
||||
items={actionItems}
|
||||
activeLayer={actionLayer}
|
||||
onActivate={castBinding}
|
||||
inputMode={inputMode}
|
||||
feedback={settings.showFloatingCombatText ? feedback?.message ?? null : null}
|
||||
/>
|
||||
/></EditableHudElement>}
|
||||
</div>
|
||||
<ExperienceBar level={level} current={xp} required={xpToNext} />
|
||||
<DesktopActionBars items={abilityItems} />
|
||||
<EditableHudElement id="feedback">{desktopBars && settings.showFloatingCombatText && feedback?.message
|
||||
? <div className="desktop-action-feedback" role="status">{feedback.message}</div> : null}</EditableHudElement>
|
||||
<EditableHudElement id="experience"><ExperienceBar level={level} current={xp} required={xpToNext} /></EditableHudElement>
|
||||
|
||||
{cameraLookActive && <span className="reticle" aria-hidden="true" />}
|
||||
<EditableHudElement id="reticle">{cameraLookActive && <span className="reticle" aria-hidden="true" />}</EditableHudElement>
|
||||
|
||||
{assetStatus === "proxy" && (
|
||||
<EditableHudElement id="assets">{assetStatus === "proxy" && (
|
||||
<div className="asset-notice" role="status">
|
||||
<strong>Cave proxy active</strong>
|
||||
<span>{assetMessage ?? `Add ${[
|
||||
@@ -491,7 +504,7 @@ export function Hud() {
|
||||
...dungeon.assets.collision,
|
||||
].map((asset) => asset.fileName).join(" and ")}.`}</span>
|
||||
</div>
|
||||
)}
|
||||
)}</EditableHudElement>
|
||||
<LoadingOverlay />
|
||||
{health <= 0 ? (
|
||||
<DefeatedPrompt
|
||||
|
||||
Reference in new issue
Block a user