Preload teleport destination streams and mute teleport footsteps
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// Maintainer-controlled web client version.
|
// Maintainer-controlled web client version.
|
||||||
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
||||||
window.CHGRID_WEB_VERSION = "2026.02.22 R181";
|
window.CHGRID_WEB_VERSION = "2026.02.22 R182";
|
||||||
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
||||||
window.CHGRID_TIME_ZONE = "America/Detroit";
|
window.CHGRID_TIME_ZONE = "America/Detroit";
|
||||||
|
|||||||
@@ -227,7 +227,6 @@ let activeTeleport:
|
|||||||
targetY: number;
|
targetY: number;
|
||||||
startedAtMs: number;
|
startedAtMs: number;
|
||||||
durationMs: number;
|
durationMs: number;
|
||||||
lastStepAtMs: number;
|
|
||||||
lastSyncAtMs: number;
|
lastSyncAtMs: number;
|
||||||
lastSentX: number;
|
lastSentX: number;
|
||||||
lastSentY: number;
|
lastSentY: number;
|
||||||
@@ -557,12 +556,12 @@ async function applyAudioLayerState(): Promise<void> {
|
|||||||
await itemEmitRuntime.setLayerEnabled(audioLayers.item, state.items.values(), listenerPosition);
|
await itemEmitRuntime.setLayerEnabled(audioLayers.item, state.items.values(), listenerPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Refreshes distance-gated radio/item stream subscriptions on movement or timer cadence. */
|
/** Refreshes distance-gated radio/item stream subscriptions for a listener position. */
|
||||||
async function refreshAudioSubscriptions(force = false): Promise<void> {
|
async function refreshAudioSubscriptionsAt(listenerPosition: { x: number; y: number }, force = false): Promise<void> {
|
||||||
if (!state.running) return;
|
if (!state.running) return;
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const tileX = Math.round(state.player.x);
|
const tileX = Math.round(listenerPosition.x);
|
||||||
const tileY = Math.round(state.player.y);
|
const tileY = Math.round(listenerPosition.y);
|
||||||
const moved = tileX !== lastSubscriptionRefreshTileX || tileY !== lastSubscriptionRefreshTileY;
|
const moved = tileX !== lastSubscriptionRefreshTileX || tileY !== lastSubscriptionRefreshTileY;
|
||||||
if (!force && !moved && now - lastSubscriptionRefreshAt < AUDIO_SUBSCRIPTION_REFRESH_MS) {
|
if (!force && !moved && now - lastSubscriptionRefreshAt < AUDIO_SUBSCRIPTION_REFRESH_MS) {
|
||||||
return;
|
return;
|
||||||
@@ -575,7 +574,6 @@ async function refreshAudioSubscriptions(force = false): Promise<void> {
|
|||||||
lastSubscriptionRefreshAt = now;
|
lastSubscriptionRefreshAt = now;
|
||||||
lastSubscriptionRefreshTileX = tileX;
|
lastSubscriptionRefreshTileX = tileX;
|
||||||
lastSubscriptionRefreshTileY = tileY;
|
lastSubscriptionRefreshTileY = tileY;
|
||||||
const listenerPosition = { x: state.player.x, y: state.player.y };
|
|
||||||
try {
|
try {
|
||||||
await radioRuntime.sync(state.items.values(), listenerPosition);
|
await radioRuntime.sync(state.items.values(), listenerPosition);
|
||||||
await itemEmitRuntime.sync(state.items.values(), listenerPosition);
|
await itemEmitRuntime.sync(state.items.values(), listenerPosition);
|
||||||
@@ -588,6 +586,15 @@ async function refreshAudioSubscriptions(force = false): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Refreshes distance-gated radio/item stream subscriptions on movement or timer cadence. */
|
||||||
|
async function refreshAudioSubscriptions(force = false): Promise<void> {
|
||||||
|
if (activeTeleport) {
|
||||||
|
await refreshAudioSubscriptionsAt({ x: activeTeleport.targetX, y: activeTeleport.targetY }, force);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await refreshAudioSubscriptionsAt({ x: state.player.x, y: state.player.y }, force);
|
||||||
|
}
|
||||||
|
|
||||||
/** Toggles a single audio layer and applies the change immediately. */
|
/** Toggles a single audio layer and applies the change immediately. */
|
||||||
function toggleAudioLayer(layer: keyof AudioLayerState): void {
|
function toggleAudioLayer(layer: keyof AudioLayerState): void {
|
||||||
audioLayers = { ...audioLayers, [layer]: !audioLayers[layer] };
|
audioLayers = { ...audioLayers, [layer]: !audioLayers[layer] };
|
||||||
@@ -1103,12 +1110,12 @@ function startTeleportTo(targetX: number, targetY: number, completionStatus: str
|
|||||||
targetY,
|
targetY,
|
||||||
startedAtMs: nowMs,
|
startedAtMs: nowMs,
|
||||||
durationMs,
|
durationMs,
|
||||||
lastStepAtMs: nowMs,
|
|
||||||
lastSyncAtMs: nowMs,
|
lastSyncAtMs: nowMs,
|
||||||
lastSentX: Math.round(startX),
|
lastSentX: Math.round(startX),
|
||||||
lastSentY: Math.round(startY),
|
lastSentY: Math.round(startY),
|
||||||
completionStatus,
|
completionStatus,
|
||||||
};
|
};
|
||||||
|
void refreshAudioSubscriptionsAt({ x: targetX, y: targetY }, true);
|
||||||
state.keysPressed.ArrowUp = false;
|
state.keysPressed.ArrowUp = false;
|
||||||
state.keysPressed.ArrowDown = false;
|
state.keysPressed.ArrowDown = false;
|
||||||
state.keysPressed.ArrowLeft = false;
|
state.keysPressed.ArrowLeft = false;
|
||||||
@@ -1125,11 +1132,6 @@ function updateTeleport(): void {
|
|||||||
state.player.x = activeTeleport.startX + (activeTeleport.targetX - activeTeleport.startX) * progress;
|
state.player.x = activeTeleport.startX + (activeTeleport.targetX - activeTeleport.startX) * progress;
|
||||||
state.player.y = activeTeleport.startY + (activeTeleport.targetY - activeTeleport.startY) * progress;
|
state.player.y = activeTeleport.startY + (activeTeleport.targetY - activeTeleport.startY) * progress;
|
||||||
|
|
||||||
if (nowMs - activeTeleport.lastStepAtMs >= MOVE_COOLDOWN_MS) {
|
|
||||||
activeTeleport.lastStepAtMs = nowMs;
|
|
||||||
void audio.playSample(randomFootstepUrl(), FOOTSTEP_GAIN, MOVE_COOLDOWN_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nowMs - activeTeleport.lastSyncAtMs >= TELEPORT_SYNC_INTERVAL_MS) {
|
if (nowMs - activeTeleport.lastSyncAtMs >= TELEPORT_SYNC_INTERVAL_MS) {
|
||||||
activeTeleport.lastSyncAtMs = nowMs;
|
activeTeleport.lastSyncAtMs = nowMs;
|
||||||
const syncX = Math.round(state.player.x);
|
const syncX = Math.round(state.player.x);
|
||||||
@@ -1160,7 +1162,9 @@ function gameLoop(): void {
|
|||||||
if (!state.running) return;
|
if (!state.running) return;
|
||||||
updateTeleport();
|
updateTeleport();
|
||||||
handleMovement();
|
handleMovement();
|
||||||
void refreshAudioSubscriptions();
|
if (!activeTeleport) {
|
||||||
|
void refreshAudioSubscriptions();
|
||||||
|
}
|
||||||
audio.updateSpatialAudio(peerManager.getPeers(), { x: state.player.x, y: state.player.y });
|
audio.updateSpatialAudio(peerManager.getPeers(), { x: state.player.x, y: state.player.y });
|
||||||
radioRuntime.updateSpatialAudio(state.items, { x: state.player.x, y: state.player.y });
|
radioRuntime.updateSpatialAudio(state.items, { x: state.player.x, y: state.player.y });
|
||||||
itemEmitRuntime.updateSpatialAudio(state.items, { x: state.player.x, y: state.player.y });
|
itemEmitRuntime.updateSpatialAudio(state.items, { x: state.player.x, y: state.player.y });
|
||||||
|
|||||||
Reference in New Issue
Block a user