105 lines
2.6 KiB
TypeScript
105 lines
2.6 KiB
TypeScript
import type { Condition, Effect, ChoiceRecord } from '../types'
|
|
|
|
export class StateManager {
|
|
variables: Record<string, number> = {}
|
|
flags: Set<string> = new Set()
|
|
history: ChoiceRecord[] = []
|
|
onAfterApply: ((variables: Record<string, number>) => void) | null = null
|
|
|
|
init(initialVars: Record<string, number>) {
|
|
this.variables = { ...initialVars }
|
|
this.flags = new Set()
|
|
this.history = []
|
|
}
|
|
|
|
getVar(name: string): number {
|
|
return this.variables[name] ?? 0
|
|
}
|
|
|
|
setVar(name: string, value: number) {
|
|
this.variables[name] = value
|
|
}
|
|
|
|
addVar(name: string, delta: number) {
|
|
this.variables[name] = (this.variables[name] ?? 0) + delta
|
|
}
|
|
|
|
hasFlag(name: string): boolean {
|
|
return this.flags.has(name)
|
|
}
|
|
|
|
setFlag(name: string) {
|
|
this.flags.add(name)
|
|
}
|
|
|
|
clearFlag(name: string) {
|
|
this.flags.delete(name)
|
|
}
|
|
|
|
evaluate(conditions: Condition[]): boolean {
|
|
return conditions.every((c) => {
|
|
switch (c.op) {
|
|
case '==':
|
|
return this.variables[c.variable] === c.value
|
|
case '!=':
|
|
return this.variables[c.variable] !== c.value
|
|
case '>':
|
|
return (this.variables[c.variable] ?? 0) > (c.value as number)
|
|
case '<':
|
|
return (this.variables[c.variable] ?? 0) < (c.value as number)
|
|
case '>=':
|
|
return (this.variables[c.variable] ?? 0) >= (c.value as number)
|
|
case '<=':
|
|
return (this.variables[c.variable] ?? 0) <= (c.value as number)
|
|
case 'hasFlag':
|
|
return this.flags.has(c.variable)
|
|
default:
|
|
return false
|
|
}
|
|
})
|
|
}
|
|
|
|
apply(effects: Effect[]) {
|
|
for (const e of effects) {
|
|
switch (e.type) {
|
|
case 'set':
|
|
this.variables[e.target] = e.value as number
|
|
break
|
|
case 'add':
|
|
this.addVar(e.target, e.value as number)
|
|
break
|
|
case 'toggleFlag':
|
|
this.setFlag(e.target)
|
|
break
|
|
}
|
|
}
|
|
this.onAfterApply?.(this.variables)
|
|
}
|
|
|
|
recordChoice(choice: ChoiceRecord) {
|
|
this.history.push(choice)
|
|
}
|
|
|
|
toJSON() {
|
|
return {
|
|
variables: { ...this.variables },
|
|
flags: [...this.flags],
|
|
history: [...this.history],
|
|
}
|
|
}
|
|
|
|
fromJSON(data: { variables: Record<string, number>; flags: string[]; history: ChoiceRecord[] }) {
|
|
this.variables = { ...data.variables }
|
|
this.flags = new Set(data.flags)
|
|
this.history = [...data.history]
|
|
}
|
|
|
|
dump() {
|
|
console.group('StateManager')
|
|
console.table(this.variables)
|
|
console.log('flags:', [...this.flags])
|
|
console.table(this.history)
|
|
console.groupEnd()
|
|
}
|
|
}
|