diff --git a/src/components/ebike/Ebike.tsx b/src/components/ebike/Ebike.tsx index e7de0dc..93186bf 100644 --- a/src/components/ebike/Ebike.tsx +++ b/src/components/ebike/Ebike.tsx @@ -344,13 +344,19 @@ export function Ebike({ // pollute the view. The prompt comes back the moment the bike comes to // a stop. window.ebikeDriveInputActive is published every frame by // PlayerController based on whether a movement key is currently held. + // Also hide entirely while the breakdown sequence is active — the bike + // must read as inert and non-interactive while the panne dialogue plays + // and during the auto-dismount that follows. const [isEbikeDriving, setIsEbikeDriving] = useState(false); + const [isEbikeBreakdown, setIsEbikeBreakdown] = useState(false); useFrame(() => { const driving = movementMode === "ebike" && window.ebikeDriveInputActive === true; if (driving !== isEbikeDriving) setIsEbikeDriving(driving); + const breakdown = window.ebikeBreakdownActive === true; + if (breakdown !== isEbikeBreakdown) setIsEbikeBreakdown(breakdown); }); - const showInteractPrompt = !isEbikeDriving; + const showInteractPrompt = !isEbikeDriving && !isEbikeBreakdown; const handleInteract = useCallback((): void => { if (window.ebikeBreakdownActive === true) return; diff --git a/src/data/ebike/ebikeConfig.ts b/src/data/ebike/ebikeConfig.ts index 9a90b75..c1279b4 100644 --- a/src/data/ebike/ebikeConfig.ts +++ b/src/data/ebike/ebikeConfig.ts @@ -19,7 +19,7 @@ export const EBIKE_WORLD_POSITION: Vector3Tuple = [68, 0.8, 65]; export const EBIKE_WORLD_ROTATION_Y = -2.5; export const EBIKE_WORLD_SCALE = 0.35; -export const EBIKE_INTRO_BREAKDOWN_DISTANCE = 15; +export const EBIKE_INTRO_BREAKDOWN_DISTANCE = 450; export const EBIKE_BREAKDOWN_DIALOGUE_DELAY_MS = 250; export const EBIKE_ACCELERATION_DURATION_MS = 2000; diff --git a/src/world/player/PlayerController.tsx b/src/world/player/PlayerController.tsx index 72cd0f2..8545f9c 100644 --- a/src/world/player/PlayerController.tsx +++ b/src/world/player/PlayerController.tsx @@ -363,7 +363,11 @@ export function PlayerController({ } _wishDir.set(0, 0, 0); - if (!isEbikeBreakdown) { + // Block drive input only when still on the bike during breakdown. + // Once auto-dismounted (movementMode === "walk"), the player must + // remain free to walk around even though ebikeBreakdownActive is true. + const blockDriveInput = isEbikeMounted && isEbikeBreakdown; + if (!blockDriveInput) { if (keys.current.forward) _wishDir.add(_forward); if (keys.current.backward) _wishDir.sub(_forward); if (!isEbikeMounted) {