// Copyright 2018-2019 Campbell Crowley. All rights reserved. // Author: Campbell Crowley (dev@campbellcrowley.com) /** * @description HG stats for a single user in a single timeframe. * @memberof HungryGames * @inner */ class Stats { /** * @description Create object. * @param {HungryGames~Stats|string} data Data to initialize this stats object * with, or ID of user this instance represents. */ constructor(data) { if (!data || typeof data !== 'object') data = {id: data}; if (typeof data.id !== 'string' || !data.id.match(/^(\d{17,19}|NPC[A-F0-9]+)$/)) { throw new TypeError(`ID is not a valid user ID. (${data.id})`); } /** * @description The ID of the user this object represents. * @public * @type {string} * @constant */ this._id = data.id; /** * @description Cache of all datapoints. All properties must match SQL * database excluding `groupId`, `guildId` and `userId` which must not be * included. * @private * @type {object} * * @property {number} kills Number of kills. * @property {number} deaths Number of deaths. * @property {number} wounds Number of times wounded. * @property {number} heals Number of times wounds have healed. * @property {number} revives Number of times revived. * @property {number} wins Number of games won. * @property {number} losses Number of games lost. * @property {number} daysAlive Number of days spent alive (includes * wounded). * @property {number} daysDead Number of days spent dead. * @property {number} daysWounded Number of days spent wounded. */ this._data = { kills: typeof data.kills === 'number' && data.kills || 0, deaths: typeof data.deaths === 'number' && data.deaths || 0, wounds: typeof data.wounds === 'number' && data.wounds || 0, heals: typeof data.heals === 'number' && data.heals || 0, revives: typeof data.revives === 'number' && data.revives || 0, wins: typeof data.wins === 'number' && data.wins || 0, losses: typeof data.losses === 'number' && data.losses || 0, daysAlive: typeof data.daysAlive === 'number' && data.daysAlive || 0, daysDead: typeof data.daysDead === 'number' && data.daysDead || 0, daysWounded: typeof data.daysWounded === 'number' && data.daysWounded || 0, }; this.get = this.get.bind(this); } /** * @description The ID this of the user this object represents. * @public * @returns {string} User ID. */ get id() { return this._id; } /** * @description Fetch the value of a certain data point. * @public * @param {string} key The name of the datapoint. * @returns {?number} The value, or undefined if unable to be found. */ get(key) { return this._data[key]; } /** * @description Get array of all keys stored by this object. * @public * @returns {string[]} Array of all keys. */ get keys() { return Object.keys(this._data); } /** * @description Get array of all keys stored by this object when requested * from a static scope. * @public * @static * @returns {string[]} Array of all keys. */ static get keys() { return new Stats('0000000000000000000').keys; } /** * @description Set a value for a certain datapoint. * @public * @param {string} key The name of this datapoint. * @param {number} value The new value to set. */ set(key, value) { if (typeof value !== 'number') throw new TypeError('Value is not a number'); if (typeof this._data[key] === 'undefined') throw new Error('Unknown key'); this._data[key] = value; } /** * @description Fetch the data stored here as a serializable object. * @public * @returns {object} Reference to serializable data. */ get serializable() { return this._data; } /** * @description Create a Stats object instance from a Stats-like object. * @public * @static * @param {object} obj The object to create a Stats instance of. * @returns {HungryGames~Stats} The created instance. */ static from(obj) { return new Stats(obj); } } module.exports = Stats;