feat: add more special opponents + introduce secret opponents

This commit is contained in:
DaInfLoop 2024-06-24 23:09:43 +01:00
parent d2dbb53d69
commit 3c77e88a4d
2 changed files with 172 additions and 74 deletions

111
index.js
View file

@ -280,7 +280,7 @@ app.view("chooseopponent", async (ctx) => {
view: {
"private_metadata": ctx.payload.private_metadata,
"type": "modal",
"callback_id": "chooseopponent-" + rank,
"callback_id": "chooseopponent1",
"title": {
"type": "plain_text",
"text": "Choose an opponent",
@ -323,7 +323,7 @@ app.view("chooseopponent", async (ctx) => {
return {
"text": {
"type": "plain_text",
"text": `${opponent.name} // ${battlePower} Battle Power`,
"text": `${opponent.name} // ${battlePower} Battle Power` + (opponent.secretCondition && !opponent.secretCondition(user) ? " :lock:" : ""),
"emoji": true
},
"value": opponent.rawId
@ -364,7 +364,7 @@ app.view("chooseopponent", async (ctx) => {
})
})
app.view("chooseopponent-BEGINNER", async (ctx) => {
app.view("chooseopponent1", async (ctx) => {
await ctx.ack();
const channelId = ctx.view.private_metadata;
@ -372,72 +372,39 @@ app.view("chooseopponent-BEGINNER", async (ctx) => {
const slackUser = (await ctx.client.users.info({ user: userId })).user.profile;
const opponent = BeginnerOpponents.find(o => o.rawId == Object.values(ctx.payload.state.values)[0].opponents.selected_option.value);
const opponent = AllOpponents.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},
opponentmin = ${opponent.stats.min},
opponentmax = ${opponent.stats.max}
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"
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
}
]
}
]
});
}
]
})
}
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);
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);
await sql`UPDATE users
SET playerhealth = ${player.health},
@ -446,9 +413,9 @@ app.view("chooseopponent-SPECIAL", async (ctx) => {
currentOpponent = ${opponent.rawId},
opponenthealth = ${opponent.stats.health(player)},
opponentmin = ${opponent.stats.min(player)},
opponentmax = ${opponent.stats.max(player)}
opponenthealth = ${opponentStats[0]},
opponentmin = ${opponentStats[1]},
opponentmax = ${opponentStats[2]}
WHERE slack_id = ${userId};`
@ -580,7 +547,7 @@ async function playerLoss(ctx) {
"type": "section",
"text": {
"type": "mrkdwn",
"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\nLosses:*\n> -1 Skill Point\n>-5 Creation Shards\n> 1 Defeat`
"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`
},
"accessory": {
"type": "image",
@ -1568,8 +1535,8 @@ app.view('downgrade', async (ctx) => {
}
})
; (async () => {
await app.start(process.env.PORT);
; (async () => {
await app.start(process.env.PORT);
console.log('⚡️ Bolt app is running!');
})();
console.log('⚡️ Bolt app is running!');
})();

View file

@ -21,9 +21,140 @@ module.exports = [
*Battler*: Good luck {player}. However, don't feel bad if you are defeated. After all, I am you... X2.
*{player}*: ...`,
"chances": {
"attack": 0.65,
"attack": 0.75,
"defend": 0.175,
"item": 0.175
"item": 0.075
}
},
{
"rawId": "elliton",
"name": "Battler Elite",
"stats": {
health: (user) => user.health * 3,
min: (user) => user.mindmg * 3,
max: (user) => user.maxdmg * 3
},
"image": "https://cdn.discordapp.com/attachments/1108683335347212389/1125324871757463592/Battler_Elite_Closeup.png?ex=667b1834&is=6679c6b4&hm=206d206c2b26af12b381055b07988e1e0fe53b777ed73d5246dd4e4c9a7d5c1a&",
"intro": `*_A glowing red portal appears as Battler Elite dramatically floats out. He is heading directly for {player}_*
*Battler Elite*: Greetings {player}. You called?
*{player}*: How did you know I wanted to-
*Battler Elite*: Details do not matter. You wish to battle correct? Why don't we proceed
*{player}*: Let's go then!
*Battler Elite*: Do not be disheartened if you are defeated. After all, I am you... X3
*{player}*: WHAT!?`,
"chances": {
"attack": 0.75,
"defend": 0.175,
"item": 0.075
},
secretCondition() { return false },
deniedIntro: `Battler Elite is a Battle Master Elite opponent. As well as this, he is due to recieve some changes, so for the time being I have locked him from being battled. If you wish to fight him, please ping me (Haroon) in <#C078SS377PE|battle-master>.`
},
{
rawId: "sleepParalysisDemon",
name: "DEMUL",
stats: {
health: (user) => user.maxdmg * 10,
min: (user) => user.mindmg,
max: (user) => user.maxdmg * 2
},
image: "https://cdn.discordapp.com/attachments/1108683335347212389/1178655141029757028/BM_-_Demul_1.png?ex=667aa6a3&is=66795523&hm=e7100e74c5ec317ed70a6637752c0e06ec40013f42541ef0875f6193a02451ce&",
intro: `*_{player} is fast asleep. They are dreaming. Running through a forest at dramatic speed. It's midnight. Dark. Foggy. Eerie... Suddenly, they notice an ominous figure in the distance. Great, this is clearly a nightmare. Instead of waking themselves up from this nightmare like they usually do, {player} summons a large scythe and charges at the dark figure. What is there to be afraid of!? It's a dream after al-_*
*DEMUL*: GPPMJTI IVNBOPJE.
*_{player} is suddenly frozen and teleported back into their bedroom. What happened to the figure? Where was it? Why is {player} shaking... Oh goodness. {player} is experiencing sleep paralysis for the first time. They cannot move. {player} is facing the wall yet they can somehow see the corner of their bedroom. The ominous figure suddenly appears. Watching. Waiting. With that creepy smile... Luckily for {player}, they are currently in the Battle Master Universe. The only way for them to escape this nightmare is to battle. Fortunate as it is, they will most likely never forget this encounter._*
*{player}*: Let's. Just. Go.`,
chances: {
attack: 0.2,
defend: 0.5,
item: 0.3
}
},
{
rawId: "TheFirewall",
name: "The Firewall",
stats: {
health: (user) => user.maxdmg * 20,
min: () => 1,
max: (user) => user.health
},
image: "https://cdn.discordapp.com/attachments/1108683335347212389/1225066244315807764/BM_-_The_Firewall.png?ex=667abe59&is=66796cd9&hm=a8e71bddc847a267e612377a58e5ed7e2cc8eb4b22ce6638734aade0ddbc5d93&",
intro: `*_After escaping the Void, {player} is sprinting through the Grand Forest. To be honest, going through a portal into the future was probably a horrible idea... Anyways, shortly after dodging and swerving some trees, they suddenly head a faint voice coming towards them..._*
*Forest Ranger*: Hey... HEYYY!!! HEEEEYYYYYY!
*_{player} and Forest Ranger collide with each other and roll in opposite directions_*
*{player}*: AH! Where did you come from!?
*Forest Ranger*: Bold of you to be talking to me like that! Who even are you, and why are you running TOWARDS the fire!? You need to get outta here ASAP!
*{player}*: Fire!? What fir-
*_A dramatic foghorn plays as the Firewall can be seen in the far distance. A mere orange glow for now, however, it is travelling at a dangerously high speed..._*
*{player}*: Oh perfect! A worthy opponent!
*Forest Ranger*: Excuse me, did you just say opponent? As in, you are going to FIGHT that fire!?
*{player}*: Of course! I can handle it!
*_Forest Ranger is extremely reluctant at this point in time. He doesn't know who {player} thinks they are, but he isn't going to stick around and find out..._*
*Forest Ranger*: Yeahhhh buddy, you do you alright? Once you're done realising your mistake just make sure to follow me. I know this forest like the back of my hand after all...
*{player}*: Hm, no problem. Let's go!`,
chances: {
attack: 0.07,
defend: 0.465,
item: 0.465
}
},
{
rawId: "cakeDay",
name: "Cake Day",
stats: {
health: (user) => user.maxdmg * 8,
min: () => 10,
max: (user) => user.health
},
image: "https://cdn.discordapp.com/attachments/1108683335347212389/1248635057585918072/BM_-_Cake_Day_20240607144930.png?ex=667acb04&is=66797984&hm=79c7a61603c13de4930216ef33bd9bb83e1900da13daed7b48372d22cc8ed1a1&",
intro: `*_The entire Battle Squad and {player} are celebrating Battle Master's birthday at Moonbase HQ. As usual on the Battle Moon, its quite lively when the whole squad is present... Anyways, Battle Support walks into the dining room with a large cake_*
*Everyone*: Happy birthday Battle Master!
*Battle Master*: You all have my gratitude.
*Battle Beginner*: No need to thank us! It's the least we could do for someone as important as yourself!
*Battle Casual*: Wow, that's a big cake Support!
*Battle Special*: Well said... Welp, luckily there's 8 of us here am I right?
*Battle Master*: I wouldn't be so certain about that.
*_Suddenly, a large pink beam can be heard in the direction of The Gate as it shoots violently into the space above. Usually, an energy force that dangerous coming from The Gate means that someone has travelled between universes... Hmm... No battler could make such a dramatic entrance so who-_*
*Cake Day*: HEY! WHAT DO YOU THINK YOU GUYS ARE DOING!?
*Battle Support*: Ermmm... And who might you two be?
*Velvet Night*: That's nunya bizznizz. All you gotta know is that the cake you're holding right there is SACRED.
*Battle Builder*: HEH!? Wait... What does sacred mean again-
*Battle Pro*: Oh please don't make me laugh. You are claiming that this food item that Battle Support created is a holy and important object to you?
*Battle Support*: Haha... Soooooo funny story guys... I didn't actually... Make the cake...
*_Everyone turns towards Battle Support in shock_*
*Battle Special*: I would be surprised but to be perfectly honest with ya, we don't even have mouths... Or need to eat... At all...
*Cake Day*: Perfect! Now please hand over the cake! It is an important part of the Strawberry Kingdom and it must be returned to-
*{player}*: Well if you want my cake slice then you're going to have to fight me for it!
*Velvet Night*: URGH. So you wanna be difficult huh? Fine then. Day. Do ya thing...
*Cake Day*: Alright then buddy. Let's do this...
*Battle Special*: Welp, guess I gotta ref this battle now huh...
*{player}*: Alright then, let's go!`,
deniedIntro: `You should not be able to see this. If you do, ping Haroon.`,
secretCondition() {
const now = new Date();
return [5, 6].includes(now.getUTCMonth())
},
chances: {
attack: 0.25,
defend: 0.375,
item: 0.375
}
}
]