Compare commits
2 Commits
b9a887259a
...
0407f4d7f1
| Author | SHA1 | Date | |
|---|---|---|---|
| 0407f4d7f1 | |||
| 0f48f09bd9 |
@@ -1,18 +0,0 @@
|
|||||||
const {
|
|
||||||
performBossAction
|
|
||||||
} = require(
|
|
||||||
"../../utils/cookieBoss"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name:
|
|
||||||
"cookieBossBurst",
|
|
||||||
|
|
||||||
async execute(interaction) {
|
|
||||||
return performBossAction(
|
|
||||||
interaction,
|
|
||||||
"Burst"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const {
|
|
||||||
joinBoss
|
|
||||||
} = require(
|
|
||||||
"../../utils/cookieBoss"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name:
|
|
||||||
"cookieBossJoinChampion",
|
|
||||||
|
|
||||||
async execute(interaction) {
|
|
||||||
return joinBoss(
|
|
||||||
interaction,
|
|
||||||
"Champion"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const {
|
|
||||||
joinBoss
|
|
||||||
} = require(
|
|
||||||
"../../utils/cookieBoss"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name:
|
|
||||||
"cookieBossJoinFighter",
|
|
||||||
|
|
||||||
async execute(interaction) {
|
|
||||||
return joinBoss(
|
|
||||||
interaction,
|
|
||||||
"Fighter"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const {
|
|
||||||
joinBoss
|
|
||||||
} = require(
|
|
||||||
"../../utils/cookieBoss"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name:
|
|
||||||
"cookieBossJoinScout",
|
|
||||||
|
|
||||||
async execute(interaction) {
|
|
||||||
return joinBoss(
|
|
||||||
interaction,
|
|
||||||
"Scout"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const {
|
|
||||||
performBossAction
|
|
||||||
} = require(
|
|
||||||
"../../utils/cookieBoss"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name:
|
|
||||||
"cookieBossLimit",
|
|
||||||
|
|
||||||
async execute(interaction) {
|
|
||||||
return performBossAction(
|
|
||||||
interaction,
|
|
||||||
"Limit"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
const {
|
|
||||||
startBossBattle
|
|
||||||
} = require(
|
|
||||||
"../../utils/cookieBoss"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name:
|
|
||||||
"cookieBossStart",
|
|
||||||
|
|
||||||
async execute(interaction) {
|
|
||||||
return startBossBattle(
|
|
||||||
interaction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -7,11 +7,19 @@ const {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
getCookieBalance,
|
getCookieBalance,
|
||||||
|
getCooldown,
|
||||||
|
getUnixTime,
|
||||||
temporaryEphemeralReply
|
temporaryEphemeralReply
|
||||||
} = require(
|
} = require(
|
||||||
"../../utils/cookieEconomy"
|
"../../utils/cookieEconomy"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
HEIST_COOLDOWN
|
||||||
|
} = require(
|
||||||
|
"../../utils/cookieHeist"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name:
|
name:
|
||||||
@@ -19,6 +27,10 @@ module.exports = {
|
|||||||
|
|
||||||
|
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
|
/*
|
||||||
|
* Verify ownership of the Crumb Saucer menu.
|
||||||
|
*/
|
||||||
|
|
||||||
const footer =
|
const footer =
|
||||||
interaction.message
|
interaction.message
|
||||||
.embeds[0]
|
.embeds[0]
|
||||||
@@ -30,17 +42,13 @@ module.exports = {
|
|||||||
type,
|
type,
|
||||||
ownerId
|
ownerId
|
||||||
] =
|
] =
|
||||||
footer
|
footer?.split(":")
|
||||||
?.split(":")
|
?? [];
|
||||||
??
|
|
||||||
[];
|
|
||||||
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
type !==
|
type !== "crumbSaucer" ||
|
||||||
"crumbSaucer" ||
|
ownerId !== interaction.user.id
|
||||||
ownerId !==
|
|
||||||
interaction.user.id
|
|
||||||
) {
|
) {
|
||||||
return temporaryEphemeralReply(
|
return temporaryEphemeralReply(
|
||||||
interaction,
|
interaction,
|
||||||
@@ -52,6 +60,43 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
* SHARED HEIST COOLDOWN PRE-CHECK
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
const now =
|
||||||
|
getUnixTime();
|
||||||
|
|
||||||
|
|
||||||
|
const cooldown =
|
||||||
|
await getCooldown(
|
||||||
|
interaction.user.id,
|
||||||
|
interaction.guildId,
|
||||||
|
"heist"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
cooldown >
|
||||||
|
now
|
||||||
|
) {
|
||||||
|
return temporaryEphemeralReply(
|
||||||
|
interaction,
|
||||||
|
{
|
||||||
|
content:
|
||||||
|
`🏦 The ShaiBot Vault is still on alert.\nYou can attempt another heist <t:${cooldown}:R>.`
|
||||||
|
},
|
||||||
|
6000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Balances
|
||||||
|
*/
|
||||||
|
|
||||||
const vaultId =
|
const vaultId =
|
||||||
interaction.client.user.id;
|
interaction.client.user.id;
|
||||||
|
|
||||||
@@ -72,7 +117,8 @@ module.exports = {
|
|||||||
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
player < 1
|
player <
|
||||||
|
1
|
||||||
) {
|
) {
|
||||||
return temporaryEphemeralReply(
|
return temporaryEphemeralReply(
|
||||||
interaction,
|
interaction,
|
||||||
@@ -85,7 +131,8 @@ module.exports = {
|
|||||||
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
vault < 1
|
vault <
|
||||||
|
1
|
||||||
) {
|
) {
|
||||||
return temporaryEphemeralReply(
|
return temporaryEphemeralReply(
|
||||||
interaction,
|
interaction,
|
||||||
@@ -97,11 +144,16 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Heist menu
|
||||||
|
*/
|
||||||
|
|
||||||
const embed =
|
const embed =
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.setTitle(
|
.setTitle(
|
||||||
"🏦 ShaiBot Cookie Vault"
|
"🏦 ShaiBot Cookie Vault"
|
||||||
)
|
)
|
||||||
|
|
||||||
.setDescription(
|
.setDescription(
|
||||||
[
|
[
|
||||||
`**Vault Balance:** ${vault.toLocaleString()} 🍪`,
|
`**Vault Balance:** ${vault.toLocaleString()} 🍪`,
|
||||||
@@ -119,6 +171,7 @@ module.exports = {
|
|||||||
"Low chance • Large haul • Large fine"
|
"Low chance • Large haul • Large fine"
|
||||||
].join("\n")
|
].join("\n")
|
||||||
)
|
)
|
||||||
|
|
||||||
.setFooter({
|
.setFooter({
|
||||||
text:
|
text:
|
||||||
`cookieHeist:${interaction.user.id}`
|
`cookieHeist:${interaction.user.id}`
|
||||||
@@ -172,19 +225,43 @@ module.exports = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const backButton =
|
||||||
|
new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(
|
||||||
|
"crumbSaucerBack"
|
||||||
|
)
|
||||||
|
.setLabel(
|
||||||
|
"Back to Crumb Saucer"
|
||||||
|
)
|
||||||
|
.setEmoji(
|
||||||
|
"◀️"
|
||||||
|
)
|
||||||
|
.setStyle(
|
||||||
|
ButtonStyle.Secondary
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
return interaction.update({
|
return interaction.update({
|
||||||
embeds: [
|
embeds: [
|
||||||
embed
|
embed
|
||||||
],
|
],
|
||||||
|
|
||||||
components: [
|
components: [
|
||||||
heistButtons
|
heistButtons,
|
||||||
|
backButton
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SECURITY LABEL
|
||||||
|
*/
|
||||||
|
|
||||||
function getSecurityLabel(
|
function getSecurityLabel(
|
||||||
vault
|
vault
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
performCrumbleStrikeAction
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeDefend",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return performCrumbleStrikeAction(
|
||||||
|
interaction,
|
||||||
|
"Defend"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
performCrumbleStrikeAction
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeHeal",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return performCrumbleStrikeAction(
|
||||||
|
interaction,
|
||||||
|
"Heal"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobAstrologian",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"Healer",
|
||||||
|
"Astrologian"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobBard",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"DPS",
|
||||||
|
"Bard"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobBlackMage",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"DPS",
|
||||||
|
"BlackMage"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobDarkKnight",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"Tank",
|
||||||
|
"DarkKnight"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobDragoon",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"DPS",
|
||||||
|
"Dragoon"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobPaladin",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"Tank",
|
||||||
|
"Paladin"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobScholar",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"Healer",
|
||||||
|
"Scholar"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobWarrior",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"Tank",
|
||||||
|
"Warrior"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeJob
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeJobWhiteMage",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeJob(
|
||||||
|
interaction,
|
||||||
|
"Healer",
|
||||||
|
"WhiteMage"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
performCrumbleStrikeAction
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeLimitBreak",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return performCrumbleStrikeAction(
|
||||||
|
interaction,
|
||||||
|
"LimitBreak"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
performCrumbleStrikeAction
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeRevive",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return performCrumbleStrikeAction(
|
||||||
|
interaction,
|
||||||
|
"Revive"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeRole
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeRoleDPS",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeRole(
|
||||||
|
interaction,
|
||||||
|
"DPS"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeRole
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeRoleHealer",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeRole(
|
||||||
|
interaction,
|
||||||
|
"Healer"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
chooseCrumbleStrikeRole
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeRoleTank",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return chooseCrumbleStrikeRole(
|
||||||
|
interaction,
|
||||||
|
"Tank"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
const {
|
||||||
|
startCrumbleStrikeBattle
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeStart",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return startCrumbleStrikeBattle(
|
||||||
|
interaction
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
const {
|
const {
|
||||||
performBossAction
|
performCrumbleStrikeAction
|
||||||
} = require(
|
} = require(
|
||||||
"../../utils/cookieBoss"
|
"../../utils/crumbleStrike"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name:
|
name:
|
||||||
"cookieBossStrike",
|
"crumbleStrikeStrike",
|
||||||
|
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
return performBossAction(
|
return performCrumbleStrikeAction(
|
||||||
interaction,
|
interaction,
|
||||||
"Strike"
|
"Strike"
|
||||||
);
|
);
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
confirmCrumbleStrikeJoin
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeTierAdventurer",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return confirmCrumbleStrikeJoin(
|
||||||
|
interaction,
|
||||||
|
"Adventurer"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
confirmCrumbleStrikeJoin
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeTierSprout",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return confirmCrumbleStrikeJoin(
|
||||||
|
interaction,
|
||||||
|
"Sprout"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const {
|
||||||
|
confirmCrumbleStrikeJoin
|
||||||
|
} = require(
|
||||||
|
"../../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name:
|
||||||
|
"crumbleStrikeTierWarriorOfLight",
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
return confirmCrumbleStrikeJoin(
|
||||||
|
interaction,
|
||||||
|
"WarriorOfLight"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,230 +0,0 @@
|
|||||||
const {
|
|
||||||
getCollections,
|
|
||||||
getUnixTime
|
|
||||||
} = require("../utils/cookieEconomy");
|
|
||||||
|
|
||||||
const {
|
|
||||||
activateBoss,
|
|
||||||
failBoss,
|
|
||||||
cancelBossAndRefund
|
|
||||||
} = require("../utils/cookieBoss");
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* How often we check persistent boss timers.
|
|
||||||
*
|
|
||||||
* Discord timestamps handle the visible countdown,
|
|
||||||
* so checking once per minute is plenty.
|
|
||||||
*/
|
|
||||||
const CHECK_INTERVAL = 60 * 1000;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Your index.js automatically loads every file
|
|
||||||
* inside /handlers and passes the Discord client:
|
|
||||||
*
|
|
||||||
* require(`./handlers/${handler}`)(client)
|
|
||||||
*/
|
|
||||||
module.exports = (client) => {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Run shortly after startup.
|
|
||||||
*
|
|
||||||
* This catches boss events whose timers expired
|
|
||||||
* while ShaiBot was offline/restarting.
|
|
||||||
*/
|
|
||||||
setTimeout(() => {
|
|
||||||
processBossEvents(client);
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Persistent boss event watcher.
|
|
||||||
*/
|
|
||||||
setInterval(() => {
|
|
||||||
processBossEvents(client);
|
|
||||||
}, CHECK_INTERVAL);
|
|
||||||
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
"[CookieBoss] Boss event watcher initialized"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check all currently pending Cookie Boss events.
|
|
||||||
*/
|
|
||||||
async function processBossEvents(client) {
|
|
||||||
try {
|
|
||||||
const {
|
|
||||||
db
|
|
||||||
} = getCollections();
|
|
||||||
|
|
||||||
|
|
||||||
const events =
|
|
||||||
db.collection(
|
|
||||||
"items_events"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
const now =
|
|
||||||
getUnixTime();
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ==========================================
|
|
||||||
* JOINING PHASE
|
|
||||||
* ==========================================
|
|
||||||
*
|
|
||||||
* Recruitment lasts for 30 minutes.
|
|
||||||
*
|
|
||||||
* If 5+ players joined:
|
|
||||||
* start the battle automatically.
|
|
||||||
*
|
|
||||||
* If fewer than 5 joined:
|
|
||||||
* cancel the boss and refund everyone.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const joiningEvents =
|
|
||||||
await events
|
|
||||||
.find({
|
|
||||||
eventType:
|
|
||||||
"CookieBoss",
|
|
||||||
|
|
||||||
state:
|
|
||||||
"Joining",
|
|
||||||
|
|
||||||
joinUntil: {
|
|
||||||
$lte: now
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.toArray();
|
|
||||||
|
|
||||||
|
|
||||||
for (
|
|
||||||
const event
|
|
||||||
of joiningEvents
|
|
||||||
) {
|
|
||||||
const participantCount =
|
|
||||||
Object.keys(
|
|
||||||
event.participants ?? {}
|
|
||||||
).length;
|
|
||||||
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`[CookieBoss] Recruitment expired for ${event.eventId} ` +
|
|
||||||
`(${participantCount}/${event.minimumParticipants} players)`
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enough players joined.
|
|
||||||
*
|
|
||||||
* Start the fight automatically.
|
|
||||||
*/
|
|
||||||
if (
|
|
||||||
participantCount >=
|
|
||||||
event.minimumParticipants
|
|
||||||
) {
|
|
||||||
const started =
|
|
||||||
await activateBoss(
|
|
||||||
client,
|
|
||||||
event.eventId
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
if (started) {
|
|
||||||
console.log(
|
|
||||||
`[CookieBoss] Battle ${event.eventId} started automatically`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Not enough players.
|
|
||||||
*
|
|
||||||
* Nobody actually entered combat,
|
|
||||||
* so refund all committed Cookies.
|
|
||||||
*/
|
|
||||||
await cancelBossAndRefund(
|
|
||||||
client,
|
|
||||||
event.eventId
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`[CookieBoss] Battle ${event.eventId} cancelled and refunded`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ==========================================
|
|
||||||
* ACTIVE BATTLES
|
|
||||||
* ==========================================
|
|
||||||
*
|
|
||||||
* If the battle timer expires while the
|
|
||||||
* boss still has HP remaining, the raid fails.
|
|
||||||
*
|
|
||||||
* All Cookies held in the encounter escrow
|
|
||||||
* are transferred to the ShaiBot vault.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const activeEvents =
|
|
||||||
await events
|
|
||||||
.find({
|
|
||||||
eventType:
|
|
||||||
"CookieBoss",
|
|
||||||
|
|
||||||
state:
|
|
||||||
"Active",
|
|
||||||
|
|
||||||
battleEndsAt: {
|
|
||||||
$lte: now
|
|
||||||
},
|
|
||||||
|
|
||||||
"boss.health": {
|
|
||||||
$gt: 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.toArray();
|
|
||||||
|
|
||||||
|
|
||||||
for (
|
|
||||||
const event
|
|
||||||
of activeEvents
|
|
||||||
) {
|
|
||||||
console.log(
|
|
||||||
`[CookieBoss] Battle ${event.eventId} expired ` +
|
|
||||||
`with ${event.boss.health}/${event.boss.maxHealth} HP remaining`
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
await failBoss(
|
|
||||||
client,
|
|
||||||
event.eventId
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`[CookieBoss] Battle ${event.eventId} failed`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
/*
|
|
||||||
* Never let an exception kill the interval.
|
|
||||||
*
|
|
||||||
* The next watcher tick will simply try again.
|
|
||||||
*/
|
|
||||||
console.error(
|
|
||||||
"[CookieBoss] Boss watcher error:",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
const {
|
||||||
|
getCollections,
|
||||||
|
getUnixTime
|
||||||
|
} = require(
|
||||||
|
"../utils/cookieEconomy"
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
activateCrumbleStrike,
|
||||||
|
failCrumbleStrike,
|
||||||
|
cancelCrumbleStrikeAndRefund
|
||||||
|
} = require(
|
||||||
|
"../utils/crumbleStrike"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const CHECK_INTERVAL =
|
||||||
|
60 * 1000;
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = client => {
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
processCrumbleStrikeEvents(
|
||||||
|
client
|
||||||
|
);
|
||||||
|
},
|
||||||
|
5000
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
setInterval(
|
||||||
|
() => {
|
||||||
|
processCrumbleStrikeEvents(
|
||||||
|
client
|
||||||
|
);
|
||||||
|
},
|
||||||
|
CHECK_INTERVAL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"[CrumbleStrike] Event watcher initialized"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
async function processCrumbleStrikeEvents(
|
||||||
|
client
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
db
|
||||||
|
} =
|
||||||
|
getCollections();
|
||||||
|
|
||||||
|
|
||||||
|
const events =
|
||||||
|
db.collection(
|
||||||
|
"items_events"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const now =
|
||||||
|
getUnixTime();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recruitment expired.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const joiningEvents =
|
||||||
|
await events
|
||||||
|
.find({
|
||||||
|
eventType:
|
||||||
|
"CrumbleStrike",
|
||||||
|
|
||||||
|
state:
|
||||||
|
"Joining",
|
||||||
|
|
||||||
|
joinUntil: {
|
||||||
|
$lte:
|
||||||
|
now
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toArray();
|
||||||
|
|
||||||
|
|
||||||
|
for (
|
||||||
|
const event
|
||||||
|
of joiningEvents
|
||||||
|
) {
|
||||||
|
const participantCount =
|
||||||
|
Object.keys(
|
||||||
|
event.participants ??
|
||||||
|
{}
|
||||||
|
).length;
|
||||||
|
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[CrumbleStrike] Recruitment expired for ${event.eventId} ` +
|
||||||
|
`(${participantCount}/${event.minimumParticipants})`
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
participantCount >=
|
||||||
|
event.minimumParticipants
|
||||||
|
) {
|
||||||
|
const started =
|
||||||
|
await activateCrumbleStrike(
|
||||||
|
client,
|
||||||
|
event.eventId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (started) {
|
||||||
|
console.log(
|
||||||
|
`[CrumbleStrike] ${event.eventId} started automatically`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const cancelled =
|
||||||
|
await cancelCrumbleStrikeAndRefund(
|
||||||
|
client,
|
||||||
|
event.eventId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (cancelled) {
|
||||||
|
console.log(
|
||||||
|
`[CrumbleStrike] ${event.eventId} cancelled and refunded`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Battle expired.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const activeEvents =
|
||||||
|
await events
|
||||||
|
.find({
|
||||||
|
eventType:
|
||||||
|
"CrumbleStrike",
|
||||||
|
|
||||||
|
state:
|
||||||
|
"Active",
|
||||||
|
|
||||||
|
battleEndsAt: {
|
||||||
|
$lte:
|
||||||
|
now
|
||||||
|
},
|
||||||
|
|
||||||
|
"boss.health": {
|
||||||
|
$gt:
|
||||||
|
0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toArray();
|
||||||
|
|
||||||
|
|
||||||
|
for (
|
||||||
|
const event
|
||||||
|
of activeEvents
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
`[CrumbleStrike] ${event.eventId} expired with ` +
|
||||||
|
`${event.boss.health}/${event.boss.maxHealth} HP remaining`
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const failed =
|
||||||
|
await failCrumbleStrike(
|
||||||
|
client,
|
||||||
|
event.eventId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
console.log(
|
||||||
|
`[CrumbleStrike] ${event.eventId} failed`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"[CrumbleStrike] Watcher error:",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
-1693
File diff suppressed because it is too large
Load Diff
+967
-181
File diff suppressed because it is too large
Load Diff
+267
-192
@@ -1,5 +1,8 @@
|
|||||||
const {
|
const {
|
||||||
EmbedBuilder
|
EmbedBuilder,
|
||||||
|
ActionRowBuilder,
|
||||||
|
ButtonBuilder,
|
||||||
|
ButtonStyle
|
||||||
} = require("discord.js");
|
} = require("discord.js");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -23,86 +26,47 @@ const HEIST_COOLDOWN =
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each approach has a different risk/reward profile.
|
* All three approaches use the SAME cooldown:
|
||||||
*
|
*
|
||||||
* Sneak:
|
* cooldowns_cookies.heist
|
||||||
* High success chance
|
|
||||||
* Small reward
|
|
||||||
* Small failure penalty
|
|
||||||
*
|
*
|
||||||
* Hack:
|
* Sneak does NOT have its own cooldown.
|
||||||
* Medium success chance
|
* Hack does NOT have its own cooldown.
|
||||||
* Medium reward
|
* Smash does NOT have its own cooldown.
|
||||||
* Medium failure penalty
|
|
||||||
*
|
|
||||||
* Smash:
|
|
||||||
* Low success chance
|
|
||||||
* Large reward
|
|
||||||
* Large failure penalty
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const HEIST_METHODS = {
|
const HEIST_METHODS = {
|
||||||
|
|
||||||
Sneak: {
|
Sneak: {
|
||||||
baseChance:
|
baseChance: 0.65,
|
||||||
0.65,
|
|
||||||
|
|
||||||
minStealPercent:
|
minStealPercent: 0.01,
|
||||||
0.01,
|
maxStealPercent: 0.03,
|
||||||
|
maxStealAmount: 1500,
|
||||||
|
|
||||||
maxStealPercent:
|
minPenaltyPercent: 0.01,
|
||||||
0.03,
|
maxPenaltyPercent: 0.04
|
||||||
|
|
||||||
maxStealAmount:
|
|
||||||
1500,
|
|
||||||
|
|
||||||
minPenaltyPercent:
|
|
||||||
0.01,
|
|
||||||
|
|
||||||
maxPenaltyPercent:
|
|
||||||
0.04
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
Hack: {
|
Hack: {
|
||||||
baseChance:
|
baseChance: 0.45,
|
||||||
0.45,
|
|
||||||
|
|
||||||
minStealPercent:
|
minStealPercent: 0.03,
|
||||||
0.03,
|
maxStealPercent: 0.06,
|
||||||
|
maxStealAmount: 3500,
|
||||||
|
|
||||||
maxStealPercent:
|
minPenaltyPercent: 0.03,
|
||||||
0.06,
|
maxPenaltyPercent: 0.07
|
||||||
|
|
||||||
maxStealAmount:
|
|
||||||
3500,
|
|
||||||
|
|
||||||
minPenaltyPercent:
|
|
||||||
0.03,
|
|
||||||
|
|
||||||
maxPenaltyPercent:
|
|
||||||
0.07
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
Smash: {
|
Smash: {
|
||||||
baseChance:
|
baseChance: 0.25,
|
||||||
0.25,
|
|
||||||
|
|
||||||
minStealPercent:
|
minStealPercent: 0.06,
|
||||||
0.06,
|
maxStealPercent: 0.12,
|
||||||
|
maxStealAmount: 7500,
|
||||||
|
|
||||||
maxStealPercent:
|
minPenaltyPercent: 0.06,
|
||||||
0.12,
|
maxPenaltyPercent: 0.12
|
||||||
|
|
||||||
maxStealAmount:
|
|
||||||
7500,
|
|
||||||
|
|
||||||
minPenaltyPercent:
|
|
||||||
0.06,
|
|
||||||
|
|
||||||
maxPenaltyPercent:
|
|
||||||
0.12
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,15 +81,12 @@ async function resolveCookieHeist(
|
|||||||
interaction,
|
interaction,
|
||||||
methodName
|
methodName
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The original /cookies heist command stores
|
* Validate ownership of this Heist menu.
|
||||||
* the player ID inside the embed footer:
|
|
||||||
*
|
*
|
||||||
* cookieHeist:123456789
|
* Footer:
|
||||||
*
|
*
|
||||||
* This prevents somebody else from pressing
|
* cookieHeist:<userId>
|
||||||
* another player's heist buttons.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const footer =
|
const footer =
|
||||||
@@ -139,10 +100,8 @@ async function resolveCookieHeist(
|
|||||||
type,
|
type,
|
||||||
ownerId
|
ownerId
|
||||||
] =
|
] =
|
||||||
footer
|
footer?.split(":")
|
||||||
?.split(":")
|
?? [];
|
||||||
??
|
|
||||||
[];
|
|
||||||
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -153,14 +112,14 @@ async function resolveCookieHeist(
|
|||||||
interaction,
|
interaction,
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
"This isn't your heist. Start your own with `/cookies heist`."
|
"This isn't your heist. Open your own from `/crumbsaucer`."
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate selected method.
|
* Validate method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const method =
|
const method =
|
||||||
@@ -182,11 +141,18 @@ async function resolveCookieHeist(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* ========================================================
|
* ========================================================
|
||||||
* CLAIM COOLDOWN
|
* SHARED HEIST COOLDOWN
|
||||||
* ========================================================
|
* ========================================================
|
||||||
*
|
*
|
||||||
* This is atomic so rapid double-clicks can't
|
* IMPORTANT:
|
||||||
* resolve the same heist multiple times.
|
*
|
||||||
|
* This is intentionally always "heist".
|
||||||
|
*
|
||||||
|
* It does NOT use:
|
||||||
|
*
|
||||||
|
* heistSneak
|
||||||
|
* heistHack
|
||||||
|
* heistSmash
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const cooldown =
|
const cooldown =
|
||||||
@@ -203,18 +169,18 @@ async function resolveCookieHeist(
|
|||||||
interaction,
|
interaction,
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
`You can attempt another vault heist <t:${cooldown.next}:R>.`
|
`🏦 The vault is still on high alert.\nYou can attempt another heist <t:${cooldown.next}:R>.`
|
||||||
}
|
},
|
||||||
|
6000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ========================================================
|
* Lock this Heist interaction immediately.
|
||||||
* LOCK THE HEIST MESSAGE
|
|
||||||
* ========================================================
|
|
||||||
*
|
*
|
||||||
* Remove all buttons immediately.
|
* Prevents selecting another approach from
|
||||||
|
* the same message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
await interaction.update({
|
await interaction.update({
|
||||||
@@ -234,12 +200,6 @@ async function resolveCookieHeist(
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ========================================================
|
|
||||||
* GET BALANCES
|
|
||||||
* ========================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
const playerId =
|
const playerId =
|
||||||
interaction.user.id;
|
interaction.user.id;
|
||||||
|
|
||||||
@@ -247,12 +207,16 @@ async function resolveCookieHeist(
|
|||||||
interaction.client.user.id;
|
interaction.client.user.id;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-fetch balances because they may have
|
||||||
|
* changed since the menu was opened.
|
||||||
|
*/
|
||||||
|
|
||||||
const [
|
const [
|
||||||
playerCookies,
|
playerCookies,
|
||||||
vaultCookies
|
vaultCookies
|
||||||
] =
|
] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
|
||||||
getCookieBalance(
|
getCookieBalance(
|
||||||
playerId
|
playerId
|
||||||
),
|
),
|
||||||
@@ -260,15 +224,9 @@ async function resolveCookieHeist(
|
|||||||
getCookieBalance(
|
getCookieBalance(
|
||||||
vaultId
|
vaultId
|
||||||
)
|
)
|
||||||
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Something may have changed between opening
|
|
||||||
* the heist menu and pressing the button.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
playerCookies < 1 ||
|
playerCookies < 1 ||
|
||||||
vaultCookies < 1
|
vaultCookies < 1
|
||||||
@@ -282,18 +240,23 @@ async function resolveCookieHeist(
|
|||||||
.setDescription(
|
.setDescription(
|
||||||
"There weren't enough Cookies available to resolve the heist."
|
"There weren't enough Cookies available to resolve the heist."
|
||||||
)
|
)
|
||||||
|
.addFields({
|
||||||
|
name:
|
||||||
|
"Next Heist",
|
||||||
|
|
||||||
|
value:
|
||||||
|
`<t:${cooldown.next}:R>`
|
||||||
|
})
|
||||||
],
|
],
|
||||||
|
|
||||||
components: []
|
components:
|
||||||
|
buildReturnButton()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Small dramatic pause.
|
* Short theatrical delay.
|
||||||
*
|
|
||||||
* Only one edit happens after this, so this is
|
|
||||||
* comfortably within Discord rate limits.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
await sleep(
|
await sleep(
|
||||||
@@ -303,13 +266,8 @@ async function resolveCookieHeist(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* ========================================================
|
* ========================================================
|
||||||
* VAULT DIFFICULTY
|
* DYNAMIC VAULT SECURITY
|
||||||
* ========================================================
|
* ========================================================
|
||||||
*
|
|
||||||
* The richer ShaiBot's vault becomes,
|
|
||||||
* the harder it is to rob.
|
|
||||||
*
|
|
||||||
* Penalty is capped at 15 percentage points.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const securityPenalty =
|
const securityPenalty =
|
||||||
@@ -339,38 +297,21 @@ async function resolveCookieHeist(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
const rolledPercent =
|
||||||
/*
|
|
||||||
* Roll percentage of the current vault.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const percent =
|
|
||||||
randomFloat(
|
randomFloat(
|
||||||
method.minStealPercent,
|
method.minStealPercent,
|
||||||
method.maxStealPercent
|
method.maxStealPercent
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Apply both:
|
|
||||||
*
|
|
||||||
* percentage roll
|
|
||||||
* AND
|
|
||||||
* hard maximum
|
|
||||||
*
|
|
||||||
* This prevents a massive vault from producing
|
|
||||||
* absurd payouts.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const amount =
|
const amount =
|
||||||
Math.max(
|
Math.max(
|
||||||
1,
|
1,
|
||||||
|
|
||||||
Math.min(
|
Math.min(
|
||||||
|
|
||||||
Math.floor(
|
Math.floor(
|
||||||
vaultCookies *
|
vaultCookies *
|
||||||
percent
|
rolledPercent
|
||||||
),
|
),
|
||||||
|
|
||||||
method.maxStealAmount,
|
method.maxStealAmount,
|
||||||
@@ -380,28 +321,67 @@ async function resolveCookieHeist(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/*
|
try {
|
||||||
* ShaiBot pays the robber.
|
await transferCookies(
|
||||||
*/
|
vaultId,
|
||||||
|
playerId,
|
||||||
await transferCookies(
|
amount
|
||||||
vaultId,
|
|
||||||
playerId,
|
|
||||||
amount
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
const remaining =
|
|
||||||
await getCookieBalance(
|
|
||||||
vaultId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error.message ===
|
||||||
|
"INSUFFICIENT_COOKIES"
|
||||||
|
) {
|
||||||
|
return interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setTitle(
|
||||||
|
"🏦 Heist Interrupted"
|
||||||
|
)
|
||||||
|
.setDescription(
|
||||||
|
"The ShaiBot Vault changed before you could complete the robbery."
|
||||||
|
)
|
||||||
|
.addFields({
|
||||||
|
name:
|
||||||
|
"Next Heist",
|
||||||
|
|
||||||
|
value:
|
||||||
|
`<t:${cooldown.next}:R>`
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
components:
|
||||||
|
buildReturnButton()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const [
|
||||||
|
playerAfter,
|
||||||
|
vaultAfter
|
||||||
|
] =
|
||||||
|
await Promise.all([
|
||||||
|
getCookieBalance(
|
||||||
|
playerId
|
||||||
|
),
|
||||||
|
|
||||||
|
getCookieBalance(
|
||||||
|
vaultId
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
const actualPercentage =
|
const actualPercentage =
|
||||||
(
|
(
|
||||||
amount /
|
amount /
|
||||||
vaultCookies
|
vaultCookies
|
||||||
) *
|
)
|
||||||
|
*
|
||||||
100;
|
100;
|
||||||
|
|
||||||
|
|
||||||
@@ -410,6 +390,7 @@ async function resolveCookieHeist(
|
|||||||
.setTitle(
|
.setTitle(
|
||||||
"💥 Vault Breached!"
|
"💥 Vault Breached!"
|
||||||
)
|
)
|
||||||
|
|
||||||
.setDescription(
|
.setDescription(
|
||||||
getSuccessText(
|
getSuccessText(
|
||||||
methodName,
|
methodName,
|
||||||
@@ -417,8 +398,8 @@ async function resolveCookieHeist(
|
|||||||
amount
|
amount
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.addFields(
|
|
||||||
|
|
||||||
|
.addFields(
|
||||||
{
|
{
|
||||||
name:
|
name:
|
||||||
"Approach",
|
"Approach",
|
||||||
@@ -465,10 +446,21 @@ async function resolveCookieHeist(
|
|||||||
|
|
||||||
{
|
{
|
||||||
name:
|
name:
|
||||||
"Vault Remaining",
|
"Your Vault",
|
||||||
|
|
||||||
value:
|
value:
|
||||||
`**${remaining.toLocaleString()} 🍪**`,
|
`**${playerAfter.toLocaleString()} 🍪**`,
|
||||||
|
|
||||||
|
inline:
|
||||||
|
true
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name:
|
||||||
|
"House Vault",
|
||||||
|
|
||||||
|
value:
|
||||||
|
`**${vaultAfter.toLocaleString()} 🍪**`,
|
||||||
|
|
||||||
inline:
|
inline:
|
||||||
true
|
true
|
||||||
@@ -482,9 +474,8 @@ async function resolveCookieHeist(
|
|||||||
`<t:${cooldown.next}:R>`,
|
`<t:${cooldown.next}:R>`,
|
||||||
|
|
||||||
inline:
|
inline:
|
||||||
true
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -493,7 +484,8 @@ async function resolveCookieHeist(
|
|||||||
embed
|
embed
|
||||||
],
|
],
|
||||||
|
|
||||||
components: []
|
components:
|
||||||
|
buildReturnButton()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,11 +494,6 @@ async function resolveCookieHeist(
|
|||||||
* ========================================================
|
* ========================================================
|
||||||
* FAILURE
|
* FAILURE
|
||||||
* ========================================================
|
* ========================================================
|
||||||
*
|
|
||||||
* Failure fines the player.
|
|
||||||
*
|
|
||||||
* Unlike normal player stealing, the fine goes
|
|
||||||
* directly into ShaiBot's vault.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const penaltyPercent =
|
const penaltyPercent =
|
||||||
@@ -521,7 +508,6 @@ async function resolveCookieHeist(
|
|||||||
1,
|
1,
|
||||||
|
|
||||||
Math.min(
|
Math.min(
|
||||||
|
|
||||||
Math.floor(
|
Math.floor(
|
||||||
playerCookies *
|
playerCookies *
|
||||||
penaltyPercent
|
penaltyPercent
|
||||||
@@ -532,11 +518,49 @@ async function resolveCookieHeist(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
await transferCookies(
|
try {
|
||||||
playerId,
|
/*
|
||||||
vaultId,
|
* Heist fines always go into
|
||||||
penalty
|
* ShaiBot's central vault.
|
||||||
);
|
*/
|
||||||
|
|
||||||
|
await transferCookies(
|
||||||
|
playerId,
|
||||||
|
vaultId,
|
||||||
|
penalty
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error.message ===
|
||||||
|
"INSUFFICIENT_COOKIES"
|
||||||
|
) {
|
||||||
|
return interaction.editReply({
|
||||||
|
embeds: [
|
||||||
|
new EmbedBuilder()
|
||||||
|
.setTitle(
|
||||||
|
"🚨 Heist Failed"
|
||||||
|
)
|
||||||
|
.setDescription(
|
||||||
|
"Your Cookie balance changed before the fine could be collected."
|
||||||
|
)
|
||||||
|
.addFields({
|
||||||
|
name:
|
||||||
|
"Next Heist",
|
||||||
|
|
||||||
|
value:
|
||||||
|
`<t:${cooldown.next}:R>`
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
components:
|
||||||
|
buildReturnButton()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const [
|
const [
|
||||||
@@ -544,7 +568,6 @@ async function resolveCookieHeist(
|
|||||||
vaultAfter
|
vaultAfter
|
||||||
] =
|
] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
|
||||||
getCookieBalance(
|
getCookieBalance(
|
||||||
playerId
|
playerId
|
||||||
),
|
),
|
||||||
@@ -552,15 +575,24 @@ async function resolveCookieHeist(
|
|||||||
getCookieBalance(
|
getCookieBalance(
|
||||||
vaultId
|
vaultId
|
||||||
)
|
)
|
||||||
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
const actualPenaltyPercentage =
|
||||||
|
(
|
||||||
|
penalty /
|
||||||
|
playerCookies
|
||||||
|
)
|
||||||
|
*
|
||||||
|
100;
|
||||||
|
|
||||||
|
|
||||||
const embed =
|
const embed =
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.setTitle(
|
.setTitle(
|
||||||
"🚨 HEIST FAILED"
|
"🚨 HEIST FAILED"
|
||||||
)
|
)
|
||||||
|
|
||||||
.setDescription(
|
.setDescription(
|
||||||
getFailureText(
|
getFailureText(
|
||||||
methodName,
|
methodName,
|
||||||
@@ -568,8 +600,8 @@ async function resolveCookieHeist(
|
|||||||
penalty
|
penalty
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.addFields(
|
|
||||||
|
|
||||||
|
.addFields(
|
||||||
{
|
{
|
||||||
name:
|
name:
|
||||||
"Approach",
|
"Approach",
|
||||||
@@ -603,6 +635,17 @@ async function resolveCookieHeist(
|
|||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name:
|
||||||
|
"Vault Lost",
|
||||||
|
|
||||||
|
value:
|
||||||
|
`**${actualPenaltyPercentage.toFixed(1)}%**`,
|
||||||
|
|
||||||
|
inline:
|
||||||
|
true
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name:
|
name:
|
||||||
"Your Vault",
|
"Your Vault",
|
||||||
@@ -633,9 +676,8 @@ async function resolveCookieHeist(
|
|||||||
`<t:${cooldown.next}:R>`,
|
`<t:${cooldown.next}:R>`,
|
||||||
|
|
||||||
inline:
|
inline:
|
||||||
true
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -644,26 +686,51 @@ async function resolveCookieHeist(
|
|||||||
embed
|
embed
|
||||||
],
|
],
|
||||||
|
|
||||||
components: []
|
components:
|
||||||
|
buildReturnButton()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ============================================================
|
* ============================================================
|
||||||
* VAULT SECURITY
|
* RETURN TO CRUMB SAUCER
|
||||||
|
* ============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
function buildReturnButton() {
|
||||||
|
return [
|
||||||
|
new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(
|
||||||
|
"crumbSaucerBack"
|
||||||
|
)
|
||||||
|
.setLabel(
|
||||||
|
"Back to Crumb Saucer"
|
||||||
|
)
|
||||||
|
.setEmoji(
|
||||||
|
"◀️"
|
||||||
|
)
|
||||||
|
.setStyle(
|
||||||
|
ButtonStyle.Secondary
|
||||||
|
)
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================
|
||||||
|
* SECURITY
|
||||||
* ============================================================
|
* ============================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getVaultSecurityPenalty(
|
function getVaultSecurityPenalty(
|
||||||
vaultCookies
|
vaultCookies
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logarithmic scaling means the vault gets harder
|
* Approximately:
|
||||||
* as it becomes richer without becoming impossible.
|
|
||||||
*
|
|
||||||
* Examples approximately:
|
|
||||||
*
|
*
|
||||||
* 100 -> 5%
|
* 100 -> 5%
|
||||||
* 1,000 -> 7.5%
|
* 1,000 -> 7.5%
|
||||||
@@ -673,10 +740,11 @@ function getVaultSecurityPenalty(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
return Math.min(
|
return Math.min(
|
||||||
|
|
||||||
Math.log10(
|
Math.log10(
|
||||||
vaultCookies + 1
|
vaultCookies +
|
||||||
) *
|
1
|
||||||
|
)
|
||||||
|
*
|
||||||
0.025,
|
0.025,
|
||||||
|
|
||||||
0.15
|
0.15
|
||||||
@@ -686,18 +754,16 @@ function getVaultSecurityPenalty(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* ============================================================
|
* ============================================================
|
||||||
* FLAVOR TEXT
|
* PROGRESS TEXT
|
||||||
* ============================================================
|
* ============================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getHeistProgressText(
|
function getHeistProgressText(
|
||||||
methodName
|
methodName
|
||||||
) {
|
) {
|
||||||
|
|
||||||
switch (
|
switch (
|
||||||
methodName
|
methodName
|
||||||
) {
|
) {
|
||||||
|
|
||||||
case "Sneak":
|
case "Sneak":
|
||||||
return [
|
return [
|
||||||
"🥷 You slip through the service entrance...",
|
"🥷 You slip through the service entrance...",
|
||||||
@@ -728,65 +794,73 @@ function getHeistProgressText(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================
|
||||||
|
* SUCCESS TEXT
|
||||||
|
* ============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
function getSuccessText(
|
function getSuccessText(
|
||||||
methodName,
|
methodName,
|
||||||
user,
|
user,
|
||||||
amount
|
amount
|
||||||
) {
|
) {
|
||||||
|
const cookies =
|
||||||
const amountText =
|
|
||||||
`**${amount.toLocaleString()} Cookies**`;
|
`**${amount.toLocaleString()} Cookies**`;
|
||||||
|
|
||||||
|
|
||||||
switch (
|
switch (
|
||||||
methodName
|
methodName
|
||||||
) {
|
) {
|
||||||
|
|
||||||
case "Sneak":
|
case "Sneak":
|
||||||
return (
|
return (
|
||||||
`🥷 ${user} slipped through security and quietly escaped with ${amountText}.`
|
`🥷 ${user} slipped through security and quietly escaped with ${cookies}.`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
case "Hack":
|
case "Hack":
|
||||||
return (
|
return (
|
||||||
`💻 ${user} convinced the vault terminal that ${amountText} belonged to them.`
|
`💻 ${user} convinced the vault terminal that ${cookies} belonged to them.`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
case "Smash":
|
case "Smash":
|
||||||
return (
|
return (
|
||||||
`💥 ${user} smashed through the Cookie Vault and escaped with ${amountText}!`
|
`💥 ${user} smashed through the Cookie Vault and escaped with ${cookies}!`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
`${user} escaped with ${amountText}.`
|
`${user} escaped with ${cookies}.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================
|
||||||
|
* FAILURE TEXT
|
||||||
|
* ============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
function getFailureText(
|
function getFailureText(
|
||||||
methodName,
|
methodName,
|
||||||
user,
|
user,
|
||||||
penalty
|
penalty
|
||||||
) {
|
) {
|
||||||
|
const cookies =
|
||||||
const penaltyText =
|
|
||||||
`**${penalty.toLocaleString()} Cookies**`;
|
`**${penalty.toLocaleString()} Cookies**`;
|
||||||
|
|
||||||
|
|
||||||
switch (
|
switch (
|
||||||
methodName
|
methodName
|
||||||
) {
|
) {
|
||||||
|
|
||||||
case "Sneak":
|
case "Sneak":
|
||||||
return [
|
return [
|
||||||
`🚨 ${user} stepped directly on the world's loudest Cookie wrapper.`,
|
`🚨 ${user} stepped directly on the world's loudest Cookie wrapper.`,
|
||||||
"",
|
"",
|
||||||
`The ShaiBot Vault collected a ${penaltyText} fine.`
|
`The ShaiBot Vault collected a ${cookies} fine.`
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
|
|
||||||
@@ -794,7 +868,7 @@ function getFailureText(
|
|||||||
return [
|
return [
|
||||||
`🚨 ${user} entered the password incorrectly one too many times.`,
|
`🚨 ${user} entered the password incorrectly one too many times.`,
|
||||||
"",
|
"",
|
||||||
`The ShaiBot Vault collected a ${penaltyText} security fee.`
|
`The ShaiBot Vault collected a ${cookies} security fee.`
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
|
|
||||||
@@ -802,13 +876,13 @@ function getFailureText(
|
|||||||
return [
|
return [
|
||||||
`🚨 ${user} discovered that the vault door is significantly stronger than expected.`,
|
`🚨 ${user} discovered that the vault door is significantly stronger than expected.`,
|
||||||
"",
|
"",
|
||||||
`Repairs cost ${penaltyText}. Naturally, you're paying.`
|
`Repairs cost ${cookies}. Naturally, you're paying.`
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
`The heist failed and cost ${user} ${penaltyText}.`
|
`The heist failed and cost ${user} ${cookies}.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -832,5 +906,6 @@ function sleep(ms) {
|
|||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
resolveCookieHeist
|
resolveCookieHeist,
|
||||||
|
HEIST_COOLDOWN
|
||||||
};
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user