2024-06-19 19:50:14 +00:00
const { App } = require ( '@slack/bolt' ) ;
2024-06-19 20:20:41 +00:00
const postgres = require ( 'postgres' ) ;
2024-06-19 19:50:14 +00:00
require ( 'dotenv' ) . config ( )
2024-06-19 22:07:29 +00:00
const sql = postgres ( {
2024-06-20 01:03:30 +00:00
host : '/var/run/postgresql' ,
2024-06-19 20:20:41 +00:00
database : 'haroon_slackmaster' ,
2024-06-20 01:03:30 +00:00
username : 'haroon'
2024-06-19 20:20:41 +00:00
} )
2024-06-19 19:50:14 +00:00
2024-06-24 19:56:44 +00:00
const SpecialOpponents = require ( './opponents/special' ) ;
2024-06-20 01:03:30 +00:00
const BeginnerOpponents = require ( './opponents/beginner' ) ;
const AllOpponents = [
2024-06-24 19:56:44 +00:00
... ( SpecialOpponents . map ( x => ( { ... x , rank : 'SPECIAL' } ) ) ) ,
... ( BeginnerOpponents . map ( x => ( { ... x , rank : 'BEGINNER' } ) ) ) ,
2024-06-20 01:03:30 +00:00
]
2024-06-19 19:50:14 +00:00
const app = new App ( {
token : process . env . SLACK _BOT _TOKEN ,
signingSecret : process . env . SLACK _SIGNING _SECRET
} ) ;
2024-06-19 22:07:29 +00:00
async function initializeUser ( slackUserId ) {
let a = await sql ` SELECT * FROM users WHERE slack_id = ${ slackUserId } ; `
2024-06-19 20:20:41 +00:00
if ( a . length === 0 ) {
2024-06-19 22:07:29 +00:00
a = await sql ` INSERT INTO users (slack_id) VALUES ( ${ slackUserId } ) RETURNING *; `
2024-06-22 18:45:37 +00:00
await sql ` INSERT INTO cooldowns (slack_id) VALUES ( ${ slackUserId } ); `
2024-06-19 20:20:41 +00:00
}
2024-06-19 22:07:29 +00:00
return a [ 0 ] ;
}
app . use ( async ( ctx ) => {
2024-06-20 01:03:30 +00:00
await initializeUser ( ctx . context . userId )
2024-06-19 22:07:29 +00:00
2024-06-19 20:20:41 +00:00
await ctx . next ( )
} )
2024-06-19 19:50:14 +00:00
app . command ( '/chooseopponent' , async ( ctx ) => {
await ctx . ack ( ) ;
2024-06-20 01:03:30 +00:00
const user = await initializeUser ( ctx . body . user _id ) ;
if ( user . currentopponent != "None" ) {
const opponent = AllOpponents . find ( x => x . rawId == user . currentopponent )
return await ctx . respond ( {
response _type : 'ephemeral' ,
text : ` You are already in a battle with ${ opponent . name } . ` ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* You are already in a battle with * ${ opponent . name } *. Please finish your battle with them before proceeding.
$ { user . battlemessage } `
}
}
]
} )
}
2024-06-19 19:50:14 +00:00
await ctx . client . views . open ( {
trigger _id : ctx . body . trigger _id ,
view : {
2024-06-20 01:03:30 +00:00
"private_metadata" : ctx . payload . channel _id ,
2024-06-19 19:50:14 +00:00
"type" : "modal" ,
"callback_id" : "chooseopponent" ,
"title" : {
"type" : "plain_text" ,
"text" : "Choose an opponent" ,
"emoji" : true
} ,
"submit" : {
"type" : "plain_text" ,
"text" : "Choose" ,
"emoji" : true
} ,
"close" : {
"type" : "plain_text" ,
"text" : "Never mind" ,
"emoji" : true
} ,
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
2024-06-20 17:31:27 +00:00
"text" : ` *Battle Support*: Hiya <@ ${ ctx . body . user _id } >! What rank opponent would you like to battle against? \n \n Not sure yet? Don't worry! Just cancel out and view what opponents you can fight with \` /viewopponents \` ! `
2024-06-19 19:50:14 +00:00
}
} ,
{
"type" : "divider"
} ,
{
"type" : "input" ,
"element" : {
"type" : "radio_buttons" ,
"options" : [
{
"text" : {
"type" : "plain_text" ,
"text" : "Special" ,
"emoji" : true
} ,
"value" : "SPECIAL"
} ,
{
"text" : {
"type" : "plain_text" ,
"text" : "Beginner" ,
"emoji" : true
} ,
"value" : "BEGINNER"
} ,
{
"text" : {
"type" : "plain_text" ,
"text" : "Casual" ,
"emoji" : true
} ,
"value" : "CASUAL"
}
] ,
"action_id" : "rank-selection"
} ,
"label" : {
"type" : "plain_text" ,
"text" : "Choose a rank:" ,
"emoji" : true
}
}
]
}
} )
} ) ;
2024-06-19 22:07:29 +00:00
function generateProfile ( dbUser , slackUser ) {
return [
{
"type" : "section" ,
"fields" : [
{
"type" : "mrkdwn" ,
"text" : "*User:* " + slackUser . display _name _normalized
} ,
{
"type" : "mrkdwn" ,
"text" : "*Rank:* " + dbUser . rank
} ,
{
"type" : "mrkdwn" ,
"text" : "*Battle Power*: " + ( dbUser . health + dbUser . mindmg + dbUser . maxdmg )
} ,
{
"type" : "mrkdwn" ,
2024-06-21 19:30:56 +00:00
"text" : ` *Victories/Losses:* ${ dbUser . victories } / ${ dbUser . losses } ( ${ ( dbUser . victories / ( dbUser . victories + dbUser . losses ) ) * 100 || 0 } %) `
2024-06-19 22:07:29 +00:00
} ,
{
"type" : "mrkdwn" ,
"text" : "*Current Win Streak:* " + dbUser . curstreak
} ,
{
"type" : "mrkdwn" ,
"text" : "*Highest Win Streak*: " + dbUser . highstreak
}
] ,
"accessory" : {
"type" : "image" ,
"image_url" : slackUser . image _1024 ,
"alt_text" : "user profile"
}
} ,
{
"type" : "section" ,
2024-06-23 19:25:19 +00:00
"fields" : [
{
"type" : "mrkdwn" ,
"text" : ` *Base Health:* ${ dbUser . health } \n *Base Min Damage:* ${ dbUser . mindmg } \n *Base Max Damage:* ${ dbUser . maxdmg } `
} ,
{
"type" : "mrkdwn" ,
"text" : ` *Creation Shards:* ${ dbUser . cshards } \n *Destruction Shards:* ${ dbUser . dshards } \n *Skill Points:* ${ dbUser . spoints } `
2024-06-24 19:56:44 +00:00
}
2024-06-23 19:25:19 +00:00
]
2024-06-19 22:07:29 +00:00
}
]
}
app . command ( '/profile' , async ( ctx ) => {
await ctx . ack ( ) ;
const args = ctx . body . text . slice ( ) . split ( / +/g ) . filter ( x => x ) ;
let match ;
// If there is an argument and the first one is a Slack ping
if ( args . length && ( match = args [ 0 ] . match ( /\<\@(.+)\|(.+)>/ ) ) ) {
const mentionedUser = match [ 1 ] ;
const dbUser = await initializeUser ( mentionedUser ) ;
const slackUser = ( await ctx . client . users . info ( { user : mentionedUser } ) ) . user . profile ;
ctx . say ( {
"text" : ` @ ${ slackUser . display _name _normalized } 's profile ` ,
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
"text" : ` <@ ${ ctx . body . user _id } > ran \` /profile @ ${ slackUser . display _name _normalized } \` `
}
} ,
... generateProfile ( dbUser , slackUser )
]
} )
}
// If there is an argument but it isn't a Slack ping
else if ( args . length ) {
ctx . respond ( {
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* Greetings <@ ${ ctx . body . user _id } >. You have tried to view the profile of an invalid user. Please ensure you either send a user ping as an argument or provide no argument at all. `
}
}
]
} )
}
// There is no argument
else {
const dbUser = await initializeUser ( ctx . body . user _id ) ;
const slackUser = ( await ctx . client . users . info ( { user : ctx . body . user _id } ) ) . user . profile ;
ctx . say ( {
"text" : ` @ ${ slackUser . display _name _normalized } 's profile ` ,
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
"text" : ` <@ ${ ctx . body . user _id } > ran \` /profile \` `
}
} ,
... generateProfile ( dbUser , slackUser )
]
} )
}
} )
2024-06-19 19:50:14 +00:00
app . view ( "chooseopponent" , async ( ctx ) => {
2024-06-21 21:19:36 +00:00
const user = await initializeUser ( ctx . context . userId ) ;
2024-06-19 19:50:14 +00:00
const { selected _option } = Object . values ( ctx . view . state . values ) [ 0 ] [ 'rank-selection' ] ;
const rank = selected _option . value ;
2024-06-19 20:27:12 +00:00
const messages = {
"SPECIAL" : ` *Battle Special*: Wasn't expecting to see ya here <@ ${ ctx . body . user . id } >... I guess you're up for a challenge huh? Alright then, who do ya wanna annoy today? ` ,
"BEGINNER" : ` *Battle Beginner*: Hey there <@ ${ ctx . body . user . id } >! Let's keep things simple, who do you want to battle against? ` ,
"CASUAL" : ` *Battle Casual*: Alright <@ ${ ctx . body . user . id } >, things are about to get a little bit tougher from here... Who do you feel like taking on today? `
}
2024-06-21 21:19:36 +00:00
const canRankUp = ( ( ) => {
if ( user . rank == 'Beginner' ) {
return ( user . health + user . mindmg + user . maxdmg ) >= 50 && user . cshards >= 50
} else if ( user . rank == 'Casual' ) {
return ( user . health + user . mindmg + user . maxdmg ) >= 200 && user . cshards >= 250
} else {
return false
}
} ) ( ) ;
2024-06-19 19:50:14 +00:00
await ctx . ack ( {
response _action : 'update' ,
view : {
2024-06-20 01:03:30 +00:00
"private_metadata" : ctx . payload . private _metadata ,
2024-06-19 19:50:14 +00:00
"type" : "modal" ,
2024-06-24 22:09:43 +00:00
"callback_id" : "chooseopponent1" ,
2024-06-19 19:50:14 +00:00
"title" : {
"type" : "plain_text" ,
"text" : "Choose an opponent" ,
"emoji" : true
} ,
"submit" : {
"type" : "plain_text" ,
"text" : "Battle" ,
"emoji" : true
} ,
"close" : {
"type" : "plain_text" ,
"text" : "Never mind" ,
"emoji" : true
} ,
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
2024-06-19 20:27:12 +00:00
"text" : messages [ rank ] || ` *Battle Master*: Greetings <@ ${ ctx . body . user . id } >. Please choose an opponent from below to battle. `
2024-06-19 19:50:14 +00:00
}
} ,
{
"type" : "divider"
} ,
{
"type" : "input" ,
"element" : {
"type" : "static_select" ,
2024-06-24 19:56:44 +00:00
"options" : AllOpponents . filter ( op => op . rank == rank ) . map ( opponent => {
const battlePower = ( ( opponent ) => {
if ( opponent . stats . health instanceof Function ) {
return opponent . stats . health ( user ) + opponent . stats . min ( user ) + opponent . stats . max ( user )
} else {
return opponent . stats . health + opponent . stats . min + opponent . stats . max
}
} ) ( opponent ) ;
return {
"text" : {
"type" : "plain_text" ,
2024-06-24 22:09:43 +00:00
"text" : ` ${ opponent . name } // ${ battlePower } Battle Power ` + ( opponent . secretCondition && ! opponent . secretCondition ( user ) ? " :lock:" : "" ) ,
2024-06-24 19:56:44 +00:00
"emoji" : true
} ,
"value" : opponent . rawId
}
} ) ,
2024-06-19 19:50:14 +00:00
"action_id" : "opponents"
} ,
"label" : {
"type" : "plain_text" ,
"text" : "Choose an opponent:" ,
"emoji" : true
}
2024-06-21 21:19:36 +00:00
} ,
2024-06-24 19:56:44 +00:00
... ( canRankUp ? [
2024-06-21 21:19:36 +00:00
{
type : 'divider' ,
} ,
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
"text" : ` You can also now participate in a rank up battle against *Battle ${ user . rank } *. Click the button below to initiate the battle. `
} ,
"accessory" : {
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "Click Me" ,
"emoji" : true
} ,
"value" : ctx . context . userId ,
"action_id" : "start-rankup-battle"
}
}
] : [ ] )
2024-06-19 19:50:14 +00:00
]
}
} )
} )
2024-06-24 22:09:43 +00:00
app . view ( "chooseopponent1" , async ( ctx ) => {
2024-06-19 20:20:41 +00:00
await ctx . ack ( ) ;
2024-06-20 01:03:30 +00:00
const channelId = ctx . view . private _metadata ;
const userId = ctx . context . userId ;
const slackUser = ( await ctx . client . users . info ( { user : userId } ) ) . user . profile ;
2024-06-24 22:09:43 +00:00
const opponent = AllOpponents . find ( o => o . rawId == Object . values ( ctx . payload . state . values ) [ 0 ] . opponents . selected _option . value ) ;
2024-06-20 01:03:30 +00:00
const player = await initializeUser ( userId ) ;
2024-06-24 22:09:43 +00:00
if ( opponent . secretCondition && ! opponent . secretCondition ( player ) ) {
return await ctx . client . chat . postEphemeral ( {
channel : channelId ,
user : ctx . context . userId ,
text : ` ${ slackUser . display _name _normalized } started a battle against ${ opponent . name } . ` ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : opponent . deniedIntro . replaceAll ( "{player}" , slackUser . display _name _normalized )
} ,
"accessory" : {
"type" : "image" ,
"image_url" : opponent . image ,
"alt_text" : opponent . name
2024-06-20 01:03:30 +00:00
}
2024-06-24 22:09:43 +00:00
}
]
} )
}
2024-06-24 19:56:44 +00:00
2024-06-24 22:09:43 +00:00
const opponentStats = ( ( opponent ) => {
if ( opponent . stats . health instanceof Function ) {
return [ opponent . stats . health ( player ) , opponent . stats . min ( player ) , opponent . stats . max ( player ) ]
} else {
return [ opponent . stats . health , opponent . stats . min , opponent . stats . max ]
}
} ) ( opponent ) ;
2024-06-24 19:56:44 +00:00
await sql ` UPDATE users
SET playerhealth = $ { player . health } ,
playermin = $ { player . mindmg } ,
playermax = $ { player . maxdmg } ,
currentOpponent = $ { opponent . rawId } ,
2024-06-24 22:09:43 +00:00
opponenthealth = $ { opponentStats [ 0 ] } ,
opponentmin = $ { opponentStats [ 1 ] } ,
opponentmax = $ { opponentStats [ 2 ] }
2024-06-24 19:56:44 +00:00
WHERE slack _id = $ { userId } ; `
const msg = await ctx . client . chat . postMessage ( {
channel : channelId ,
text : ` ${ slackUser . display _name _normalized } started a battle against ${ opponent . name } . ` ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : opponent . intro . replaceAll ( "{player}" , slackUser . display _name _normalized )
} ,
"accessory" : {
"type" : "image" ,
"image_url" : opponent . image ,
"alt_text" : opponent . name
}
} ,
{
"type" : "actions" ,
"elements" : [
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "Continue" ,
"emoji" : true
} ,
"value" : userId ,
"action_id" : "continue"
}
]
}
]
} ) ;
await sql ` UPDATE users SET battlemessage = ${ ` https://hackclub.slack.com/archives/ ${ channelId } /p ${ msg . ts . replace ( '.' , '' ) } ` } WHERE slack_id = ${ userId } ; `
} )
2024-06-20 17:31:27 +00:00
async function checkButton ( ctx ) {
await ctx . ack ( ) ;
if ( ctx . payload . value != ctx . context . userId ) {
return ctx . respond ( {
replace _original : false ,
response _type : 'ephemeral' ,
text : "Battle Support: Please do not click other battlers buttons!" ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Support:* Erm, <@ ${ ctx . context . userId } >?... Please don't press other battlers buttons!
If you want to choose an opponent yourself , simply use \ ` /chooseopponent \` to get started! `
}
}
]
} )
}
await ctx . next ( ) ;
2024-06-20 21:17:26 +00:00
}
2024-06-20 17:31:27 +00:00
2024-06-21 19:30:56 +00:00
function chooseAction ( chances ) {
const random = Math . random ( ) ;
let cumulative = 0 ;
2024-06-20 19:49:30 +00:00
2024-06-21 19:30:56 +00:00
for ( const action in chances ) {
cumulative += chances [ action ] ;
if ( random < cumulative ) {
return action ;
}
}
}
async function takeOutOfBattle ( slack _id ) {
return await sql ` UPDATE users SET
currentopponent = 'None' ,
playerhealth = NULL ,
playermin = NULL ,
playermax = NULL ,
playerdefense = NULL ,
playerdefendcount = 0 ,
opponenthealth = NULL ,
opponentmin = NULL ,
opponentmax = NULL ,
opponentdefense = NULL ,
opponentdefendcount = 0 ,
battlemessage = NULL
WHERE slack _id = $ { slack _id } ;
`
}
async function playerLoss ( ctx ) {
const user = await initializeUser ( ctx . context . userId ) ;
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
await takeOutOfBattle ( ctx . context . userId ) ;
await sql `
UPDATE users
SET spoints = $ { user . spoints - 1 } ,
cshards = $ { user . cshards - 5 } ,
2024-06-24 19:56:44 +00:00
losses = $ { user . losses + 1 }
2024-06-21 19:30:56 +00:00
WHERE slack _id = $ { ctx . context . userId } ;
`
ctx . respond ( {
replace _original : true ,
text : ` ${ slackUser . display _name _normalized } lost against ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } ` ,
"blocks" : [
{
"type" : "context" ,
"elements" : [
{
"type" : "mrkdwn" ,
"text" : "*DEFEAT :trophy:*"
}
]
} ,
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
2024-06-24 22:09:43 +00:00
"text" : ` Oh no ${ slackUser . display _name _normalized } ... You've been defeated by ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } ... Don't give up! There's always room for improvement! \n \n \n *Losses:* \n > -1 Skill Point \n >-5 Creation Shards \n > 1 Defeat `
2024-06-21 19:30:56 +00:00
} ,
"accessory" : {
"type" : "image" ,
"image_url" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . image ,
"alt_text" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . name
}
}
]
} )
}
async function playerWin ( ctx ) {
const user = await initializeUser ( ctx . context . userId ) ;
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
await takeOutOfBattle ( ctx . context . userId ) ;
await sql `
UPDATE users
SET spoints = $ { user . spoints + 1 } ,
cshards = $ { user . cshards + 5 } ,
victories = $ { user . victories + 1 }
WHERE slack _id = $ { ctx . context . userId } ;
`
ctx . respond ( {
replace _original : true ,
text : ` ${ slackUser . display _name _normalized } won against ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } ` ,
"blocks" : [
{
"type" : "context" ,
"elements" : [
{
"type" : "mrkdwn" ,
"text" : "*YOU WON! :trophy:*"
}
]
} ,
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
"text" : ` Congratulations ${ slackUser . display _name _normalized } ! You have defeated ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } in battle! Good job! \n \n \n *Rewards:* \n > 1 Skill Point \n >5 Creation Shards \n > 1 Victory `
} ,
"accessory" : {
"type" : "image" ,
"image_url" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . image ,
"alt_text" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . name
}
}
]
} )
}
2024-06-20 19:49:30 +00:00
2024-06-20 17:31:27 +00:00
app . action ( "continue" , checkButton , async ( ctx ) => {
const user = await initializeUser ( ctx . context . userId ) ;
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
2024-06-20 19:49:30 +00:00
if ( user . playerhealth <= 0 ) {
return playerLoss ( ctx )
}
2024-06-20 17:31:27 +00:00
ctx . respond ( {
replace _original : true ,
text : "" ,
"blocks" : [
{
"type" : "section" ,
"fields" : [
{
"type" : "mrkdwn" ,
2024-06-20 19:49:30 +00:00
"text" : ` ${ slackUser . display _name _normalized } : \n \n *Health:* ${ user . playerhealth } \n *Min Damage:* ${ user . playermin } \n *Max Damage:* ${ user . playermax } `
2024-06-20 17:31:27 +00:00
} ,
{
"type" : "mrkdwn" ,
2024-06-20 21:17:26 +00:00
"text" : ` ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } : \n \n *Health:* ${ user . opponenthealth } \n *Min Damage:* ${ user . opponentmin } \n *Max Damage:* ${ user . opponentmax } `
2024-06-20 17:31:27 +00:00
}
] ,
"accessory" : {
"type" : "image" ,
2024-06-20 21:17:26 +00:00
"image_url" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . image ,
"alt_text" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . name
2024-06-20 17:31:27 +00:00
}
} ,
{
"type" : "context" ,
"elements" : [
{
"type" : "mrkdwn" ,
2024-06-20 21:17:26 +00:00
"text" : ` * ${ slackUser . display _name _normalized } * vs * ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } * | Your Turn `
2024-06-20 17:31:27 +00:00
}
]
} ,
{
"type" : "actions" ,
"elements" : [
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "⚔️ Attack" ,
"emoji" : true
} ,
"value" : ctx . context . userId ,
"action_id" : "attack"
} ,
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "🛡️ Defend" ,
"emoji" : true
} ,
"value" : ctx . context . userId ,
"action_id" : "defend"
} ,
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : " 🎁 Item" ,
"emoji" : true
} ,
"value" : ctx . context . userId ,
"action_id" : "item"
} ,
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "☠️ Forfeit" ,
"emoji" : true
} ,
"style" : "danger" ,
"value" : ctx . context . userId ,
2024-06-20 19:49:30 +00:00
"action_id" : "forfeit"
2024-06-20 17:31:27 +00:00
}
]
2024-06-20 21:17:26 +00:00
}
2024-06-20 17:31:27 +00:00
]
} )
} )
2024-06-20 19:49:30 +00:00
app . action ( 'forfeit' , checkButton , async ( ctx ) => {
ctx . respond ( {
replace _original : false ,
response _type : 'ephemeral' ,
2024-06-21 19:30:56 +00:00
text : 'Not yet...' ,
2024-06-20 19:49:30 +00:00
} )
} )
app . action ( /attack|defend|item/ , checkButton , async ( ctx ) => {
2024-06-20 21:17:26 +00:00
let response = "This error message isn't meant to show up. If it does, contact Haroon." ;
2024-06-20 19:49:30 +00:00
const user = await initializeUser ( ctx . context . userId ) ;
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
switch ( ctx . payload . action _id ) {
case 'attack' :
if ( user . opponentdefense == 'Strong' ) {
2024-06-20 21:17:26 +00:00
response = ` *_ ${ slackUser . display _name _normalized } attacks ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` NO DAMAGE \` \` \` `
2024-06-20 19:49:30 +00:00
} else if ( user . opponentdefense == 'Moderate' ) {
if ( Math . random ( ) < 0.5 ) {
2024-06-20 21:17:26 +00:00
response = ` *_ ${ slackUser . display _name _normalized } attacks ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` NO DAMAGE \` \` \` `
2024-06-20 19:49:30 +00:00
} else {
2024-06-20 21:17:26 +00:00
const damage = Math . floor ( Math . random ( ) * ( user . playermax - user . playermin + 1 ) ) + user . playermin ;
2024-06-20 19:49:30 +00:00
await sql ` UPDATE users SET opponenthealth = ${ user . opponenthealth - damage } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-20 21:17:26 +00:00
response = ` *_ ${ slackUser . display _name _normalized } attacks ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` ${ damage . toLocaleString ( ) } DAMAGE \` \` \` `
2024-06-20 19:49:30 +00:00
}
} else if ( user . opponentdefense == 'Weak' ) {
if ( Math . random ( ) < 0.25 ) {
2024-06-20 21:17:26 +00:00
response = ` *_ ${ slackUser . display _name _normalized } attacks ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` NO DAMAGE \` \` \` `
2024-06-20 19:49:30 +00:00
} else {
2024-06-20 21:17:26 +00:00
const damage = Math . floor ( Math . random ( ) * ( user . playermax - user . playermin + 1 ) ) + user . playermin ;
2024-06-20 19:49:30 +00:00
await sql ` UPDATE users SET opponenthealth = ${ user . opponenthealth - damage } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-20 21:17:26 +00:00
response = ` *_ ${ slackUser . display _name _normalized } attacks ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` ${ damage . toLocaleString ( ) } DAMAGE \` \` \` `
}
} else {
const damage = Math . floor ( Math . random ( ) * ( user . playermax - user . playermin + 1 ) ) + user . playermin ;
await sql ` UPDATE users SET opponenthealth = ${ user . opponenthealth - damage } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_ ${ slackUser . display _name _normalized } attacks ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` ${ damage . toLocaleString ( ) } DAMAGE \` \` \` `
}
break ;
case 'defend' :
if ( user . playerdefendcount < 3 ) {
await sql ` UPDATE users SET playerdefense = 'Strong' WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_A blue forcefield magically appears around ${ slackUser . display _name _normalized } _* \n \n \` \` \` STRONG DEFENCE \` \` \` `
} else {
const type = [ "Strong" , "Moderate" , "Weak" ] [ Math . floor ( Math . random ( ) * 3 ) ] ;
await sql ` UPDATE users SET playerdefense = ${ type } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_A blue forcefield magically appears around ${ slackUser . display _name _normalized } _* \n \n \` \` \` ${ type . toUpperCase ( ) } DEFENCE \` \` \` `
2024-06-20 19:49:30 +00:00
}
2024-06-21 19:30:56 +00:00
await sql ` UPDATE users SET playerdefendcount = ${ user . opponentdefendcount + 1 } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-20 19:49:30 +00:00
break ;
2024-06-20 21:17:26 +00:00
case 'item' :
const increase = Math . floor ( Math . random ( ) * 5 ) + 1 ;
switch ( [ 'health' , 'min' , 'max' , 'nothing' ] [ Math . floor ( Math . random ( ) * 4 ) ] ) {
case 'health' :
await sql ` UPDATE users SET playerhealth = ${ user . playerhealth + increase } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_ ${ slackUser . display _name _normalized } drinks some squash. U N D I L U T E D._* \n \n \` \` \` + ${ increase } HEALTH \` \` \` `
break ;
case 'min' :
if ( ( user . playermin + increase ) < user . playermax ) {
response = ` *_ ${ slackUser . display _name _normalized } touches some grass_* \n \n \` \` \` NOTHING HAPPENED \` \` \` `
break ;
}
await sql ` UPDATE users SET playermin = ${ user . playermin + increase } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_ ${ slackUser . display _name _normalized } drinks some squash. U N D I L U T E D._* \n \n \` \` \` + ${ increase } MIN DAMAGE \` \` \` `
break ;
case 'max' :
await sql ` UPDATE users SET playermax = ${ user . playermax + increase } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_ ${ slackUser . display _name _normalized } drinks some squash. U N D I L U T E D._* \n \n \` \` \` + ${ increase } MAX DAMAGE \` \` \` `
break ;
case 'nothing' :
response = ` *_ ${ slackUser . display _name _normalized } touches some grass_* \n \n \` \` \` NOTHING HAPPENED \` \` \` `
2024-06-21 19:30:56 +00:00
break ;
2024-06-20 21:17:26 +00:00
}
2024-06-20 19:49:30 +00:00
}
2024-06-20 21:17:26 +00:00
await sql ` UPDATE users SET opponentdefense = 'None' WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-20 19:49:30 +00:00
await ctx . respond ( {
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
2024-06-20 21:17:26 +00:00
"text" : response
2024-06-20 19:49:30 +00:00
}
} ,
{
"type" : "actions" ,
"elements" : [
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "Continue" ,
"emoji" : true
} ,
"value" : ctx . context . userId ,
"action_id" : "continue-opponent"
}
]
}
]
2024-06-20 21:17:26 +00:00
} )
2024-06-20 19:49:30 +00:00
} )
2024-06-21 19:30:56 +00:00
app . action ( "continue-opponent" , checkButton , async ( ctx ) => {
const user = await initializeUser ( ctx . context . userId ) ;
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
if ( user . opponenthealth <= 0 ) {
return playerWin ( ctx )
}
ctx . respond ( {
replace _original : true ,
text : "" ,
"blocks" : [
{
"type" : "section" ,
"fields" : [
{
"type" : "mrkdwn" ,
"text" : ` ${ slackUser . display _name _normalized } : \n \n *Health:* ${ user . playerhealth } \n *Min Damage:* ${ user . playermin } \n *Max Damage:* ${ user . playermax } `
} ,
{
"type" : "mrkdwn" ,
"text" : ` ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } : \n \n *Health:* ${ user . opponenthealth } \n *Min Damage:* ${ user . opponentmin } \n *Max Damage:* ${ user . opponentmax } `
}
] ,
"accessory" : {
"type" : "image" ,
"image_url" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . image ,
"alt_text" : AllOpponents . find ( x => x . rawId == user . currentopponent ) . name
}
} ,
{
"type" : "context" ,
"elements" : [
{
"type" : "mrkdwn" ,
"text" : ` * ${ slackUser . display _name _normalized } * vs * ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } * | ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } 's Turn `
}
]
} ,
{
"type" : "actions" ,
"elements" : [
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "Continue" ,
"emoji" : true
} ,
"value" : ctx . context . userId ,
"action_id" : "viewaction-opponent"
}
]
}
]
} )
} )
app . action ( 'viewaction-opponent' , checkButton , async ( ctx ) => {
let response = "This error message isn't meant to show up. If it does, contact Haroon." ;
const user = await initializeUser ( ctx . context . userId ) ;
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
const chances = AllOpponents . find ( x => x . rawId == user . currentopponent ) . chances ;
const action = chooseAction ( chances ) ;
switch ( action ) {
case 'attack' :
if ( user . playerdefense == 'Strong' ) {
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } attacks ${ slackUser . display _name _normalized } _* \n \n \` \` \` NO DAMAGE \` \` \` `
} else if ( user . playerdefense == 'Moderate' ) {
if ( Math . random ( ) < 0.5 ) {
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } attacks ${ slackUser . display _name _normalized } _* \n \n \` \` \` NO DAMAGE \` \` \` `
} else {
const damage = Math . floor ( Math . random ( ) * ( user . opponentmax - user . opponentmin + 1 ) ) + user . opponentmin ;
2024-06-24 19:56:44 +00:00
await sql ` UPDATE users SET playerhealth = ${ user . playerhealth - damage } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-21 19:30:56 +00:00
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } attacks ${ slackUser . display _name _normalized } _* \n \n \` \` \` ${ damage . toLocaleString ( ) } DAMAGE \` \` \` `
}
} else if ( user . playerdefense == 'Weak' ) {
if ( Math . random ( ) < 0.25 ) {
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } attacks ${ lackUser . display _name _normalized } _* \n \n \` \` \` NO DAMAGE \` \` \` `
} else {
2024-06-24 19:56:44 +00:00
const damage = Math . floor ( Math . random ( ) * ( user . opponentmax - user . opponentmin + 1 ) ) + user . opponentmin ;
await sql ` UPDATE users SET playerhealth = ${ user . playerhealth - damage } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-21 19:30:56 +00:00
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } attacks ${ slackUser . display _name _normalized } _* \n \n \` \` \` ${ damage . toLocaleString ( ) } DAMAGE \` \` \` `
}
} else {
2024-06-24 19:56:44 +00:00
const damage = Math . floor ( Math . random ( ) * ( user . opponentmax - user . opponentmin + 1 ) ) + user . opponentmin ;
await sql ` UPDATE users SET playerhealth = ${ user . playerhealth - damage } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-21 19:30:56 +00:00
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } attacks ${ slackUser . display _name _normalized } _* \n \n \` \` \` ${ damage . toLocaleString ( ) } DAMAGE \` \` \` `
}
break ;
case 'defend' :
if ( user . opponentdefendcount < 3 ) {
await sql ` UPDATE users SET opponentdefense = 'Strong' WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_A blue forcefield magically appears around ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` STRONG DEFENCE \` \` \` `
} else {
const type = [ "Strong" , "Moderate" , "Weak" ] [ Math . floor ( Math . random ( ) * 3 ) ] ;
await sql ` UPDATE users SET opponentdefense = ${ type } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_A blue forcefield magically appears around ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } _* \n \n \` \` \` ${ type . toUpperCase ( ) } DEFENCE \` \` \` `
}
await sql ` UPDATE users SET opponentdefendcount = ${ user . opponentdefendcount + 1 } WHERE slack_id = ${ ctx . context . userId } ; `
break ;
case 'item' :
const increase = Math . floor ( Math . random ( ) * 5 ) + 1 ;
2024-06-21 21:19:36 +00:00
switch ( [ 'health' , 'health' , 'min' , 'min' , 'max' , 'nothing' , 'nothing' , 'nothing' ] [ Math . floor ( Math . random ( ) * 8 ) ] ) {
2024-06-21 19:30:56 +00:00
case 'health' :
await sql ` UPDATE users SET opponenthealth = ${ user . opponenthealth + increase } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } drinks some squash. U N D I L U T E D._* \n \n \` \` \` + ${ increase } HEALTH \` \` \` `
break ;
case 'min' :
if ( ( user . opponentmin + increase ) < user . opponentmax ) {
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } touches some grass_* \n \n \` \` \` NOTHING HAPPENED \` \` \` `
break ;
}
await sql ` UPDATE users SET opponentmin = ${ user . opponentmin + increase } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } drinks some squash. U N D I L U T E D._* \n \n \` \` \` + ${ increase } MIN DAMAGE \` \` \` `
break ;
case 'max' :
await sql ` UPDATE users SET opponentmax = ${ user . opponentmax + increase } WHERE slack_id = ${ ctx . context . userId } ; `
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } drinks some squash. U N D I L U T E D._* \n \n \` \` \` + ${ increase } MAX DAMAGE \` \` \` `
break ;
case 'nothing' :
response = ` *_ ${ AllOpponents . find ( x => x . rawId == user . currentopponent ) . name } touches some grass_* \n \n \` \` \` NOTHING HAPPENED \` \` \` `
break ;
}
}
await sql ` UPDATE users SET playerdefense = 'None' WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-20 19:49:30 +00:00
2024-06-21 19:30:56 +00:00
await ctx . respond ( {
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
"text" : response
}
} ,
{
"type" : "actions" ,
"elements" : [
{
"type" : "button" ,
"text" : {
"type" : "plain_text" ,
"text" : "Continue" ,
"emoji" : true
} ,
"value" : ctx . context . userId ,
"action_id" : "continue"
}
]
}
]
} )
} )
2024-06-20 19:49:30 +00:00
2024-06-19 20:49:07 +00:00
app . command ( '/bm-eval' , async ( ctx ) => {
await ctx . ack ( ) ;
2024-06-20 21:17:26 +00:00
if ( ctx . context . userId != 'U06TBP41C3E' ) return ;
2024-06-19 20:49:07 +00:00
const resp = require ( 'util' ) . inspect ( await eval ( ctx . body . text ) , undefined , 1 )
ctx . respond ( {
text : resp ,
response _type : 'ephemeral' ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : "```" + resp + "```"
}
}
]
} )
} )
2024-06-19 19:50:14 +00:00
app . command ( '/viewopponents' , async ( ctx ) => {
await ctx . ack ( ) ;
2024-06-19 22:07:29 +00:00
const args = ctx . body . text . slice ( ) . split ( / +/g ) ;
2024-06-19 19:50:14 +00:00
switch ( args [ 0 ] . toUpperCase ( ) ) {
case "SPECIAL" :
ctx . respond ( {
text : "You're trying to view Special opponents." ,
response _type : 'ephemeral'
} )
break ;
case "BEGINNER" :
const mappedBeginner = BeginnerOpponents . map ( opponent =>
( {
name : opponent . name ,
battlePower :
opponent . stats . health +
opponent . stats . min +
opponent . stats . max
} )
)
ctx . respond ( {
response _type : 'ephemeral' ,
text : ` *Battle Master:* Greetings battler. Here are the avaliable *Beginner* opponents for you to battle. ` ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* Greetings <@ ${ ctx . body . user _id } >. Here are the avaliable *Beginner* opponents for you to battle. `
}
} ,
{
type : 'section' ,
2024-06-21 21:19:36 +00:00
fields : mappedBeginner . map ( opponent => ( {
2024-06-19 19:50:14 +00:00
type : 'mrkdwn' ,
2024-06-21 21:19:36 +00:00
text : ` * ${ opponent . name } * // ${ opponent . battlePower } Battle Power `
} ) )
2024-06-19 19:50:14 +00:00
}
]
} )
break ;
case "CASUAL" :
ctx . say ( "You're trying to view Casual opponents." )
break ;
default :
ctx . say ( "You either wrote nothing or just chose a rank that doesn't exist." )
}
} ) ;
2024-06-22 18:45:37 +00:00
function getTimeDifference ( date1 , date2 ) {
// Ensure both dates are Date objects
const start = new Date ( date1 ) ;
const end = new Date ( date2 ) ;
2024-06-24 19:56:44 +00:00
2024-06-22 18:45:37 +00:00
// Calculate the difference in milliseconds
const diff = Math . abs ( end - start ) ;
2024-06-24 19:56:44 +00:00
2024-06-22 18:45:37 +00:00
// Calculate the difference in weeks, days, hours, minutes, and seconds
const weeks = Math . floor ( diff / ( 1000 * 60 * 60 * 24 * 7 ) ) ;
const days = Math . floor ( diff / ( 1000 * 60 * 60 * 24 ) ) % 7 ;
const hours = Math . floor ( diff / ( 1000 * 60 * 60 ) ) % 24 ;
const minutes = Math . floor ( diff / ( 1000 * 60 ) ) % 60 ;
const seconds = Math . floor ( diff / 1000 ) % 60 ;
2024-06-24 19:56:44 +00:00
2024-06-22 18:45:37 +00:00
// Determine which unit to use for the output
if ( weeks > 0 ) {
return ` ${ weeks } Week ${ weeks > 1 ? 's' : '' } ` ;
} else if ( days > 0 ) {
return ` ${ days } Day ${ days > 1 ? 's' : '' } ` ;
} else if ( hours > 0 ) {
return ` ${ hours } Hour ${ hours > 1 ? 's' : '' } ` ;
} else if ( minutes > 0 ) {
return ` ${ minutes } Minute ${ minutes > 1 ? 's' : '' } ` ;
} else {
return ` ${ seconds } Second ${ seconds > 1 ? 's' : '' } ` ;
}
}
2024-06-23 19:25:19 +00:00
app . command ( '/daily' , async ( ctx ) => {
2024-06-22 18:45:37 +00:00
await ctx . ack ( ) ;
2024-06-24 19:56:44 +00:00
const [ cooldown ] = await sql ` SELECT * FROM cooldowns WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-22 18:45:37 +00:00
const user = await initializeUser ( ctx . context . userId )
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
const now = new Date ( ) ;
if ( ! cooldown . daily || ( cooldown . daily . getTime ( ) <= now . getTime ( ) ) ) {
const cshards = Math . floor ( Math . random ( ) * 10 ) + 1 ;
const spoints = Math . floor ( Math . random ( ) * 5 ) + 1 ;
2024-06-24 19:56:44 +00:00
2024-06-22 18:45:37 +00:00
ctx . respond ( {
response _type : 'ephemeral' ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* Oh ${ slackUser . display _name _normalized } , apologies for the wait. Here is your reward for today. \n \n > ${ cshards } Creation Shards \n > ${ spoints } Skill Points `
}
}
]
2024-06-24 19:56:44 +00:00
} )
2024-06-22 18:45:37 +00:00
await sql ` UPDATE users SET cshards = ${ user . cshards + cshards } , spoints = ${ user . spoints + spoints } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-22 18:51:55 +00:00
await sql ` UPDATE cooldowns SET daily = ${ new Date ( now . getTime ( ) + ( 24 * 60 * 60 * 1000 ) ) } ; `
2024-06-22 18:45:37 +00:00
} else {
ctx . respond ( {
response _type : 'ephemeral' ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* Apologies battler. Unfortunately you must wait * ${ getTimeDifference ( now , cooldown . daily ) } * before you can collect your next daily reward. `
}
}
]
} )
}
} )
2024-06-23 19:25:19 +00:00
app . command ( '/weekly' , async ( ctx ) => {
2024-06-22 18:45:37 +00:00
await ctx . ack ( ) ;
2024-06-24 19:56:44 +00:00
const [ cooldown ] = await sql ` SELECT * FROM cooldowns WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-22 18:45:37 +00:00
const user = await initializeUser ( ctx . context . userId )
2024-06-24 19:56:44 +00:00
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
2024-06-22 18:45:37 +00:00
const now = new Date ( ) ;
if ( ! cooldown . weekly || ( cooldown . weekly . getTime ( ) <= now . getTime ( ) ) ) {
const cshards = Math . floor ( Math . random ( ) * 20 ) + 1 ;
const dshards = Math . floor ( Math . random ( ) * 15 ) + 1 ;
const spoints = Math . floor ( Math . random ( ) * 10 ) + 1 ;
ctx . respond ( {
response _type : 'ephemeral' ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* It's that time again ${ slackUser . display _name _normalized } . Enjoy your weekly reward. \n \n > ${ cshards } Creation Shards \n > ${ dshards } Destruction Shards \n > ${ spoints } Skill Points `
}
}
]
2024-06-24 19:56:44 +00:00
} )
2024-06-22 18:45:37 +00:00
await sql ` UPDATE users SET cshards = ${ user . cshards + cshards } , dshards = ${ user . dshards + dshards } , spoints = ${ user . spoints + spoints } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-24 19:56:44 +00:00
await sql ` UPDATE cooldowns SET weekly = ${ new Date ( now . getTime ( ) + ( 7 * 24 * 60 * 60 * 1000 ) ) } ; `
2024-06-22 18:45:37 +00:00
} else {
ctx . respond ( {
response _type : 'ephemeral' ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* Apologies battler. Unfortunately you must wait * ${ getTimeDifference ( now , cooldown . weekly ) } * before you can collect your next weekly reward. `
}
}
]
} )
}
} )
2024-06-23 19:25:19 +00:00
app . command ( '/monthly' , async ( ctx ) => {
2024-06-22 18:45:37 +00:00
await ctx . ack ( ) ;
2024-06-24 19:56:44 +00:00
const [ cooldown ] = await sql ` SELECT * FROM cooldowns WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-22 18:45:37 +00:00
const user = await initializeUser ( ctx . context . userId )
const slackUser = ( await ctx . client . users . info ( { user : ctx . context . userId } ) ) . user . profile ;
const now = new Date ( ) ;
if ( ! cooldown . monthly || ( cooldown . monthly . getTime ( ) <= now . getTime ( ) ) ) {
const cshards = Math . floor ( Math . random ( ) * 30 ) + 1 ;
const dshards = Math . floor ( Math . random ( ) * 25 ) + 1 ;
const spoints = Math . floor ( Math . random ( ) * 15 ) + 1 ;
ctx . respond ( {
response _type : 'ephemeral' ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* Another month, another reward. You have my appreciation ${ slackUser . display _name _normalized } . \n \n > ${ cshards } Creation Shards \n > ${ dshards } Destruction Shards \n > ${ spoints } Skill Points `
}
}
]
2024-06-24 19:56:44 +00:00
} )
2024-06-22 18:45:37 +00:00
await sql ` UPDATE users SET cshards = ${ user . cshards + cshards } , dshards = ${ user . dshards + dshards } , spoints = ${ user . spoints + spoints } WHERE slack_id = ${ ctx . context . userId } ; `
2024-06-24 19:56:44 +00:00
await sql ` UPDATE cooldowns SET monthly = ${ new Date ( now . getTime ( ) + ( 30 * 24 * 60 * 60 * 1000 ) ) } ; `
2024-06-22 18:45:37 +00:00
} else {
ctx . respond ( {
response _type : 'ephemeral' ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Master:* Apologies battler. Unfortunately you must wait * ${ getTimeDifference ( now , cooldown . monthly ) } * before you can collect your next monthly reward. `
}
}
]
} )
}
} )
2024-06-23 19:25:19 +00:00
app . command ( '/upgrade' , async ( ctx ) => {
await ctx . ack ( ) ;
const user = await initializeUser ( ctx . context . userId ) ;
await ctx . client . views . open ( {
trigger _id : ctx . body . trigger _id ,
view : {
"private_metadata" : ctx . payload . channel _id ,
"type" : "modal" ,
"callback_id" : "upgrade" ,
"title" : {
"type" : "plain_text" ,
"text" : "Upgrade your stats" ,
"emoji" : true
} ,
"submit" : {
"type" : "plain_text" ,
"text" : "Upgrade" ,
"emoji" : true
} ,
"close" : {
"type" : "plain_text" ,
"text" : "Never mind" ,
"emoji" : true
} ,
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
"text" : ` *Battle Builder:* Helloooo <@ ${ ctx . context . userId } >! You're here to upgrade yourself right? No problem! What would you like to... Erm... Upgrade?- `
}
} ,
{
"block_id" : "select" ,
"type" : "input" ,
"element" : {
"type" : "static_select" ,
"placeholder" : {
"type" : "plain_text" ,
"text" : "Choose a statistic..." ,
"emoji" : true
} ,
"options" : [
{
"text" : {
"type" : "plain_text" ,
"text" : "Health // 5 Skill Points" + ( user . spoints < 5 ? " :lock:" : "" ) ,
"emoji" : true
} ,
"value" : "health"
} ,
{
"text" : {
"type" : "plain_text" ,
"text" : "Min Damage // 10 Skill Points" + ( user . spoints < 10 || user . mindmg + 5 == user . maxdmg ? " :lock:" : "" ) ,
"emoji" : true
} ,
"value" : "mindmg"
} ,
{
"text" : {
"type" : "plain_text" ,
"text" : "Max Damage // 15 Skill Points" + ( user . spoints < 15 ? " :lock:" : "" ) ,
"emoji" : true
} ,
"value" : "maxdmg"
}
] ,
"action_id" : "upgrade-modal"
} ,
"label" : {
"type" : "plain_text" ,
"text" : "What would you like to upgrade?" ,
"emoji" : true
}
}
]
}
} )
} ) ;
app . view ( 'upgrade' , async ( ctx ) => {
const user = await initializeUser ( ctx . context . userId ) ;
const { selected _option } = ctx . view . state . values [ 'select' ] [ 'upgrade-modal' ] ;
if ( selected _option . value == "health" && user . spoints < 5 ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You don't have enough skill points to upgrade your health!"
}
} ) ;
} else if ( selected _option . value == "mindmg" && user . spoints < 10 ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You don't have enough skill points to upgrade your minimum damage!"
}
} ) ;
} else if ( selected _option == "mindmg" && user . mindmg + 5 == user . maxdmg ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You need to upgrade your maximum damage first!"
}
2024-06-24 19:56:44 +00:00
} ) ;
2024-06-23 19:25:19 +00:00
} else if ( selected _option . value == "maxdmg" && user . spoints < 15 ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You don't have enough skill points to upgrade your maximum damage!"
}
} ) ;
}
2024-06-24 19:56:44 +00:00
2024-06-23 19:25:19 +00:00
await ctx . ack ( ) ;
if ( selected _option . value == "health" ) {
await sql ` UPDATE users SET spoints = ${ user . spoints - 5 } , health = ${ user . health + 1 } WHERE slack_id = ${ ctx . context . userId } ; `
await ctx . client . chat . postEphemeral ( {
channel : ctx . view . private _metadata ,
user : ctx . context . userId ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Builder:* Yayyy <@ ${ ctx . context . userId } >! Your health has been successfully increased! \n \n \` \` \` HEALTH INCREASED ( ${ user . health } > ${ user . health + 1 } ) \` \` \` `
}
}
]
} )
} else if ( selected _option . value == "mindmg" ) {
await sql ` UPDATE users SET spoints = ${ user . spoints - 10 } , mindmg = ${ user . mindmg + 1 } WHERE slack_id = ${ ctx . context . userId } ; `
await ctx . client . chat . postEphemeral ( {
channel : ctx . view . private _metadata ,
user : ctx . context . userId ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Builder:* Yayyy <@ ${ ctx . context . userId } >! Your minimum damage has been successfully increased! \n \n \` \` \` MIN DAMAGE INCREASED ( ${ user . mindmg } > ${ user . mindmg + 1 } ) \` \` \` `
}
}
]
} )
} else if ( selected _option . value == "maxdmg" ) {
await sql ` UPDATE users SET spoints = ${ user . spoints - 15 } , maxdmg = ${ user . maxdmg + 1 } WHERE slack_id = ${ ctx . context . userId } ; `
await ctx . client . chat . postEphemeral ( {
channel : ctx . view . private _metadata ,
user : ctx . context . userId ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Builder:* Yayyy <@ ${ ctx . context . userId } >! Your maximum damage has been successfully increased! \n \n \` \` \` MAX DAMAGE INCREASED ( ${ user . maxdmg } > ${ user . maxdmg + 1 } ) \` \` \` `
}
}
]
} )
}
} )
2024-06-24 19:56:44 +00:00
app . command ( '/downgrade' , async ( ctx ) => {
await ctx . ack ( ) ;
const user = await initializeUser ( ctx . context . userId ) ;
await ctx . client . views . open ( {
trigger _id : ctx . body . trigger _id ,
view : {
"private_metadata" : ctx . payload . channel _id ,
"type" : "modal" ,
"callback_id" : "downgrade" ,
"title" : {
"type" : "plain_text" ,
"text" : "Downgrade your stats" ,
"emoji" : true
} ,
"submit" : {
"type" : "plain_text" ,
"text" : "Downgrade" ,
"emoji" : true
} ,
"close" : {
"type" : "plain_text" ,
"text" : "Never mind" ,
"emoji" : true
} ,
"blocks" : [
{
"type" : "section" ,
"text" : {
"type" : "mrkdwn" ,
"text" : ` *Battle Builder:* Helloooo <@ ${ ctx . context . userId } >! You're downgrading today huh? No problem! What would you like to... Erm... Downgrade?- `
}
} ,
{
"block_id" : "select" ,
"type" : "input" ,
"element" : {
"type" : "static_select" ,
"placeholder" : {
"type" : "plain_text" ,
"text" : "Choose a statistic..." ,
"emoji" : true
} ,
"options" : [
{
"text" : {
"type" : "plain_text" ,
"text" : "Health // 30 Creation Shards" + ( user . cshards < 30 ? " :lock:" : "" ) ,
"emoji" : true
} ,
"value" : "health"
} ,
{
"text" : {
"type" : "plain_text" ,
"text" : "Min Damage // 40 Creation Shards" + ( user . cshards < 40 ? " :lock:" : "" ) ,
"emoji" : true
} ,
"value" : "mindmg"
} ,
{
"text" : {
"type" : "plain_text" ,
"text" : "Max Damage // 50 Creation Shards" + ( user . cshards < 50 || user . mindmg + 5 == user . maxdmg ? " :lock:" : "" ) ,
"emoji" : true
} ,
"value" : "maxdmg"
}
] ,
"action_id" : "downgrade-modal"
} ,
"label" : {
"type" : "plain_text" ,
"text" : "What would you like to downgrade?" ,
"emoji" : true
}
}
]
}
} )
} ) ;
app . view ( 'downgrade' , async ( ctx ) => {
const user = await initializeUser ( ctx . context . userId ) ;
const { selected _option } = ctx . view . state . values [ 'select' ] [ 'downgrade-modal' ] ;
if ( selected _option . value == "health" && user . cshards < 30 ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You don't have enough creation shards to downgrade your health!"
}
} ) ;
} else if ( selected _option . value == "mindmg" && user . cshards < 40 ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You don't have enough creation shards to downgrade your minimum damage!"
}
} ) ;
} else if ( selected _option == "maxdmg" && user . mindmg + 5 == user . maxdmg ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You need to downgrade your minimum damage first!"
}
} ) ;
} else if ( selected _option . value == "maxdmg" && user . cshards < 50 ) {
return await ctx . ack ( {
response _action : 'errors' ,
errors : {
'select' : "You don't have enough creation shards to downgrade your maximum damage!"
}
} ) ;
}
await ctx . ack ( ) ;
if ( selected _option . value == "health" ) {
await sql ` UPDATE users SET spoints = ${ user . spoints + 5 } , health = ${ user . health - 1 } , cshards = ${ user . cshards - 30 } WHERE slack_id = ${ ctx . context . userId } ; `
await ctx . client . chat . postEphemeral ( {
channel : ctx . view . private _metadata ,
user : ctx . context . userId ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Builder:* Yayyy <@ ${ ctx . context . userId } >! Your health has been successfully decreased! \n \n \` \` \` HEALTH DECREASED ( ${ user . health } > ${ user . health - 1 } ) \` \` \` `
}
}
]
} )
} else if ( selected _option . value == "mindmg" ) {
await sql ` UPDATE users SET spoints = ${ user . spoints + 10 } , mindmg = ${ user . mindmg - 1 } , cshards = ${ user . cshards - 40 } WHERE slack_id = ${ ctx . context . userId } ; `
await ctx . client . chat . postEphemeral ( {
channel : ctx . view . private _metadata ,
user : ctx . context . userId ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Builder:* Yayyy <@ ${ ctx . context . userId } >! Your minimum damage has been successfully decreased! \n \n \` \` \` MIN DAMAGE DECREASED ( ${ user . mindmg } > ${ user . mindmg - 1 } ) \` \` \` `
}
}
]
} )
} else if ( selected _option . value == "maxdmg" ) {
await sql ` UPDATE users SET spoints = ${ user . spoints + 15 } , maxdmg = ${ user . maxdmg - 1 } , cshards = ${ user . cshards - 50 } WHERE slack_id = ${ ctx . context . userId } ; `
await ctx . client . chat . postEphemeral ( {
channel : ctx . view . private _metadata ,
user : ctx . context . userId ,
blocks : [
{
type : 'section' ,
text : {
type : 'mrkdwn' ,
text : ` *Battle Builder:* Yayyy <@ ${ ctx . context . userId } >! Your maximum damage has been successfully decreased! \n \n \` \` \` MAX DAMAGE DECREASED ( ${ user . maxdmg } > ${ user . maxdmg - 1 } ) \` \` \` `
}
}
]
} )
}
} )
2024-06-24 22:09:43 +00:00
; ( async ( ) => {
await app . start ( process . env . PORT ) ;
2024-06-19 19:50:14 +00:00
2024-06-24 22:09:43 +00:00
console . log ( '⚡️ Bolt app is running!' ) ;
} ) ( ) ;