diff --git a/src/buttonEvents/Sacrifice.ts b/src/buttonEvents/Sacrifice.ts new file mode 100644 index 0000000..6c4a1a6 --- /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); + + const 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); + + const 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 new file mode 100644 index 0000000..c6dc7b3 --- /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); + + const 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 ${interaction.user.id} ${cardnumber.value!}`) + .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/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 3ea5528..15202c5 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"; @@ -20,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"; @@ -32,6 +34,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()); @@ -45,6 +48,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()); }