UNPKG

textadv

Version:

Text Adventures generator from Markdown files

102 lines 3.46 kB
import { Project } from "./types.js"; import { generateInputVariations, removeDiacritics } from "./utils.js"; export class Engine { constructor(project) { this.project = project; } static fromJSON(jsonProject) { const project = Project.fromJSON(jsonProject); return new Engine(project); } start() { return { roomIndex: this.project.initialRoomIndex, output: [], flags: {}, gameover: false }; } getRoomIntro(roomIndex) { const room = this.project.getChild(roomIndex); return [`[${room.name.trim()}]`, ...room.intro]; } input(str, state) { const newState = Object.assign({}, state); newState.output = []; const room = this.project.getChild(state.roomIndex); if (!room) { throw new Error(`invalid room ${state.roomIndex}`); } const codes = room.onInput.concat(this.project.onInput); for (const code of codes) { if (this.matchesOn(str, code.on)) { let done = true; for (const op of code.ops) { const success = this.runOp(op, newState); if (!success) { done = false; break; } } if (done) { break; } } } return newState; } matchesOn(str, on) { str = removeDiacritics(str).trim().replace(/ +/g, ' ').toLocaleLowerCase(); on = removeDiacritics(on).trim().replace(/ +/g, ' ').toLocaleLowerCase(); const variations = generateInputVariations(on); for (const variation of variations) { if (variation.endsWith('*')) { if (variation === '*') { return true; } const codeOnStart = variation.replace('*', '').trim(); if (str.substring(0, codeOnStart.length) === codeOnStart) { return true; } } if (str === variation) { return true; } } return false; } runOp(op, state) { var _a; switch (op.cmd) { case "print": state.output.push(String(op.params[0])); break; case "check-room": state.output.push(...this.getRoomIntro(state.roomIndex)); break; case "goto": const roomIndex = (_a = this.project.getChildById(String(op.params[0]))) === null || _a === void 0 ? void 0 : _a.index; if (roomIndex === undefined) { throw new Error(`could not find room "${op.params[0]}"`); } state.roomIndex = roomIndex; break; case "set": state.flags[op.params[0]] = 1; break; case "clear": state.flags[op.params[0]] = 0; break; case "zero": return !state.flags[op.params[0]]; case "notzero": return !!state.flags[op.params[0]]; case "continue": return false; default: throw new Error(`invalid op ${op.cmd}`); } return true; } } //# sourceMappingURL=engine.js.map