feat(slay-the-spire-like): implement CombatGameHost

Introduce CombatGameHost to manage the combat lifecycle and
integrate ContentModule triggers with the combat run context.
This commit is contained in:
hypercross 2026-04-23 09:45:56 +08:00
parent 2e2ddebec4
commit bbab3cc43b
4 changed files with 29 additions and 7 deletions

View File

@ -2,6 +2,7 @@ import { LoadResult as YarnDialogues } from "yarn-spinner-loader";
import { Triggers } from "../system/combat/triggers"; import { Triggers } from "../system/combat/triggers";
import type * as desert from "./desert"; import type * as desert from "./desert";
import { IRunContext } from "../system/combat";
export type ContentModule = { export type ContentModule = {
getCards: () => desert.Card[]; getCards: () => desert.Card[];
@ -13,5 +14,5 @@ export type ContentModule = {
getStartingItems: () => desert.Item[]; getStartingItems: () => desert.Item[];
dialogues: YarnDialogues; dialogues: YarnDialogues;
addTriggers: (triggers: Triggers) => void; addTriggers: (triggers: Triggers, run: IRunContext) => void;
}; };

View File

@ -3,3 +3,27 @@ export * from "./factory";
export * from "./prompts"; export * from "./prompts";
export * from "./triggers"; export * from "./triggers";
export * from "./types"; export * from "./types";
import { GameHost } from "@/core/game-host";
import { ContentModule } from "../types";
import { createCommandRegistry } from "@/utils/command";
import { createStart, createTriggers, Triggers } from "./triggers";
import { CombatState, IRunContext } from "./types";
export class CombatGameHost extends GameHost<CombatState> {
public readonly triggers: Triggers;
constructor(
private module: ContentModule,
private runContext: IRunContext,
private initialState: CombatState,
) {
let triggers: Triggers;
super(
createCommandRegistry(),
() => initialState,
createStart((triggers = createTriggers(runContext)), runContext),
);
module.addTriggers(triggers, runContext);
this.triggers = triggers;
}
}

View File

@ -287,12 +287,7 @@ export function createTriggers(run: IRunContext) {
return triggers; return triggers;
} }
export type Triggers = ReturnType<typeof createTriggers>; export type Triggers = ReturnType<typeof createTriggers>;
export function createStartWith( export function createStart(triggers: Triggers, run: IRunContext) {
build: (triggers: Triggers, run: IRunContext) => void,
run: IRunContext,
) {
const triggers = createTriggers(run);
build(triggers, run);
return async function (game: CombatGameContext) { return async function (game: CombatGameContext) {
await triggers.onCombatStart.execute(game, {}); await triggers.onCombatStart.execute(game, {});

View File

@ -21,3 +21,5 @@ export {
CardEffectTarget, CardEffectTarget,
IntentEffectTarget, IntentEffectTarget,
} from "../data/desert"; } from "../data/desert";
export { ContentModule } from "../data";