diff --git a/src/game/Loader.ts b/src/game/Loader.ts index 25eeae6..a87d458 100644 --- a/src/game/Loader.ts +++ b/src/game/Loader.ts @@ -1,6 +1,7 @@ import GameState from './GameState'; import Room from './entities/Room'; import Item from './entities/Item'; +import Transition from './entities/Transition'; export default class Loader { static loadCampaign(name: string): GameState { @@ -14,11 +15,46 @@ export default class Loader { { aliases: ['pick up'], action: () => 'It stows away nicely.' } // just temporarily. ] }); - const room = new Room({ + const start = new Room({ name: 'the room', - description: 'Dry air, murky gray concrete walls, a flickering light bulb hanging from the ceiling... This place makes you feel uncomfortable.', + description: + 'Dry air, murky gray concrete walls, a flickering light bulb hanging from the ceiling... This place makes you feel uncomfortable.', items: [key] }); - return new GameState({ currentRoom: room, inventory: [] }); + const hallway = new Room({ + name: 'long hallway', + description: + 'Speckles of dust dance in the light of a solitary lamp. The hallway extends far into the distance, leaving you unsure about your very being.', + paths: [] + }); + start.paths.push( + new Transition({ + from: start, + to: hallway, + description: 'You enter a long, murky hallway.', + actions: ['enter', 'go through'], + aliases: ['door'] + }) + ); + hallway.paths.push( + new Transition({ + from: hallway, + to: start, + actions: ['enter', 'go through'], + description: 'You leave the hallway and go back.', + aliases: ['door', 'back'] + }) + ); + return new GameState({ + currentRoom: start, + inventory: [ + new Item({ + name: 'long thread', + aliases: ['thread'], + description: 'A long, thin thread of white silk', + actions: [] + }) + ] + }); } } diff --git a/src/game/Vocabulary.ts b/src/game/Vocabulary.ts new file mode 100644 index 0000000..24a7b83 --- /dev/null +++ b/src/game/Vocabulary.ts @@ -0,0 +1,3 @@ +export default class Vocabulary { + private static directionalActions = []; +} \ No newline at end of file diff --git a/src/game/entities/Atmosphere.ts b/src/game/entities/Atmosphere.ts new file mode 100644 index 0000000..b88f92d --- /dev/null +++ b/src/game/entities/Atmosphere.ts @@ -0,0 +1,16 @@ +export class Atmosphere { + readonly color: string; + private static instances: Map = new Map([ + ['dark', new Atmosphere({ color: '#232323' })], + ['wooden', new Atmosphere({color: 'brown'})] + ]); + + protected constructor({color}: {color: string}) { + this.color = color; + } + + public get(mood: string): Atmosphere | undefined { + return Atmosphere.instances.get(mood); + } +} + diff --git a/src/game/entities/Room.ts b/src/game/entities/Room.ts index dd69991..3843078 100644 --- a/src/game/entities/Room.ts +++ b/src/game/entities/Room.ts @@ -1,30 +1,39 @@ import Item from './Item'; +import Transition from './Transition'; export default class Room { name: string; description: string; items: Item[]; + paths: Transition[]; // TODO pathways to other rooms // TODO various event-based messages somehow constructor({ name, description, - items = [] + items = [], + paths = [] }: { name: string; description: string; - items: Item[]; + items?: Item[]; + paths?: Transition[]; }) { this.name = name; this.description = description; this.items = items; + this.paths = paths; } find = (name: string) => { return this.items.find(item => item.name === name || item.aliases.indexOf(name) > -1); }; + explore = (phrase: string) => { + return this.paths.find(path => path.aliases.indexOf(phrase) > -1); + }; + enter = () => { // return [this.description, this.items.reduce((acc: string, item: Item): string => `${acc}, ${item.description}`, 'It holds')]; return [this.description, 'It holds:', ...this.items.map(item => item.description)]; diff --git a/src/game/entities/Transition.ts b/src/game/entities/Transition.ts new file mode 100644 index 0000000..bc159e4 --- /dev/null +++ b/src/game/entities/Transition.ts @@ -0,0 +1,41 @@ +import Room from './Room'; + +export default class Transition { + readonly from: Room; + readonly to: Room; + _blocked: boolean; + readonly description?: string; + readonly aliases: string[]; + readonly actions: string[]; + + constructor({ + from, + to, + actions, + aliases, + description, + blocked + }: { + from: Room; + to: Room; + actions: string[] + aliases: string[] + description?: string; + blocked?: boolean; + }) { + this.from = from; + this.to = to; + this.aliases = aliases; + this.description = description; + this._blocked = blocked || false; + this.actions = actions; + } + + set blocked(blocked: boolean) { + this._blocked = blocked; + } + + get blocked() { + return this._blocked; + } +} diff --git a/src/game/performer.ts b/src/game/performer.ts index 14c0170..dd125a1 100644 --- a/src/game/performer.ts +++ b/src/game/performer.ts @@ -28,7 +28,14 @@ export const perform = (stack: ParsedPhrase[], gameState: GameState): string[] = return [action.perform(argument), message]; } else if (action instanceof DirectionalAction && argument instanceof Direction) { // requires there being a passage in that direction - return [action.perform(argument)]; + const path = gameState.currentRoom.explore(argument.word); + console.log('oh yes', path); + if (path) { + gameState.currentRoom = path.to; + return [action.perform(argument), path.description || 'to somewhere', ...path.to.enter()]; + } else { + return ['there is nothing in that direction']; + } } else { return ['no viable 2-phrase action']; } diff --git a/src/game/words.ts b/src/game/words.ts index cc64291..9c4b62d 100644 --- a/src/game/words.ts +++ b/src/game/words.ts @@ -1,5 +1,5 @@ const singularActions = ['sleep', 'wait', 'die']; -const directions = ['up', 'down', 'left', 'right', 'north', 'south', 'east', 'west']; +const directions = ['up', 'down', 'left', 'right', 'north', 'south', 'east', 'west', 'door', 'back']; const directionalActions = ['go', 'walk', 'run']; const objects = ['door', 'key', 'exit', 'two furry dice']; const objectActions = ['eat', 'open', 'pick up', 'take', 'inspect', 'look at', 'throw', 'stroke'];