This commit is contained in:
DeSqBlocki
2026-08-22 22:29:16 +02:00
parent ca823726e3
commit 9e0870c1ed
6 changed files with 797 additions and 2946 deletions
+50 -21
View File
@@ -1,34 +1,63 @@
const { SlashCommandBuilder } = require("discord.js"); const {
SlashCommandBuilder
} = require(
"discord.js"
);
const { const {
buildProfileOverview, buildProfileOverview,
buildProfileButtons, buildProfileButtons
ensureGuildBadges } = require(
} = require("../../utils/profileSystem"); "../../utils/profileSystem"
);
module.exports = { module.exports = {
data: new SlashCommandBuilder() data:
.setName("profile") new SlashCommandBuilder()
.setDescription("View a player profile") .setName(
.addUserOption(option => "profile"
option )
.setName("user") .setDescription(
.setDescription("Player to view") "View a player profile"
), )
.addUserOption(
option =>
option
.setName(
"user"
)
.setDescription(
"Player to view"
)
),
async execute(interaction) {
const user = interaction.options.getUser("user") ?? interaction.user;
await ensureGuildBadges(interaction.guildId); async execute(
interaction
) {
const user =
interaction.options.getUser(
"user"
)
??
interaction.user;
const embed =
await buildProfileOverview(
interaction.guildId,
user
);
const embed = await buildProfileOverview(
interaction.guildId,
user
);
return interaction.reply({ return interaction.reply({
embeds: [embed], embeds: [
components: buildProfileButtons() embed
],
components:
buildProfileButtons()
}); });
} }
}; };
+50 -283
View File
@@ -18,83 +18,41 @@ const {
trackProfileEvent trackProfileEvent
} = require("./profileSystem"); } = require("./profileSystem");
const HEIST_COOLDOWN = const HEIST_COOLDOWN =
60 * 60; 60 * 60;
const HEIST_METHODS = { const HEIST_METHODS = {
Sneak: { Sneak: {
baseChance: baseChance: 0.65,
0.65, minStealPercent: 0.01,
maxStealPercent: 0.03,
minStealPercent: maxStealAmount: 1500,
0.01, minPenaltyPercent: 0.01,
maxPenaltyPercent: 0.04,
maxStealPercent: maxPenaltyAmount: 750
0.03,
maxStealAmount:
1500,
minPenaltyPercent:
0.01,
maxPenaltyPercent:
0.04,
maxPenaltyAmount:
750
}, },
Hack: { Hack: {
baseChance: baseChance: 0.45,
0.45, minStealPercent: 0.03,
maxStealPercent: 0.06,
minStealPercent: maxStealAmount: 3500,
0.03, minPenaltyPercent: 0.03,
maxPenaltyPercent: 0.07,
maxStealPercent: maxPenaltyAmount: 2000
0.06,
maxStealAmount:
3500,
minPenaltyPercent:
0.03,
maxPenaltyPercent:
0.07,
maxPenaltyAmount:
2000
}, },
Smash: { Smash: {
baseChance: baseChance: 0.25,
0.25, minStealPercent: 0.06,
maxStealPercent: 0.12,
minStealPercent: maxStealAmount: 7500,
0.06, minPenaltyPercent: 0.06,
maxPenaltyPercent: 0.12,
maxStealPercent: maxPenaltyAmount: 5000
0.12,
maxStealAmount:
7500,
minPenaltyPercent:
0.06,
maxPenaltyPercent:
0.12,
maxPenaltyAmount:
5000
} }
}; };
async function resolveCookieHeist( async function resolveCookieHeist(
interaction, interaction,
methodName methodName
@@ -105,20 +63,13 @@ async function resolveCookieHeist(
?.footer ?.footer
?.text; ?.text;
const [ const [
type, type,
ownerId ownerId
] = ] = footer?.split(":") ?? [];
footer?.split(":")
??
[];
if ( if (
type !== type !== "cookieHeist" ||
"cookieHeist"
||
ownerId !== ownerId !==
interaction.user.id interaction.user.id
) { ) {
@@ -131,13 +82,11 @@ async function resolveCookieHeist(
); );
} }
const method = const method =
HEIST_METHODS[ HEIST_METHODS[
methodName methodName
]; ];
if (!method) { if (!method) {
return temporaryEphemeralReply( return temporaryEphemeralReply(
interaction, interaction,
@@ -148,7 +97,6 @@ async function resolveCookieHeist(
); );
} }
const cooldown = const cooldown =
await claimCooldown( await claimCooldown(
interaction.user.id, interaction.user.id,
@@ -157,10 +105,7 @@ async function resolveCookieHeist(
HEIST_COOLDOWN HEIST_COOLDOWN
); );
if (!cooldown.claimed) {
if (
!cooldown.claimed
) {
return temporaryEphemeralReply( return temporaryEphemeralReply(
interaction, interaction,
{ {
@@ -171,7 +116,6 @@ async function resolveCookieHeist(
); );
} }
await interaction.update({ await interaction.update({
embeds: [ embeds: [
new EmbedBuilder() new EmbedBuilder()
@@ -188,40 +132,26 @@ async function resolveCookieHeist(
`cookieHeist:${interaction.user.id}` `cookieHeist:${interaction.user.id}`
}) })
], ],
components: [] components: []
}); });
const playerId = const playerId =
interaction.user.id; interaction.user.id;
const vaultId = const vaultId =
interaction.client.user.id; interaction.client.user.id;
const [ const [
playerCookies, playerCookies,
vaultCookies vaultCookies
] = ] = await Promise.all([
await Promise.all([ getCookieBalance(playerId),
getCookieBalance( getCookieBalance(vaultId)
playerId ]);
),
getCookieBalance(
vaultId
)
]);
if ( if (
playerCookies < playerCookies < 1 ||
1 vaultCookies < 1
||
vaultCookies <
1
) { ) {
return interaction.editReply({ return interaction.editReply({
embeds: [ embeds: [
@@ -235,7 +165,6 @@ async function resolveCookieHeist(
.addFields({ .addFields({
name: name:
"Next Heist", "Next Heist",
value: value:
`<t:${cooldown.next}:R>` `<t:${cooldown.next}:R>`
}) })
@@ -244,38 +173,29 @@ async function resolveCookieHeist(
`cookieHeist:${playerId}` `cookieHeist:${playerId}`
}) })
], ],
components: components:
buildReturnButton() buildReturnButton()
}); });
} }
await sleep(1200);
await sleep(
1200
);
const securityPenalty = const securityPenalty =
getVaultSecurityPenalty( getVaultSecurityPenalty(
vaultCookies vaultCookies
); );
const successChance = const successChance =
Math.max( Math.max(
0.10, 0.10,
method.baseChance - method.baseChance -
securityPenalty securityPenalty
); );
const success = const success =
Math.random() < Math.random() <
successChance; successChance;
if (success) { if (success) {
const rolledPercent = const rolledPercent =
randomFloat( randomFloat(
@@ -283,31 +203,25 @@ async function resolveCookieHeist(
method.maxStealPercent method.maxStealPercent
); );
const amount = const amount =
Math.max( Math.max(
1, 1,
Math.min( Math.min(
Math.floor( Math.floor(
vaultCookies * vaultCookies *
rolledPercent rolledPercent
), ),
method.maxStealAmount, method.maxStealAmount,
vaultCookies vaultCookies
) )
); );
try { try {
await transferCookies( await transferCookies(
vaultId, vaultId,
playerId, playerId,
amount amount
); );
} catch (error) { } catch (error) {
if ( if (
error.message === error.message ===
@@ -325,7 +239,6 @@ async function resolveCookieHeist(
.addFields({ .addFields({
name: name:
"Next Heist", "Next Heist",
value: value:
`<t:${cooldown.next}:R>` `<t:${cooldown.next}:R>`
}) })
@@ -334,90 +247,68 @@ async function resolveCookieHeist(
`cookieHeist:${playerId}` `cookieHeist:${playerId}`
}) })
], ],
components: components:
buildReturnButton() buildReturnButton()
}); });
} }
throw error; throw error;
} }
await trackProfileEvent( await trackProfileEvent(
interaction, interaction,
playerId, playerId,
{ {
type: type:
"game_result", "game_result",
game: game:
"heist", "heist",
result: result:
"win", "win",
profit: profit:
amount amount
} }
); );
await trackProfileEvent( await trackProfileEvent(
interaction, interaction,
playerId, playerId,
{ {
type: type:
"vault_steal", "vault_steal",
amount amount
} }
); );
await trackProfileEvent( await trackProfileEvent(
interaction, interaction,
playerId, playerId,
{ {
type: type:
"cookie_gain", "cookie_gain",
amount amount
} }
); );
const [ const [
playerAfter, playerAfter,
vaultAfter vaultAfter
] = ] = await Promise.all([
await Promise.all([ getCookieBalance(playerId),
getCookieBalance( getCookieBalance(vaultId)
playerId ]);
),
getCookieBalance(
vaultId
)
]);
const actualPercentage = const actualPercentage =
( (
amount / amount /
vaultCookies vaultCookies
) ) * 100;
*
100;
const embed = const embed =
new EmbedBuilder() new EmbedBuilder()
.setTitle( .setTitle(
"💥 Vault Breached!" "💥 Vault Breached!"
) )
.setDescription( .setDescription(
getSuccessText( getSuccessText(
methodName, methodName,
@@ -425,134 +316,101 @@ async function resolveCookieHeist(
amount amount
) )
) )
.addFields( .addFields(
{ {
name: name:
"Approach", "Approach",
value: value:
methodName, methodName,
inline: inline:
true true
}, },
{ {
name: name:
"Success Chance", "Success Chance",
value: value:
`**${formatPercentage(successChance)}**`, `**${formatPercentage(successChance)}**`,
inline: inline:
true true
}, },
{ {
name: name:
"Vault Taken", "Vault Taken",
value: value:
`**${actualPercentage.toFixed(2)}%**`, `**${actualPercentage.toFixed(2)}%**`,
inline: inline:
true true
}, },
{ {
name: name:
"Cookies Stolen", "Cookies Stolen",
value: value:
`**${amount.toLocaleString()} 🍪**`, `**${amount.toLocaleString()} 🍪**`,
inline: inline:
true true
}, },
{ {
name: name:
"Your Vault", "Your Vault",
value: value:
`**${playerAfter.toLocaleString()} 🍪**`, `**${playerAfter.toLocaleString()} 🍪**`,
inline: inline:
true true
}, },
{ {
name: name:
"House Vault", "House Vault",
value: value:
`**${vaultAfter.toLocaleString()} 🍪**`, `**${vaultAfter.toLocaleString()} 🍪**`,
inline: inline:
true true
}, },
{ {
name: name:
"Next Heist", "Next Heist",
value: value:
`<t:${cooldown.next}:R>`, `<t:${cooldown.next}:R>`,
inline: inline:
false false
} }
) )
.setFooter({ .setFooter({
text: text:
`cookieHeist:${playerId}` `cookieHeist:${playerId}`
}); });
return interaction.editReply({ return interaction.editReply({
embeds: [ embeds: [embed],
embed
],
components: components:
buildReturnButton() buildReturnButton()
}); });
} }
const penaltyPercent = const penaltyPercent =
randomFloat( randomFloat(
method.minPenaltyPercent, method.minPenaltyPercent,
method.maxPenaltyPercent method.maxPenaltyPercent
); );
const penalty = const penalty =
Math.max( Math.max(
1, 1,
Math.min( Math.min(
Math.floor( Math.floor(
playerCookies * playerCookies *
penaltyPercent penaltyPercent
), ),
method.maxPenaltyAmount, method.maxPenaltyAmount,
playerCookies playerCookies
) )
); );
try { try {
await transferCookies( await transferCookies(
playerId, playerId,
vaultId, vaultId,
penalty penalty
); );
} catch (error) { } catch (error) {
if ( if (
error.message === error.message ===
@@ -570,7 +428,6 @@ async function resolveCookieHeist(
.addFields({ .addFields({
name: name:
"Next Heist", "Next Heist",
value: value:
`<t:${cooldown.next}:R>` `<t:${cooldown.next}:R>`
}) })
@@ -579,79 +436,59 @@ async function resolveCookieHeist(
`cookieHeist:${playerId}` `cookieHeist:${playerId}`
}) })
], ],
components: components:
buildReturnButton() buildReturnButton()
}); });
} }
throw error; throw error;
} }
await trackProfileEvent( await trackProfileEvent(
interaction, interaction,
playerId, playerId,
{ {
type: type:
"game_result", "game_result",
game: game:
"heist", "heist",
result: result:
"loss", "loss",
profit: profit:
-penalty -penalty
} }
); );
await trackProfileEvent( await trackProfileEvent(
interaction, interaction,
playerId, playerId,
{ {
type: type:
"cookie_loss", "cookie_loss",
amount: amount:
penalty penalty
} }
); );
const [ const [
playerAfter, playerAfter,
vaultAfter vaultAfter
] = ] = await Promise.all([
await Promise.all([ getCookieBalance(playerId),
getCookieBalance( getCookieBalance(vaultId)
playerId ]);
),
getCookieBalance(
vaultId
)
]);
const actualPenaltyPercentage = const actualPenaltyPercentage =
( (
penalty / penalty /
playerCookies playerCookies
) ) * 100;
*
100;
const embed = const embed =
new EmbedBuilder() new EmbedBuilder()
.setTitle( .setTitle(
"🚨 HEIST FAILED" "🚨 HEIST FAILED"
) )
.setDescription( .setDescription(
getFailureText( getFailureText(
methodName, methodName,
@@ -659,103 +496,76 @@ async function resolveCookieHeist(
penalty penalty
) )
) )
.addFields( .addFields(
{ {
name: name:
"Approach", "Approach",
value: value:
methodName, methodName,
inline: inline:
true true
}, },
{ {
name: name:
"Success Chance", "Success Chance",
value: value:
`**${formatPercentage(successChance)}**`, `**${formatPercentage(successChance)}**`,
inline: inline:
true true
}, },
{ {
name: name:
"Fine", "Fine",
value: value:
`**${penalty.toLocaleString()} 🍪**`, `**${penalty.toLocaleString()} 🍪**`,
inline: inline:
true true
}, },
{ {
name: name:
"Vault Lost", "Vault Lost",
value: value:
`**${actualPenaltyPercentage.toFixed(1)}%**`, `**${actualPenaltyPercentage.toFixed(1)}%**`,
inline: inline:
true true
}, },
{ {
name: name:
"Your Vault", "Your Vault",
value: value:
`**${playerAfter.toLocaleString()} 🍪**`, `**${playerAfter.toLocaleString()} 🍪**`,
inline: inline:
true true
}, },
{ {
name: name:
"House Vault", "House Vault",
value: value:
`**${vaultAfter.toLocaleString()} 🍪**`, `**${vaultAfter.toLocaleString()} 🍪**`,
inline: inline:
true true
}, },
{ {
name: name:
"Next Heist", "Next Heist",
value: value:
`<t:${cooldown.next}:R>`, `<t:${cooldown.next}:R>`,
inline: inline:
false false
} }
) )
.setFooter({ .setFooter({
text: text:
`cookieHeist:${playerId}` `cookieHeist:${playerId}`
}); });
return interaction.editReply({ return interaction.editReply({
embeds: [ embeds: [embed],
embed
],
components: components:
buildReturnButton() buildReturnButton()
}); });
} }
function buildReturnButton() { function buildReturnButton() {
return [ return [
new ActionRowBuilder() new ActionRowBuilder()
@@ -767,9 +577,7 @@ function buildReturnButton() {
.setLabel( .setLabel(
"Back to Crumb Saucer" "Back to Crumb Saucer"
) )
.setEmoji( .setEmoji("◀️")
"◀️"
)
.setStyle( .setStyle(
ButtonStyle.Secondary ButtonStyle.Secondary
) )
@@ -777,63 +585,47 @@ function buildReturnButton() {
]; ];
} }
function getVaultSecurityPenalty( function getVaultSecurityPenalty(
vaultCookies vaultCookies
) { ) {
return Math.min( return Math.min(
Math.log10( Math.log10(
vaultCookies + vaultCookies + 1
1 ) * 0.025,
)
*
0.025,
0.15 0.15
); );
} }
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...",
"", "",
"The Cookie Vault guards haven't noticed you yet." "The Cookie Vault guards haven't noticed you yet."
].join("\n"); ].join("\n");
case "Hack": case "Hack":
return [ return [
"💻 You connect to the vault terminal...", "💻 You connect to the vault terminal...",
"", "",
"Several extremely suspicious progress bars appear." "Several extremely suspicious progress bars appear."
].join("\n"); ].join("\n");
case "Smash": case "Smash":
return [ return [
"💥 You charge directly at the vault...", "💥 You charge directly at the vault...",
"", "",
"Subtlety has been abandoned." "Subtlety has been abandoned."
].join("\n"); ].join("\n");
default: default:
return "The heist is underway..."; return "The heist is underway...";
} }
} }
function getSuccessText( function getSuccessText(
methodName, methodName,
user, user,
@@ -842,40 +634,29 @@ function getSuccessText(
const cookies = const cookies =
`**${amount.toLocaleString()} Cookies**`; `**${amount.toLocaleString()} Cookies**`;
switch (methodName) {
switch (
methodName
) {
case "Sneak": case "Sneak":
return ( return (
`🥷 ${user} slipped through security and quietly escaped with ${cookies}.` `🥷 ${user} slipped through security and quietly escaped with ${cookies}.`
); );
case "Hack": case "Hack":
return ( return (
`💻 ${user} convinced the vault terminal that ${cookies} 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 ${cookies}!` `💥 ${user} smashed through the Cookie Vault and escaped with ${cookies}!`
); );
default: default:
return ( return (
`${user} escaped with ${cookies}.` `${user} escaped with ${cookies}.`
); );
} }
} }
function getFailureText( function getFailureText(
methodName, methodName,
user, user,
@@ -884,49 +665,36 @@ function getFailureText(
const cookies = const cookies =
`**${penalty.toLocaleString()} Cookies**`; `**${penalty.toLocaleString()} Cookies**`;
switch (methodName) {
switch (
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 ${cookies} fine.` `The ShaiBot Vault collected a ${cookies} fine.`
].join("\n"); ].join("\n");
case "Hack": case "Hack":
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 ${cookies} security fee.` `The ShaiBot Vault collected a ${cookies} security fee.`
].join("\n"); ].join("\n");
case "Smash": case "Smash":
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 ${cookies}. 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} ${cookies}.` `The heist failed and cost ${user} ${cookies}.`
); );
} }
} }
function sleep(ms) {
function sleep(
ms
) {
return new Promise( return new Promise(
resolve => resolve =>
setTimeout( setTimeout(
@@ -936,7 +704,6 @@ function sleep(
); );
} }
module.exports = { module.exports = {
resolveCookieHeist, resolveCookieHeist,
HEIST_COOLDOWN HEIST_COOLDOWN
+119 -589
View File
File diff suppressed because it is too large Load Diff
+88 -370
View File
File diff suppressed because it is too large Load Diff
+76 -376
View File
File diff suppressed because it is too large Load Diff
+408 -1301
View File
File diff suppressed because it is too large Load Diff