ecs-observable/examples/three-monks/gameflow.ts

72 lines
1.6 KiB
TypeScript

import type { World } from "../../src/index";
import {
action,
buildTree,
sequential,
wait,
whilst,
type TaskControl,
type TaskRunner,
} from "../../src/bt/index";
import { allPlayersSelected, hasWinner } from "./components";
import {
beginSelectionPhase,
chantPhase,
exchangePhase,
fetchWaterPhase,
drinkPhase,
endOfRoundPhase,
prepareNextRound,
} from "./rules";
export interface ThreeMonksFlow {
runner: TaskRunner;
start(): void;
notifySelectionChanged(): void;
}
export function createThreeMonksFlow(world: World): ThreeMonksFlow {
let selectionControl: TaskControl | null = null;
const completeSelectionIfReady = () => {
if (selectionControl && allPlayersSelected(world)) {
const control = selectionControl;
selectionControl = null;
control.succeed();
}
};
const runner = buildTree(
world,
whilst(
(world) => !hasWinner(world),
sequential([
action((world) => beginSelectionPhase(world)),
wait((world, _entity, control) => {
selectionControl = control;
if (allPlayersSelected(world)) {
selectionControl = null;
control.succeed();
}
}),
action((world) => chantPhase(world)),
action((world) => fetchWaterPhase(world)),
action((world) => exchangePhase(world)),
action((world) => drinkPhase(world)),
action((world) => endOfRoundPhase(world)),
action((world) => prepareNextRound(world)),
]),
),
);
return {
runner,
start() {
runner.schedule(runner.root!);
},
notifySelectionChanged() {
completeSelectionIfReady();
},
};
}