feat: downgrading + special opponents

battler is you x2
This commit is contained in:
DaInfLoop 2024-06-24 20:55:29 +01:00
parent b5cea8ee2e
commit 9a46ab9c85

326
index.js
View file

@ -8,10 +8,12 @@ const sql = postgres({
username: 'haroon'
})
const SpecialOpponents = require('./opponents/special');
const BeginnerOpponents = require('./opponents/beginner');
const AllOpponents = [
...BeginnerOpponents
...(SpecialOpponents.map(x => ({ ...x, rank: 'SPECIAL' }))),
...(BeginnerOpponents.map(x => ({ ...x, rank: 'BEGINNER' }))),
]
const app = new App({
@ -181,7 +183,7 @@ function generateProfile(dbUser, slackUser) {
{
"type": "mrkdwn",
"text": `*Creation Shards:* ${dbUser.cshards}\n*Destruction Shards:* ${dbUser.dshards}\n*Skill Points:* ${dbUser.spoints}`
}
}
]
}
]
@ -309,16 +311,24 @@ app.view("chooseopponent", async (ctx) => {
"type": "input",
"element": {
"type": "static_select",
"options": BeginnerOpponents.map(opponent =>
({
"text": {
"type": "plain_text",
"text": `${opponent.name} // ${opponent.stats.health + opponent.stats.min + opponent.stats.max} Battle Power`,
"emoji": true
},
"value": opponent.rawId
})
),
"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",
"text": `${opponent.name} // ${battlePower} Battle Power`,
"emoji": true
},
"value": opponent.rawId
}
}),
"action_id": "opponents"
},
"label": {
@ -327,7 +337,7 @@ app.view("chooseopponent", async (ctx) => {
"emoji": true
}
},
...( canRankUp ? [
...(canRankUp ? [
{
type: 'divider',
},
@ -417,6 +427,69 @@ app.view("chooseopponent-BEGINNER", async (ctx) => {
await sql`UPDATE users SET battlemessage = ${`https://hackclub.slack.com/archives/${channelId}/p${msg.ts.replace('.', '')}`} WHERE slack_id = ${userId};`
})
app.view("chooseopponent-SPECIAL", async (ctx) => {
await ctx.ack();
const channelId = ctx.view.private_metadata;
const userId = ctx.context.userId;
const slackUser = (await ctx.client.users.info({ user: userId })).user.profile;
const opponent = SpecialOpponents.find(o => o.rawId == Object.values(ctx.payload.state.values)[0].opponents.selected_option.value);
const player = await initializeUser(userId);
await sql`UPDATE users
SET playerhealth = ${player.health},
playermin = ${player.mindmg},
playermax = ${player.maxdmg},
currentOpponent = ${opponent.rawId},
opponenthealth = ${opponent.stats.health(player)},
opponentmin = ${opponent.stats.min(player)},
opponentmax = ${opponent.stats.max(player)}
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};`
})
async function checkButton(ctx) {
await ctx.ack();
@ -486,7 +559,7 @@ async function playerLoss(ctx) {
UPDATE users
SET spoints = ${user.spoints - 1},
cshards = ${user.cshards - 5},
defeats = ${user.defeats + 1}
losses = ${user.losses + 1}
WHERE slack_id = ${ctx.context.userId};
`
@ -832,20 +905,20 @@ app.action('viewaction-opponent', checkButton, async (ctx) => {
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;
await sql`UPDATE users SET opponenthealth = ${user.opponenthealth - damage} WHERE slack_id = ${ctx.context.userId};`
await sql`UPDATE users SET playerhealth = ${user.playerhealth - damage} WHERE slack_id = ${ctx.context.userId};`
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 {
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};`
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};`
response = `*_${AllOpponents.find(x => x.rawId == user.currentopponent).name} attacks ${slackUser.display_name_normalized}_*\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};`
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};`
response = `*_${AllOpponents.find(x => x.rawId == user.currentopponent).name} attacks ${slackUser.display_name_normalized}_*\n\n\`\`\`${damage.toLocaleString()} DAMAGE\`\`\``
}
break;
@ -993,17 +1066,17 @@ function getTimeDifference(date1, date2) {
// Ensure both dates are Date objects
const start = new Date(date1);
const end = new Date(date2);
// Calculate the difference in milliseconds
const diff = Math.abs(end - start);
// 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;
// Determine which unit to use for the output
if (weeks > 0) {
return `${weeks} Week${weeks > 1 ? 's' : ''}`;
@ -1020,7 +1093,7 @@ function getTimeDifference(date1, date2) {
app.command('/daily', async (ctx) => {
await ctx.ack();
const [ cooldown ] = await sql`SELECT * FROM cooldowns WHERE slack_id = ${ctx.context.userId};`
const [cooldown] = await sql`SELECT * FROM cooldowns WHERE slack_id = ${ctx.context.userId};`
const user = await initializeUser(ctx.context.userId)
const slackUser = (await ctx.client.users.info({ user: ctx.context.userId })).user.profile;
@ -1029,7 +1102,7 @@ app.command('/daily', async (ctx) => {
if (!cooldown.daily || (cooldown.daily.getTime() <= now.getTime())) {
const cshards = Math.floor(Math.random() * 10) + 1;
const spoints = Math.floor(Math.random() * 5) + 1;
ctx.respond({
response_type: 'ephemeral',
@ -1042,8 +1115,8 @@ app.command('/daily', async (ctx) => {
}
}
]
})
})
await sql`UPDATE users SET cshards = ${user.cshards + cshards}, spoints = ${user.spoints + spoints} WHERE slack_id = ${ctx.context.userId};`
await sql`UPDATE cooldowns SET daily = ${new Date(now.getTime() + (24 * 60 * 60 * 1000))};`
@ -1065,9 +1138,9 @@ app.command('/daily', async (ctx) => {
app.command('/weekly', async (ctx) => {
await ctx.ack();
const [ cooldown ] = await sql`SELECT * FROM cooldowns WHERE slack_id = ${ctx.context.userId};`
const [cooldown] = await sql`SELECT * FROM cooldowns WHERE slack_id = ${ctx.context.userId};`
const user = await initializeUser(ctx.context.userId)
const slackUser = (await ctx.client.users.info({ user: ctx.context.userId })).user.profile;
const slackUser = (await ctx.client.users.info({ user: ctx.context.userId })).user.profile;
const now = new Date();
@ -1087,11 +1160,11 @@ app.command('/weekly', async (ctx) => {
}
}
]
})
})
await sql`UPDATE users SET cshards = ${user.cshards + cshards}, dshards = ${user.dshards + dshards}, spoints = ${user.spoints + spoints} WHERE slack_id = ${ctx.context.userId};`
await sql`UPDATE cooldowns SET weekly = ${new Date(now.getTime() + (7 * 24 * 60 * 60 * 1000))};`
await sql`UPDATE cooldowns SET weekly = ${new Date(now.getTime() + (7 * 24 * 60 * 60 * 1000))};`
} else {
ctx.respond({
response_type: 'ephemeral',
@ -1110,7 +1183,7 @@ app.command('/weekly', async (ctx) => {
app.command('/monthly', async (ctx) => {
await ctx.ack();
const [ cooldown ] = await sql`SELECT * FROM cooldowns WHERE slack_id = ${ctx.context.userId};`
const [cooldown] = await sql`SELECT * FROM cooldowns WHERE slack_id = ${ctx.context.userId};`
const user = await initializeUser(ctx.context.userId)
const slackUser = (await ctx.client.users.info({ user: ctx.context.userId })).user.profile;
@ -1132,11 +1205,11 @@ app.command('/monthly', async (ctx) => {
}
}
]
})
})
await sql`UPDATE users SET cshards = ${user.cshards + cshards}, dshards = ${user.dshards + dshards}, spoints = ${user.spoints + spoints} WHERE slack_id = ${ctx.context.userId};`
await sql`UPDATE cooldowns SET monthly = ${new Date(now.getTime() + (30 * 24 * 60 * 60 * 1000))};`
await sql`UPDATE cooldowns SET monthly = ${new Date(now.getTime() + (30 * 24 * 60 * 60 * 1000))};`
} else {
ctx.respond({
response_type: 'ephemeral',
@ -1261,7 +1334,7 @@ app.view('upgrade', async (ctx) => {
errors: {
'select': "You need to upgrade your maximum damage first!"
}
});
});
} else if (selected_option.value == "maxdmg" && user.spoints < 15) {
return await ctx.ack({
response_action: 'errors',
@ -1270,7 +1343,7 @@ app.view('upgrade', async (ctx) => {
}
});
}
await ctx.ack();
if (selected_option.value == "health") {
@ -1324,8 +1397,179 @@ app.view('upgrade', async (ctx) => {
}
})
; (async () => {
await app.start(process.env.PORT);
app.command('/downgrade', async (ctx) => {
await ctx.ack();
console.log('⚡️ Bolt app is running!');
})();
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})\`\`\``
}
}
]
})
}
})
; (async () => {
await app.start(process.env.PORT);
console.log('⚡️ Bolt app is running!');
})();