made collect logic actually connect to the utils

This commit is contained in:
DeSqBlocki
2026-08-23 00:21:52 +02:00
parent 9c867b1adb
commit 4d858554be
2 changed files with 264 additions and 608 deletions
File diff suppressed because it is too large Load Diff
+172 -171
View File
@@ -23,24 +23,159 @@ const {
* ============================================================ * ============================================================
*/ */
const COLLECT_COOLDOWN = const COLLECT_COOLDOWN = 60 * 60;
60 * 60; const COLLECT_MIN = 1;
const COLLECT_MAX = 1000; const COLLECT_MAX = 1000;
/* const COLLECT_COOLDOWN_KEY = "collect";
* IMPORTANT:
*
* Always use exactly the same cooldown key.
*/
const COLLECT_COOLDOWN_KEY =
"collect";
/* /*
* ============================================================ * ============================================================
* SHOW COLLECT PAGE * SHARED COLLECT LOGIC
* ============================================================
*
* This is the one authoritative implementation used by:
*
* - /cookies collect
* - Crumb Saucer Cookie Bakery
*
* It does not reply/update Discord itself.
*/
async function collectCookies(
interaction,
userId = interaction.user.id
) {
const cooldown = await claimCooldown(
userId,
interaction.guildId,
COLLECT_COOLDOWN_KEY,
COLLECT_COOLDOWN
);
if (!cooldown.claimed) {
const balance = await getCookieBalance(
userId
);
return {
collected: false,
cooldown,
balance,
amount: 0
};
}
const amount =
Math.floor(
Math.random() *
(
COLLECT_MAX -
COLLECT_MIN +
1
)
) +
COLLECT_MIN;
await changeCookies(
userId,
amount
);
await trackProfileEvent(
interaction,
userId,
{
type: "cookie_gain",
amount
}
);
const balance = await getCookieBalance(
userId
);
return {
collected: true,
cooldown,
balance,
amount
};
}
/*
* ============================================================
* SHARED EMBED BUILDERS
* ============================================================
*/
function buildCollectSuccessEmbed(
userId,
result,
footerType = "crumbSaucerCollect"
) {
return new EmbedBuilder()
.setTitle(
"🍪 Fresh Batch!"
)
.setDescription(
[
`You collected **${result.amount.toLocaleString()} Cookies**! 🍪`,
"",
`Your next batch will be ready <t:${result.cooldown.next}:R>.`
].join("\n")
)
.addFields({
name: "Your Vault",
value:
`**${result.balance.toLocaleString()} 🍪**`
})
.setFooter({
text:
`${footerType}:${userId}`
});
}
function buildCollectCooldownEmbed(
userId,
result,
footerType = "crumbSaucerCollect"
) {
return new EmbedBuilder()
.setTitle(
"🍪 Cookie Bakery"
)
.setDescription(
[
"Your next batch isn't ready yet.",
"",
`Come back <t:${result.cooldown.next}:R>.`
].join("\n")
)
.addFields({
name: "Your Vault",
value:
`**${result.balance.toLocaleString()} 🍪**`
})
.setFooter({
text:
`${footerType}:${userId}`
});
}
/*
* ============================================================
* SHOW SAUCER COLLECT PAGE
* ============================================================ * ============================================================
*/ */
@@ -78,7 +213,6 @@ async function showCollectPage(
.setTitle( .setTitle(
"🍪 Crumb Saucer Cookie Bakery" "🍪 Crumb Saucer Cookie Bakery"
) )
.setDescription( .setDescription(
[ [
"Fresh Cookies are prepared regularly.", "Fresh Cookies are prepared regularly.",
@@ -88,15 +222,11 @@ async function showCollectPage(
"Your collection cooldown is shared with `/cookies collect`." "Your collection cooldown is shared with `/cookies collect`."
].join("\n") ].join("\n")
) )
.addFields({ .addFields({
name: name: "Your Vault",
"Your Vault",
value: value:
`**${balance.toLocaleString()} 🍪**` `**${balance.toLocaleString()} 🍪**`
}) })
.setFooter({ .setFooter({
text: text:
`crumbSaucerCollect:${interaction.user.id}` `crumbSaucerCollect:${interaction.user.id}`
@@ -104,10 +234,7 @@ async function showCollectPage(
return interaction.update({ return interaction.update({
embeds: [ embeds: [embed],
embed
],
components: components:
buildCollectButtons() buildCollectButtons()
}); });
@@ -116,7 +243,7 @@ async function showCollectPage(
/* /*
* ============================================================ * ============================================================
* COLLECT * SAUCER COLLECT WRAPPER
* ============================================================ * ============================================================
*/ */
@@ -143,154 +270,27 @@ async function collectCookiesFromSaucer(
} }
/* const result =
* Mongo-backed cooldown. await collectCookies(
* interaction,
* Same pattern as Cookie Heist:
*
* userId
* guildId
* cooldown key
* duration
*/
const cooldown =
await claimCooldown(
interaction.user.id,
interaction.guildId,
COLLECT_COOLDOWN_KEY,
COLLECT_COOLDOWN
);
/*
* Already collected.
*/
if (
!cooldown.claimed
) {
const balance =
await getCookieBalance(
interaction.user.id
);
const embed =
new EmbedBuilder()
.setTitle(
"🍪 Cookie Bakery"
)
.setDescription(
[
"Your next batch isn't ready yet.",
"",
`Come back <t:${cooldown.next}:R>.`
].join("\n")
)
.addFields({
name:
"Your Vault",
value:
`**${balance.toLocaleString()} 🍪**`
})
.setFooter({
text:
`crumbSaucerCollect:${interaction.user.id}`
});
return interaction.update({
embeds: [
embed
],
components:
buildCollectButtons()
});
}
/*
* ========================================================
* GENERATE BATCH
* ========================================================
*/
const amount =
Math.floor(
Math.random() *
COLLECT_MAX
)
+
1;
await changeCookies(
interaction.user.id,
amount
);
/*
* Profile / achievements.
*/
await trackProfileEvent(
interaction,
interaction.user.id,
{
type:
"cookie_gain",
amount
}
);
const balance =
await getCookieBalance(
interaction.user.id interaction.user.id
); );
const embed = const embed =
new EmbedBuilder() result.collected
.setTitle( ? buildCollectSuccessEmbed(
"🍪 Fresh Batch!" interaction.user.id,
result
) )
: buildCollectCooldownEmbed(
.setDescription( interaction.user.id,
[ result
`You collected **${amount.toLocaleString()} Cookies**! 🍪`, );
"",
`Your next batch will be ready <t:${cooldown.next}:R>.`
].join("\n")
)
.addFields({
name:
"Your Vault",
value:
`**${balance.toLocaleString()} 🍪**`
})
.setFooter({
text:
`crumbSaucerCollect:${interaction.user.id}`
});
return interaction.update({ return interaction.update({
embeds: [ embeds: [embed],
embed
],
components: components:
buildCollectButtons() buildCollectButtons()
}); });
@@ -361,10 +361,6 @@ function getCollectOwner(
[]; [];
/*
* Main menu -> Cookie Bakery.
*/
if ( if (
parts[0] === parts[0] ===
"crumbSaucer" "crumbSaucer"
@@ -373,10 +369,6 @@ function getCollectOwner(
} }
/*
* Bakery page/result.
*/
if ( if (
parts[0] === parts[0] ===
"crumbSaucerCollect" "crumbSaucerCollect"
@@ -396,6 +388,15 @@ function getCollectOwner(
*/ */
module.exports = { module.exports = {
collectCookies,
buildCollectSuccessEmbed,
buildCollectCooldownEmbed,
showCollectPage, showCollectPage,
collectCookiesFromSaucer collectCookiesFromSaucer,
COLLECT_COOLDOWN,
COLLECT_MIN,
COLLECT_MAX
}; };