// Copyright 2019 Campbell Crowley. All rights reserved. // Author: Campbell Crowley (dev@campbellcrowley.com) const Discord = require('discord.js'); /** * @description Serializable container for data pertaining to a single user. * @memberof HungryGames * @inner */ class Player { /** * @description Create a player object for a game. Requires a unique ID and a * username. * @param {string} id The id of the user this object is representing. * @param {string} username The name of the user to show in the game. * @param {string} avatarURL URL to avatar to show for the user in the game. * @param {?string} [nickname=null] The nickname for this user usually * assigned by the guild. If the user does not have a nickname, this will have * the same value as `name`. */ constructor(id, username, avatarURL = '', nickname = null) { // Replace backtick with Unicode 1FEF Greek Varia because it looks the same, // but it wont ruin formatting. username = username.replace(/`/g, '`'); if (typeof nickname === 'string') nickname = nickname.replace(/`/g, '`'); /** * The id of the User this Player represents. * * @type {string} * @public */ this.id = id; /** * The name of this Player. * * @type {string} * @public */ this.name = username; /** * The URL to the discord avatar of the User. * * @type {string} * @public * @default '' */ this.avatarURL = avatarURL || ''; /** * The nickname for this user usually assigned by the guild. If the user * does * not have a nickname, this will have the same value as `name`. * * @type {string} */ this.nickname = nickname || username; /** * Is the player still alive. * * @type {boolean} * @public * @default */ this.living = true; /** * How many days has the player been wounded. * * @type {number} * @public * @default */ this.bleeding = 0; /** * The current rank of the player in the game. * * @type {number} * @public * @default */ this.rank = 1; /** * The current player state (normal, wounded, dead, zombie). * * @type {string} * @public * @default */ this.state = 'normal'; /** * The number of players this player has caused to die. * * @type {number} * @public * @default */ this.kills = 0; /** * The weapons the player currently has and how many of each. * * @type {object.<number>} * @public * @default */ this.weapons = {}; /** * Custom settings for this user associated with the games. * * @type {object} * @public * @default */ this.settings = {}; /** * The day at which the player last died in the game. Only a valid number if * the player is currently dead. Otherwise a garbage value will be * available. * * @type {number} * @public * @default */ this.dayOfDeath = -1; } } /** * @description Create a Player from a given Discord.User or Player-like Object. * Can be used as a copy-constructor. * * @public * @static * @param { * Discord~User|Discord~GuildMember|object * } member Object, User or GuildMember to make a Player from. * @returns {HungryGames~Player} Player object created. */ Player.from = function(member) { let player; if (typeof member === 'string') { player = new Player(member, member); } else { const isDiscord = (member instanceof Discord.GuildMember) || (member instanceof Discord.User); const user = isDiscord ? member.user || member : member; const avatar = isDiscord ? user.displayAvatarURL({extension: 'png'}) : user.avatarURL; const name = isDiscord ? user.username : member.name; player = new Player(user.id, name, avatar, member.nickname); if (!isDiscord) { if (typeof player.living === 'boolean' || player.living === 'true' || player.living === 'false') { if (typeof player.living !== 'boolean') { player.living = player.living === 'true' ? true : false; } player.living = member.living; } player.bleeding = member.bleeding || 0; player.rank = member.rank || 1; player.state = member.state || 'normal'; player.kills = member.kills || 0; player.weapons = member.weapons || {}; player.settings = member.settings || {}; if (!isNaN(member.dayOfDeath)) { player.dayOfDeath = member.dayOfDeath; } } } return player; }; module.exports = Player;