UNPKG

warframe-worldstate-parser

Version:
289 lines (249 loc) 7.94 kB
'use strict'; const WorldstateObject = require('./WorldstateObject.js'); const SyndicateJob = require('./SyndicateJob.js'); /** * Interim step for an event reward system. * @typedef {Object} InterimStep * * @property {Number} goal Goal amount * @property {Reward} reward Reward for reaching the step * @property {Number} winnerCount Amount of players at this step * @property {Object} message Message received when reaching the interim step */ /** * Progress for one of multiple stages * @typedef {Object} ProgessStep * * @property {string} type * @property {Number} progressAmt */ /** * Represents an in-game special event * * @extends {WorldstateObject} */ class WorldEvent extends WorldstateObject { /** * @param {Object} data The event data * @param {Object} deps The dependencies object * @param {MarkdownSettings} deps.mdConfig The markdown settings * @param {Translator} deps.translator The string translator * @param {TimeDateFunctions} deps.timeDate The time and date functions * @param {Reward} deps.Reward The Reward parser * @param {string} deps.locale Locale to use for translations */ constructor(data, { mdConfig, translator, timeDate, Reward, locale, }) { super(data, { timeDate }); const opts = { translator, mdConfig, Reward, timeDate, locale, }; /** * The markdown settings * @type {MarkdownSettings} * @private */ this.mdConfig = mdConfig; Object.defineProperty(this, 'mdConfig', { enumerable: false, configurable: false }); /** * The time and date functions * @type {TimeDateFunctions} */ this.timeDate = timeDate; Object.defineProperty(this, 'timeDate', { enumerable: false, configurable: false }); /** * The date and time at which the event ends * @type {Date} */ this.expiry = timeDate.parseDate(data.Expiry); /** * The event's main score goal * @type {number} */ this.maximumScore = data.Goal; /** * The current score on the event * @type {number} */ this.currentScore = data.Count; /** * The first intermediate score goal * @type {?number} */ this.smallInterval = data.GoalInterim; /** * The second intermediate score goal * @type {?number} */ this.largeInterval = data.GoalInterim2; /** * The faction that the players must fight in the event * @type {string} */ this.faction = translator.faction(data.Faction, locale); /** * The description of the event * @type {string} */ this.description = translator.languageString(data.Desc, locale); /** * Tooltip for the event * @type {?string} */ this.tooltip = translator.languageString(data.ToolTip, locale); /** * The node where the event takes place * @type {?string} */ this.node = translator.node(data.Node, locale); /** * The other nodes where the event takes place * @type {string[]} */ this.concurrentNodes = data.ConcurrentNodes ? data.ConcurrentNodes.map(n => translator.node(n), locale) : []; /** * The victim node * @type {?string} */ this.victimNode = translator.node(data.VictimNode, locale); /** * The score description * @type {?string} */ this.scoreLocTag = data.Fomorian ? 'Fomorian Assault Score' : translator.languageString(data.ScoreLocTag, locale); /** * The event's rewards * @type {Reward[]} */ this.rewards = Object.keys(data) .filter(k => (k.includes('Reward') || k.includes('reward'))) .map(k => new Reward(data[k], opts)); /** * Whether or not this is expired (at time of object creation) * @type {boolean} */ this.expired = this.getExpired(); /** * Health remaining for the target * @type {Number} */ this.health = typeof data.HealthPct !== 'undefined' ? ((data.HealthPct || 0.00) * 100).toFixed(2) : undefined; if (data.JobAffiliationTag) { this.affiliatedWith = translator.syndicate(data.JobAffiliationTag, locale); if (data.Jobs) { this.jobs = (data.Jobs || []).map(j => new SyndicateJob(j, this.expiry, opts)); } } /** * Array of steps * @type {InterimStep[]} */ this.interimSteps = []; (data.InterimRewards || []).forEach((reward, index) => { const msg = ((data.InterimRewardMessages || [])[index] || {}); this.interimSteps[index] = { goal: data.InterimGoals[index], reward: reward ? new Reward(reward, opts) : undefined, message: { sender: translator.languageString(msg.sender, locale), subject: translator.languageString(msg.subject, locale), message: translator.languageString(msg.message, locale), senderIcon: msg.senderIcon, attachments: msg.attachments, }, winnerCount: (data._interimWinnerCounts || [])[index], }; }); /** * Progress Steps, if any are present * @type {ProgessStep[]} */ this.progressSteps = []; if (data.IsMultiProgress) { data.Types.forEach((type, index) => { this.progressSteps[index] = { type: translator.languageString(type, locale), progressAmt: data.MultiProgress[index], }; }); /** * Total of all MultiProgress * @type {Number} */ this.progressTotal = data.MultiProgress.reduce((accumulator, val) => accumulator + val); } /** * Whether or not to show the total score at the end of the mission * @type {boolean} */ this.showTotalAtEndOfMission = data.ShowTotalAtEOM; /** * Whether or not the event is personal * @type {Boolean} */ this.isPersonal = data.Personal; /** * Whether or not the event is community * @type {Boolean} */ this.isCommunity = data.Community; /** * Affectors for this mission * @type {string[]} */ this.regionDrops = (data.RegionDrops || []) .map(drop => translator.languageString(drop, locale)); /** * Archwing Drops in effect while this event is active * @type {string[]} */ this.archwingDrops = (data.ArchwingDrops || []) .map(drop => translator.languageString(drop, locale)); this.asString = this.toString(); } /** * Get whether or not the event has expired * @returns {boolean} */ getExpired() { return this.timeDate.fromNow(this.expiry) < 0; } /** * The event's string representation * @returns {string} */ toString() { let lines = [ `${this.description} : ${this.faction}`, ]; if (this.scoreLocTag && this.maximumScore) { lines.push(`${this.scoreLocTag} : ${this.maximumScore}`); } if (this.rewards.length) { lines.push('Rewards:'); lines = lines.concat(this.rewards.map(r => r.toString())); } if (this.node) { lines.push(`Battle on ${this.node}`); } if (this.victim) { lines.push(`Protect ${this.victimNode}`); } if (this.health) { lines.push(`${this.health}% Remaining`); } if (this.affiliatedWith) { lines.push(`${this.affiliatedWith} will reward you for performing ` + `${this.jobs.map(job => job.type).join(', ')} job${this.jobs.length > 1 ? 's' : ''}`); } return lines.join(this.mdConfig.lineEnd); } } module.exports = WorldEvent;