diff --git a/packages/framework/src/scenes/GameHostScene.ts b/packages/framework/src/scenes/GameHostScene.ts index 263d819..b67865e 100644 --- a/packages/framework/src/scenes/GameHostScene.ts +++ b/packages/framework/src/scenes/GameHostScene.ts @@ -1,17 +1,23 @@ import { ReactiveScene } from "./ReactiveScene"; -import type { GameHost } from "boardgame-core"; +import type { GameHost, GameModule } from "boardgame-core"; -export interface GameHostSceneOptions> { - gameHost: GameHost; +export interface GameHostSceneOptions< + TState extends Record, + TResult, + TModule extends GameModule, +> { + gameHost: GameHost; [key: string]: unknown; } export abstract class GameHostScene< TState extends Record, -> extends ReactiveScene> { - public get gameHost(): GameHost { - const gameHost = this.initData.gameHost as GameHost; + TResult, + TModule extends GameModule, +> extends ReactiveScene> { + public get gameHost(): GameHost { + const gameHost = this.initData.gameHost; if (!gameHost) { throw new Error( `GameHostScene (${this.scene.key}): gameHost ζœͺ提供。` + diff --git a/packages/sts-like-viewer/src/scenes/CombatTestScene.ts b/packages/sts-like-viewer/src/scenes/CombatTestScene.ts index 070f9d0..bc95c97 100644 --- a/packages/sts-like-viewer/src/scenes/CombatTestScene.ts +++ b/packages/sts-like-viewer/src/scenes/CombatTestScene.ts @@ -2,6 +2,7 @@ import Phaser from "phaser"; import { GameHostScene } from "boardgame-phaser"; import { spawnEffect, type Spawner } from "boardgame-phaser"; import { + CombatResult, type CombatState, prompts, } from "boardgame-core/samples/slay-the-spire-like"; @@ -12,12 +13,17 @@ import { type CombatUnitData, } from "@/gameobjects/CombatUnitContainer"; import { CardSpawner } from "@/gameobjects/CardSpawner"; +import { CombatModule } from "@/state/combatState"; const CARD_SPACING = 160; const HAND_MARGIN = 100; const HAND_Y = 140; -export class CombatTestScene extends GameHostScene { +export class CombatTestScene extends GameHostScene< + CombatState, + CombatResult | null, + CombatModule +> { private selectedCardId: string | null = null; private isTargeting = false; private targetingText!: Phaser.GameObjects.Text; @@ -150,8 +156,9 @@ export class CombatTestScene extends GameHostScene { } private tryPlayCard(cardId: string, targetId?: string): void { - const error = this.gameHost.tryAnswerPrompt( + const error = this.gameHost.prompts.tryCommit( prompts.mainAction, + "player", cardId, targetId, ); diff --git a/packages/sts-like-viewer/src/state/combatState.ts b/packages/sts-like-viewer/src/state/combatState.ts index f0eb96e..a1a7ea1 100644 --- a/packages/sts-like-viewer/src/state/combatState.ts +++ b/packages/sts-like-viewer/src/state/combatState.ts @@ -1,8 +1,8 @@ import { buildCombatState, - CombatState, createRunState, - createStartWith, + createStart, + createTriggers, data, generateDeckFromInventory, getAdjacentItems, @@ -10,9 +10,9 @@ import { IRunContext, } from "boardgame-core/samples/slay-the-spire-like"; import { createInventorySignal } from "./inventory"; -import { GameModule } from "boardgame-core"; -export function createCombatState() { +export type CombatModule = ReturnType; +export function createCombatModule() { const inventory = createInventorySignal(true); const deck = generateDeckFromInventory(inventory.value); @@ -51,12 +51,13 @@ export function createCombatState() { }, }; - const start = createStartWith((triggers, ctx) => { - data.desert.addTriggers(triggers, runContext); - }, runContext); + const triggers = createTriggers(runContext); + const start = createStart(triggers, runContext); return { start, createInitialState: () => combat, - } as GameModule; + triggers, + runContext, + }; } diff --git a/packages/sts-like-viewer/src/ui/App.tsx b/packages/sts-like-viewer/src/ui/App.tsx index cd558ad..4fdfdc6 100644 --- a/packages/sts-like-viewer/src/ui/App.tsx +++ b/packages/sts-like-viewer/src/ui/App.tsx @@ -1,19 +1,25 @@ -import { createGameHost, type GameModule } from "boardgame-core"; +import { GAME_CONFIG } from "@/config"; +import { CombatTestScene } from "@/scenes/CombatTestScene"; +import { GridViewerScene } from "@/scenes/GridViewerScene"; +import { IndexScene } from "@/scenes/IndexScene"; +import { InventoryTestScene } from "@/scenes/InventoryTestScene"; +import { MapViewerScene } from "@/scenes/MapViewerScene"; +import { ShapeViewerScene } from "@/scenes/ShapeViewerScene"; +import { CombatModule, createCombatModule } from "@/state/combatState"; +import { createGameHost } from "boardgame-core"; +import { + CombatResult, + CombatState, +} from "boardgame-core/samples/slay-the-spire-like"; import { PhaserGame, PhaserScene } from "boardgame-phaser"; import { useMemo } from "preact/hooks"; -import { IndexScene } from "@/scenes/IndexScene"; -import { MapViewerScene } from "@/scenes/MapViewerScene"; -import { GridViewerScene } from "@/scenes/GridViewerScene"; -import { ShapeViewerScene } from "@/scenes/ShapeViewerScene"; -import { GAME_CONFIG } from "@/config"; -import { InventoryTestScene } from "@/scenes/InventoryTestScene"; -import { CombatTestScene } from "@/scenes/CombatTestScene"; -import { createCombatState } from "@/state/combatState"; -import type { CombatState } from "boardgame-core/samples/slay-the-spire-like"; export default function App() { const gameHost = useMemo( - () => createGameHost(createCombatState() as GameModule), + () => + createGameHost( + createCombatModule(), + ), [], );