converted ShaiBot casino to Nut Economy
This commit is contained in:
@@ -0,0 +1,975 @@
|
||||
const {
|
||||
EmbedBuilder,
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle
|
||||
} = require("discord.js");
|
||||
|
||||
const {
|
||||
getNutBalance,
|
||||
transferNuts,
|
||||
temporaryEphemeralReply
|
||||
} = require("./nutEconomy");
|
||||
|
||||
|
||||
const ROULETTE_BETS = [
|
||||
10,
|
||||
50,
|
||||
100,
|
||||
500,
|
||||
1000
|
||||
];
|
||||
|
||||
|
||||
const CHOICES = {
|
||||
Red: {
|
||||
name:
|
||||
"Red",
|
||||
|
||||
emoji:
|
||||
"🔴",
|
||||
|
||||
multiplier:
|
||||
2
|
||||
},
|
||||
|
||||
Black: {
|
||||
name:
|
||||
"Black",
|
||||
|
||||
emoji:
|
||||
"⚫",
|
||||
|
||||
multiplier:
|
||||
2
|
||||
},
|
||||
|
||||
Odd: {
|
||||
name:
|
||||
"Odd",
|
||||
|
||||
emoji:
|
||||
"1️⃣",
|
||||
|
||||
multiplier:
|
||||
2
|
||||
},
|
||||
|
||||
Even: {
|
||||
name:
|
||||
"Even",
|
||||
|
||||
emoji:
|
||||
"2️⃣",
|
||||
|
||||
multiplier:
|
||||
2
|
||||
},
|
||||
|
||||
Zero: {
|
||||
name:
|
||||
"Zero",
|
||||
|
||||
emoji:
|
||||
"🟢",
|
||||
|
||||
multiplier:
|
||||
36
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const RED_NUMBERS =
|
||||
new Set([
|
||||
1,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
9,
|
||||
12,
|
||||
14,
|
||||
16,
|
||||
18,
|
||||
19,
|
||||
21,
|
||||
23,
|
||||
25,
|
||||
27,
|
||||
30,
|
||||
32,
|
||||
34,
|
||||
36
|
||||
]);
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* MENU
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
async function showNutRoulette(
|
||||
interaction
|
||||
) {
|
||||
const ownerId =
|
||||
getRouletteOwner(
|
||||
interaction
|
||||
);
|
||||
|
||||
|
||||
if (
|
||||
ownerId !==
|
||||
interaction.user.id
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Das ist nicht deine Nut-Hub-Session."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const balance =
|
||||
await getNutBalance(
|
||||
interaction.user.id
|
||||
);
|
||||
|
||||
|
||||
const embed =
|
||||
new EmbedBuilder()
|
||||
.setTitle(
|
||||
"🎡 Nut Roulette"
|
||||
)
|
||||
|
||||
.setDescription(
|
||||
[
|
||||
"European Roulette — **0 bis 36**.",
|
||||
"",
|
||||
"🔴 **Red** — x2",
|
||||
"⚫ **Black** — x2",
|
||||
"1️⃣ **Odd** — x2",
|
||||
"2️⃣ **Even** — x2",
|
||||
"🟢 **Zero** — x36",
|
||||
"",
|
||||
"Choose your wager."
|
||||
].join("\n")
|
||||
)
|
||||
|
||||
.addFields({
|
||||
name:
|
||||
"Deine Nüsse",
|
||||
|
||||
value:
|
||||
`${balance.toLocaleString()} 🥜`
|
||||
})
|
||||
|
||||
.setFooter({
|
||||
text:
|
||||
`nutRouletteMenu:${interaction.user.id}`
|
||||
});
|
||||
|
||||
|
||||
return interaction.update({
|
||||
embeds: [
|
||||
embed
|
||||
],
|
||||
|
||||
components:
|
||||
buildBetButtons()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* WAGER
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
async function chooseNutRouletteBet(
|
||||
interaction,
|
||||
bet
|
||||
) {
|
||||
const ownerId =
|
||||
getRouletteOwner(
|
||||
interaction
|
||||
);
|
||||
|
||||
|
||||
if (
|
||||
ownerId !==
|
||||
interaction.user.id
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Das ist nicht dein Roulette-Tisch."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
!ROULETTE_BETS.includes(
|
||||
bet
|
||||
)
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Dieser Einsatz ist ungültig."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const balance =
|
||||
await getNutBalance(
|
||||
interaction.user.id
|
||||
);
|
||||
|
||||
|
||||
if (
|
||||
balance <
|
||||
bet
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
`Du brauchst **${bet.toLocaleString()} Nüsse**.`
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const embed =
|
||||
new EmbedBuilder()
|
||||
.setTitle(
|
||||
"🎡 Nut Roulette"
|
||||
)
|
||||
|
||||
.setDescription(
|
||||
[
|
||||
`Einsatz: **${bet.toLocaleString()} 🥜**`,
|
||||
"",
|
||||
"Wo sollen deine Nüsse landen?",
|
||||
"",
|
||||
"🔴 Red",
|
||||
"⚫ Black",
|
||||
"1️⃣ Odd",
|
||||
"2️⃣ Even",
|
||||
"🟢 Zero"
|
||||
].join("\n")
|
||||
)
|
||||
|
||||
.setFooter({
|
||||
text:
|
||||
`nutRouletteBet:${interaction.user.id}:${bet}`
|
||||
});
|
||||
|
||||
|
||||
return interaction.update({
|
||||
embeds: [
|
||||
embed
|
||||
],
|
||||
|
||||
components:
|
||||
buildChoiceButtons()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* PLAY
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
async function playNutRoulette(
|
||||
interaction,
|
||||
choiceKey
|
||||
) {
|
||||
const choice =
|
||||
CHOICES[
|
||||
choiceKey
|
||||
];
|
||||
|
||||
|
||||
if (!choice) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Diese Roulette-Wette existiert nicht."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const footer =
|
||||
interaction.message
|
||||
?.embeds?.[0]
|
||||
?.footer
|
||||
?.text;
|
||||
|
||||
|
||||
const parts =
|
||||
footer?.split(":")
|
||||
??
|
||||
[];
|
||||
|
||||
|
||||
if (
|
||||
parts[0] !==
|
||||
"nutRouletteBet"
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Diese Roulette-Wette ist nicht mehr gültig."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const ownerId =
|
||||
parts[1];
|
||||
|
||||
|
||||
const bet =
|
||||
Number(
|
||||
parts[2]
|
||||
);
|
||||
|
||||
|
||||
if (
|
||||
ownerId !==
|
||||
interaction.user.id
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Das ist nicht dein Roulette-Tisch."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const playerId =
|
||||
interaction.user.id;
|
||||
|
||||
|
||||
const houseId =
|
||||
interaction.client.user.id;
|
||||
|
||||
|
||||
const [
|
||||
playerBalance,
|
||||
houseBalance
|
||||
] =
|
||||
await Promise.all([
|
||||
getNutBalance(
|
||||
playerId
|
||||
),
|
||||
|
||||
getNutBalance(
|
||||
houseId
|
||||
)
|
||||
]);
|
||||
|
||||
|
||||
if (
|
||||
playerBalance <
|
||||
bet
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Du hast nicht mehr genug Nüsse."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const maxPayout =
|
||||
bet *
|
||||
choice.multiplier;
|
||||
|
||||
|
||||
if (
|
||||
houseBalance +
|
||||
bet <
|
||||
maxPayout
|
||||
) {
|
||||
return temporaryEphemeralReply(
|
||||
interaction,
|
||||
{
|
||||
content:
|
||||
"Der Nut Vault kann diesen Einsatz nicht absichern."
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
await transferNuts(
|
||||
playerId,
|
||||
houseId,
|
||||
bet
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Pseudo animation.
|
||||
*/
|
||||
|
||||
await interaction.update({
|
||||
embeds: [
|
||||
buildSpinEmbed(
|
||||
choice,
|
||||
bet,
|
||||
randomRouletteNumber(),
|
||||
"Das Rad beginnt sich zu drehen..."
|
||||
)
|
||||
],
|
||||
|
||||
components: []
|
||||
});
|
||||
|
||||
|
||||
await delay(
|
||||
650
|
||||
);
|
||||
|
||||
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
buildSpinEmbed(
|
||||
choice,
|
||||
bet,
|
||||
randomRouletteNumber(),
|
||||
"Round and round..."
|
||||
)
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
await delay(
|
||||
650
|
||||
);
|
||||
|
||||
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
buildSpinEmbed(
|
||||
choice,
|
||||
bet,
|
||||
randomRouletteNumber(),
|
||||
"Die Kugel wird langsamer..."
|
||||
)
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
await delay(
|
||||
750
|
||||
);
|
||||
|
||||
|
||||
const result =
|
||||
randomRouletteNumber();
|
||||
|
||||
|
||||
const won =
|
||||
didBetWin(
|
||||
choiceKey,
|
||||
result
|
||||
);
|
||||
|
||||
|
||||
const payout =
|
||||
won
|
||||
? bet *
|
||||
choice.multiplier
|
||||
: 0;
|
||||
|
||||
|
||||
if (
|
||||
payout >
|
||||
0
|
||||
) {
|
||||
await transferNuts(
|
||||
houseId,
|
||||
playerId,
|
||||
payout
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const balance =
|
||||
await getNutBalance(
|
||||
playerId
|
||||
);
|
||||
|
||||
|
||||
const profit =
|
||||
payout -
|
||||
bet;
|
||||
|
||||
|
||||
const embed =
|
||||
new EmbedBuilder()
|
||||
.setTitle(
|
||||
won
|
||||
? "🎉 Nut Roulette — WIN!"
|
||||
: "🎡 Nut Roulette"
|
||||
)
|
||||
|
||||
.setDescription(
|
||||
[
|
||||
"## Die Kugel landet auf...",
|
||||
"",
|
||||
`# ${formatRouletteNumber(result)}`,
|
||||
"",
|
||||
`${choice.emoji} Deine Wette: **${choice.name}**`,
|
||||
"",
|
||||
won
|
||||
? `🎉 **${payout.toLocaleString()} Nüsse gewonnen!**`
|
||||
: "Das Haus gewinnt."
|
||||
].join("\n")
|
||||
)
|
||||
|
||||
.addFields(
|
||||
{
|
||||
name:
|
||||
"Einsatz",
|
||||
|
||||
value:
|
||||
`${bet.toLocaleString()} 🥜`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
|
||||
{
|
||||
name:
|
||||
"Payout",
|
||||
|
||||
value:
|
||||
`${payout.toLocaleString()} 🥜`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
|
||||
{
|
||||
name:
|
||||
"Profit",
|
||||
|
||||
value:
|
||||
`${profit >= 0 ? "+" : ""}${profit.toLocaleString()} 🥜`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
|
||||
{
|
||||
name:
|
||||
"Deine Nüsse",
|
||||
|
||||
value:
|
||||
`${balance.toLocaleString()} 🥜`
|
||||
}
|
||||
)
|
||||
|
||||
.setFooter({
|
||||
text:
|
||||
`nutRouletteResult:${playerId}`
|
||||
});
|
||||
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
embed
|
||||
],
|
||||
|
||||
components:
|
||||
buildResultButtons()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* RULES
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
function didBetWin(
|
||||
choice,
|
||||
number
|
||||
) {
|
||||
if (
|
||||
number ===
|
||||
0
|
||||
) {
|
||||
return choice ===
|
||||
"Zero";
|
||||
}
|
||||
|
||||
|
||||
switch (choice) {
|
||||
case "Red":
|
||||
return RED_NUMBERS.has(
|
||||
number
|
||||
);
|
||||
|
||||
case "Black":
|
||||
return !RED_NUMBERS.has(
|
||||
number
|
||||
);
|
||||
|
||||
case "Odd":
|
||||
return number %
|
||||
2 ===
|
||||
1;
|
||||
|
||||
case "Even":
|
||||
return number %
|
||||
2 ===
|
||||
0;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function formatRouletteNumber(
|
||||
number
|
||||
) {
|
||||
if (
|
||||
number ===
|
||||
0
|
||||
) {
|
||||
return "🟢 0";
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
RED_NUMBERS.has(
|
||||
number
|
||||
)
|
||||
) {
|
||||
return `🔴 ${number}`;
|
||||
}
|
||||
|
||||
|
||||
return `⚫ ${number}`;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* DISPLAY
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
function buildSpinEmbed(
|
||||
choice,
|
||||
bet,
|
||||
number,
|
||||
text
|
||||
) {
|
||||
return new EmbedBuilder()
|
||||
.setTitle(
|
||||
"🎡 Nut Roulette"
|
||||
)
|
||||
|
||||
.setDescription(
|
||||
[
|
||||
"## 🎡 Spinning...",
|
||||
"",
|
||||
`### ${formatRouletteNumber(number)}`,
|
||||
"",
|
||||
`**${text}**`
|
||||
].join("\n")
|
||||
)
|
||||
|
||||
.addFields(
|
||||
{
|
||||
name:
|
||||
"Wette",
|
||||
|
||||
value:
|
||||
`${choice.emoji} ${choice.name}`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
|
||||
{
|
||||
name:
|
||||
"Einsatz",
|
||||
|
||||
value:
|
||||
`${bet.toLocaleString()} 🥜`,
|
||||
|
||||
inline:
|
||||
true
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* BUTTONS
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
function buildBetButtons() {
|
||||
return [
|
||||
new ActionRowBuilder()
|
||||
.addComponents(
|
||||
...ROULETTE_BETS.map(
|
||||
bet =>
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
`nutRouletteBet${bet}`
|
||||
)
|
||||
.setLabel(
|
||||
bet.toLocaleString()
|
||||
)
|
||||
.setEmoji(
|
||||
"🥜"
|
||||
)
|
||||
.setStyle(
|
||||
bet >=
|
||||
500
|
||||
? ButtonStyle.Primary
|
||||
: ButtonStyle.Secondary
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutHubBack"
|
||||
)
|
||||
.setLabel(
|
||||
"Nut Hub"
|
||||
)
|
||||
.setEmoji(
|
||||
"◀️"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Secondary
|
||||
)
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
function buildChoiceButtons() {
|
||||
return [
|
||||
new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutRouletteRed"
|
||||
)
|
||||
.setLabel(
|
||||
"Red"
|
||||
)
|
||||
.setEmoji(
|
||||
"🔴"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Danger
|
||||
),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutRouletteBlack"
|
||||
)
|
||||
.setLabel(
|
||||
"Black"
|
||||
)
|
||||
.setEmoji(
|
||||
"⚫"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Secondary
|
||||
),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutRouletteOdd"
|
||||
)
|
||||
.setLabel(
|
||||
"Odd"
|
||||
)
|
||||
.setEmoji(
|
||||
"1️⃣"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Primary
|
||||
),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutRouletteEven"
|
||||
)
|
||||
.setLabel(
|
||||
"Even"
|
||||
)
|
||||
.setEmoji(
|
||||
"2️⃣"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Primary
|
||||
),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutRouletteZero"
|
||||
)
|
||||
.setLabel(
|
||||
"Zero"
|
||||
)
|
||||
.setEmoji(
|
||||
"🟢"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Success
|
||||
)
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
function buildResultButtons() {
|
||||
return [
|
||||
new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutHubRoulette"
|
||||
)
|
||||
.setLabel(
|
||||
"Play Again"
|
||||
)
|
||||
.setEmoji(
|
||||
"🎡"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Primary
|
||||
),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"nutHubBack"
|
||||
)
|
||||
.setLabel(
|
||||
"Nut Hub"
|
||||
)
|
||||
.setEmoji(
|
||||
"◀️"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Secondary
|
||||
)
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* OWNERSHIP
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
function getRouletteOwner(
|
||||
interaction
|
||||
) {
|
||||
const footer =
|
||||
interaction.message
|
||||
?.embeds?.[0]
|
||||
?.footer
|
||||
?.text;
|
||||
|
||||
|
||||
const parts =
|
||||
footer?.split(":")
|
||||
??
|
||||
[];
|
||||
|
||||
|
||||
if (
|
||||
parts[0] ===
|
||||
"nutHub"
|
||||
) {
|
||||
return parts[1];
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
parts[0] ===
|
||||
"nutRouletteMenu"
|
||||
||
|
||||
parts[0] ===
|
||||
"nutRouletteResult"
|
||||
) {
|
||||
return parts[1];
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
parts[0] ===
|
||||
"nutRouletteBet"
|
||||
) {
|
||||
return parts[1];
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function randomRouletteNumber() {
|
||||
return Math.floor(
|
||||
Math.random() *
|
||||
37
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function delay(
|
||||
ms
|
||||
) {
|
||||
return new Promise(
|
||||
resolve =>
|
||||
setTimeout(
|
||||
resolve,
|
||||
ms
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
showNutRoulette,
|
||||
chooseNutRouletteBet,
|
||||
playNutRoulette
|
||||
};
|
||||
Reference in New Issue
Block a user