mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-06 17:53:19 +08:00
feat: scenario picker, flow chaining UX, reliable frequency checks
Scenario picker & completion:
- Login → scenario selection screen with complete chains + individual phases
- Completion screen with "fly again / try opposite / back to scenarios"
- Scenario.airport ('dep'|'arr') drives which airport frequencies to fetch;
arrival scenarios (vfr-arrival, circuit-landing, taxi-in) use arr ICAO
Backend session integration:
- createSession forwards no_chain; response carries active_flow + session_complete
- Pass all six airport frequency variables to session so every chained flow
has the real airport values from creation
- fetchAirportFrequencies now runs before session creation so resolved
frequencies are included in backendVariables
Wrong-frequency check:
- airportFreqMap computed (from airportFrequencies, always up-to-date)
used as primary source in expectedFrequencyForState — immune to flow
snapshot switches
- setActiveFlow called when response.active_flow changes so local engine
cursor moves to the correct flow's states after a chain
- Wrong-freq ATC reply appended to communication log (offSchema entry)
Engine fixes (communicationsEngine.ts):
- patchVariables / patchFlags: write directly to the internal reactive
store, bypassing readonly(ref) which silently blocked all (vars as any)
.value[k] = v mutations
- appendLogEntry: push ATC speech (and wrong-freq replies) into comm log
- ATC controller_say_rendered appended to comm log after every transmission
This commit is contained in:
@@ -1391,6 +1391,45 @@ export default function useCommunicationsEngine() {
|
||||
communicationLog.value.push(entry)
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch arbitrary variables directly on the active flow's reactive variable
|
||||
* store. Use this from outside the engine instead of trying to mutate
|
||||
* `readonly(variables).value` (which Vue 3 silently blocks).
|
||||
*/
|
||||
function patchVariables(updates: Record<string, any>) {
|
||||
for (const [key, value] of Object.entries(updates)) {
|
||||
variables.value[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
function patchFlags(updates: Record<string, boolean>) {
|
||||
for (const [key, value] of Object.entries(updates)) {
|
||||
if (typeof value === 'boolean') {
|
||||
(flags.value as Record<string, any>)[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function appendLogEntry(
|
||||
speaker: Role,
|
||||
message: string,
|
||||
stateId: string,
|
||||
options: { frequency?: string; flow?: string; radioCheck?: boolean; offSchema?: boolean } = {},
|
||||
) {
|
||||
const entry: EngineLog = {
|
||||
timestamp: new Date(),
|
||||
frequency: options.frequency ?? activeFrequency.value,
|
||||
speaker,
|
||||
message,
|
||||
normalized: normalizeATCText(message, exposeCtxFlat()),
|
||||
state: stateId,
|
||||
flow: options.flow ?? (activeFlowSlug.value || undefined),
|
||||
radioCheck: options.radioCheck,
|
||||
offSchema: options.offSchema,
|
||||
}
|
||||
communicationLog.value.push(entry)
|
||||
}
|
||||
|
||||
function renderATCMessage(tpl: string) {
|
||||
return renderTpl(tpl, exposeCtx())
|
||||
}
|
||||
@@ -1511,6 +1550,9 @@ export default function useCommunicationsEngine() {
|
||||
// Utilities
|
||||
normalizeATCText,
|
||||
renderATCMessage,
|
||||
appendLogEntry,
|
||||
patchVariables,
|
||||
patchFlags,
|
||||
getStateDetails,
|
||||
updateTelemetry,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user