Files
healer-man/src/ui/Minimap.tsx
T
2026-09-13 13:21:27 -04:00

54 lines
2.2 KiB
TypeScript

import type { CSSProperties } from "react";
import type { Vector3Tuple } from "../game/dungeonManifest";
import { DungeonMapGraphic } from "./DungeonMapGraphic";
import { useInputBindingLabels } from "../input/useInputBindingLabels";
import { useGameStore } from "../game/store";
import { requireDungeonDefinition } from "../game/dungeonRegistry";
import { wowDungeonMapFor, wowMapFloorFor, wowMapHeading } from "../game/wowDungeonMap";
export interface MinimapProps {
position: Vector3Tuple;
yaw: number;
areaName: string;
distanceTravelled?: number;
rotationMode?: "north-up" | "player-up";
onOpenMap: () => void;
}
export function Minimap({
position,
yaw,
areaName,
distanceTravelled = 0,
rotationMode = "north-up",
onOpenMap,
}: MinimapProps) {
const bindingLabel = useInputBindingLabels();
const inputMode = useGameStore((state) => state.inputMode);
const dungeonId = useGameStore((state) => state.activeDungeonId);
const map = wowDungeonMapFor(requireDungeonDefinition(dungeonId));
const direction = map ? wowMapHeading(map, wowMapFloorFor(map, position), position, yaw) : null;
const compassYaw = direction ? Math.atan2(direction[0], -direction[1]) : yaw;
const mapKey = bindingLabel(inputMode === "gamepad" ? "controller" : "pc", "map");
const heading = ((Math.round((compassYaw * 180) / Math.PI) % 360) + 360) % 360;
return (
<section className="hud-minimap" aria-label="Dungeon minimap">
<button type="button" className="hud-minimap__map" onClick={onOpenMap} aria-label="Open full dungeon map">
<span className="hud-minimap__north" aria-hidden="true">N</span>
<span
className="hud-minimap__viewport"
style={{ "--minimap-turn": rotationMode === "player-up" ? `${-compassYaw}rad` : "0rad" } as CSSProperties}
aria-hidden="true"
>
<DungeonMapGraphic position={position} yaw={yaw} compact />
</span>
<span className="hud-minimap__heading" aria-hidden="true">{heading}°</span>
</button>
<div className="hud-minimap__caption">
<strong>{areaName}</strong>
<span>{Math.round(distanceTravelled)} m explored · {mapKey !== "Unbound" && <kbd>{mapKey}</kbd>} map</span>
</div>
</section>
);
}