From 11fd8596158b869dd897834b2a74d7ac2fde03fe Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 10 May 2024 17:52:37 +0100 Subject: [PATCH 1/3] Create sacrifice command and embed --- src/commands/sacrifice.ts | 73 +++++++++++++++++++++++++++++++++++++ src/constants/CardRarity.ts | 17 +++++++++ src/registry.ts | 2 + 3 files changed, 92 insertions(+) create mode 100644 src/commands/sacrifice.ts diff --git a/src/commands/sacrifice.ts b/src/commands/sacrifice.ts new file mode 100644 index 0000000..96b3bf4 --- /dev/null +++ b/src/commands/sacrifice.ts @@ -0,0 +1,73 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CacheType, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import { Command } from "../type/command"; +import Inventory from "../database/entities/app/Inventory"; +import { CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity"; +import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; +import EmbedColours from "../constants/EmbedColours"; + +export default class Sacrifice extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("sacrifice") + .setDescription("Sacrifices a card for currency") + .addStringOption(x => + x + .setName("cardnumber") + .setDescription("The card to sacrifice from your inventory") + .setRequired(true)); + } + + public override async execute(interaction: CommandInteraction): Promise { + const cardnumber = interaction.options.get("cardnumber", true); + + const cardInInventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, cardnumber.value! as string); + + if (!cardInInventory || cardInInventory.Quantity == 0) { + await interaction.reply("Unable to find card in your inventory."); + return; + } + + const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardnumber.value! as string); + + if (!cardData) { + await interaction.reply("Unable to find card in the database."); + return; + } + + const cardValue = GetSacrificeAmount(cardData.card.type); + const cardRarityString = CardRarityToString(cardData.card.type); + + let description = [ + `Card: ${cardData.card.name}`, + `Series: ${cardData.series.name}`, + `Rarity: ${cardRarityString}`, + `Quantity Owned: ${cardInInventory.Quantity}`, + `Sacrifice Amount: ${cardValue}`, + ]; + + const embed = new EmbedBuilder() + .setTitle("Sacrifice") + .setDescription(description.join("\n")) + .setColor(EmbedColours.Grey) + .setFooter({ text: `${interaction.user.username} · ${cardData.card.name}` }); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setCustomId(`sacrifice confirm ${interaction.user.id} ${cardnumber.value!}`) + .setLabel("Confirm") + .setStyle(ButtonStyle.Success), + new ButtonBuilder() + .setCustomId(`sacrifice cancel`) + .setLabel("Cancel") + .setStyle(ButtonStyle.Secondary), + ]); + + await interaction.reply({ + embeds: [ embed ], + components: [ row ], + }); + } +} \ No newline at end of file diff --git a/src/constants/CardRarity.ts b/src/constants/CardRarity.ts index 8202a12..82ecee1 100644 --- a/src/constants/CardRarity.ts +++ b/src/constants/CardRarity.ts @@ -58,4 +58,21 @@ export function CardRarityParse(rarity: string): CardRarity { default: return CardRarity.Unknown; } +} + +export function GetSacrificeAmount(rarity: CardRarity): number { + switch (rarity) { + case CardRarity.Bronze: + return 5; + case CardRarity.Silver: + return 15; + case CardRarity.Gold: + return 30; + case CardRarity.Manga: + return 50; + case CardRarity.Legendary: + return 100; + default: + return 0; + } } \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index bb68685..1694e47 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -8,6 +8,7 @@ import Gdrivesync from "./commands/gdrivesync"; import Give from "./commands/give"; import Inventory from "./commands/inventory"; import Resync from "./commands/resync"; +import Sacrifice from "./commands/sacrifice"; import Series from "./commands/series"; import Trade from "./commands/trade"; import View from "./commands/view"; @@ -32,6 +33,7 @@ export default class Registry { CoreClient.RegisterCommand("give", new Give()); CoreClient.RegisterCommand("inventory", new Inventory()); CoreClient.RegisterCommand("resync", new Resync()); + CoreClient.RegisterCommand("sacrifice", new Sacrifice()); CoreClient.RegisterCommand("series", new Series()); CoreClient.RegisterCommand("trade", new Trade()); CoreClient.RegisterCommand("view", new View()); -- 2.43.4 From 94ad819c95bb67c8c07f643db39c38a7835f3883 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 16 May 2024 18:46:26 +0100 Subject: [PATCH 2/3] Add confirmation button event --- src/buttonEvents/Sacrifice.ts | 147 +++++++++++++++++++++++++ src/commands/sacrifice.ts | 2 +- src/database/entities/app/Inventory.ts | 6 + src/registry.ts | 2 + 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/buttonEvents/Sacrifice.ts diff --git a/src/buttonEvents/Sacrifice.ts b/src/buttonEvents/Sacrifice.ts new file mode 100644 index 0000000..440e37b --- /dev/null +++ b/src/buttonEvents/Sacrifice.ts @@ -0,0 +1,147 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder } from "discord.js"; +import { ButtonEvent } from "../type/buttonEvent"; +import Inventory from "../database/entities/app/Inventory"; +import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; +import { CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity"; +import EmbedColours from "../constants/EmbedColours"; +import User from "../database/entities/app/User"; + +export default class Sacrifice extends ButtonEvent { + public override async execute(interaction: ButtonInteraction) { + const subcommand = interaction.customId.split(" ")[1]; + + switch(subcommand) { + case "confirm": + await this.confirm(interaction); + break; + case "cancel": + await this.cancel(interaction); + break; + } + } + + private async confirm(interaction: ButtonInteraction) { + const userId = interaction.customId.split(" ")[2]; + const cardNumber = interaction.customId.split(" ")[3]; + + const cardInInventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); + + if (!cardInInventory) { + await interaction.reply("Unable to find card in inventory."); + return; + } + + const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + + if (!cardData) { + await interaction.reply("Unable to find card in the database."); + return; + } + + const user = await User.FetchOneById(User, userId); + + if (!user) { + await interaction.reply("Unable to find user in database."); + return; + } + + cardInInventory.RemoveQuantity(1); + + await cardInInventory.Save(Inventory, cardInInventory); + + const cardValue = GetSacrificeAmount(cardData.card.type); + const cardRarityString = CardRarityToString(cardData.card.type); + + user.AddCurrency(cardValue); + + await user.Save(User, user); + + let description = [ + `Card: ${cardData.card.name}`, + `Series: ${cardData.series.name}`, + `Rarity: ${cardRarityString}`, + `Quantity Owned: ${cardInInventory.Quantity}`, + `Sacrifice Amount: ${cardValue}`, + ]; + + const embed = new EmbedBuilder() + .setTitle("Card Sacrificed") + .setDescription(description.join("\n")) + .setColor(EmbedColours.Ok) + .setFooter({ text: `${interaction.user.username} · ${cardData.card.name}` }); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setCustomId(`sacrifice confirm ${interaction.user.id} ${cardNumber}`) + .setLabel("Confirm") + .setStyle(ButtonStyle.Success) + .setDisabled(true), + new ButtonBuilder() + .setCustomId(`sacrifice cancel`) + .setLabel("Cancel") + .setStyle(ButtonStyle.Secondary) + .setDisabled(true), + ]); + + await interaction.update({ + embeds: [ embed ], + components: [ row ], + }); + } + + private async cancel(interaction: ButtonInteraction) { + const userId = interaction.customId.split(" ")[2]; + const cardNumber = interaction.customId.split(" ")[3]; + + const cardInInventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); + + if (!cardInInventory) { + await interaction.reply("Unable to find card in inventory."); + return; + } + + const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + + if (!cardData) { + await interaction.reply("Unable to find card in the database."); + return; + } + + const cardValue = GetSacrificeAmount(cardData.card.type); + const cardRarityString = CardRarityToString(cardData.card.type); + + let description = [ + `Card: ${cardData.card.name}`, + `Series: ${cardData.series.name}`, + `Rarity: ${cardRarityString}`, + `Quantity Owned: ${cardInInventory.Quantity}`, + `Sacrifice Amount: ${cardValue}`, + ]; + + const embed = new EmbedBuilder() + .setTitle("Sacrifice Cancelled") + .setDescription(description.join("\n")) + .setColor(EmbedColours.Error) + .setFooter({ text: `${interaction.user.username} · ${cardData.card.name}` }); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setCustomId(`sacrifice confirm ${interaction.user.id} ${cardNumber}`) + .setLabel("Confirm") + .setStyle(ButtonStyle.Success) + .setDisabled(true), + new ButtonBuilder() + .setCustomId(`sacrifice cancel`) + .setLabel("Cancel") + .setStyle(ButtonStyle.Secondary) + .setDisabled(true), + ]); + + await interaction.update({ + embeds: [ embed ], + components: [ row ], + }); + } +} \ No newline at end of file diff --git a/src/commands/sacrifice.ts b/src/commands/sacrifice.ts index 96b3bf4..fb54c76 100644 --- a/src/commands/sacrifice.ts +++ b/src/commands/sacrifice.ts @@ -60,7 +60,7 @@ export default class Sacrifice extends Command { .setLabel("Confirm") .setStyle(ButtonStyle.Success), new ButtonBuilder() - .setCustomId(`sacrifice cancel`) + .setCustomId(`sacrifice cancel ${interaction.user.id} ${cardnumber.value!}`) .setLabel("Cancel") .setStyle(ButtonStyle.Secondary), ]); diff --git a/src/database/entities/app/Inventory.ts b/src/database/entities/app/Inventory.ts index bde4450..a5d0026 100644 --- a/src/database/entities/app/Inventory.ts +++ b/src/database/entities/app/Inventory.ts @@ -29,6 +29,12 @@ export default class Inventory extends AppBaseEntity { this.Quantity = quantity; } + public RemoveQuantity(amount: number) { + if (this.Quantity < amount) return; + + this.Quantity -= amount; + } + public AddClaim(claim: Claim) { this.Claims.push(claim); } diff --git a/src/registry.ts b/src/registry.ts index 1694e47..8e6a713 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -21,6 +21,7 @@ import Droprarity from "./commands/stage/droprarity"; import Claim from "./buttonEvents/Claim"; import InventoryButtonEvent from "./buttonEvents/Inventory"; import Reroll from "./buttonEvents/Reroll"; +import SacrificeButtonEvent from "./buttonEvents/Sacrifice"; import SeriesEvent from "./buttonEvents/Series"; import TradeButtonEvent from "./buttonEvents/Trade"; @@ -51,6 +52,7 @@ export default class Registry { CoreClient.RegisterButtonEvent("claim", new Claim()); CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent()); CoreClient.RegisterButtonEvent("reroll", new Reroll()); + CoreClient.RegisterButtonEvent("sacrifice", new SacrificeButtonEvent()); CoreClient.RegisterButtonEvent("series", new SeriesEvent()); CoreClient.RegisterButtonEvent("trade", new TradeButtonEvent()); } -- 2.43.4 From 43998fbfc83c24045fe49e7ef2703397f32cfee8 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 16 May 2024 18:47:43 +0100 Subject: [PATCH 3/3] Fix linting issues --- src/buttonEvents/Sacrifice.ts | 8 ++++---- src/commands/sacrifice.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/buttonEvents/Sacrifice.ts b/src/buttonEvents/Sacrifice.ts index 440e37b..6c4a1a6 100644 --- a/src/buttonEvents/Sacrifice.ts +++ b/src/buttonEvents/Sacrifice.ts @@ -56,7 +56,7 @@ export default class Sacrifice extends ButtonEvent { await user.Save(User, user); - let description = [ + const description = [ `Card: ${cardData.card.name}`, `Series: ${cardData.series.name}`, `Rarity: ${cardRarityString}`, @@ -78,7 +78,7 @@ export default class Sacrifice extends ButtonEvent { .setStyle(ButtonStyle.Success) .setDisabled(true), new ButtonBuilder() - .setCustomId(`sacrifice cancel`) + .setCustomId("sacrifice cancel") .setLabel("Cancel") .setStyle(ButtonStyle.Secondary) .setDisabled(true), @@ -111,7 +111,7 @@ export default class Sacrifice extends ButtonEvent { const cardValue = GetSacrificeAmount(cardData.card.type); const cardRarityString = CardRarityToString(cardData.card.type); - let description = [ + const description = [ `Card: ${cardData.card.name}`, `Series: ${cardData.series.name}`, `Rarity: ${cardRarityString}`, @@ -133,7 +133,7 @@ export default class Sacrifice extends ButtonEvent { .setStyle(ButtonStyle.Success) .setDisabled(true), new ButtonBuilder() - .setCustomId(`sacrifice cancel`) + .setCustomId("sacrifice cancel") .setLabel("Cancel") .setStyle(ButtonStyle.Secondary) .setDisabled(true), diff --git a/src/commands/sacrifice.ts b/src/commands/sacrifice.ts index fb54c76..c6dc7b3 100644 --- a/src/commands/sacrifice.ts +++ b/src/commands/sacrifice.ts @@ -39,7 +39,7 @@ export default class Sacrifice extends Command { const cardValue = GetSacrificeAmount(cardData.card.type); const cardRarityString = CardRarityToString(cardData.card.type); - let description = [ + const description = [ `Card: ${cardData.card.name}`, `Series: ${cardData.series.name}`, `Rarity: ${cardRarityString}`, -- 2.43.4