diff --git a/scenes/authentication/authenticationScene.js b/scenes/authentication/authenticationScene.js index 4ce939d..7c4a066 100755 --- a/scenes/authentication/authenticationScene.js +++ b/scenes/authentication/authenticationScene.js @@ -10,14 +10,11 @@ import { gGame } from "../../models/globals.js"; /** @property {Session} session */ export class AuthenticationScene extends Scene { - introText = [ - "= Welcome!", // - ]; - /** @type {Player} */ player; onReady() { + this.session.sendText("= Welcome"); this.show(UsernamePrompt); } diff --git a/scenes/gameLoop/gameScene.js b/scenes/gameLoop/gameScene.js index 606d9f5..80cb94f 100755 --- a/scenes/gameLoop/gameScene.js +++ b/scenes/gameLoop/gameScene.js @@ -1,3 +1,4 @@ +import { Prompt } from "../prompt.js"; import { Scene } from "../scene.js"; /** @@ -6,7 +7,38 @@ import { Scene } from "../scene.js"; * It's here we listen for player commands. */ export class GameScene extends Scene { - introText = ` + onReady() { + // + // Find out which state the player and their characters are in + // Find out where we are + // Re-route to the relevant scene if necessary. + // + // IF player has stored state THEN + // restore it and resume [main flow] + // END + // + // IF player has no characters THEN + // go to createCharacterScene + // END + // + // set player's current location = Hovedstad + // display the welcome to Hovedstad stuff, and + // await the player's commands. + // + // + // IDEA: + // Does a player have a previous state? + // The state that was on the previous session? + // + // If player does not have a previous session + // then we start in the Adventurers Guild in the Hovedstad + // + this.show(GameScenePlaceholderPrompt); + } +} + +class GameScenePlaceholderPrompt extends Prompt { + promptText = ` ▄ █▐▀▀▀▌▄ █ ▐▀▀▀▌▌▓▌ @@ -49,33 +81,6 @@ export class GameScene extends Scene { = Welcome to Hovedstad +(( type :quit to quit )) `; - - onReady() { - // - // Find out which state the player and their characters are in - // Find out where we are - // Re-route to the relevant scene if necessary. - // - // IF player has stored state THEN - // restore it and resume [main flow] - // END - // - // IF player has no characters THEN - // go to createCharacterScene - // END - // - // set player's current location = Hovedstad - // display the welcome to Hovedstad stuff, and - // await the player's commands. - // - // - // IDEA: - // Does a player have a previous state? - // The state that was on the previous session? - // - // If player does not have a previous session - // then we start in the Adventurers Guild in the Hovedstad - // - } } diff --git a/scenes/playerCreation/playerCreationScene.js b/scenes/playerCreation/playerCreationScene.js index 3de20dd..0bd1c48 100755 --- a/scenes/playerCreation/playerCreationScene.js +++ b/scenes/playerCreation/playerCreationScene.js @@ -5,7 +5,7 @@ import { Scene } from "../scene.js"; import { CreateUsernamePrompt } from "./createUsernamePrompt.js"; export class PlayerCreationScene extends Scene { - introText = "= Create Player"; + intro = "= Create Player"; /** @protected @type {Player} */ player; diff --git a/scenes/playerCreation/playerCreationSene.js b/scenes/playerCreation/playerCreationSene.js index 3de20dd..0bd1c48 100755 --- a/scenes/playerCreation/playerCreationSene.js +++ b/scenes/playerCreation/playerCreationSene.js @@ -5,7 +5,7 @@ import { Scene } from "../scene.js"; import { CreateUsernamePrompt } from "./createUsernamePrompt.js"; export class PlayerCreationScene extends Scene { - introText = "= Create Player"; + intro = "= Create Player"; /** @protected @type {Player} */ player; diff --git a/scenes/prompt.js b/scenes/prompt.js index b74120b..bf11234 100755 --- a/scenes/prompt.js +++ b/scenes/prompt.js @@ -43,7 +43,7 @@ export class Prompt { /** @type {string|string[]} Default prompt text to send if we don't want to send something in the execute() call. */ promptText = [ - "Please enter some very important info", // Stupid placeholder text + "Please enter some very important info", // Silly placeholder text "((or type :quit to run away))", // strings in double parentheses is rendered shaded/faintly ]; diff --git a/scenes/scene.js b/scenes/scene.js index 9911980..f035d53 100755 --- a/scenes/scene.js +++ b/scenes/scene.js @@ -1,8 +1,10 @@ import { sprintf } from "sprintf-js"; +import { Prompt } from "./prompt.js"; /** @typedef {import("../utils/messages.js").WebsocketMessage} WebsocketMessage */ /** @typedef {import("../models/session.js").Session} Session */ /** @typedef {import("./prompt.js").Prompt } Prompt */ +/** @typedef {new (scene: Scene) => Prompt} PromptClassReference */ /** * Scene - a class for showing one or more prompts in a row. @@ -16,13 +18,8 @@ import { sprintf } from "sprintf-js"; * @abstract */ export class Scene { - /** - * @type {string|string[]} This text is shown when the scene begins - */ - introText = ""; - - /** @constant @readonly @type {Prompt?} */ - introPrompt; + /** @constant @readonly @type {string|string[]|PromptClassReference} Text or prompt to show when this scene begins */ + intro; /** @readonly @constant @protected @type {Session} */ #session; @@ -47,21 +44,15 @@ export class Scene { /** @param {Session} session */ execute(session) { this.#session = session; - - if (this.introText) { - this.session.sendText(this.introText); - } - - if (this.introPrompt) { - this.showPrompt(this.introPrompt); - } else { - this.onReady(); - } + this.onReady(); } - /** @abstract */ onReady() { - throw new Error("Abstract method must be implemented by subclass"); + if (!this.intro) { + return; + } + + this.show(this.intro); } /** @param {Prompt} prompt */ @@ -70,9 +61,33 @@ export class Scene { prompt.execute(); } - /** @param {new (scene: Scene) => Prompt} promptClassReference */ - show(promptClassReference) { - this.showPrompt(new promptClassReference(this)); + /** @param {string|string[]} text */ + showText(text) { + this.session.sendText(text); + } + + /** @param {PromptClassReference|string|string[]|Prompt} value */ + show(value) { + if (value instanceof Prompt) { + this.showPrompt(value); + return; + } + + if (typeof value === "string" || typeof value[0] === "string") { + this.showText(value); + return; + } + + if (typeof value !== "function") { + throw new Error("Invalid type. Value must be string, string[], Prompt, or a class reference to Prompt"); + } + + const prompt = new value(this); + if (!(prompt instanceof Prompt)) { + throw new Error("Invalid class reference"); + } + + this.showPrompt(new value(this)); } /** @@ -91,6 +106,11 @@ export class Scene { message, type: typeof message, }); + + if (!this.currentPrompt) { + throw new Error("LogicError: cannot get a reply when you have not prompted the player"); + } + this.currentPrompt.onReply(message.text); } @@ -107,7 +127,7 @@ export class Scene { * - call this method directly */ onQuit() { - this.currentPrompt.onQuit(); + this.currentPrompt?.onQuit(); } /** @@ -127,7 +147,7 @@ export class Scene { * @param {WebsocketMessage} message */ onHelp(message) { - this.currentPrompt.onHelp(message.text); + this.currentPrompt?.onHelp(message.text); } /** @@ -185,7 +205,7 @@ export class Scene { * @param {WebsocketMessage} message */ onColon(message) { - const handledByPrompt = this.currentPrompt.onColon(message.command, message.args); + const handledByPrompt = this.currentPrompt?.onColon(message.command, message.args); if (!handledByPrompt) { this.onColonFallback(message.command, message.args); @@ -203,7 +223,7 @@ export class Scene { const n = Number(args[0]); this.session.sendText( - sprintf("%.2f centimeters is only %.2f inches. This is american wands are so short!", n, n / 2.54), + sprintf("%.2f centimeters is only %.2f inches. This is why american wands are so short!", n, n / 2.54), ); } diff --git a/test.js b/test.js index 516eb05..fc17164 100644 --- a/test.js +++ b/test.js @@ -22,4 +22,4 @@ class TestChild extends TestParent { } } -console.log(new TestChild()); +console.log(Function.prototype.toString.call(TestChild));