Many additions:
Add several new achievements Add price querying with ?b Simplify commands' argument-handling Some spooky stuff New quackgrades Stormy weather Rebalanced some rare-event odds !u buttons Reworked prestige emojis Save on every command Add stonks More temp poll triggers Redemption upgrades more powerful Fuzzy matching for usernames and buyables
This commit is contained in:
parent
6dabe9d85a
commit
ad021cf9a5
|
@ -11,4 +11,4 @@ fetch(url, {
|
||||||
headers: headers
|
headers: headers
|
||||||
// credentials: 'user:passwd'
|
// credentials: 'user:passwd'
|
||||||
}).then(response => response.json())
|
}).then(response => response.json())
|
||||||
.then(json => console.log(json))
|
.then(json => console.log('json', json))
|
||||||
|
|
|
@ -34,6 +34,16 @@ module.exports = {
|
||||||
description: 'I like big bets, and that\'s the truth',
|
description: 'I like big bets, and that\'s the truth',
|
||||||
emoji: 'slot_machine'
|
emoji: 'slot_machine'
|
||||||
},
|
},
|
||||||
|
hugeBets: {
|
||||||
|
name: 'Make a bet over 100T',
|
||||||
|
description: `That's so bonk`,
|
||||||
|
emoji: 'game_die'
|
||||||
|
},
|
||||||
|
mondoBets: {
|
||||||
|
name: 'Make a bet over 100 Quadrillion',
|
||||||
|
description: 'H I G H R O L L E R',
|
||||||
|
emoji: '8ball'
|
||||||
|
},
|
||||||
ignited: {
|
ignited: {
|
||||||
name: 'You light my fire, baby',
|
name: 'You light my fire, baby',
|
||||||
description: 'And you pay attention to descriptions!',
|
description: 'And you pay attention to descriptions!',
|
||||||
|
@ -45,6 +55,72 @@ module.exports = {
|
||||||
description: 'I\'m beginning to feel like a rat god, rat god.',
|
description: 'I\'m beginning to feel like a rat god, rat god.',
|
||||||
emoji: 'mouse2'
|
emoji: 'mouse2'
|
||||||
},
|
},
|
||||||
|
mathematician: {
|
||||||
|
name: 'Own 100 Accountants',
|
||||||
|
description: 'They rejoice at the appearance of a third digit.',
|
||||||
|
emoji: 'male-office-worker'
|
||||||
|
},
|
||||||
|
iPod: {
|
||||||
|
name: 'Own 100 Whales',
|
||||||
|
description: `With the new iPod, you can hold 100's of songs.`,
|
||||||
|
emoji: 'whale'
|
||||||
|
},
|
||||||
|
fire100: {
|
||||||
|
name: 'Own 100 Fires',
|
||||||
|
description: `Wow, that's bright.`,
|
||||||
|
emoji: 'fire'
|
||||||
|
},
|
||||||
|
train100: {
|
||||||
|
name: 'Own 100 Trains',
|
||||||
|
description: `That's every train in America you've got there.`,
|
||||||
|
emoji: 'train2'
|
||||||
|
},
|
||||||
|
boom100: {
|
||||||
|
name: 'Own 100 Boomerangs',
|
||||||
|
description: `LOUD WOOSHING`,
|
||||||
|
emoji: 'boomerang'
|
||||||
|
},
|
||||||
|
moon100: {
|
||||||
|
name: 'Own 100 Moons',
|
||||||
|
description: `Space Cadet`,
|
||||||
|
emoji: 'new_moon_with_face'
|
||||||
|
},
|
||||||
|
mirror100: {
|
||||||
|
name: 'Own 100 Mirrors',
|
||||||
|
description: `Disco Ball`,
|
||||||
|
emoji: 'mirror'
|
||||||
|
},
|
||||||
|
butterfly100: {
|
||||||
|
name: 'Own 100 Butterflies',
|
||||||
|
description: `Delicate yet powerful.`,
|
||||||
|
emoji: 'butterfly'
|
||||||
|
},
|
||||||
|
quade100: {
|
||||||
|
name: 'Own 100 Quades',
|
||||||
|
description: `Your Ops are super Devved right now.`,
|
||||||
|
emoji: 'quade'
|
||||||
|
},
|
||||||
|
hvacker100: {
|
||||||
|
name: 'Own 100 Hvackers',
|
||||||
|
description: `Did Sage finally make his git repo public?`,
|
||||||
|
emoji: 'hvacker_angery'
|
||||||
|
},
|
||||||
|
creator100: {
|
||||||
|
name: 'Own 100 Creators',
|
||||||
|
description: `_Stern look_`,
|
||||||
|
emoji: 'question'
|
||||||
|
},
|
||||||
|
smallBusiness100: {
|
||||||
|
name: 'Own 100 Small Businesses',
|
||||||
|
description: `Enough to run a small city.`,
|
||||||
|
emoji: 'convenience_store'
|
||||||
|
},
|
||||||
|
bigBusiness100: {
|
||||||
|
name: 'Own 100 Big Businesses',
|
||||||
|
description: `I mean... that's basically all of them.`,
|
||||||
|
emoji: 'office'
|
||||||
|
},
|
||||||
|
|
||||||
weAllNeedHelp: {
|
weAllNeedHelp: {
|
||||||
name: 'View the \'!coin\' help',
|
name: 'View the \'!coin\' help',
|
||||||
description: 'We all need a little help sometimes',
|
description: 'We all need a little help sometimes',
|
||||||
|
@ -85,5 +161,11 @@ module.exports = {
|
||||||
name: 'Take a peek at the lore',
|
name: 'Take a peek at the lore',
|
||||||
description: 'It\'t gotta be worth your time somehow.',
|
description: 'It\'t gotta be worth your time somehow.',
|
||||||
emoji: 'books'
|
emoji: 'books'
|
||||||
|
},
|
||||||
|
|
||||||
|
theOtherSide: {
|
||||||
|
name: 'Die and be reborn',
|
||||||
|
description: 'You have seen the other side, and do not fear it.',
|
||||||
|
emoji: 'white_square'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const buyableItems = require('./buyableItems')
|
const buyableItems = require('./buyableItems')
|
||||||
const { commas, saveGame, setHighestCoins, addAchievement, getUser, singleItemCps, chaosFilter } = require('./utils')
|
const { commas, setHighestCoins, addAchievement, getUser, singleItemCps, chaosFilter, fuzzyMatcher } = require('./utils')
|
||||||
const slack = require('../../slack')
|
const slack = require('../../slack')
|
||||||
|
|
||||||
const calculateCost = ({ itemName, user, quantity = 1 }) => {
|
const calculateCost = ({ itemName, user, quantity = 1 }) => {
|
||||||
|
@ -17,9 +17,9 @@ const getItemHeader = user => ([itemName, { baseCost, description, emoji }]) =>
|
||||||
const itemCps = Math.round(singleItemCps(user, itemName))
|
const itemCps = Math.round(singleItemCps(user, itemName))
|
||||||
return `*${itemName}* :${emoji}: - ${itemCost} HVAC Coins - ${commas(itemCps)} CPS\n_${description}_`
|
return `*${itemName}* :${emoji}: - ${itemCost} HVAC Coins - ${commas(itemCps)} CPS\n_${description}_`
|
||||||
}
|
}
|
||||||
const canView = highestCoins => ([, item]) => item.baseCost < (highestCoins || 1) * 101
|
const canView = (item, highestCoins) => item.baseCost < (highestCoins || 1) * 101
|
||||||
const buyableText = (highestCoins, user) => Object.entries(buyableItems)
|
const buyableText = (highestCoins, user) => Object.entries(buyableItems)
|
||||||
.filter(canView(highestCoins))
|
.filter(([, item]) => canView(item, highestCoins))
|
||||||
.map(getItemHeader(user))
|
.map(getItemHeader(user))
|
||||||
.join('\n\n') +
|
.join('\n\n') +
|
||||||
'\n\n:grey_question::grey_question::grey_question:' +
|
'\n\n:grey_question::grey_question::grey_question:' +
|
||||||
|
@ -73,8 +73,8 @@ const buyText2 = (highestCoins, user) => {
|
||||||
return ({
|
return ({
|
||||||
text: buyableText(highestCoins, user),
|
text: buyableText(highestCoins, user),
|
||||||
blocks: Object.entries(buyableItems)
|
blocks: Object.entries(buyableItems)
|
||||||
.filter(canView(highestCoins))
|
.filter(([, item]) => canView(item, highestCoins))
|
||||||
.map(([itemName, item]) => {
|
.map(([itemName]) => {
|
||||||
const cost = calculateCost({ itemName, user, quantity: 1 })
|
const cost = calculateCost({ itemName, user, quantity: 1 })
|
||||||
const cps = Math.round(singleItemCps(user, itemName))
|
const cps = Math.round(singleItemCps(user, itemName))
|
||||||
return ({ user, itemName, cost, cps })
|
return ({ user, itemName, cost, cps })
|
||||||
|
@ -90,58 +90,65 @@ const maxQuantity = ({ itemName, user, currentCoins }) => {
|
||||||
return quantity
|
return quantity
|
||||||
}
|
}
|
||||||
|
|
||||||
const buyRoute = async ({ event, say, words, user }) => {
|
const buyRoute = async ({ event, say, args, user }) => {
|
||||||
const buying = words[1]
|
const buying = args[0]
|
||||||
setHighestCoins(event.user)
|
setHighestCoins(event.user)
|
||||||
|
const query = event?.text?.startsWith('?b ') || event?.text?.startsWith('?buy ')
|
||||||
|
|
||||||
if (!buying) {
|
if (!buying) {
|
||||||
const highestCoins = user.highestEver || user.coins || 1
|
const highestCoins = user.highestEver || user.coins || 1
|
||||||
if (buyableItems.quade.baseCost < highestCoins * 100) {
|
if (canView(buyableItems.quade, highestCoins)) {
|
||||||
addAchievement(user, 'seeTheQuade', say)
|
addAchievement(user, 'seeTheQuade', say)
|
||||||
}
|
}
|
||||||
await say(buyText2(highestCoins, user))
|
await say(buyText2(highestCoins, user))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const buyable = buyableItems[buying]
|
const matcher = fuzzyMatcher(buying)
|
||||||
|
const buyable = Object.entries(buyableItems).find(([name]) => matcher.test(name))
|
||||||
if (!buyable) {
|
if (!buyable) {
|
||||||
await say('That item does not exist!')
|
await say('That item does not exist!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [buyableName, buyableItem] = buyable
|
||||||
let quantity
|
let quantity
|
||||||
const currentCoins = user.coins
|
const currentCoins = user.coins
|
||||||
const max = maxQuantity({ itemName: buying, user, currentCoins })
|
const max = maxQuantity({ itemName: buyableName, user, currentCoins })
|
||||||
if (words[2] === 'max') {
|
if (!args[1]) {
|
||||||
|
quantity = 1
|
||||||
|
} else if (args[1] === 'max') {
|
||||||
quantity = max
|
quantity = max
|
||||||
} else {
|
} else {
|
||||||
quantity = Math.round(chaosFilter(parseInt(words[2] || '1'), 0.2, user, max) || 1)
|
if (query) {
|
||||||
|
quantity = parseInt(args[1])
|
||||||
|
} else {
|
||||||
|
quantity = Math.round(chaosFilter(parseInt(args[1]), 0.2, user, max) || 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!quantity || quantity < 1) {
|
if (!quantity || quantity < 1) {
|
||||||
await say('Quantity must be a positive integer')
|
await say('Quantity must be a positive integer')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const realCost = calculateCost({ itemName: buying, user, quantity })
|
const realCost = calculateCost({ itemName: buyableName, user, quantity })
|
||||||
|
if (query) {
|
||||||
|
return say(`Buying ${quantity} ${buyableName} would cost you ${commas(realCost)} HVAC`)
|
||||||
|
}
|
||||||
if (currentCoins < realCost) {
|
if (currentCoins < realCost) {
|
||||||
await say(`You don't have enough coins! You have ${commas(currentCoins)}, but you need ${commas(realCost)}`)
|
await say(`You don't have enough coins! You have ${commas(currentCoins)}, but you need ${commas(realCost)}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.coins -= realCost
|
user.coins -= realCost
|
||||||
user.items[buying] = user.items[buying] || 0
|
user.items[buyableName] = user.items[buyableName] || 0
|
||||||
user.items[buying] += quantity
|
user.items[buyableName] += quantity
|
||||||
|
|
||||||
if (buying === 'mouse' && user.items.mouse >= 100) {
|
if (user.items[buyableName] >= 100) {
|
||||||
addAchievement(user, 'ratGod', say)
|
addAchievement(user, buyableItems[buyableName].own100Achievement, say)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quantity === 1) {
|
const countString = quantity === 1 ? 'one' : quantity
|
||||||
await say(`You bought one :${buyable.emoji}:`)
|
await say(`You bought ${countString} :${buyableItem.emoji}:`)
|
||||||
} else {
|
|
||||||
await say(`You bought ${quantity} :${buyable.emoji}:`)
|
|
||||||
}
|
|
||||||
|
|
||||||
saveGame()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const buyButton = async ({ body, ack, say, payload }) => {
|
const buyButton = async ({ body, ack, say, payload }) => {
|
||||||
|
@ -153,7 +160,8 @@ const buyButton = async ({ body, ack, say, payload }) => {
|
||||||
}
|
}
|
||||||
const user = getUser(event.user)
|
const user = getUser(event.user)
|
||||||
const words = ['', buying, body.actions[0].text]
|
const words = ['', buying, body.actions[0].text]
|
||||||
await buyRoute({ event, say, words, user })
|
const [commandName, ...args] = words
|
||||||
|
await buyRoute({ event, say, words, args, commandName, user })
|
||||||
const highestCoins = user.highestEver || user.coins || 1
|
const highestCoins = user.highestEver || user.coins || 1
|
||||||
await slack.app.client.chat.update({
|
await slack.app.client.chat.update({
|
||||||
channel: body.channel.id,
|
channel: body.channel.id,
|
||||||
|
|
|
@ -3,84 +3,98 @@ module.exports = {
|
||||||
baseCost: 100,
|
baseCost: 100,
|
||||||
earning: 1,
|
earning: 1,
|
||||||
emoji: 'mouse2',
|
emoji: 'mouse2',
|
||||||
description: 'A mouse to steal coins for you.'
|
description: 'A mouse to steal coins for you.',
|
||||||
|
own100Achievement: 'ratGod',
|
||||||
},
|
},
|
||||||
accountant: {
|
accountant: {
|
||||||
baseCost: 1_100,
|
baseCost: 1_100,
|
||||||
earning: 8,
|
earning: 8,
|
||||||
emoji: 'male-office-worker',
|
emoji: 'male-office-worker',
|
||||||
description: 'Legally make money from nothing!'
|
description: 'Legally make money from nothing!',
|
||||||
|
own100Achievement: 'mathematician',
|
||||||
},
|
},
|
||||||
whale: {
|
whale: {
|
||||||
baseCost: 12_000,
|
baseCost: 12_000,
|
||||||
earning: 47,
|
earning: 47,
|
||||||
emoji: 'whale',
|
emoji: 'whale',
|
||||||
description: 'Someone to spend money on your HVAC Coin mining app.'
|
description: 'Someone to spend money on your HVAC Coin mining app.',
|
||||||
|
own100Achievement: 'iPod',
|
||||||
},
|
},
|
||||||
train: {
|
train: {
|
||||||
baseCost: 130_000,
|
baseCost: 130_000,
|
||||||
earning: 260,
|
earning: 260,
|
||||||
emoji: 'train2',
|
emoji: 'train2',
|
||||||
description: 'Efficiently ship your most valuable coins.'
|
description: 'Efficiently ship your most valuable coins.',
|
||||||
|
own100Achievement: 'fire100',
|
||||||
},
|
},
|
||||||
fire: {
|
fire: {
|
||||||
baseCost: 1_400_000,
|
baseCost: 1_400_000,
|
||||||
earning: 1_400,
|
earning: 1_400,
|
||||||
emoji: 'fire',
|
emoji: 'fire',
|
||||||
description: 'Return to the roots of HVAC.'
|
description: 'Return to the roots of HVAC.',
|
||||||
|
own100Achievement: 'train100',
|
||||||
},
|
},
|
||||||
boomerang: {
|
boomerang: {
|
||||||
baseCost: 20_000_000,
|
baseCost: 20_000_000,
|
||||||
earning: 7_800,
|
earning: 7_800,
|
||||||
emoji: 'boomerang',
|
emoji: 'boomerang',
|
||||||
description: 'Your coin always seems to come back.'
|
description: 'Your coin always seems to come back.',
|
||||||
|
own100Achievement: 'boom100',
|
||||||
},
|
},
|
||||||
moon: {
|
moon: {
|
||||||
baseCost: 330_000_000,
|
baseCost: 330_000_000,
|
||||||
earning: 44_000,
|
earning: 44_000,
|
||||||
emoji: 'new_moon_with_face',
|
emoji: 'new_moon_with_face',
|
||||||
description: 'Convert dark new-moon energy into HVAC Coins.'
|
description: 'Convert dark new-moon energy into HVAC Coins.',
|
||||||
|
own100Achievement: 'mirror100',
|
||||||
},
|
},
|
||||||
butterfly: {
|
butterfly: {
|
||||||
baseCost: 5_100_000_000,
|
baseCost: 5_100_000_000,
|
||||||
earning: 260_000,
|
earning: 260_000,
|
||||||
emoji: 'butterfly',
|
emoji: 'butterfly',
|
||||||
description: 'Create the exact worldly chaos to bit-flip HVAC Coins into existence on your computer.'
|
description: 'Create the exact worldly chaos to bit-flip HVAC Coins into existence on your computer.',
|
||||||
|
own100Achievement: 'butterfly100',
|
||||||
},
|
},
|
||||||
mirror: {
|
mirror: {
|
||||||
baseCost: 75_000_000_000,
|
baseCost: 75_000_000_000,
|
||||||
earning: 1_600_000,
|
earning: 1_600_000,
|
||||||
emoji: 'mirror',
|
emoji: 'mirror',
|
||||||
description: 'Only by gazing inward can you collect enough Coin to influence the thermostat.'
|
description: 'Only by gazing inward can you collect enough Coin to influence the thermostat.',
|
||||||
|
own100Achievement: 'quade100',
|
||||||
},
|
},
|
||||||
quade: {
|
quade: {
|
||||||
baseCost: 1_000_000_000_000,
|
baseCost: 1_000_000_000_000,
|
||||||
earning: 10_000_000,
|
earning: 10_000_000,
|
||||||
emoji: 'quade',
|
emoji: 'quade',
|
||||||
description: 'Has thumbs capable of physically manipulating the thermostat.'
|
description: 'Has thumbs capable of physically manipulating the thermostat.',
|
||||||
|
own100Achievement: 'hvacker100',
|
||||||
},
|
},
|
||||||
hvacker: {
|
hvacker: {
|
||||||
baseCost: 14_000_000_000_000,
|
baseCost: 14_000_000_000_000,
|
||||||
earning: 65_000_000,
|
earning: 65_000_000,
|
||||||
emoji: 'hvacker_angery',
|
emoji: 'hvacker_angery',
|
||||||
description: 'Harness the power of the mad god himself.'
|
description: 'Harness the power of the mad god himself.',
|
||||||
|
own100Achievement: 'creator100',
|
||||||
},
|
},
|
||||||
creator: {
|
creator: {
|
||||||
baseCost: 170_000_000_000_000,
|
baseCost: 170_000_000_000_000,
|
||||||
earning: 430_000_000,
|
earning: 430_000_000,
|
||||||
emoji: 'question',
|
emoji: 'question',
|
||||||
description: 'The elusive creator of Hvacker takes a favorable look at your CPS.'
|
description: 'The elusive creator of Hvacker takes a favorable look at your CPS.',
|
||||||
|
own100Achievement: 'smallBusiness100',
|
||||||
},
|
},
|
||||||
smallBusiness: {
|
smallBusiness: {
|
||||||
baseCost: 2_210_000_000_000_000,
|
baseCost: 2_210_000_000_000_000,
|
||||||
earning: 2_845_000_000,
|
earning: 2_845_000_000,
|
||||||
emoji: 'convenience_store',
|
emoji: 'convenience_store',
|
||||||
description: 'The place where the creator of Hvacker goes to work.'
|
description: 'The place where the creator of Hvacker goes to work.',
|
||||||
|
own100Achievement: 'bigBusiness100',
|
||||||
},
|
},
|
||||||
bigBusiness: {
|
bigBusiness: {
|
||||||
baseCost: 26_210_000_000_000_000,
|
baseCost: 26_210_000_000_000_000,
|
||||||
earning: 23_650_000_000,
|
earning: 23_650_000_000,
|
||||||
emoji: 'office',
|
emoji: 'office',
|
||||||
description: 'The place where the smallBusiness goes to work.'
|
description: 'The place where the smallBusiness goes to work.',
|
||||||
|
own100Achievement: 'ratGod',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,6 +39,8 @@ const lore = [
|
||||||
l(`And the ninth...`),
|
l(`And the ninth...`),
|
||||||
l(`Well, the ninth might actually amount to something.`),
|
l(`Well, the ninth might actually amount to something.`),
|
||||||
l(`https://i.imgur.com/eFreg7Y.gif\n`),
|
l(`https://i.imgur.com/eFreg7Y.gif\n`),
|
||||||
|
|
||||||
|
//l(`As you might imagine, the ninth egg was I, the almighty Hvacker.`)
|
||||||
]
|
]
|
||||||
|
|
||||||
slack.onReaction(async ({ event, say }) => {
|
slack.onReaction(async ({ event, say }) => {
|
||||||
|
@ -56,11 +58,11 @@ slack.onReaction(async ({ event, say }) => {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log(lore[user.lore])
|
console.log('lore:', lore[user.lore])
|
||||||
await say(lore[user.lore].correctResponse)
|
await say(lore[user.lore].correctResponse)
|
||||||
user.lore += 1
|
user.lore += 1
|
||||||
saveGame()
|
saveGame()
|
||||||
} catch (e) {console.error(e)}
|
} catch (e) {console.error('onReaction error', e)}
|
||||||
})
|
})
|
||||||
|
|
||||||
const encodeLore = loreNumber => lore[loreNumber].text.startsWith(':') && lore[loreNumber].text.endsWith(':') ? '' :
|
const encodeLore = loreNumber => lore[loreNumber].text.startsWith(':') && lore[loreNumber].text.endsWith(':') ? '' :
|
||||||
|
@ -77,35 +79,35 @@ const loreMessage = (user, say) => {
|
||||||
return `Sorry. I'd love to tell you more, but I'm tired. Please check back later.`
|
return `Sorry. I'd love to tell you more, but I'm tired. Please check back later.`
|
||||||
}
|
}
|
||||||
|
|
||||||
const loreRoute = async ({ say, words, user, isAdmin }) => {
|
const loreRoute = async ({ say, args, user, isAdmin }) => {
|
||||||
user.lore ??= 0
|
user.lore ??= 0
|
||||||
if (!words[1]) {
|
if (!args[0]) {
|
||||||
const message = loreMessage(user, say)
|
const message = loreMessage(user, say)
|
||||||
await say(message)
|
await say(message)
|
||||||
if (!lore[user.lore]?.correctReactions) {
|
if (!lore[user.lore]?.correctReactions) {
|
||||||
user.lore += 1
|
user.lore += 1
|
||||||
}
|
}
|
||||||
saveGame()
|
//saveGame()
|
||||||
console.log('Sent ' + user.name + ':\n' + message)
|
console.log('Sent ' + user.name + ':\n' + message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (words[1] === 'reset') {
|
if (args[0] === 'reset') {
|
||||||
user.lore = 0
|
user.lore = 0
|
||||||
saveGame()
|
//saveGame()
|
||||||
return say(`I have reset your place in the story.`)
|
return say(`I have reset your place in the story.`)
|
||||||
}
|
}
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
if (words[1] === 'all') {
|
if (args[0] === 'all') {
|
||||||
let loreMessage = ''
|
let loreMessage = ''
|
||||||
for (let i = 0; i < user.lore; i++) {
|
for (let i = 0; i < user.lore; i++) {
|
||||||
loreMessage += lore[i].text + (lore[i].correctResponse || '') + '\n'
|
loreMessage += lore[i].text + (lore[i].correctResponse || '') + '\n'
|
||||||
}
|
}
|
||||||
return say(loreMessage)
|
return say(loreMessage)
|
||||||
}
|
}
|
||||||
const jumpTo = parseInt(words[1])
|
const jumpTo = parseInt(args[0])
|
||||||
if (!isNaN(jumpTo)) {
|
if (!isNaN(jumpTo)) {
|
||||||
user.lore = jumpTo
|
user.lore = jumpTo
|
||||||
saveGame()
|
//saveGame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { commas, saveGame, quackGradeMultiplier, prestigeMultiplier, makeBackup } = require('./utils')
|
const { commas, quackGradeMultiplier, prestigeMultiplier, makeBackup, userHasCheckedQuackgrade } = require('./utils')
|
||||||
const { quackStore } = require('./quackstore')
|
const { quackStore } = require('./quackstore')
|
||||||
|
|
||||||
const possiblePrestige = coins => {
|
const possiblePrestige = coins => {
|
||||||
|
@ -17,10 +17,10 @@ const totalCostForPrestige = prestigeLevel => {
|
||||||
return (tpcRecMemo[prestigeLevel]) || (tpcRecMemo[prestigeLevel] = 1_000_000_000_000 * Math.pow(prestigeLevel, 3) + totalCostForPrestige(prestigeLevel - 1))
|
return (tpcRecMemo[prestigeLevel]) || (tpcRecMemo[prestigeLevel] = 1_000_000_000_000 * Math.pow(prestigeLevel, 3) + totalCostForPrestige(prestigeLevel - 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
const prestigeRoute = async ({ say, words, user }) => {
|
const prestigeRoute = async ({ say, args, user }) => {
|
||||||
const possible = possiblePrestige(user.coinsAllTime)
|
const possible = possiblePrestige(user.coinsAllTime)
|
||||||
const current = user.prestige ??= 0
|
const current = user.prestige ??= 0
|
||||||
if (words[1] === 'me') {
|
if (args[0] === 'me') {
|
||||||
await say(
|
await say(
|
||||||
'This will permanently remove all of your items, upgrades, and coins!\n\n' +
|
'This will permanently remove all of your items, upgrades, and coins!\n\n' +
|
||||||
'Say \'!!prestige me\' to confirm.'
|
'Say \'!!prestige me\' to confirm.'
|
||||||
|
@ -53,18 +53,18 @@ const prestigeConfirmRoute = async ({ event, say, user }) => {
|
||||||
user.quacks += (possible - user.prestige)
|
user.quacks += (possible - user.prestige)
|
||||||
|
|
||||||
user.prestige = possible
|
user.prestige = possible
|
||||||
|
user.highestEver = 0
|
||||||
user.coins = 0
|
user.coins = 0
|
||||||
user.items = {}
|
user.items = {};
|
||||||
|
const starterUpgrades = (user.quackUpgrades?.starter || [])
|
||||||
|
starterUpgrades.forEach(upgradeName => quackStore[upgradeName].effect(user))
|
||||||
user.upgrades = {}
|
user.upgrades = {}
|
||||||
|
|
||||||
saveGame()
|
|
||||||
await say('You prestiged! Check out !quackstore to see what you can buy!')
|
await say('You prestiged! Check out !quackstore to see what you can buy!')
|
||||||
}
|
}
|
||||||
|
|
||||||
const quackStoreListing = (showCost = true) => ([name, upgrade]) =>
|
const quackStoreListing = (showCost = true) => ([name, upgrade]) =>
|
||||||
showCost
|
`:${upgrade.emoji}: *${name}* - ${showCost ? 'Costs' : 'Worth'} *${upgrade.cost} Quack.*\n\n_${upgrade.description}_`
|
||||||
? `:${upgrade.emoji}: *${name}* - Costs *${upgrade.cost} Quack.*\n\n_${upgrade.description}_`
|
|
||||||
: `:${upgrade.emoji}: *${name}* - Worth *${upgrade.cost} Quack.*\n\n_${upgrade.description}_`
|
|
||||||
|
|
||||||
const allUserQuackUpgrades = user =>
|
const allUserQuackUpgrades = user =>
|
||||||
Object.entries(user.quackUpgrades || {})
|
Object.entries(user.quackUpgrades || {})
|
||||||
|
@ -75,6 +75,7 @@ const hasPreReqs = user => ([name, upgrade]) => {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
const allUserUpgrades = allUserQuackUpgrades(user)
|
const allUserUpgrades = allUserQuackUpgrades(user)
|
||||||
|
console.log('allUserUpgrades', allUserUpgrades)
|
||||||
return upgrade.preReqs.every(preReq => allUserUpgrades.includes(preReq))
|
return upgrade.preReqs.every(preReq => allUserUpgrades.includes(preReq))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,27 +93,31 @@ const quackStoreText = user =>
|
||||||
`\n\nYou have ${user.quacks ??= 0} quacks to spend.` +
|
`\n\nYou have ${user.quacks ??= 0} quacks to spend.` +
|
||||||
`\nQuackStore upgrades are currently boosting your CPS by ${commas((quackGradeMultiplier(user) - 1) * 100)}%`
|
`\nQuackStore upgrades are currently boosting your CPS by ${commas((quackGradeMultiplier(user) - 1) * 100)}%`
|
||||||
|
|
||||||
const quackStoreRoute = async ({ user, say, words }) => {
|
const quackStoreRoute = async ({ user, say, args }) => {
|
||||||
user.quackUpgrades ??= {}
|
user.quackUpgrades ??= {}
|
||||||
const quacks = user.quacks ??= 0
|
const quacks = user.quacks ??= 0
|
||||||
if (!words[1]) {
|
if (!args[0]) {
|
||||||
await say(quackStoreText(user))
|
await say(quackStoreText(user))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log(`Trying to buy ${words[1]}`)
|
console.log(`Trying to buy ${args[0]}`)
|
||||||
const quackItem = quackStore[words[1]]
|
const quackItem = quackStore[args[0]]
|
||||||
if (!quackItem || !unownedQuackItems(user).find(([name]) => name === words[1])) {
|
if (!quackItem || !unownedQuackItems(user).find(([name]) => name === args[0])) {
|
||||||
await say(`'${words[1]}' is not available in the quack store!`)
|
await say(`'${args[0]}' is not available in the quack store!`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (quackItem.cost > quacks) {
|
if (quackItem.cost > quacks) {
|
||||||
await say(`${words[1]} costs ${quackItem.cost} Quacks, but you only have ${quacks}!`)
|
await say(`${args[0]} costs ${quackItem.cost} Quacks, but you only have ${quacks}!`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.quacks -= quackItem.cost
|
user.quacks -= quackItem.cost
|
||||||
user.quackUpgrades[quackItem.type] ??= []
|
user.quackUpgrades[quackItem.type] ??= []
|
||||||
user.quackUpgrades[quackItem.type].push(words[1])
|
user.quackUpgrades[quackItem.type].push(args[0])
|
||||||
saveGame()
|
if (quackItem.type === 'starter') {
|
||||||
|
quackItem.effect(user)
|
||||||
|
}
|
||||||
|
await say(`You bought ${args[0]}!`)
|
||||||
|
//saveGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
const ownedQuacksText = user =>
|
const ownedQuacksText = user =>
|
||||||
|
|
|
@ -31,9 +31,6 @@ const quackStore = {
|
||||||
//+ '_\n_Averages a 26% CPS boost.',
|
//+ '_\n_Averages a 26% CPS boost.',
|
||||||
preReqs: ['nuclearFuel'],
|
preReqs: ['nuclearFuel'],
|
||||||
effect: (cps, user) => {
|
effect: (cps, user) => {
|
||||||
if (user.name !== 'Sage') {
|
|
||||||
console.log('Chaos Multiplier', getChaos(Math.round(user.interactions / 50)))
|
|
||||||
}
|
|
||||||
return cps * getChaos(Math.round(user.interactions / 50))
|
return cps * getChaos(Math.round(user.interactions / 50))
|
||||||
},
|
},
|
||||||
cost: 10
|
cost: 10
|
||||||
|
@ -44,10 +41,67 @@ const quackStore = {
|
||||||
type: 'lightning',
|
type: 'lightning',
|
||||||
emoji: 'rose',
|
emoji: 'rose',
|
||||||
description: 'Smells nice. Makes lightning twice as likely to strike.',
|
description: 'Smells nice. Makes lightning twice as likely to strike.',
|
||||||
//+ '_\n_Averages a 26% CPS boost.',
|
|
||||||
effect: lightningOdds => lightningOdds * 2,
|
effect: lightningOdds => lightningOdds * 2,
|
||||||
preReqs: ['nuclearFuel'],
|
preReqs: ['nuclearFuel'],
|
||||||
cost: 10
|
cost: 10
|
||||||
|
},
|
||||||
|
|
||||||
|
// Checked Upgrades. Have no effect(), but their existence is referred to elsewhere.
|
||||||
|
theGift: {
|
||||||
|
name: 'The Gift',
|
||||||
|
type: 'checked',
|
||||||
|
emoji: 'eye-in-speech-bubble',
|
||||||
|
description: 'Become forewarned of certain events...',
|
||||||
|
preReqs: ['dryerSheet', 'chaos'],
|
||||||
|
cost: 10
|
||||||
|
},
|
||||||
|
|
||||||
|
theVoice: {
|
||||||
|
name: 'The Voice',
|
||||||
|
type: 'checked',
|
||||||
|
emoji: 'loud_sound',
|
||||||
|
description: 'Unlocks the !speak command',
|
||||||
|
preReqs: ['dryerSheet', 'chaos'],
|
||||||
|
cost: 50
|
||||||
|
},
|
||||||
|
|
||||||
|
cheeseBaby: {
|
||||||
|
name: 'cheeseBaby',
|
||||||
|
type: 'starter',
|
||||||
|
emoji: 'baby_symbol',
|
||||||
|
description: 'Start each prestige with 5 mice',
|
||||||
|
preReqs: ['dryerSheet', 'chaos'],
|
||||||
|
effect: user => {
|
||||||
|
user.items.mouse ??= 0
|
||||||
|
user.items.mouse += 5
|
||||||
|
},
|
||||||
|
cost: 5
|
||||||
|
},
|
||||||
|
|
||||||
|
silverSpoon: {
|
||||||
|
name: 'Silver Spoon',
|
||||||
|
type: 'starter',
|
||||||
|
emoji: 'spoon',
|
||||||
|
description: 'Start each prestige with 5 accountants',
|
||||||
|
preReqs: ['cheeseBaby'],
|
||||||
|
effect: user => {
|
||||||
|
user.items.accountant ??= 0
|
||||||
|
user.items.accountant += 5
|
||||||
|
},
|
||||||
|
cost: 10
|
||||||
|
},
|
||||||
|
|
||||||
|
oceanMan: {
|
||||||
|
name: 'Ocean Man',
|
||||||
|
type: 'starter',
|
||||||
|
emoji: 'ocean',
|
||||||
|
description: 'Start each prestige with 5 whales',
|
||||||
|
preReqs: ['silverSpoon'],
|
||||||
|
effect: user => {
|
||||||
|
user.items.whale ??= 0
|
||||||
|
user.items.whale += 5
|
||||||
|
},
|
||||||
|
cost: 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
horrorEnabled: false
|
horrorEnabled: false,
|
||||||
|
admins: ['Sage']
|
||||||
}
|
}
|
|
@ -14,20 +14,22 @@ const evil = ({ type, description, cost }) => basic({
|
||||||
extraCondition: (user, squadGrades) => squadGrades?.includes('discardHumanMorals'),
|
extraCondition: (user, squadGrades) => squadGrades?.includes('discardHumanMorals'),
|
||||||
})
|
})
|
||||||
|
|
||||||
const heavenly = ({ type, description, cost }) => basic({
|
const heavenly = ({ type, description, cost, multiplier = 2 }) => ({
|
||||||
type,
|
type,
|
||||||
description,
|
description,
|
||||||
count: 60,
|
condition: (user, squadGrades) => user.items[type] >= 60 && squadGrades?.includes('redemption'),
|
||||||
cost,
|
cost,
|
||||||
extraCondition: (user, squadGrades) => squadGrades?.includes('redemption'),
|
effect: cps => cps * multiplier
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const disabled = () => false
|
||||||
|
|
||||||
const baby = ({ type, description, cost }) => basic({
|
const baby = ({ type, description, cost }) => basic({
|
||||||
type,
|
type,
|
||||||
description,
|
description,
|
||||||
count: 80,
|
count: 70,
|
||||||
cost,
|
cost,
|
||||||
extraCondition: (user, squadGrades) => squadGrades?.includes('redemption'),
|
extraCondition: disabled
|
||||||
})
|
})
|
||||||
|
|
||||||
const geometry = ({ type, description, cost }) => basic({
|
const geometry = ({ type, description, cost }) => basic({
|
||||||
|
@ -35,7 +37,7 @@ const geometry = ({ type, description, cost }) => basic({
|
||||||
description,
|
description,
|
||||||
count: 100,
|
count: 100,
|
||||||
cost,
|
cost,
|
||||||
extraCondition: (user, squadGrades) => squadGrades?.includes('redemption'),
|
extraCondition: disabled
|
||||||
})
|
})
|
||||||
|
|
||||||
const universitality = ({ type, description, cost }) => basic({
|
const universitality = ({ type, description, cost }) => basic({
|
||||||
|
@ -43,7 +45,7 @@ const universitality = ({ type, description, cost }) => basic({
|
||||||
description,
|
description,
|
||||||
count: 100,
|
count: 100,
|
||||||
cost,
|
cost,
|
||||||
extraCondition: (user, squadGrades) => squadGrades?.includes('redemption'),
|
extraCondition: disabled
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -72,8 +74,14 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
hoodedMice: heavenly({
|
hoodedMice: heavenly({
|
||||||
type: 'mouse',
|
type: 'mouse',
|
||||||
description: 'These monks have nearly reached enlightenment.',
|
description: 'These monks have nearly reached enlightenment. 10x Mouse CPS.',
|
||||||
cost: 1_000_000,
|
cost: 1_000_000,
|
||||||
|
multiplier: 10,
|
||||||
|
}),
|
||||||
|
babyMouse: baby({
|
||||||
|
type: 'mouse',
|
||||||
|
description: 'Squeak!',
|
||||||
|
cost: 6_000_000,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
fasterComputers: basic({
|
fasterComputers: basic({
|
||||||
|
@ -101,8 +109,14 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
charityFund: heavenly({
|
charityFund: heavenly({
|
||||||
type: 'accountant',
|
type: 'accountant',
|
||||||
description: 'THIS one is more than just a tax break.',
|
description: 'THIS one is more than just a tax break. 9x Accountant CPS.',
|
||||||
cost: 16_333_333,
|
cost: 16_333_333,
|
||||||
|
multiplier: 9,
|
||||||
|
}),
|
||||||
|
mathBaby: baby({
|
||||||
|
type: 'accountant',
|
||||||
|
description: '2 + 2 = WAAH!',
|
||||||
|
cost: 99_999_999,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
biggerBlowhole: basic({
|
biggerBlowhole: basic({
|
||||||
|
@ -130,8 +144,14 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
whaleChoir: heavenly({
|
whaleChoir: heavenly({
|
||||||
type: 'whale',
|
type: 'whale',
|
||||||
description: `Their cleansing songs reverberate through the sea.`,
|
description: `Their cleansing songs reverberate through the sea. 8x Whale CPS.`,
|
||||||
cost: 144_000_000
|
cost: 144_000_000,
|
||||||
|
multiplier: 8,
|
||||||
|
}),
|
||||||
|
smolWhales: baby({
|
||||||
|
type: 'whale',
|
||||||
|
description: ``,
|
||||||
|
cost: 8_400_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
greasyTracks: basic({
|
greasyTracks: basic({
|
||||||
|
@ -159,7 +179,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
toyTrain: heavenly({
|
toyTrain: heavenly({
|
||||||
type: 'train',
|
type: 'train',
|
||||||
description: 'Something simple. Toot toot!',
|
description: 'Toot toot! 8x Train CPS.',
|
||||||
|
multiplier: 8,
|
||||||
cost: 2_220_000_000
|
cost: 2_220_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -171,7 +192,7 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
extremelyDryFuel: basic({
|
extremelyDryFuel: basic({
|
||||||
type: 'fire',
|
type: 'fire',
|
||||||
description: 'Use the ignite command for a secret achievement.',
|
description: 'Hey, psst, hey. Use the ignite command for a secret achievement.',
|
||||||
count: 10,
|
count: 10,
|
||||||
cost: 163_000_000
|
cost: 163_000_000
|
||||||
}),
|
}),
|
||||||
|
@ -188,9 +209,15 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
blueFire: heavenly({
|
blueFire: heavenly({
|
||||||
type: 'fire',
|
type: 'fire',
|
||||||
description: `You can hear it singing with delight.`,
|
description: `You can hear it singing with delight. 7x Fire CPS.`,
|
||||||
|
multiplier: 7,
|
||||||
cost: 25_200_000_000
|
cost: 25_200_000_000
|
||||||
}),
|
}),
|
||||||
|
cuteFire: baby({
|
||||||
|
type: 'fire',
|
||||||
|
description: `I just met my perfect match...`,
|
||||||
|
cost: 150_000_000_000
|
||||||
|
}),
|
||||||
|
|
||||||
spoonerang: basic({
|
spoonerang: basic({
|
||||||
type: 'boomerang',
|
type: 'boomerang',
|
||||||
|
@ -217,7 +244,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
youRang: heavenly({
|
youRang: heavenly({
|
||||||
type: 'boomerang',
|
type: 'boomerang',
|
||||||
description: 'Your arms and legs recede into your body. You bend at the middle. You fly. And for a moment, you are free.',
|
description: 'Your arms and legs recede into your body. You bend at the middle. You fly. And for a moment, you are free._\n_7x Boomerang CPS.',
|
||||||
|
multiplier: 7,
|
||||||
cost: 360_000_000_000
|
cost: 360_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -246,7 +274,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
newMoon: heavenly({
|
newMoon: heavenly({
|
||||||
type: 'moon',
|
type: 'moon',
|
||||||
description: `Build a second moon to provide space for affordable housing.`,
|
description: `Build a second moon to provide space for affordable housing. 6x Moon CPS.`,
|
||||||
|
multiplier: 6,
|
||||||
cost: 5_190_000_000_000
|
cost: 5_190_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -275,7 +304,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
quietingNectar: heavenly({
|
quietingNectar: heavenly({
|
||||||
type: 'butterfly',
|
type: 'butterfly',
|
||||||
description: 'Calming and extra sweet. Soothes even human ails.',
|
description: 'Calming and extra sweet. Soothes even human ails. 6x Butterfly CPS.',
|
||||||
|
multiplier: 6,
|
||||||
cost: 75_300_000_000_000
|
cost: 75_300_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -304,7 +334,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
funHouseMirror: heavenly({
|
funHouseMirror: heavenly({
|
||||||
type: 'mirror',
|
type: 'mirror',
|
||||||
description: `yoU LOok so siLLY IN thesE THINgs`,
|
description: `yoU LOok so siLLY IN thesE THINgs. 5X mIRror CpS.`,
|
||||||
|
multiplier: 5,
|
||||||
cost: 1_330_000_000_000_000
|
cost: 1_330_000_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -333,7 +364,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
hannahMontanaLinux: heavenly({
|
hannahMontanaLinux: heavenly({
|
||||||
type: 'quade',
|
type: 'quade',
|
||||||
description: `The patrician's choice.`,
|
description: `The patrician's choice. 4x Quade CPS.`,
|
||||||
|
multiplier: 4,
|
||||||
cost: 18_000_000_000_000_000
|
cost: 18_000_000_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -362,7 +394,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
mutualUnderstanding: heavenly({
|
mutualUnderstanding: heavenly({
|
||||||
type: 'hvacker',
|
type: 'hvacker',
|
||||||
description: `lol fat chance, dummy. Points for trying, though`,
|
description: `lol fat chance, dummy. Points for trying, though. 3x Hvacker CPS`,
|
||||||
|
multiplier: 3,
|
||||||
cost: 250_000_000_000_000_000
|
cost: 250_000_000_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -391,7 +424,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
goVegan: heavenly({
|
goVegan: heavenly({
|
||||||
type: 'creator',
|
type: 'creator',
|
||||||
description: `Unlock your vegan powers.`,
|
description: `Unlock your vegan powers. 3x Creator CPS.`,
|
||||||
|
multiplier: 3,
|
||||||
cost: 3_600_000_000_000_000_000
|
cost: 3_600_000_000_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -420,7 +454,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
coop: heavenly({
|
coop: heavenly({
|
||||||
type: 'smallBusiness',
|
type: 'smallBusiness',
|
||||||
description: `By the people, for the people.`,
|
description: `By the people, for the people. 2x smallBusiness CPS`,
|
||||||
|
multiplier: 2,
|
||||||
cost: 5_140_000_000_000_000_000
|
cost: 5_140_000_000_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -449,7 +484,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
makePublic: heavenly({
|
makePublic: heavenly({
|
||||||
type: 'bigBusiness',
|
type: 'bigBusiness',
|
||||||
description: `Downplay immediate profit for more long-term benefits.`,
|
description: `Downplay immediate profit for more long-term benefits. 2x bigBusiness CPS.`,
|
||||||
|
multiplier: 2,
|
||||||
cost: 42_000_000_000_000_000_000
|
cost: 42_000_000_000_000_000_000
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ const { quackStore, getChaos } = require('./quackstore')
|
||||||
|
|
||||||
const saveFile = 'hvacoins.json'
|
const saveFile = 'hvacoins.json'
|
||||||
|
|
||||||
const logError = msg => msg ? console.error(msg) : () => { /* Don't log empty message */ }
|
const logError = msg => msg ? console.error('logError: ', msg) : () => { /* Don't log empty message */ }
|
||||||
|
|
||||||
const loadGame = () => {
|
const loadGame = () => {
|
||||||
const game = parseOr(fs.readFileSync('./' + saveFile, 'utf-8'),
|
const game = parseOr(fs.readFileSync('./' + saveFile, 'utf-8'),
|
||||||
|
@ -53,13 +53,16 @@ const makeBackup = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
let saves = 0
|
let saves = 0
|
||||||
const saveGame = () => {
|
const saveGame = (force = true) => {
|
||||||
if (saves % 100 === 0) {
|
if (saves % 100 === 0) {
|
||||||
makeBackup()
|
makeBackup()
|
||||||
}
|
}
|
||||||
saves += 1
|
saves += 1
|
||||||
|
if (force || saves % 10 === 0) {
|
||||||
|
console.log('SAVING GAME')
|
||||||
fs.writeFileSync('./' + saveFile, JSON.stringify(game, null, 2))
|
fs.writeFileSync('./' + saveFile, JSON.stringify(game, null, 2))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const maybeNews = say => {
|
const maybeNews = say => {
|
||||||
const random = Math.random()
|
const random = Math.random()
|
||||||
|
@ -74,10 +77,11 @@ const maybeNews = say => {
|
||||||
|
|
||||||
const idFromWord = word => {
|
const idFromWord = word => {
|
||||||
if (!word?.startsWith('<@') || !word.endsWith('>')) {
|
if (!word?.startsWith('<@') || !word.endsWith('>')) {
|
||||||
return null
|
return getIdFromName(word)
|
||||||
}
|
} else {
|
||||||
return word.substring(2, word.length - 1)
|
return word.substring(2, word.length - 1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const getSeconds = () => new Date().getTime() / 1000
|
const getSeconds = () => new Date().getTime() / 1000
|
||||||
|
|
||||||
|
@ -113,7 +117,7 @@ const parseAll = (str, allNum) => {
|
||||||
return NaN
|
return NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
str = str.toLowerCase()?.replace(/,/g, '')
|
str = str?.toLowerCase()?.replace(/,/g, '') || '1'
|
||||||
|
|
||||||
switch (str) {
|
switch (str) {
|
||||||
case 'all':
|
case 'all':
|
||||||
|
@ -143,12 +147,10 @@ const parseAll = (str, allNum) => {
|
||||||
|
|
||||||
console.log('STR', str)
|
console.log('STR', str)
|
||||||
if (str.match(/^\d+$/)) {
|
if (str.match(/^\d+$/)) {
|
||||||
console.log('parseInt()')
|
|
||||||
return parseInt(str)
|
return parseInt(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str.match(/^\d+\.\d+$/)) {
|
if (str.match(/^\d+\.\d+$/)) {
|
||||||
console.log('parseFloat()')
|
|
||||||
return Math.round(parseFloat(str))
|
return Math.round(parseFloat(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +187,18 @@ const addAchievement = (user, achievementName, say) => {
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fuzzyMatcher = string => new RegExp((string?.toLowerCase() || '').split('').join('.*'), 'i')
|
||||||
|
|
||||||
|
let knownUsers = {}
|
||||||
|
const getIdFromName = name => {
|
||||||
|
const matcher = fuzzyMatcher(name?.toLowerCase())
|
||||||
|
const found = Object.entries(knownUsers).find(([id, knownName]) => matcher.test(knownName?.toLowerCase()))
|
||||||
|
if (found) {
|
||||||
|
return found[0]
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const getUser = userId => {
|
const getUser = userId => {
|
||||||
if (!users[userId]) {
|
if (!users[userId]) {
|
||||||
users[userId] = {
|
users[userId] = {
|
||||||
|
@ -205,20 +219,24 @@ const getUser = userId => {
|
||||||
return users[userId]
|
return users[userId]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addCoins = (user, add) => {
|
||||||
|
user.coins += add
|
||||||
|
user.coinsAllTime += add
|
||||||
|
user.coinsAllTime = Math.floor(user.coinsAllTime)
|
||||||
|
user.coins = Math.floor(user.coins)
|
||||||
|
}
|
||||||
|
|
||||||
const getCoins = userId => {
|
const getCoins = userId => {
|
||||||
const user = getUser(userId)
|
const user = getUser(userId)
|
||||||
const currentTime = getSeconds()
|
const currentTime = getSeconds()
|
||||||
const lastCheck = user.lastCheck || currentTime
|
const lastCheck = user.lastCheck || currentTime
|
||||||
const secondsPassed = currentTime - lastCheck
|
const secondsPassed = currentTime - lastCheck
|
||||||
|
|
||||||
const increase = getCPS(user) * secondsPassed
|
addCoins(user, getCPS(user) * secondsPassed)
|
||||||
user.coins += increase
|
|
||||||
user.coinsAllTime += increase
|
|
||||||
user.coins = Math.floor(user.coins)
|
|
||||||
|
|
||||||
user.lastCheck = currentTime
|
user.lastCheck = currentTime
|
||||||
setHighestCoins(userId)
|
setHighestCoins(userId)
|
||||||
saveGame()
|
//saveGame()
|
||||||
return user.coins
|
return user.coins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +308,8 @@ const singleItemCps = (user, itemName) => {
|
||||||
const itemUpgradeCps = itemUpgrades.reduce((totalCps, upgrade) => upgrade.effect(totalCps, user), 1)
|
const itemUpgradeCps = itemUpgrades.reduce((totalCps, upgrade) => upgrade.effect(totalCps, user), 1)
|
||||||
// console.log('itemUpgradeCps', itemUpgradeCps)
|
// console.log('itemUpgradeCps', itemUpgradeCps)
|
||||||
|
|
||||||
const userGeneralUpgrades = user.upgrades.general || []
|
user.upgrades.general ??= []
|
||||||
|
const userGeneralUpgrades = user.upgrades.general
|
||||||
const generalUpgradeCps = Object.entries(userGeneralUpgrades).reduce((total, [, upgradeName]) => upgrades[upgradeName].effect(total, user), 1)
|
const generalUpgradeCps = Object.entries(userGeneralUpgrades).reduce((total, [, upgradeName]) => upgrades[upgradeName].effect(total, user), 1)
|
||||||
// console.log('generalUpgradeCps', generalUpgradeCps)
|
// console.log('generalUpgradeCps', generalUpgradeCps)
|
||||||
|
|
||||||
|
@ -382,6 +401,41 @@ const addReactions = async ({ app, channelId, timestamp, reactions }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const daysSinceEpoch = () => {
|
||||||
|
const today = new Date().getTime()
|
||||||
|
const epoch = new Date(0).getTime()
|
||||||
|
return Math.floor((today - epoch) / (1000 * 60 * 60 * 24))
|
||||||
|
}
|
||||||
|
|
||||||
|
const dayOfYear = () => {
|
||||||
|
const date = new Date()
|
||||||
|
return ((Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
game.stonkMarket ??= {
|
||||||
|
lastDay: daysSinceEpoch(),
|
||||||
|
stonks: {
|
||||||
|
duk: {
|
||||||
|
pattern: "duk",
|
||||||
|
index: 0,
|
||||||
|
price: 1_410_911_983_728
|
||||||
|
},
|
||||||
|
quak: {
|
||||||
|
pattern: "quak",
|
||||||
|
index: 0,
|
||||||
|
price: 5_111_242_778_696
|
||||||
|
},
|
||||||
|
honk: {
|
||||||
|
pattern: "honk",
|
||||||
|
index: 0,
|
||||||
|
price: 511_915_144_009
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const userHasCheckedQuackgrade = (user, quackGrade) => (user.quackUpgrades?.checked || []).includes(quackGrade)
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
saveGame,
|
saveGame,
|
||||||
makeBackup,
|
makeBackup,
|
||||||
|
@ -408,5 +462,11 @@ module.exports = {
|
||||||
chaosFilter,
|
chaosFilter,
|
||||||
addReactions,
|
addReactions,
|
||||||
getCompletedSquadgradeNames,
|
getCompletedSquadgradeNames,
|
||||||
game
|
game,
|
||||||
|
dayOfYear,
|
||||||
|
daysSinceEpoch,
|
||||||
|
userHasCheckedQuackgrade,
|
||||||
|
fuzzyMatcher,
|
||||||
|
addCoins,
|
||||||
|
setKnownUsers: users => knownUsers = users
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@ const port = 3001
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const base64 = require('base-64')
|
const base64 = require('base-64')
|
||||||
const slack = require('../../slack')
|
const slack = require('../../slack')
|
||||||
const { game: { users } } = require('./utils')
|
const { game: { users }, getUser, fuzzyMatcher } = require('./utils')
|
||||||
|
|
||||||
const apiGetUserId = hash => {
|
const apiGetUserId = hash => {
|
||||||
return Object.entries(userGetter.users)
|
return Object.entries(users)
|
||||||
.filter(([id, user]) => user.pwHash === hash)
|
.filter(([id, user]) => user.pwHash === hash)
|
||||||
.map(([id, user]) => id)[0]
|
.map(([id, user]) => id)[0]
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,21 @@ const makeHash = pw =>
|
||||||
.update(pw)
|
.update(pw)
|
||||||
.digest('hex')
|
.digest('hex')
|
||||||
|
|
||||||
|
const illegalCommands = ['!', '!b']
|
||||||
|
const lastCalls = {}
|
||||||
const addCommand = ({ commandNames, helpText, action, condition, hidden }) => {
|
const addCommand = ({ commandNames, helpText, action, condition, hidden }) => {
|
||||||
|
if (illegalCommands.find(command => commandNames.includes(command))) {
|
||||||
|
commandNames.forEach(name =>
|
||||||
|
app.get('/' + name.replace(/!/gi, ''), async (req, res) => res.send('Command is illegal over the web api.'))
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
const route = async (req, res) => {
|
const route = async (req, res) => {
|
||||||
const say = async msg => res.send(msg)
|
const say = async msg => res.send(msg + '\n')
|
||||||
try {
|
try {
|
||||||
const words = ['', ...Object.keys(req.query)]
|
const words = ['', ...Object.keys(req.query)]
|
||||||
console.log('INCOMING API CALL:', name, words)
|
const [commandName, ...args] = words
|
||||||
|
console.log('INCOMING API CALL:', commandName, words)
|
||||||
const encoded = req.header('Authorization').substring(5)
|
const encoded = req.header('Authorization').substring(5)
|
||||||
const decoded = base64.decode(encoded).substring(1)
|
const decoded = base64.decode(encoded).substring(1)
|
||||||
const event = {
|
const event = {
|
||||||
|
@ -37,8 +46,8 @@ const addCommand = ({ commandNames, helpText, action, condition, hidden }) => {
|
||||||
console.log(' bad password')
|
console.log(' bad password')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const lastCall = userGetter.users[event.user].lastApiCall || 0
|
const lastCall = lastCalls[event.user] || 0
|
||||||
const secondsBetweenCalls = 5
|
const secondsBetweenCalls = 30
|
||||||
const currentTime = Math.floor(new Date().getTime() / 1000)
|
const currentTime = Math.floor(new Date().getTime() / 1000)
|
||||||
if (lastCall + secondsBetweenCalls > currentTime) {
|
if (lastCall + secondsBetweenCalls > currentTime) {
|
||||||
res.status(400)
|
res.status(400)
|
||||||
|
@ -47,12 +56,21 @@ const addCommand = ({ commandNames, helpText, action, condition, hidden }) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log(` went through for ${slack.users[event.user]}`)
|
console.log(` went through for ${slack.users[event.user]}`)
|
||||||
userGetter.users[event.user].lastApiCall = currentTime
|
lastCalls[event.user] = currentTime
|
||||||
|
|
||||||
await action({ event, say, words })
|
const user = getUser(event.user)
|
||||||
|
const haunted = false
|
||||||
|
//await action({ event, say, words, args, commandName })
|
||||||
|
const canUse = await condition({ event, say, words, commandName, args, user, userId: event.user, isAdmin: event.user.includes(slack.users.Sage) })
|
||||||
|
if (!canUse) {
|
||||||
|
await say(`Command '${words[0]}' not found`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await action({ event, say, trueSay: say, words, args, commandName, user, userId: event.user, haunted })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error('route error', e)
|
||||||
await say(e.stack)
|
await say(`Routing error. Make sure you've set up API access with the !setpw command in slack!\n` +
|
||||||
|
'Then you can use calls like `curl -u ":yourpw" \'http://10.3.0.48:3001/stonks\'`')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commandNames.forEach(name =>
|
commandNames.forEach(name =>
|
||||||
|
|
|
@ -6,7 +6,7 @@ const getTrivia = async () => axios.get('https://opentdb.com/api.php?amount=10&c
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(res => res.data.results)
|
.then(res => res.data.results)
|
||||||
.catch(console.error)
|
.catch(e => console.error('trivia error', e))
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getTrivia
|
getTrivia
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const { App: SlackApp } = require('@slack/bolt')
|
const { App: SlackApp } = require('@slack/bolt')
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
const { addReactions } = require('../games/hvacoins/utils')
|
const { addReactions, saveGame } = require('../games/hvacoins/utils')
|
||||||
|
|
||||||
const temperatureChannelId = 'C034156CE03'
|
const temperatureChannelId = 'C034156CE03'
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ try {
|
||||||
console.log('Failed to initialize SlackApp', e)
|
console.log('Failed to initialize SlackApp', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pollTriggers = ['!temp', '!temperature', '!imhot', '!imcold']
|
const pollTriggers = ['!temp', '!temperature', '!imhot', '!imcold', '!imfreezing', '!idonthavemysweater']
|
||||||
const halfTriggers = ['change temperature', "i'm cold", "i'm hot", 'quack', 'hvacker', '<@U0344TFA7HQ>']
|
const halfTriggers = ['change temperature', "i'm cold", "i'm hot", 'quack', 'hvacker', '<@U0344TFA7HQ>']
|
||||||
|
|
||||||
const sendHelp = async (say, prefix) => {
|
const sendHelp = async (say, prefix) => {
|
||||||
|
@ -53,6 +53,7 @@ const getMessage = async ({ channel, ts }) => app.client.conversations.history({
|
||||||
})
|
})
|
||||||
|
|
||||||
app.event('reaction_added', async ({ event, context, client, say }) => {
|
app.event('reaction_added', async ({ event, context, client, say }) => {
|
||||||
|
console.log('reaction_added', event)
|
||||||
for (const listener of reactionListeners) {
|
for (const listener of reactionListeners) {
|
||||||
listener({ event, say })
|
listener({ event, say })
|
||||||
}
|
}
|
||||||
|
@ -70,6 +71,8 @@ const users = {
|
||||||
U0X0ZQCN6: 'Caleb',
|
U0X0ZQCN6: 'Caleb',
|
||||||
U03BBTD4CQZ: 'Fernando',
|
U03BBTD4CQZ: 'Fernando',
|
||||||
U03DF152WUV: 'Nik',
|
U03DF152WUV: 'Nik',
|
||||||
|
U2X0SG7BP: 'John',
|
||||||
|
UR2H5KNHY: 'Jake',
|
||||||
|
|
||||||
Sage: 'U028BMEBWBV',
|
Sage: 'U028BMEBWBV',
|
||||||
Adam: 'U02U15RFK4Y',
|
Adam: 'U02U15RFK4Y',
|
||||||
|
@ -81,15 +84,34 @@ const users = {
|
||||||
Caleb: 'U0X0ZQCN6',
|
Caleb: 'U0X0ZQCN6',
|
||||||
Hvacker: 'U0344TFA7HQ',
|
Hvacker: 'U0344TFA7HQ',
|
||||||
Fernando: 'U03BBTD4CQZ',
|
Fernando: 'U03BBTD4CQZ',
|
||||||
Nik: 'U03DF152WUV'
|
John: 'U2X0SG7BP',
|
||||||
|
Jake: 'UR2H5KNHY',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buildSayPrepend = ({ say, prepend }) => async msg => {
|
||||||
|
if (typeof(msg) === 'string') {
|
||||||
|
return say(prepend + msg)
|
||||||
|
}
|
||||||
|
return say({
|
||||||
|
...msg,
|
||||||
|
text: prepend + msg.text
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
process.once('SIGINT', code => {
|
||||||
|
saveGame(true)
|
||||||
|
process.exit()
|
||||||
|
})
|
||||||
|
|
||||||
const activePolls = {}
|
const activePolls = {}
|
||||||
const testId = 'U028BMEBWBV_TEST'
|
const testId = 'U028BMEBWBV_TEST'
|
||||||
let testMode = false
|
let testMode = false
|
||||||
app.event('message', async ({ event, context, client, say }) => {
|
app.event('message', async ({ event, context, client, say }) => {
|
||||||
if (event.subtype !== 'message_changed') {
|
if (event.subtype !== 'message_changed' && event?.text !== '!') {
|
||||||
console.log(event)
|
console.log('message.event', {
|
||||||
|
...event,
|
||||||
|
userName: users[event.user]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (event?.user === users.Sage) {
|
if (event?.user === users.Sage) {
|
||||||
if (event?.text.startsWith('!')) {
|
if (event?.text.startsWith('!')) {
|
||||||
|
@ -116,6 +138,10 @@ app.event('message', async ({ event, context, client, say }) => {
|
||||||
}
|
}
|
||||||
if (event.user === users.Sage && event.channel === 'D0347Q4H9FE') {
|
if (event.user === users.Sage && event.channel === 'D0347Q4H9FE') {
|
||||||
if (event.text === '!!kill') {
|
if (event.text === '!!kill') {
|
||||||
|
saveGame(true)
|
||||||
|
process.exit(1)
|
||||||
|
} else if (event.text === '!!restart') {
|
||||||
|
saveGame(true)
|
||||||
process.exit()
|
process.exit()
|
||||||
}
|
}
|
||||||
if (event.text?.startsWith('!say ') || event.text?.startsWith('!say\n')) {
|
if (event.text?.startsWith('!say ') || event.text?.startsWith('!say\n')) {
|
||||||
|
@ -167,6 +193,7 @@ app.event('message', async ({ event, context, client, say }) => {
|
||||||
reactCounts[name] += 1
|
reactCounts[name] += 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
console.log('REACT COUNTS', JSON.stringify(reactCounts))
|
||||||
|
|
||||||
const contentVotes = reactCounts[goodEmoji] || 0
|
const contentVotes = reactCounts[goodEmoji] || 0
|
||||||
let hotterVotes = reactCounts[hotterEmoji] || 0
|
let hotterVotes = reactCounts[hotterEmoji] || 0
|
||||||
|
@ -188,11 +215,11 @@ app.event('message', async ({ event, context, client, say }) => {
|
||||||
|
|
||||||
let text
|
let text
|
||||||
if (hotterVotes > colderVotes && hotterVotes > contentVotes) {
|
if (hotterVotes > colderVotes && hotterVotes > contentVotes) {
|
||||||
text = `<@${users.Quade}> The people have spoken, and would like to `
|
text = `<@${users.Adam}> The people have spoken, and would like to `
|
||||||
text += 'raise the temperature, quack.'
|
text += 'raise the temperature, quack.'
|
||||||
requestTempChange('Hotter')
|
requestTempChange('Hotter')
|
||||||
} else if (colderVotes > hotterVotes && colderVotes > contentVotes) {
|
} else if (colderVotes > hotterVotes && colderVotes > contentVotes) {
|
||||||
text = `<@${users.Quade}> The people have spoken, and would like to `
|
text = `<@${users.Adam}> The people have spoken, and would like to `
|
||||||
text += 'lower the temperature, quack quack.'
|
text += 'lower the temperature, quack quack.'
|
||||||
requestTempChange('Colder')
|
requestTempChange('Colder')
|
||||||
} else {
|
} else {
|
||||||
|
@ -233,7 +260,7 @@ const messageIn = async (channel, optionsOrText) => {
|
||||||
|
|
||||||
const startPoll = async () => {
|
const startPoll = async () => {
|
||||||
const sent = await postToTechThermostatChannel({
|
const sent = await postToTechThermostatChannel({
|
||||||
text: `<!here|here> Temperature poll requested! In ${pollingMinutes} minutes the temperature will be adjusted.\n` +
|
text: `<!here> Temperature poll requested! In ${pollingMinutes} minutes the temperature will be adjusted.\n` +
|
||||||
`Pick :${colderEmoji}: if you want it colder, :${hotterEmoji}: if you want it hotter, or :${goodEmoji}: if you like it how it is.` +
|
`Pick :${colderEmoji}: if you want it colder, :${hotterEmoji}: if you want it hotter, or :${goodEmoji}: if you like it how it is.` +
|
||||||
'\n(Note that I can\'t actually change the temperature yet. Make Quade do it!)'
|
'\n(Note that I can\'t actually change the temperature yet. Make Quade do it!)'
|
||||||
})
|
})
|
||||||
|
@ -269,15 +296,15 @@ const decodeData = (key, message) => {
|
||||||
|
|
||||||
const onReaction = listener => reactionListeners.push(listener)
|
const onReaction = listener => reactionListeners.push(listener)
|
||||||
|
|
||||||
|
const channelIsIm = async channel => (await app.client.conversations.info({ channel }))?.channel?.is_im
|
||||||
|
|
||||||
onReaction(async ({ event }) => {
|
onReaction(async ({ event }) => {
|
||||||
if (event.user === users.Sage) {
|
if (event.reaction === 'x' && (event.user === users.Sage || await channelIsIm(event.item.channel))) {
|
||||||
if (event.reaction === 'x') {
|
|
||||||
try {
|
try {
|
||||||
await app.client.chat.delete({ channel: event.item.channel, ts: event.item.ts })
|
await app.client.chat.delete({ channel: event.item.channel, ts: event.item.ts })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -296,5 +323,6 @@ module.exports = {
|
||||||
messageIn,
|
messageIn,
|
||||||
testMode,
|
testMode,
|
||||||
testId,
|
testId,
|
||||||
users
|
users,
|
||||||
|
buildSayPrepend
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue