refactoring
This commit is contained in:
@@ -10,14 +10,11 @@ import { gGame } from "../../models/globals.js";
|
|||||||
|
|
||||||
/** @property {Session} session */
|
/** @property {Session} session */
|
||||||
export class AuthenticationScene extends Scene {
|
export class AuthenticationScene extends Scene {
|
||||||
introText = [
|
|
||||||
"= Welcome!", //
|
|
||||||
];
|
|
||||||
|
|
||||||
/** @type {Player} */
|
/** @type {Player} */
|
||||||
player;
|
player;
|
||||||
|
|
||||||
onReady() {
|
onReady() {
|
||||||
|
this.session.sendText("= Welcome");
|
||||||
this.show(UsernamePrompt);
|
this.show(UsernamePrompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Prompt } from "../prompt.js";
|
||||||
import { Scene } from "../scene.js";
|
import { Scene } from "../scene.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6,7 +7,38 @@ import { Scene } from "../scene.js";
|
|||||||
* It's here we listen for player commands.
|
* It's here we listen for player commands.
|
||||||
*/
|
*/
|
||||||
export class GameScene extends Scene {
|
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
|
= 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
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Scene } from "../scene.js";
|
|||||||
import { CreateUsernamePrompt } from "./createUsernamePrompt.js";
|
import { CreateUsernamePrompt } from "./createUsernamePrompt.js";
|
||||||
|
|
||||||
export class PlayerCreationScene extends Scene {
|
export class PlayerCreationScene extends Scene {
|
||||||
introText = "= Create Player";
|
intro = "= Create Player";
|
||||||
|
|
||||||
/** @protected @type {Player} */
|
/** @protected @type {Player} */
|
||||||
player;
|
player;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Scene } from "../scene.js";
|
|||||||
import { CreateUsernamePrompt } from "./createUsernamePrompt.js";
|
import { CreateUsernamePrompt } from "./createUsernamePrompt.js";
|
||||||
|
|
||||||
export class PlayerCreationScene extends Scene {
|
export class PlayerCreationScene extends Scene {
|
||||||
introText = "= Create Player";
|
intro = "= Create Player";
|
||||||
|
|
||||||
/** @protected @type {Player} */
|
/** @protected @type {Player} */
|
||||||
player;
|
player;
|
||||||
|
|||||||
@@ -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. */
|
/** @type {string|string[]} Default prompt text to send if we don't want to send something in the execute() call. */
|
||||||
promptText = [
|
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
|
"((or type :quit to run away))", // strings in double parentheses is rendered shaded/faintly
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { sprintf } from "sprintf-js";
|
import { sprintf } from "sprintf-js";
|
||||||
|
import { Prompt } from "./prompt.js";
|
||||||
|
|
||||||
/** @typedef {import("../utils/messages.js").WebsocketMessage} WebsocketMessage */
|
/** @typedef {import("../utils/messages.js").WebsocketMessage} WebsocketMessage */
|
||||||
/** @typedef {import("../models/session.js").Session} Session */
|
/** @typedef {import("../models/session.js").Session} Session */
|
||||||
/** @typedef {import("./prompt.js").Prompt } Prompt */
|
/** @typedef {import("./prompt.js").Prompt } Prompt */
|
||||||
|
/** @typedef {new (scene: Scene) => Prompt} PromptClassReference */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scene - a class for showing one or more prompts in a row.
|
* Scene - a class for showing one or more prompts in a row.
|
||||||
@@ -16,13 +18,8 @@ import { sprintf } from "sprintf-js";
|
|||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
export class Scene {
|
export class Scene {
|
||||||
/**
|
/** @constant @readonly @type {string|string[]|PromptClassReference} Text or prompt to show when this scene begins */
|
||||||
* @type {string|string[]} This text is shown when the scene begins
|
intro;
|
||||||
*/
|
|
||||||
introText = "";
|
|
||||||
|
|
||||||
/** @constant @readonly @type {Prompt?} */
|
|
||||||
introPrompt;
|
|
||||||
|
|
||||||
/** @readonly @constant @protected @type {Session} */
|
/** @readonly @constant @protected @type {Session} */
|
||||||
#session;
|
#session;
|
||||||
@@ -47,21 +44,15 @@ export class Scene {
|
|||||||
/** @param {Session} session */
|
/** @param {Session} session */
|
||||||
execute(session) {
|
execute(session) {
|
||||||
this.#session = session;
|
this.#session = session;
|
||||||
|
this.onReady();
|
||||||
if (this.introText) {
|
|
||||||
this.session.sendText(this.introText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.introPrompt) {
|
|
||||||
this.showPrompt(this.introPrompt);
|
|
||||||
} else {
|
|
||||||
this.onReady();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @abstract */
|
|
||||||
onReady() {
|
onReady() {
|
||||||
throw new Error("Abstract method must be implemented by subclass");
|
if (!this.intro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.show(this.intro);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {Prompt} prompt */
|
/** @param {Prompt} prompt */
|
||||||
@@ -70,9 +61,33 @@ export class Scene {
|
|||||||
prompt.execute();
|
prompt.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {new (scene: Scene) => Prompt} promptClassReference */
|
/** @param {string|string[]} text */
|
||||||
show(promptClassReference) {
|
showText(text) {
|
||||||
this.showPrompt(new promptClassReference(this));
|
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,
|
message,
|
||||||
type: typeof 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);
|
this.currentPrompt.onReply(message.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +127,7 @@ export class Scene {
|
|||||||
* - call this method directly
|
* - call this method directly
|
||||||
*/
|
*/
|
||||||
onQuit() {
|
onQuit() {
|
||||||
this.currentPrompt.onQuit();
|
this.currentPrompt?.onQuit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +147,7 @@ export class Scene {
|
|||||||
* @param {WebsocketMessage} message
|
* @param {WebsocketMessage} message
|
||||||
*/
|
*/
|
||||||
onHelp(message) {
|
onHelp(message) {
|
||||||
this.currentPrompt.onHelp(message.text);
|
this.currentPrompt?.onHelp(message.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,7 +205,7 @@ export class Scene {
|
|||||||
* @param {WebsocketMessage} message
|
* @param {WebsocketMessage} message
|
||||||
*/
|
*/
|
||||||
onColon(message) {
|
onColon(message) {
|
||||||
const handledByPrompt = this.currentPrompt.onColon(message.command, message.args);
|
const handledByPrompt = this.currentPrompt?.onColon(message.command, message.args);
|
||||||
|
|
||||||
if (!handledByPrompt) {
|
if (!handledByPrompt) {
|
||||||
this.onColonFallback(message.command, message.args);
|
this.onColonFallback(message.command, message.args);
|
||||||
@@ -203,7 +223,7 @@ export class Scene {
|
|||||||
const n = Number(args[0]);
|
const n = Number(args[0]);
|
||||||
|
|
||||||
this.session.sendText(
|
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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user