A couple moderate changes.

New achievements.
Only allow upgrades/achievements in DMs.
Add !steal joke.
Add more upgrades.
This commit is contained in:
Sage Vaillancourt 2022-03-04 08:26:20 -05:00
parent 0476720a54
commit f054154717
4 changed files with 190 additions and 20 deletions

View File

@ -23,6 +23,21 @@ module.exports = {
name: 'Lucky Gem Acquired', name: 'Lucky Gem Acquired',
description: 'It sparkles', description: 'It sparkles',
emoji: 'gem' emoji: 'gem'
},
bugFinder: {
name: 'Bug-Finder',
description: 'You must have a magnifying glass or something',
emoji: 'bug'
},
bigBets: {
name: 'Make a bet over 100B',
description: 'I like big bets, and that\'s the truth',
emoji: 'slot_machine'
},
ignited: {
name: 'You light my fire, baby',
description: 'And you pay attention to descriptions!',
emoji: 'fire'
} }
} }

View File

@ -5,6 +5,20 @@ const buyableItems = require('./buyableItems')
const upgrades = require('./upgrades') const upgrades = require('./upgrades')
const achievements = require('./achievements') const achievements = require('./achievements')
// const readline = require('readline').createInterface({
// input: process.stdin,
// output: process.stdout
// })
// const read = () => {
// readline.question(`What do YOU want? `, async want => {
// want && await slack.messageSage(want)
// read()
// })
// }
// ;(async () => {
// read()
// })();
const saveFile = 'hvacoins.json' const saveFile = 'hvacoins.json'
const parseOr = (parseable, orFunc) => { const parseOr = (parseable, orFunc) => {
@ -58,9 +72,17 @@ const helpText = (highestCoins, user) => Object.entries(buyableItems)
const getUpgradeEmoji = upgrade => upgrade.emoji || buyableItems[upgrade.type].emoji const getUpgradeEmoji = upgrade => upgrade.emoji || buyableItems[upgrade.type].emoji
const upgradeText = user => { const upgradeText = user => {
return (!user ? '' : '\n\n' + Object.entries(upgrades).filter(([upgradeName, upgrade]) => !hasUpgrade(user, upgrade, upgradeName)).filter(([, upgrade]) => upgrade.condition(user)).map(([key, value]) => `:${getUpgradeEmoji(value)}: *${key}* - ${commas(value.cost)}\n_${value.description}_`).join('\n\n')) + const userDoesNotHave = ([upgradeName, upgrade]) => !hasUpgrade(user, upgrade, upgradeName)
'\n\n:grey_question::grey_question::grey_question:' + const userMeetsCondition = ([, upgrade]) => upgrade.condition(user)
'\n\nJust type \'!upgrade upgrade_name\' to purchase' const format = ([key, value]) => `:${getUpgradeEmoji(value)}: *${key}* - ${commas(value.cost)}\n_${value.description}_`
return '\n\n' +
Object.entries(upgrades)
.filter(userDoesNotHave)
.filter(userMeetsCondition)
.map(format)
.join('\n\n') +
'\n\n:grey_question::grey_question::grey_question:' +
'\n\nJust type \'!upgrade upgrade_name\' to purchase'
} }
const getUser = userId => { const getUser = userId => {
@ -90,13 +112,15 @@ const setHighestCoins = userId => {
const hasUpgrade = (user, upgrade, upgradeName) => user.upgrades[upgrade.type]?.includes(upgradeName) const hasUpgrade = (user, upgrade, upgradeName) => user.upgrades[upgrade.type]?.includes(upgradeName)
const addAchievement = async (user, achievementName, say) => { const addAchievement = (user, achievementName, say) => {
if (user.achievements[achievementName]) { if (user.achievements[achievementName]) {
return return
} }
user.achievements[achievementName] = true setTimeout(async () => {
saveGame() user.achievements[achievementName] = true
await say(`You earned the achievement ${achievements[achievementName].name}!`) saveGame()
await say(`You earned the achievement ${achievements[achievementName].name}!`)
}, 500)
} }
const alwaysAccessible = () => true const alwaysAccessible = () => true
@ -130,7 +154,7 @@ slack.onMessage(async ({ event, say }) => {
return return
} }
if (!c?.condition(event.user)) { if (!c?.condition(event.user)) {
await say(`Command '${words[0]}' not found`) //await say(`Command '${words[0]}' not found`)
return return
} }
if (words[1] === 'help') { if (words[1] === 'help') {
@ -144,6 +168,10 @@ command(
['!a', '!ach', '!achievements'], ['!a', '!ach', '!achievements'],
'List your glorious achievements', 'List your glorious achievements',
async ({ event, say }) => { async ({ event, say }) => {
if (event.channel_type !== 'im') {
await say('Please only use !ach in DMs!')
return
}
const user = getUser(event.user) const user = getUser(event.user)
const achievementCount = Object.keys(user.achievements).length const achievementCount = Object.keys(user.achievements).length
@ -214,17 +242,17 @@ command(
if (random > 0.9967) { if (random > 0.9967) {
diff = 500 + Math.floor(c * 0.10) + secondsOfCps(60 * 30) diff = 500 + Math.floor(c * 0.10) + secondsOfCps(60 * 30)
prefix = `:gem: You found a lucky gem worth ${commas(diff)} HVAC!\n` prefix = `:gem: You found a lucky gem worth ${commas(diff)} HVAC!\n`
await addAchievement(user, 'luckyGem', say) addAchievement(user, 'luckyGem', say)
await slack.messageSage(`${slack.ourUsers[event.user]} FOUND A LUCKY GEM COIN WORTH ${commas(diff)} HVAC!`) await slack.messageSage(`${slack.ourUsers[event.user]} FOUND A LUCKY GEM COIN WORTH ${commas(diff)} HVAC!`)
} else if (random > 0.986) { } else if (random > 0.986) {
diff = 50 + Math.floor(c * 0.025) + secondsOfCps(60) diff = 50 + Math.floor(c * 0.025) + secondsOfCps(60)
prefix = `:goldbrick: You found a lucky gold coin worth ${commas(diff)} HVAC!\n` prefix = `:goldbrick: You found a lucky gold coin worth ${commas(diff)} HVAC!\n`
await slack.messageSage(`${slack.ourUsers[event.user]} found a lucky gold coin worth ${commas(diff)} HVAC!`) await slack.messageSage(`${slack.ourUsers[event.user]} found a lucky gold coin worth ${commas(diff)} HVAC!`)
await addAchievement(user, 'goldBrick', say) addAchievement(user, 'goldBrick', say)
} else if (random > 0.96) { } else if (random > 0.96) {
diff = 10 + Math.floor(c * 0.01) + secondsOfCps(10) diff = 10 + Math.floor(c * 0.01) + secondsOfCps(10)
prefix = `:money_with_wings: You found a lucky green coin worth ${commas(diff)} HVAC!\n` prefix = `:money_with_wings: You found a lucky green coin worth ${commas(diff)} HVAC!\n`
await addAchievement(user, 'greenCoin', say) addAchievement(user, 'greenCoin', say)
} else { } else {
prefix = `You mined one HVAC.\n` prefix = `You mined one HVAC.\n`
diff = 1 diff = 1
@ -261,6 +289,9 @@ command(
await say(`You don\'t have that many coins! You have ${commas(user.coins)}.`) await say(`You don\'t have that many coins! You have ${commas(user.coins)}.`)
return return
} }
if (n > 100_000_000_000) {
addAchievement(user, 'bigBets', say)
}
user.coins -= n user.coins -= n
let outcome let outcome
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
@ -317,8 +348,12 @@ command(
['!upgrade', '!u'], ['!upgrade', '!u'],
'Improve the performance of your HVAC-generators.\n' + 'Improve the performance of your HVAC-generators.\n' +
' Say \'!upgrade\' to list available upgrades, or \'!upgrade upgrade_name\' to purchase.', ' Say \'!upgrade\' to list available upgrades, or \'!upgrade upgrade_name\' to purchase.',
async ({ userId, say, words }) => { async ({ event, say, words }) => {
const user = getUser(userId) if (event.channel_type !== 'im') {
await say('Please only use !upgrade in DMs!')
return
}
const user = getUser(event.user)
const upgradeName = words[1] const upgradeName = words[1]
if (!upgradeName) { if (!upgradeName) {
await say(upgradeText(user)) await say(upgradeText(user))
@ -340,7 +375,7 @@ command(
await say('That item does not exist!') await say('That item does not exist!')
return return
} }
const c = getCoins(userId) const c = getCoins(event.user)
if (c < upgrade.cost) { if (c < upgrade.cost) {
await say(`You don't have enough coins! You have ${commas(c)}, but you need ${commas(upgrade.cost)}`) await say(`You don't have enough coins! You have ${commas(c)}, but you need ${commas(upgrade.cost)}`)
return return
@ -369,7 +404,7 @@ command(
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 (buyableItems.quade.baseCost < highestCoins * 100) {
await addAchievement(user, 'seeTheQuade', say) addAchievement(user, 'seeTheQuade', say)
} }
await say(helpText(highestCoins, user)) await say(helpText(highestCoins, user))
return return
@ -402,15 +437,16 @@ command(
command( command(
['!check', '!ch'], ['!check', '!ch'],
'Check how many coins another player has', 'Check how many coins another player has',
async ({ target, say }) => { async ({ say, words }) => {
const target = words[1]
if (!target?.startsWith('<@') || !target.endsWith('>')) { if (!target?.startsWith('<@') || !target.endsWith('>')) {
await say('Target must be a valid @') await say('Target must be a valid @')
return return
} }
const targetId = target.substring(2, target.length - 1) const targetId = target.substring(2, target.length - 1)
if (targetId !== 'U0344TFA7HQ') { if (targetId !== 'U0344TFA7HQ') {
const user = getUser(targetId) const coins = getCoins(targetId)
await say(`<@${targetId}> has ${commas(user.coins)} HVAC.`) await say(`<@${targetId}> has ${commas(coins)} HVAC.`)
} else { } else {
const members = (await slack.app.client.conversations.members({channel: slack.temperatureChannelId})).members const members = (await slack.app.client.conversations.members({channel: slack.temperatureChannelId})).members
const humanMembers = members.filter(name => name.length === 11) const humanMembers = members.filter(name => name.length === 11)
@ -534,4 +570,57 @@ command(
`They currently have ${commas(getCoins(targetId))} HVAC Coins\n\n` + `They currently have ${commas(getCoins(targetId))} HVAC Coins\n\n` +
`${collection(targetId)}\n\n` `${collection(targetId)}\n\n`
) )
}, true, adminOnly)
command(
['!steal', '!sagesteal'],
'Highly illegal',
async ({ event, words, say }) => {
const userId = event.user
const user = getUser(userId)
let [, target] = words
const amount = getCoins(userId) / 100
if (!amount || amount < 0) {
return
}
let targetId
if (!target?.startsWith('<@') || !target.endsWith('>')) {
targetId = slack.sageUserId
} else {
targetId = target.substring(2, target.length - 1)
}
if (user.coins < amount) {
return
}
const targetUser = getUser(targetId)
user.coins -= amount
targetUser.coins += amount
await say(`Stealing is wrong. Gave ${commas(Math.floor(amount))} of your HVAC to ${slack.ourUsers[targetId]}`)
}, true)
command(
['!lottery'],
'Once per day, try for a big win!',
async ({ event, say }) => {
const user = getUser(event.user)
addAchievement(user, 'ignited', say)
}, true)
command(
['!ignite'],
'You found me!',
async ({ event, say }) => {
const user = getUser(event.user)
addAchievement(user, 'ignited', say)
}
)
command(
['!giveach'],
'!giveach @player ach_name',
async ({ words, say }) => {
const targetId = words[1].substring(2, words[1].length - 1)
const user = getUser(targetId)
console.log(user, words[2], say)
addAchievement(user, words[2], say)
saveGame()
}, true, adminOnly) }, true, adminOnly)

View File

@ -6,6 +6,8 @@ const basic = ({ type, description, count, cost }) => ({
effect: itemCps => itemCps * 2 effect: itemCps => itemCps * 2
}) })
const nothing = itemCps => itemCps
module.exports = { module.exports = {
doubleClick: basic({ doubleClick: basic({
type: 'mouse', type: 'mouse',
@ -13,96 +15,152 @@ module.exports = {
count: 1, count: 1,
cost: 1_000, cost: 1_000,
}), }),
stinkierCheese: basic({
type: 'mouse',
description: 'Mice are doubly motivated to hunt down HVAC Coins',
count: 10,
cost: 21_000,
}),
biggerTeeth: basic({ biggerTeeth: basic({
type: 'mouse', type: 'mouse',
description: 'Mice can intimidate twice as much HVAC out of their victims.', description: 'Mice can intimidate twice as much HVAC out of their victims.',
count: 25, count: 25,
cost: 50_000, cost: 50_000,
}), }),
fasterComputers: basic({ fasterComputers: basic({
type: 'accountant', type: 'accountant',
description: 'Accountants can ~steal~ optimize twice as much HVAC!', description: 'Accountants can ~steal~ optimize twice as much HVAC!',
count: 1, count: 1,
cost: 11_000, cost: 11_000,
}), }),
lackOfMorality: basic({
type: 'accountant',
description: 'Accountants are taking a hint from nearby CEOs.',
count: 10,
cost: 200_000,
}),
widerBrains: basic({ widerBrains: basic({
type: 'accountant', type: 'accountant',
description: 'For accountant do double of thinking.', description: 'For accountant do double of thinking.',
count: 25, count: 25,
cost: 550_000, cost: 550_000,
}), }),
biggerBlowhole: basic({ biggerBlowhole: basic({
type: 'whale', type: 'whale',
description: 'With all that extra air, whales have double power!', description: 'With all that extra air, whales have double power!',
count: 1, count: 1,
cost: 120_000, cost: 120_000,
}), }),
sassyWhales: basic({
type: 'whale',
description: 'These are the kind of whales that know how to get twice as much done',
count: 10,
cost: 3_000_000,
}),
thinnerWater: basic({ thinnerWater: basic({
type: 'whale', type: 'whale',
description: 'Whales can move twice as quickly through this physics-defying liquid', description: 'Whales can move twice as quickly through this physics-defying liquid',
count: 25, count: 25,
cost: 6_000_000, cost: 6_000_000,
}), }),
greasyTracks: basic({ greasyTracks: basic({
type: 'train', type: 'train',
description: 'Lets trains deliver HVAC twice as efficiently', description: 'Lets trains deliver HVAC twice as efficiently',
count: 1, count: 1,
cost: 1_300_000, cost: 1_300_000,
}), }),
rocketThrusters: basic({
type: 'train',
description: 'That\'ll put some quack on your track',
count: 10,
cost: 22_000_000,
}),
loudConductors: basic({ loudConductors: basic({
type: 'train', type: 'train',
description: 'Conductors can onboard twice as much HVAC', description: 'Conductors can onboard twice as much HVAC',
count: 25, count: 25,
cost: 65_000_000, cost: 65_000_000,
}), }),
gasolineFire: basic({ gasolineFire: basic({
type: 'fire', type: 'fire',
description: 'Extremely good for breathing in.', description: 'Extremely good for breathing in.',
count: 1, count: 1,
cost: 14_000_000, cost: 14_000_000,
}), }),
extremelyDryFuel: basic({
type: 'fire',
description: 'Use the ignite command for a secret achievement.',
count: 10,
cost: 163_000_000,
}),
cavemanFire: basic({ cavemanFire: basic({
type: 'fire', type: 'fire',
description: 'They just don\'t make \'em like they used to.', description: 'They just don\'t make \'em like they used to.',
count: 25, count: 25,
cost: 700_000_000, cost: 700_000_000,
}), }),
spoonerang: basic({ spoonerang: basic({
type: 'boomerang', type: 'boomerang',
description: 'Scoops up HVAC mid-flight', description: 'Scoops up HVAC mid-flight',
count: 1, count: 1,
cost: 200_000_000, cost: 200_000_000,
}), }),
boomerAng: basic({
type: 'boomerang',
description: 'It\'s... old.',
count: 10,
cost: 1_200_000_000,
}),
doubleRang: basic({ doubleRang: basic({
type: 'boomerang', type: 'boomerang',
description: 'You throw one, but somehow catch two', description: 'You throw one, but somehow catch two',
count: 25, count: 25,
cost: 10_000_000_000, cost: 10_000_000_000,
}), }),
lunarPower: basic({ lunarPower: basic({
type: 'moon', type: 'moon',
description: 'Out with the sol, in with the lun!', description: 'Out with the sol, in with the lun!',
count: 1, count: 1,
cost: 3_300_000_000, cost: 3_300_000_000,
}), }),
womanOnTheMoon: basic({
type: 'moon',
description: 'There\'s no reason for it not to be a woman!',
count: 10,
cost: 39_700_000_000,
}),
doubleCraters: basic({ doubleCraters: basic({
type: 'moon', type: 'moon',
description: 'Making every side look like the dark side.', description: 'Making every side look like the dark side.',
count: 25, count: 25,
cost: 165_000_000_000, cost: 165_000_000_000,
}), }),
glassButterfly: basic({ glassButterfly: basic({
type: 'butterfly', type: 'butterfly',
description: 'Not your grandma\'s universe manipulation.', description: 'Not your grandma\'s universe manipulation.',
count: 1, count: 1,
cost: 51_000_000_000, cost: 51_000_000_000,
}), }),
monarchMigration: basic({
type: 'butterfly',
description: 'This upgrade brought to you by milkweed.',
count: 10,
cost: 870_000_000_000,
}),
quadWing: basic({ quadWing: basic({
type: 'butterfly', type: 'butterfly',
description: 'Sounds a lot like a trillion bees buzzing inside your head.', description: 'Sounds a lot like a trillion bees buzzing inside your head.',
count: 25, count: 25,
cost: 2_550_000_000_000, cost: 2_550_000_000_000,
}), }),
silverMirror: basic({ silverMirror: basic({
type: 'mirror', type: 'mirror',
description: 'Excellent for stabbing vampires.', description: 'Excellent for stabbing vampires.',
@ -136,5 +194,14 @@ module.exports = {
cost: 10_000_000_000, cost: 10_000_000_000,
effect: (itemCps, user) => Math.ceil(itemCps * 1.1) effect: (itemCps, user) => Math.ceil(itemCps * 1.1)
}, },
// moreUpgrades: {
// type: 'general',
// description: 'Adds additional upgrades',
// condition: user => Object.entries(user.items).reduce((total, [, countOwned]) => countOwned + total, 0) >= 400,
// emoji: 'cookie',
// cost: 10_000_000_000_000,
// effect: nothing
// },
} }

View File

@ -69,11 +69,10 @@ const ourUsers = {
let activePolls = {} let activePolls = {}
app.event('message', async ({ event, context, client, say }) => { app.event('message', async ({ event, context, client, say }) => {
console.log(event)
for (const listener of messageListeners) { for (const listener of messageListeners) {
listener({ event, say }) listener({ event, say })
} }
const words = event.text?.split('\s') console.log('MSG', ourUsers[event.user], "'" + event.text + "'", new Date().toLocaleTimeString())
if (event.user === 'U028BMEBWBV' && event.channel === 'D0347Q4H9FE') { if (event.user === 'U028BMEBWBV' && event.channel === 'D0347Q4H9FE') {
if (event.text?.startsWith('!say ') || event.text?.startsWith('!say\n')) { if (event.text?.startsWith('!say ') || event.text?.startsWith('!say\n')) {
await postToTechThermostatChannel(event.text.substring(4).trim()) await postToTechThermostatChannel(event.text.substring(4).trim())