diff --git a/src/commands/Worldstate/SteelPath.js b/src/commands/Worldstate/SteelPath.js new file mode 100644 index 000000000..2a2f0d7e6 --- /dev/null +++ b/src/commands/Worldstate/SteelPath.js @@ -0,0 +1,21 @@ +'use strict'; + +const Command = require('../../models/Command.js'); +const SteelPathEmbed = require('../../embeds/SteelPathEmbed'); + +module.exports = class SteelPath extends Command { + constructor(bot) { + super(bot, 'warframe.worldstate.steelpath', 'steelpath', 'Display the currently active Steel Path Rotating offering.', 'WARFRAME'); + } + + async run(message, ctx) { + const offering = await this.ws.get('steelPath', ctx.platform, ctx.language); + if (!offering.currentReward) { + await this.messageManager.sendMessage(message, 'There is currently no Steel Path Offering', true, true); + return this.messageManager.statuses.FAILURE; + } + const embed = new SteelPathEmbed(this.bot, offering, { isCommand: true, i18n: ctx.i18n }); + await this.messageManager.embed(message, embed, true, false); + return this.messageManager.statuses.SUCCESS; + } +}; diff --git a/src/embeds/SteelPathEmbed.js b/src/embeds/SteelPathEmbed.js new file mode 100644 index 000000000..7eb9d5ee9 --- /dev/null +++ b/src/embeds/SteelPathEmbed.js @@ -0,0 +1,39 @@ +'use strict'; + +const BaseEmbed = require('./BaseEmbed.js'); +const { assetBase, emojify } = require('../CommonFunctions'); + +const steelPathThumb = `${assetBase}/img/steelpath.png`; + +module.exports = class SteelPathEmbed extends BaseEmbed { + constructor(bot, offering, { isCommand = false, i18n }) { + super(); + + const evergreen = [ + { name: i18n`Bishamo Pauldrons Blueprint`, cost: 15 }, + { name: i18n`Bishamo Cuirass Blueprint`, cost: 25 }, + { name: i18n`Bishamo Helmet Blueprint`, cost: 20 }, + { name: i18n`Bishamo Greaves Blueprint`, cost: 25 }, + { name: i18n`10k Kuva`, cost: 15 }, + { name: i18n`Relic Pack`, cost: 15 }, + { name: i18n`Stance Forma Blueprint`, cost: 10 }, + { name: i18n`Trio Orbit Ephermera`, cost: 3 }, + { name: i18n`Crania Ephemera`, cost: 85 }, + ]; + + this.description = `${i18n`**Rotating:**`} ${offering.currentReward.name || offering.currentReward}: ${offering.currentReward.cost || '???'}${isCommand ? emojify('steelessence') : i18n` essence`} + + ${i18n`**Evergreen:**`} + ${evergreen + .map(reward => `:white_small_square: ${reward.name}: ${reward.cost}${isCommand + ? emojify('steelessence') + : i18n` essence`}`) + .join('\n')}`; + + this.footer.text = i18n`Cycles at`; + this.timestamp = offering.expiry; + this.title = i18n`Steel Path Offerings`; + this.thumbnail.url = steelPathThumb; + this.color = 0x43464b; + } +}; diff --git a/src/notifications/Notifier.js b/src/notifications/Notifier.js index dfcd05bc3..38b7de7d7 100644 --- a/src/notifications/Notifier.js +++ b/src/notifications/Notifier.js @@ -53,6 +53,14 @@ async function getThumbnailForItem(query, fWiki) { return ''; } +const asId = (event, label) => { + const uppedTime = new Date(event.expiry); + uppedTime.setMilliseconds(0); + uppedTime.setSeconds(0); + + return `${label}:${uppedTime.getTime()}`; +}; + /** * Returns the number of milliseconds between now and a given date * @param {string} d The date from which the current time will be subtracted @@ -89,6 +97,10 @@ function buildNotifiableData(newData, platform, notified) { ? newData.sortie : undefined, streams: newData.news.filter(n => n.stream && !notified.includes(n.id)), + steelPath: newData.steelPath.currentReward + && !notified.includes(asId(newData.steelPath, 'steelpath')) + ? newData.steelPath + : undefined, syndicateM: newData.syndicateMissions.filter(m => !notified.includes(m.id)), tweets: newData.twitter ? newData.twitter.filter(t => t && !notified.includes(t.uniqueId)) @@ -106,7 +118,7 @@ function buildNotifiableData(newData, platform, notified) { earthCycle: newData.earthCycle, vallisCycle: newData.vallisCycle, arbitration: newData.arbitration && newData.arbitration.enemy - && !notified.includes(`arbitration:${new Date(newData.arbitration.expiry).getTime()}`) + && !notified.includes(asId(newData.arbitration, 'arbitration')) ? newData.arbitration : undefined, outposts: newData.sentientOutposts.active && !notified.includes(newData.sentientOutposts.id), @@ -201,7 +213,7 @@ class Notifier { cetusCycle, earthCycle, vallisCycle, tweets, nightwave, cetusCycleChange, earthCycleChange, vallisCycleChange, featuredDeals, streams, popularDeals, primeAccess, updates, conclave, - cambionCycle, cambionCycleChange, outposts, + cambionCycle, cambionCycleChange, outposts, steelPath, }) { // Send all notifications const cycleIds = []; @@ -236,6 +248,7 @@ class Notifier { this.sendSentientOutposts(outposts, platform); this.sendNightwave(nightwave, platform); this.sendArbitration(arbitration, platform); + this.sendSteelPath(steelPath, platform); cycleIds.push( await this.sendCetusCycle(cetusCycle, platform, cetusCycleChange, notifiedIds), ); @@ -270,14 +283,17 @@ class Notifier { ...rawData.conclaveChallenges.map(cc => cc.id), ...rawData.weeklyChallenges.map(w => w.id), rawData.arbitration && rawData.arbitration.enemy - ? `arbitration:${new Date(rawData.arbitration.expiry).getTime()}` + ? asId(rawData.arbitration, 'arbitration') : 'arbitration:0', ...(rawData.twitter ? rawData.twitter.map(t => t.uniqueId) : []), ...(rawData.nightwave && rawData.nightwave.active ? rawData.nightwave.activeChallenges.map(c => c.id) : []), rawData.sentientOutposts.id, - ]; + rawData.steelPath && rawData.steelPath.expiry + ? asId(rawData.steelPath, 'steelpath') + : 'steelpath:0', + ].filter(a => a); await this.settings.setNotifiedIds(platform, alreadyNotified); logger.silly(`completed sending notifications for ${platform}`); @@ -510,6 +526,19 @@ class Notifier { } } + async sendSteelPath(steelPath, platform) { + if (!steelPath || !steelPath.currentReward) return; + + for (const [locale, i18n] of Object.entries(i18ns)) { + const embed = new embeds.SteelPath({ logger }, steelPath, { isCommand: false, i18n }); + embed.locale = locale; + if (steelPath.currentReward.name && steelPath.currentReward.name.includes('Umbra')) { + await this.broadcaster.broadcast(embed, platform, 'steelpath.umbra'); + } + await this.broadcaster.broadcast(embed, platform, 'steelpath'); + } + } + async sendStreams(newStreams, platform) { return Promise.all(newStreams.map(i => this.broadcaster.broadcast(new embeds.News({ logger }, [i], undefined, platform), platform, 'streams'))); } diff --git a/src/notifications/NotifierUtils.js b/src/notifications/NotifierUtils.js index c9f5a0da2..d34550f5e 100644 --- a/src/notifications/NotifierUtils.js +++ b/src/notifications/NotifierUtils.js @@ -22,6 +22,7 @@ const embeds = { Solaris: require('../embeds/SolarisEmbed'), Nightwave: require('../embeds/NightwaveEmbed'), Outposts: require('../embeds/SentientOutpostEmbed'), + SteelPath: require('../embeds/SteelPathEmbed'), RSS: require('../embeds/RSSEmbed'), }; diff --git a/src/resources/emoji.json b/src/resources/emoji.json index 63acf2e72..bb9fcb9db 100644 --- a/src/resources/emoji.json +++ b/src/resources/emoji.json @@ -33,5 +33,6 @@ "pc": "<:pc:428183152490577928>", "ps4": "<:ps4:428183152448503808>", "swi": "<:switch:471082770974900244>", - "xb1": "<:xb1:428183151467298817>" + "xb1": "<:xb1:428183151467298817>", + "steelessence": "<:SteelEssence:823032629804400703>" } diff --git a/src/resources/trackables.json b/src/resources/trackables.json index ef5d34ecb..8e4f10f95 100644 --- a/src/resources/trackables.json +++ b/src/resources/trackables.json @@ -82,7 +82,8 @@ "nightwave.weekly", "outposts", "cambion.fass", - "cambion.vome" + "cambion.vome", + "steelpath" ], "opts": [ "all",