Add functions to format runner telemetry signals, audio hook, and animation hook in App.tsx

This commit is contained in:
2026-04-11 19:13:06 +02:00
parent 9291f9f2ce
commit 430770d645

View File

@@ -1237,6 +1237,90 @@ function formatRunnerGroundContact(
return `${slope === null ? "?" : slope.toFixed(1)} deg @ ${distance === null ? "?" : distance.toFixed(2)}m`;
}
function formatRunnerMovementSignals(
telemetry: FirstPersonTelemetry | null
): string {
if (telemetry === null) {
return "n/a";
}
const activeSignals: string[] = [];
if (telemetry.signals.jumpStarted) {
activeSignals.push("jump");
}
if (telemetry.signals.leftGround) {
activeSignals.push("left ground");
}
if (telemetry.signals.startedFalling) {
activeSignals.push("fall");
}
if (telemetry.signals.landed) {
activeSignals.push("land");
}
if (telemetry.signals.enteredWater) {
activeSignals.push("enter water");
}
if (telemetry.signals.exitedWater) {
activeSignals.push("exit water");
}
if (telemetry.signals.wallContactStarted) {
activeSignals.push("wall");
}
if (telemetry.signals.headBump) {
activeSignals.push("head bump");
}
return activeSignals.length > 0 ? activeSignals.join(", ") : "none";
}
function formatRunnerAudioHook(telemetry: FirstPersonTelemetry | null): string {
if (telemetry === null) {
return "n/a";
}
const underwaterAmount = telemetry.hooks.audio.underwaterAmount;
if (underwaterAmount >= 0.99) {
return "submerged";
}
if (underwaterAmount <= 0.01) {
return "dry";
}
return `wet ${underwaterAmount.toFixed(2)}`;
}
function formatRunnerAnimationHook(
telemetry: FirstPersonTelemetry | null
): string {
if (telemetry === null) {
return "n/a";
}
const animationHook = telemetry.hooks.animation;
if (animationHook.locomotionMode === "airborne") {
return animationHook.airborneKind === "jumping" ? "jump" : "fall";
}
if (animationHook.locomotionMode === "swimming") {
return `swim ${animationHook.movementAmount.toFixed(2)}`;
}
return animationHook.moving
? `${animationHook.gait} ${animationHook.movementAmount.toFixed(2)}`
: "idle";
}
function formatWorldBackgroundLabel(world: WorldSettings): string {
if (world.background.mode === "solid") {
return "Solid";
@@ -7286,6 +7370,24 @@ export function App({ store, initialStatusMessage }: AppProps) {
: "outside"}
</div>
</div>
<div className="stat-card">
<div className="label">Signals</div>
<div className="value">
{formatRunnerMovementSignals(firstPersonTelemetry)}
</div>
</div>
<div className="stat-card">
<div className="label">Audio Hook</div>
<div className="value">
{formatRunnerAudioHook(firstPersonTelemetry)}
</div>
</div>
<div className="stat-card">
<div className="label">Animation Hook</div>
<div className="value">
{formatRunnerAnimationHook(firstPersonTelemetry)}
</div>
</div>
</div>
<div className="stat-card">