import State from './state'; import Room from './room'; import Player from './player'; import Output from './output'; import Input from './input'; import Commands from './commands'; export default class Game { constructor() { this.player = new Player(); this.state = State; this.rooms = []; this.items = []; this.output = new Output(); this.commandHandler = new Commands(this); this.input = new Input(this.commandHandler, this.output); this.visitedRooms = new Map(); this.interval = null; } print(string) { this.output.say(string); } init(data) { this.rooms = data.rooms.map((room) => { room.context = this; return room; }); this.items = data.items.map((item) => { item.context = this; return item; }); this.state = data.state || State; this.commandHandler.addCommands(data.commands); this.player = new Player(); this.player.context = this; this.move(this.player.currentRoom); this.start(); } advanceTick() { this.items.forEach((item) => item.onTick()); this.rooms.forEach((room) => room.onTick()); } start() { this.interval = setInterval(() => this.advanceTick(), 1000); } stop() { clearInterval(this.interval); this.interval = null; } examineRoom() { const room = this.getRoom(this.player.currentRoom); this.output.say(room.title); if (!this.visitedRooms.get(this.player.currentRoom) && room.firstDescription != "") { this.output.say(room.firstDescription); } else { this.output.say(room.description); } this.examineItems(); this.examineExits(); } examineItems() { const room = this.getRoom(this.player.currentRoom); const items = room.getItems(); if (items.length < 1) return; let itemDescription = `You see `; items.forEach((item, index) => { if (index < items.length - 2) { itemDescription += `${item.name}, `; } else if (index < items.length - 1) { itemDescription += `${item.name} and `; } else { itemDescription += item.name } }); this.output.say(itemDescription + "."); } examineExits() { const room = this.getRoom(this.player.currentRoom); let exits = []; let exitDescription = "You can go "; const exitKeys = room.exits.keys(); for (let exit of exitKeys) { exits.push(exit); } exits.forEach((item, index) => { if (index < exits.length - 2) { exitDescription += `${item}, `; } else if (index < exits.length - 1) { exitDescription += `${item} and `; } else { exitDescription += item } }); this.output.say(exitDescription + "."); } getRoom(id) { return this.rooms.find((room) => room.id == id); } getItem(id) { return this.items.find((item) => item.id == id); } wait(ms) { return new Promise((resolve, reject) => { setTimeout(resolve, ms); }); } async move(roomID) { const currentRoom = this.getRoom(this.player.currentRoom); const newRoom = this.getRoom(roomID); if (currentRoom.canExit() && newRoom.canEnter()) { await currentRoom.onExit(); await newRoom.onEnter(); this.player.currentRoom = roomID; this.examineRoom(); this.visitedRooms.set(roomID, true); } } enableCommandInput(value) { this.commandHandler.enabled = value; } setInputEcho(value) { this.input.setEcho(value); } }