From 8f6d7e4db494580014be2d734182894821e0eac5 Mon Sep 17 00:00:00 2001 From: nolwn Date: Mon, 31 May 2021 12:12:34 -0700 Subject: [PATCH] Describe room exits --- Scene.ts | 26 ++++++++- data/rooms.ts | 152 ++++++++++++++++++++++++++++---------------------- main.ts | 4 +- types.ts | 99 ++++++++++++++++++-------------- 4 files changed, 168 insertions(+), 113 deletions(-) diff --git a/Scene.ts b/Scene.ts index 3a6ab33..75740cc 100644 --- a/Scene.ts +++ b/Scene.ts @@ -2,7 +2,7 @@ * Scene.ts contains the Scene class. It represents the state of the current scene. */ -import { StoryScene, Item, SceneProperties } from "./types.ts"; +import type { Exit, StoryScene, Item, SceneProperties } from "./types.ts"; import Vessel from "./Vessel.ts"; // The Scene is a type of "Vessel" which is a generic object that can have effects @@ -23,11 +23,16 @@ export default class Scene extends Vessel { // description of the items in the scene const itemsDescription = super.description(properties.items || []); - const { description } = properties; // description of the room + const { description, exits = [] } = properties; // description of the room // will be a string that includes both the room and item descriptions let fullDescription = description || "Nothing to see here..."; + const exitsDescription = Scene.describeExits(exits); + + fullDescription += + exitsDescription && `\n\nThere is ${exitsDescription}.`; + // if there is a description of the items... if (itemsDescription) { fullDescription += `\n\nThere is ${itemsDescription}`; @@ -52,4 +57,21 @@ export default class Scene extends Vessel { // if an item wasn't found and returned, return null return null; } + + // Turn exits into a string description with an "and" separating the last two items + private static describeExits(exits: Exit[]) { + const exitDescriptions = exits.map(({ description }) => description); + if (exits.length === 0) { + return ""; + } else if (exits.length === 1) { + return exitDescriptions[0]; + } else { + const lastExit = exitDescriptions[exitDescriptions.length - 1]; + const restExits = exitDescriptions.slice( + 0, + exitDescriptions.length - 1 + ); + return `${restExits.join(", ")} and ${lastExit}`; + } + } } diff --git a/data/rooms.ts b/data/rooms.ts index 6da1628..fdad51c 100644 --- a/data/rooms.ts +++ b/data/rooms.ts @@ -9,81 +9,99 @@ import { StoryScene, SceneProperties } from "../types.ts"; -// hall represents a room -export const hall: StoryScene = { - // properties represent the base, default state for this room. - properties: { - // This is what the user will see if the look while in the room. - description: "It's very dark", - // This array lists all the items that are in the room. - items: [ - // flashlight is an item that can be used. When it is, it applies an effect - // to the room that it's being used in. - { - name: "flashlight", - actions: { - // Use is the name of the ActionTerm that will be used here. If a - // player types "use flashlight" then this describes what should - // happen. - use: { - // These are the pieces of information that the engine needs to - // exectue a use action of type "applyEffect." - args: { - // This is the name of the effect. It is defined in this file - // and should correspond to some condition on the player or - // scene. - effect: "flashlight-on", +const game: { map: StoryScene[] } = { + map: [ + { + // properties represent the base, default state for this room. + properties: { + // This is what the user will see if the look while in the room. + description: "It's very dark", + // This array lists all the items that are in the room. + items: [ + // flashlight is an item that can be used. When it is, it applies an effect + // to the room that it's being used in. + { + name: "flashlight", + actions: { + // Use is the name of the ActionTerm that will be used here. If a + // player types "use flashlight" then this describes what should + // happen. + use: { + // These are the pieces of information that the engine needs to + // exectue a use action of type "applyEffect." + args: { + // This is the name of the effect. It is defined in this file + // and should correspond to some condition on the player or + // scene. + effect: "flashlight-on", - // can be "player" or "scene" - applyTo: "player", + // can be "player" or "scene" + applyTo: "player", - // When it's used, this is what should be reported back to - // the user. - result: "The flashlight is on.", + // When it's used, this is what should be reported back to + // the user. + result: "The flashlight is on.", - // If the effect is reversed—unapplied—this is what should be - // reported back to the user. - reverseResult: "The flashlight is off.", + // If the effect is reversed—unapplied—this is what should be + // reported back to the user. + reverseResult: "The flashlight is off.", - // This indicates that the effect can be unapplied after it - // is applied. This should be done by calling use again after - // it has already been called and the effect has been applied. - reversible: true, + // This indicates that the effect can be unapplied after it + // is applied. This should be done by calling use again after + // it has already been called and the effect has been applied. + reversible: true, + }, + // applyEffect means that when this item is used, it will apply + // an effect to either the player or the scene. + type: "applyEffect", + }, }, - // applyEffect means that when this item is used, it will apply - // an effect to either the player or the scene. - type: "applyEffect", }, - }, + ], + // exit to the north leads to the Hall Closet + exits: [ + { + description: "a closet to the north", + direction: "north", + scene: "Hall Closet", + }, + { + description: "a dining room to the south", + direction: "south", + scene: "Dining Room", + }, + ], }, - ], - }, - // conditions are a set of conditions that, when met, will make alterations to the - // player or the scene. - conditions: { - // effects are conditions that revolve around effects that have been applied to - // either the player or the scene. - effects: [ - { - // This is the name of the effect that, if present, will make alterations - // to the scene. - name: "flashlight-on", + // conditions are a set of conditions that, when met, will make alterations to the + // player or the scene. + conditions: { + // effects are conditions that revolve around effects that have been applied to + // either the player or the scene. + effects: [ + { + // This is the name of the effect that, if present, will make alterations + // to the scene. + name: "flashlight-on", - // properties describes the properties on the scene that will be altered - // by the presents of this effect. - properties: { - // description means that, when this effect is applied, i.e. when - // the flashlight is on, the description will change to the one - // written here. - description: - "You are standing in a big hall. There's lots of nooks, " + - "crannies, and room for general testing. Aw yeah... sweet testing!", - }, + // properties describes the properties on the scene that will be altered + // by the presents of this effect. + properties: { + // description means that, when this effect is applied, i.e. when + // the flashlight is on, the description will change to the one + // written here. + description: + "You are standing in a big hall. There's lots of nooks, " + + "crannies, and room for general testing. Aw yeah... sweet testing!", + }, - // source indicates where the effect should be applied. In this case, the - // effect should be applied to the player. - source: "player", + // source indicates where the effect should be applied. In this case, the + // effect should be applied to the player. + source: "player", + }, + ], }, - ], - }, + }, + ], }; + +export default game; diff --git a/main.ts b/main.ts index 12bebf5..d2d78a2 100644 --- a/main.ts +++ b/main.ts @@ -2,11 +2,11 @@ import Interpreter from "./Interpreter.ts"; import Player from "./Player.ts"; import Scene from "./Scene.ts"; import User from "./User.ts"; -import { hall } from "./types.ts"; +import game from "./data/rooms.ts"; async function main() { const user = new User(); // for communication with the user - const scene = new Scene(hall); // the room that player is in. + const scene = new Scene(game.map[0]); // the room that player is in. const player = new Player(); // the players current state let running = true; // running flag for the game loop. Stops on false. let statement = ""; // holds a statement for the user. diff --git a/types.ts b/types.ts index ac8dabe..cd43111 100644 --- a/types.ts +++ b/types.ts @@ -1,27 +1,7 @@ -/** - * types.ts describes basic types used by the engine. - */ - -export * from "./data/rooms.ts"; - // ActionArgs is a union of all the different argument types that can be used with an // action export type ActionArgs = ApplyEffectArgs; -// ItemActionType is a union of all the types of action that can be used -export type ItemActionType = "applyEffect"; - -// Args is a base interface for the various argument interfaces -export interface Args { - result: string; -} - -// ItemAction represents an action that can be taken by an item -export interface ItemAction { - type: ItemActionType; - args: ActionArgs; -} - // ApplyEffectArgs are the arguments required to apply effects to a player or scene export interface ApplyEffectArgs extends Args { effect: string; @@ -36,28 +16,9 @@ export interface ApplyEffectItemAction extends ItemAction { args: ApplyEffectArgs; } -// Item represents some item either in the scene or in the player's inventory -export interface Item { - name: string; - actions: { [name: string]: ItemAction }; -} - -// Effect represents some effect that may be applied to a scene or player -export interface Effect { - name: string; - properties: T; - source: "player" | "scene"; // where the effect is applied -} - -// VesselProperties is a base interface for the properties that a user or scene might have -export interface VesselProperties { - items?: Item[]; -} - -// SceneProperties are the properties (in addition to the VesselProperties) that are -// needed by the scene -export interface SceneProperties extends VesselProperties { - description?: string; +// Args is a base interface for the various argument interfaces +export interface Args { + result: string; } // Conditions contains story elements that can be conditionally applied to the scene or @@ -66,8 +27,62 @@ export interface Conditions { effects: Effect[]; } +// Direction is union that contains the different directions a player can go +export type Direction = + | "north" + | "northeast" + | "east" + | "southest" + | "south" + | "southwest" + | "west" + | "northwest" + | "up" + | "down"; + +// Effect represents some effect that may be applied to a scene or player +export interface Effect { + name: string; + properties: T; + source: "player" | "scene"; // where the effect is applied +} + +// Exit describes the exits that the user can take to go to another scene +export interface Exit { + description: string; + direction: Direction; + scene: string; +} + +// Item represents some item either in the scene or in the player's inventory +export interface Item { + name: string; + actions: { [name: string]: ItemAction }; +} + +// ItemActionType is a union of all the types of action that can be used +export type ItemActionType = "applyEffect"; + +// ItemAction represents an action that can be taken by an item +export interface ItemAction { + type: ItemActionType; + args: ActionArgs; +} + +// SceneProperties are the properties (in addition to the VesselProperties) that are +// needed by the scene +export interface SceneProperties extends VesselProperties { + description?: string; + exits?: Exit[]; +} + // StoryScene holds both the conditions and properties for a scene. export interface StoryScene { conditions: Conditions; properties: SceneProperties; } + +// VesselProperties is a base interface for the properties that a user or scene might have +export interface VesselProperties { + items?: Item[]; +}