mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-07-11 22:44:47 +00:00
reset/stop moves during map cycle
This commit is contained in:
parent
d9c18334b2
commit
25b4a53a00
27 changed files with 791 additions and 731 deletions
|
|
@ -135,6 +135,7 @@ export function InputConsumer() {
|
|||
const { moveQueue, mode, setMode } = useInputContext();
|
||||
const adapter = useLiveSelector((s) => s.adapter);
|
||||
const gameStatus = useLiveSelector((s) => s.gameStatus);
|
||||
const liveReady = useLiveSelector((s) => s.liveReady);
|
||||
const sendMoves = useLiveSelector((s) => s.sendMoves);
|
||||
const store = useEngineStoreApi();
|
||||
const camera = useThree((state) => state.camera);
|
||||
|
|
@ -238,9 +239,35 @@ export function InputConsumer() {
|
|||
}
|
||||
}, [isLive, adapter, store, setMode]);
|
||||
|
||||
// Reset prediction state and mode when liveReady goes false (map cycle).
|
||||
// During map transitions, liveReady is false from MissionStartPhase1 until
|
||||
// the first ghost arrives on the new map. The adapter resets observerMode
|
||||
// to "fly" at phase 1, and we mirror that here.
|
||||
useEffect(() => {
|
||||
if (!liveReady && activeAdapterRef.current) {
|
||||
log.info("mission change: resetting prediction state and mode");
|
||||
predInitialized.current = false;
|
||||
orbitTargetInitialized.current = false;
|
||||
lastOrbitSnapshot.current = null;
|
||||
moveBuffer.current.length = 0;
|
||||
nextMoveIndex.current = 0;
|
||||
lastProcessedAck.current = 0;
|
||||
lastReconciledCamera.current = null;
|
||||
tickDeltaYaw.current = 0;
|
||||
tickDeltaPitch.current = 0;
|
||||
tickMoveX.current = 0;
|
||||
tickMoveY.current = 0;
|
||||
tickMoveZ.current = 0;
|
||||
tickTriggers.current.fill(false);
|
||||
prevTriggers.current.fill(false);
|
||||
setMode("fly");
|
||||
}
|
||||
}, [liveReady, setMode]);
|
||||
|
||||
// ── processTick: send moves at the Torque tick rate (32Hz). ──
|
||||
useTick(() => {
|
||||
if (!activeAdapterRef.current || gameStatus !== "connected") return;
|
||||
if (!activeAdapterRef.current || gameStatus !== "connected" || !liveReady)
|
||||
return;
|
||||
|
||||
// Consume accumulated deltas.
|
||||
const yaw = tickDeltaYaw.current;
|
||||
|
|
@ -412,7 +439,12 @@ export function InputConsumer() {
|
|||
}
|
||||
moveQueue.current.length = 0;
|
||||
|
||||
if (isLive && activeAdapterRef.current && gameStatus === "connected") {
|
||||
if (
|
||||
isLive &&
|
||||
activeAdapterRef.current &&
|
||||
gameStatus === "connected" &&
|
||||
liveReady
|
||||
) {
|
||||
// Live mode: accumulate for useTick to consume and send.
|
||||
tickDeltaYaw.current += dYaw;
|
||||
tickDeltaPitch.current += dPitch;
|
||||
|
|
@ -443,7 +475,12 @@ export function InputConsumer() {
|
|||
|
||||
// ── Live mode: server reconciliation + interpolateTick ──
|
||||
|
||||
if (!isLive || !activeAdapterRef.current || gameStatus !== "connected") {
|
||||
if (
|
||||
!isLive ||
|
||||
!activeAdapterRef.current ||
|
||||
gameStatus !== "connected" ||
|
||||
!liveReady
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import { useKeyboardControls } from "@react-three/drei";
|
||||
import { Controls } from "./MouseAndKeyboardHandler";
|
||||
import { useRecording } from "./RecordingProvider";
|
||||
import { useLiveSelector } from "../state/liveConnectionStore";
|
||||
import styles from "./KeyboardOverlay.module.css";
|
||||
|
||||
export function KeyboardOverlay() {
|
||||
const recording = useRecording();
|
||||
const liveReady = useLiveSelector((s) => s.liveReady);
|
||||
const forward = useKeyboardControls<Controls>((s) => s.forward);
|
||||
const backward = useKeyboardControls<Controls>((s) => s.backward);
|
||||
const left = useKeyboardControls<Controls>((s) => s.left);
|
||||
|
|
@ -16,9 +18,10 @@ export function KeyboardOverlay() {
|
|||
const lookLeft = useKeyboardControls<Controls>((s) => s.lookLeft);
|
||||
const lookRight = useKeyboardControls<Controls>((s) => s.lookRight);
|
||||
|
||||
// Show when no recording (map browsing) or during live mode.
|
||||
// Hidden during demo playback (recording with finite duration).
|
||||
// Show when no recording (map browsing) or during live mode once ready.
|
||||
// Hidden during demo playback and during live map transitions.
|
||||
if (recording && recording.source !== "live") return null;
|
||||
if (recording?.source === "live" && !liveReady) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.Root}>
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ export class LiveStreamAdapter extends StreamEngine {
|
|||
this._ready = false;
|
||||
this._snapshot = null;
|
||||
this._snapshotTick = -1;
|
||||
this.observerMode = "fly";
|
||||
this.lastMoveAck = 0;
|
||||
// Clear stale mission info — new values arrive via MsgClientReady
|
||||
// and MsgMissionDropInfo after the mission finishes loading.
|
||||
this.missionDisplayName = null;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue