refactor: yarn runner man
This commit is contained in:
parent
8d5b15ad51
commit
e13ead2309
|
|
@ -2,9 +2,8 @@ import { customElement, noShadowDOM } from 'solid-element';
|
|||
import { For, Show, createEffect } from 'solid-js';
|
||||
import type {TextResult, RuntimeResult, OptionsResult} from '../yarn-spinner/runtime/results';
|
||||
import { createYarnStore } from './stores/yarnStore';
|
||||
import {RunnerOptions} from "../yarn-spinner/runtime/runner";
|
||||
|
||||
customElement<RunnerOptions>('md-yarn-spinner', {startAt: 'start'}, (props, { element }) => {
|
||||
customElement<{start: string}>('md-yarn-spinner', {start: 'start'}, (props, { element }) => {
|
||||
noShadowDOM();
|
||||
|
||||
let historyContainer: HTMLDivElement | undefined;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export function getTtrpgFunctions(runner: IRunner){
|
|||
}
|
||||
/* stat related */
|
||||
function ensure_stat(stat: string){
|
||||
if(!runner.getVariable(stat)){
|
||||
if(runner.getVariable(stat) === undefined){
|
||||
const statBase = `${stat}_base`;
|
||||
const statMod = `${stat}_mod`;
|
||||
const statDamage = `${stat}_damage`;
|
||||
|
|
@ -74,6 +74,7 @@ export function getTtrpgFunctions(runner: IRunner){
|
|||
const progress = runner.getVariable(key) as number || 0;
|
||||
const newProgress = progress + Math.ceil(Math.random() * 4);
|
||||
runner.setVariable(key, newProgress);
|
||||
console.log(`check ${stat}(${statVal}) ${pass ? 'pass' : 'fail'}, now ${newProgress}`);
|
||||
return pass ? newProgress : -newProgress;
|
||||
}
|
||||
function rollStat(){
|
||||
|
|
@ -94,15 +95,17 @@ export function getTtrpgFunctions(runner: IRunner){
|
|||
heal(stat, 1);
|
||||
}
|
||||
return {
|
||||
add_minutes: add_minute,
|
||||
add_hours: add_hour,
|
||||
add_days: add_day,
|
||||
|
||||
damage,
|
||||
heal,
|
||||
check,
|
||||
|
||||
fatigue,
|
||||
regen,
|
||||
};
|
||||
commands: {
|
||||
add_minute,
|
||||
add_hour,
|
||||
add_day,
|
||||
damage,
|
||||
heal,
|
||||
fatigue,
|
||||
regen
|
||||
} as Record<string, (...args: any[]) =>any>,
|
||||
functions: {
|
||||
check
|
||||
} as Record<string, (...args: any[]) =>any>
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import {compile, parseYarn, YarnRunner} from "../../yarn-spinner";
|
|||
import {loadElementSrc, resolvePath} from "../utils/path";
|
||||
import {createStore} from "solid-js/store";
|
||||
import {RunnerOptions} from "../../yarn-spinner/runtime/runner";
|
||||
import {getTtrpgFunctions} from "./ttrpgRunner";
|
||||
|
||||
type YarnSpinnerStore = {
|
||||
dialogueHistory: (RuntimeResult | OptionsResult['options'][0])[],
|
||||
|
|
@ -12,7 +13,7 @@ type YarnSpinnerStore = {
|
|||
runnerInstance: YarnRunner | null,
|
||||
}
|
||||
|
||||
export function createYarnStore(element: HTMLElement, props: RunnerOptions){
|
||||
export function createYarnStore(element: HTMLElement, props: {start: string}){
|
||||
const [store, setStore] = createStore<YarnSpinnerStore>({
|
||||
dialogueHistory: [],
|
||||
currentOptions: null,
|
||||
|
|
@ -39,19 +40,11 @@ export function createYarnStore(element: HTMLElement, props: RunnerOptions){
|
|||
const program = compile(ast);
|
||||
|
||||
const runner = new YarnRunner(program, {
|
||||
functions: {
|
||||
check(id: string, stat: string): number {
|
||||
const statVal = runner.getVariable(stat) as number || 10;
|
||||
const pass = Math.ceil(Math.random() * 20) <= statVal;
|
||||
const key = `${id}_${pass ? 'pass' : 'fail'}`;
|
||||
const progress = runner.getVariable(key) as number || 0;
|
||||
const newProgress = progress + Math.ceil(Math.random() * 4);
|
||||
runner.setVariable(key, newProgress);
|
||||
return pass ? newProgress : -newProgress;
|
||||
}
|
||||
},
|
||||
startAt: props.startAt,
|
||||
startAt: props.start,
|
||||
});
|
||||
const {commands, functions} = getTtrpgFunctions(runner);
|
||||
runner.registerFunctions(functions);
|
||||
runner.registerCommands(commands);
|
||||
return runner;
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize YarnRunner:', error);
|
||||
|
|
|
|||
|
|
@ -499,4 +499,11 @@ export class ExpressionEvaluator {
|
|||
getVariable(name: string): unknown {
|
||||
return this.variables[name];
|
||||
}
|
||||
|
||||
registerFunctions(functions: Record<string, (...args: unknown[]) => unknown>){
|
||||
this.functions = {
|
||||
...this.functions,
|
||||
...functions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ type CompiledOption = {
|
|||
export class YarnRunner {
|
||||
private readonly program: IRProgram;
|
||||
private readonly variables: Record<string, unknown>;
|
||||
private readonly functions: Record<string, (...args: unknown[]) => unknown>;
|
||||
private readonly handleCommand?: (command: string, parsed?: ReturnType<typeof parseCommand>) => void;
|
||||
private readonly commandHandler: CommandHandler;
|
||||
private readonly evaluator: ExpressionEvaluator;
|
||||
|
|
@ -59,7 +58,7 @@ export class YarnRunner {
|
|||
this.variables[normalizedKey] = value;
|
||||
}
|
||||
}
|
||||
this.functions = {
|
||||
let functions = {
|
||||
// Default conversion helpers
|
||||
string: (v: unknown) => String(v ?? ""),
|
||||
number: (v: unknown) => Number(v),
|
||||
|
|
@ -115,12 +114,25 @@ export class YarnRunner {
|
|||
} as Record<string, (...args: unknown[]) => unknown>;
|
||||
this.handleCommand = opts.handleCommand;
|
||||
this.onStoryEnd = opts.onStoryEnd;
|
||||
this.evaluator = new ExpressionEvaluator(this.variables, this.functions, this.program.enums);
|
||||
this.evaluator = new ExpressionEvaluator(this.variables, functions, this.program.enums);
|
||||
this.commandHandler = opts.commandHandler ?? new CommandHandler(this.variables);
|
||||
this.nodeTitle = opts.startAt;
|
||||
|
||||
this.step();
|
||||
}
|
||||
|
||||
public registerFunctions(functions: Record<string, (...args: unknown[]) => unknown>){
|
||||
this.evaluator.registerFunctions(functions);
|
||||
}
|
||||
|
||||
public registerCommands(commands: Record<string, (args: unknown[], evaluator?: ExpressionEvaluator) => void | Promise<void>>) {
|
||||
for(const key in commands){
|
||||
this.commandHandler.register(key, (args, evaluator) => {
|
||||
if(!evaluator) return;
|
||||
commands[key].call(this, args.map(arg => evaluator.evaluateExpression(arg)));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve a node title to an actual node (handling node groups).
|
||||
|
|
@ -599,6 +611,8 @@ export class YarnRunner {
|
|||
* Get variable value.
|
||||
*/
|
||||
getVariable(name: string): unknown {
|
||||
if(this.evaluator.isSmartVariable(name))
|
||||
return this.evaluator.evaluateExpression(`$${name}`);
|
||||
return this.variables[name];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue