/* * The game object holds everything. * All the locations, players, characters, items, npcs, quests, loot, etc. * * It is a pseudo-singleton in that you should only ever create one. * * Serializing this object effectively saves the game. */ import { isIdSane, miniUid } from "../utils/id.js"; import { Character } from "./character.js"; import { ItemAttributes, ItemBlueprint } from "./item.js"; import { Player } from "./player.js"; export class Game { /** @type {Map} List of all item blueprints in the game */ _itemBlueprints = new Map(); /** @type {Map} The list of locations in the game */ _locations = new Map(); /** * The characters in the game. * * @protected * @type {Map} */ _characters = new Map(); /* * @protected * @type {Map} Map of users in the game username->Player */ _players = new Map(); getPlayer(username) { return this._players.get(username); } /** * Atomic player creation. * * @param {string} username * @param {string?} passwordHash * @param {string?} salt * * @returns {Player|null} Returns the player if username wasn't already taken, or null otherwise. */ createPlayer(username, passwordHash = undefined, salt = undefined) { if (this._players.has(username)) { return false; } const player = new Player( username, typeof passwordHash === "string" ? passwordHash : "", typeof salt === "string" && salt.length > 0 ? salt : miniUid(), ); this._players.set(username, player); return player; } /** * Create an ItemBlueprint with a given blueprintId * * @param {string} blueprintId * @param {ItemAttributes} attributes * * @returns {ItemBlueprint|false} */ addItemBlueprint(blueprintId, attributes) { console.log(attributes); if (typeof blueprintId !== "string" || !blueprintId) { throw new Error("Invalid blueprintId!"); } const existing = this._itemBlueprints.get(blueprintId); if (existing) { console.debug("we tried to create the same item blueprint more than once", blueprintId, attributes); return existing; } attributes.blueprintId = blueprintId; const result = new ItemBlueprint(attributes); this._itemBlueprints.set(blueprintId, result); return result; } /** * @param {string} blueprintId * @returns {ItemBlueprint?} */ getItemBlueprint(blueprintId) { if (!isIdSane(blueprintId)) { throw new Error(`blueprintId >>${blueprintId}<< is insane!`); } const tpl = this._itemBlueprints.get(blueprintId); return tpl || undefined; } }