302 lines
8.9 KiB
JavaScript
302 lines
8.9 KiB
JavaScript
const { commas, quackGradeMultiplier, prestigeMultiplier, makeBackup, userHasCheckedQuackgrade, getUser } = require('./utils')
|
|
const { quackStore } = require('./quackstore')
|
|
const buyableItems = require('./buyableItems')
|
|
const slack = require('../../slack')
|
|
|
|
const possiblePrestige = coins => {
|
|
let p = 0
|
|
while (totalCostForPrestige(p + 1) <= coins) {
|
|
p += 1
|
|
}
|
|
return p
|
|
}
|
|
|
|
const tpcRecMemo = []
|
|
const totalCostForPrestige = prestigeLevel => {
|
|
if (prestigeLevel === 0) {
|
|
return 0
|
|
}
|
|
return (tpcRecMemo[prestigeLevel]) || (tpcRecMemo[prestigeLevel] = 1_000_000_000_000 * Math.pow(prestigeLevel, 3) + totalCostForPrestige(prestigeLevel - 1))
|
|
}
|
|
|
|
const prestigeRoute = async ({ say, args, user }) => {
|
|
const possible = possiblePrestige(user.coinsAllTime)
|
|
const current = user.prestige ??= 0
|
|
if (args[0] === 'me') {
|
|
await say(
|
|
'This will permanently remove all of your items, upgrades, and coins!\n\n' +
|
|
'Say \'!!prestige me\' to confirm.'
|
|
)
|
|
} else {
|
|
const currentCost = totalCostForPrestige(possible)
|
|
const nextCost = totalCostForPrestige(possible + 1)
|
|
const diff = nextCost - currentCost
|
|
const progress = user.coinsAllTime - currentCost
|
|
const bars = Math.round((progress / diff) * 10)
|
|
const empty = 10 - bars
|
|
const progressBar = '[' + '='.repeat(bars) + ' '.repeat(empty) + ']'
|
|
await say(
|
|
`Current Prestige: ${commas(current)}\n\n` +
|
|
`Quacks gained if you prestige now: ${commas(possible - current)}\n\n` +
|
|
`Next quack progress: \`${progressBar} ${commas(diff)} \`\n\n` +
|
|
'Say \'!prestige me\' to start the prestige process.' +
|
|
`\n\nYour prestige is currently boosting your CPS by ${commas((prestigeMultiplier(user) - 1) * 100)}%`
|
|
)
|
|
}
|
|
}//, true, adminOnly)
|
|
|
|
const prestigeConfirmRoute = async ({ event, say, user, YEET }) => {
|
|
if (YEET) {
|
|
return say(prestigeMenu(user))
|
|
}
|
|
const possible = possiblePrestige(user.coinsAllTime)
|
|
const current = user.prestige
|
|
if (possible <= current) {
|
|
await say('You don\'t have enough HVAC to prestige right now!')
|
|
return
|
|
}
|
|
if (event?.text !== '!!prestige me') {
|
|
await say('Say exactly \'!!prestige me\' to confirm')
|
|
return
|
|
}
|
|
await makeBackup()
|
|
|
|
user.isPrestiging = true
|
|
|
|
user.quacks ??= 0
|
|
user.quacks += (possible - user.prestige)
|
|
|
|
user.prestige = possible
|
|
user.highestEver = 0
|
|
user.coins = 0
|
|
user.items = {}
|
|
user.holdings = {}
|
|
const starterUpgrades = (user.quackUpgrades?.starter || [])
|
|
starterUpgrades.forEach(upgradeName => quackStore[upgradeName].effect(user))
|
|
user.upgrades = {}
|
|
|
|
await say(prestigeMenu(user))
|
|
await say(`Say !quack _upgrade-name_ to purchase new quackgrades!`)
|
|
//await say('You prestiged! Check out !quackstore to see what you can buy!')
|
|
}
|
|
|
|
const quackStoreListing = (showCost = true) => ([name, upgrade]) =>
|
|
`:${upgrade.emoji}: *${name}* - ${showCost ? 'Costs' : 'Worth'} *${upgrade.cost} Quack.*\n\n_${upgrade.description}_`
|
|
|
|
const allUserQuackUpgrades = user =>
|
|
Object.entries(user.quackUpgrades || {})
|
|
.map(([type, upgrades]) => upgrades).flatMap(x => x)
|
|
|
|
const hasPreReqs = user => ([name, upgrade]) => {
|
|
if (!upgrade.preReqs) {
|
|
return true
|
|
}
|
|
const allUserUpgrades = allUserQuackUpgrades(user)
|
|
return upgrade.preReqs.every(preReq => allUserUpgrades.includes(preReq))
|
|
}
|
|
|
|
const owns = (user, [name, upgrade]) => allUserQuackUpgrades(user).includes(name)
|
|
|
|
const ownedQuackItems = user => Object.entries(quackStore).filter(upgrade => owns(user, upgrade))
|
|
|
|
const unownedQuackItems = user => Object.entries(quackStore).filter(upgrade => !owns(user, upgrade))
|
|
|
|
const quackStoreText = user =>
|
|
unownedQuackItems(user)
|
|
.filter(hasPreReqs(user))
|
|
.map(quackStoreListing(true))
|
|
.join('\n\n') +
|
|
`\n\nYou have ${user.quacks ??= 0} quacks to spend.` +
|
|
`\nQuackStore upgrades are currently boosting your CPS by ${commas((quackGradeMultiplier(user) - 1) * 100)}%`
|
|
|
|
const quackStoreRoute = async ({ user, say, args, YEET }) => {
|
|
user.quackUpgrades ??= {}
|
|
if (!args[0] || !YEET) {
|
|
await say(quackStoreText(user))
|
|
return
|
|
}
|
|
const quackItem = quackStore[args[0]]
|
|
if (!quackItem || !unownedQuackItems(user).find(([name]) => name === args[0])) {
|
|
await say(`'${args[0]}' is not available in the quack store!`)
|
|
return
|
|
}
|
|
const quacks = user.quacks ??= 0
|
|
if (quackItem.cost > quacks) {
|
|
await say(`${args[0]} costs ${quackItem.cost} Quacks, but you only have ${quacks}!`)
|
|
return
|
|
}
|
|
user.quacks -= quackItem.cost
|
|
user.quackUpgrades[quackItem.type] ??= []
|
|
user.quackUpgrades[quackItem.type].push(args[0])
|
|
if (quackItem.type === 'starter') {
|
|
quackItem.effect(user)
|
|
}
|
|
await say(`You bought ${args[0]}!`)
|
|
}
|
|
|
|
const buyQuackGradeButton = quackgrade => {
|
|
//console.log('buyQuackGradeButton', quackgrade[1])
|
|
const [name, object] = quackgrade
|
|
return {
|
|
type: 'section',
|
|
text: {
|
|
type: 'mrkdwn',
|
|
text: `:${object.emoji}: ${object.name} - ${object.cost} Quacks\n_${object.description}_`
|
|
},
|
|
accessory: {
|
|
type: 'button',
|
|
text: {
|
|
type: 'plain_text',
|
|
text: 'Buy',
|
|
emoji: true
|
|
},
|
|
value: 'click_me_123',
|
|
action_id: `buy-quackgrade-${name}`
|
|
}
|
|
}
|
|
}
|
|
|
|
const prestigeMenu = (user, extraMessage = '') => {
|
|
user.quackUpgrades ??= {}
|
|
const quacks = user.quacks ??= 0
|
|
return {
|
|
text: 'Prestige menu',
|
|
blocks: [
|
|
{
|
|
type: 'section',
|
|
text: {
|
|
type: 'mrkdwn',
|
|
text: `${extraMessage && extraMessage + '\n'}\n_You have ${quacks} quacks to spend._`
|
|
// text: `${extraMessage && extraMessage + '\n'}_*PRESTIGE IN PROGRESS*_\n_You have ${quacks} quacks to spend. You may ONLY spend quacks on this menu._`
|
|
}
|
|
},
|
|
// {
|
|
// type: 'section',
|
|
// text: {
|
|
// type: 'mrkdwn',
|
|
// text: '~Challenge mode~ _TODO_'
|
|
// },
|
|
// accessory: {
|
|
// type: 'static_select',
|
|
// placeholder: {
|
|
// type: 'plain_text',
|
|
// text: 'No challenge',
|
|
// emoji: true
|
|
// },
|
|
// options: [
|
|
// {
|
|
// text: {
|
|
// type: 'plain_text',
|
|
// text: 'No challenge',
|
|
// emoji: true
|
|
// },
|
|
// value: 'no-challenge'
|
|
// },
|
|
// /*
|
|
// {
|
|
// text: {
|
|
// type: 'plain_text',
|
|
// text: 'Clean Start (no prestige bonuses)',
|
|
// emoji: true
|
|
// },
|
|
// value: 'clean-start'
|
|
// }*/
|
|
// ],
|
|
// action_id: 'challenge_select-action'
|
|
// }
|
|
// },
|
|
{
|
|
type: 'section',
|
|
text: {
|
|
type: 'mrkdwn',
|
|
text: '*Available Quackgrades:*'
|
|
}
|
|
},
|
|
...unownedQuackItems(user).filter(hasPreReqs(user)).map(buyQuackGradeButton),
|
|
// {
|
|
// type: 'actions',
|
|
// elements: [
|
|
// {
|
|
// type: 'button',
|
|
// text: {
|
|
// type: 'plain_text',
|
|
// text: 'Complete Prestige',
|
|
// emoji: true
|
|
// },
|
|
// value: 'complete_prestige',
|
|
// action_id: 'complete_prestige'
|
|
// }
|
|
// ]
|
|
// }
|
|
]
|
|
}
|
|
}
|
|
|
|
const buyQuackGrade = async ({ body, ack, say, trueSay, payload }) => {
|
|
await ack()
|
|
const buying = payload.action_id.substring('buy-quackgrade-'.length)
|
|
|
|
console.log(`buyQuackGrade ${buying} clicked`)
|
|
const user = getUser(body.user.id)
|
|
// if (!user.isPrestiging) {
|
|
// console.log('You must be prestiging!')
|
|
// return say(`You must be prestiging to use this menu!`)
|
|
// }
|
|
const words = ['', buying, body.actions[0].text]
|
|
const [, ...args] = words
|
|
|
|
let extraMessage = ''
|
|
//say = async text => extraMessage = text
|
|
console.log('quackStoreRoute')
|
|
await quackStoreRoute({ say, args, user, YEET: true })
|
|
|
|
await slack.app.client.chat.update({
|
|
channel: body.channel.id,
|
|
ts: body.message.ts,
|
|
...prestigeMenu(user, extraMessage)
|
|
})
|
|
}
|
|
|
|
Object.keys(quackStore).forEach(itemName => slack.app.action('buy-quackgrade-' + itemName, buyQuackGrade))
|
|
|
|
slack.app.action('complete_prestige', async ({ body, ack, say }) => {
|
|
await ack()
|
|
|
|
const user = getUser(body.user.id)
|
|
delete user.isPrestiging
|
|
|
|
await slack.app.client.chat.delete({
|
|
channel: body.channel.id,
|
|
ts: body.message.ts,
|
|
})
|
|
|
|
await say(`Prestige complete!`)
|
|
})
|
|
|
|
const prestigeMenuRoute = async ({ say, user }) => {
|
|
user.quackUpgrades ??= {}
|
|
user.quacks ??= 0
|
|
await say(prestigeMenu(user))
|
|
}
|
|
|
|
const ownedQuacksText = user =>
|
|
ownedQuackItems(user)
|
|
.filter(hasPreReqs(user))
|
|
.map(quackStoreListing(false))
|
|
.join('\n\n') +
|
|
`\n\nQuackStore upgrades are currently boosting your CPS by ${commas((quackGradeMultiplier(user) - 1) * 100)}%`
|
|
|
|
const ownedQuacksRoute = async ({ say, user }) => {
|
|
user.quackUpgrades ??= {}
|
|
user.quacks ??= 0
|
|
await say(ownedQuacksText(user))
|
|
}
|
|
|
|
module.exports = {
|
|
quackStoreRoute,
|
|
prestigeRoute,
|
|
prestigeConfirmRoute,
|
|
prestigeMenuRoute,
|
|
ownedQuacksRoute
|
|
}
|