From 31cc9e056a372e4bed8309a0d711ec305f855bec Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 10 Jan 2025 18:23:17 +0000 Subject: [PATCH] WIP: Fix some of the suggested changes --- src/buttonEvents/Claim.ts | 9 +- src/buttonEvents/Effects.ts | 152 +---------- src/buttonEvents/Effects/List.ts | 20 ++ src/buttonEvents/Effects/Use.ts | 125 ++++++++++ src/buttonEvents/Multidrop.ts | 19 +- src/buttonEvents/Reroll.ts | 9 +- src/buttonEvents/Sacrifice.ts | 6 +- src/commands/drop.ts | 12 +- src/commands/effects.ts | 9 +- src/commands/give.ts | 4 +- src/commands/id.ts | 4 +- src/commands/multidrop.ts | 9 +- src/commands/sacrifice.ts | 4 +- src/commands/stage/dropnumber.ts | 6 +- src/commands/stage/droprarity.ts | 9 +- src/constants/CardConstants.ts | 2 +- src/helpers/CardDropHelperMetadata.ts | 235 ------------------ src/helpers/CardSearchHelper.ts | 15 +- src/helpers/DropHelpers/DropEmbedHelper.ts | 79 ++++++ src/helpers/DropHelpers/GetCardsHelper.ts | 78 ++++++ .../DropHelpers/GetUnclaimedCardsHelper.ts | 69 +++++ .../DropHelpers/MultidropEmbedHelper.ts | 28 +++ 22 files changed, 469 insertions(+), 434 deletions(-) create mode 100644 src/buttonEvents/Effects/List.ts create mode 100644 src/buttonEvents/Effects/Use.ts delete mode 100644 src/helpers/CardDropHelperMetadata.ts create mode 100644 src/helpers/DropHelpers/DropEmbedHelper.ts create mode 100644 src/helpers/DropHelpers/GetCardsHelper.ts create mode 100644 src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts create mode 100644 src/helpers/DropHelpers/MultidropEmbedHelper.ts diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 522ab40..27b82b1 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -4,9 +4,10 @@ import Inventory from "../database/entities/app/Inventory"; import { CoreClient } from "../client/client"; import { default as eClaim } from "../database/entities/app/Claim"; import AppLogger from "../client/appLogger"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Claim extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -69,7 +70,7 @@ export default class Claim extends ButtonEvent { await claim.Save(eClaim, claim); - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!card) { return; @@ -77,8 +78,8 @@ export default class Claim extends ButtonEvent { const imageFileName = card.card.path.split("/").pop()!; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, inventory.Quantity, imageFileName, interaction.user.username, user.Currency); - const row = CardDropHelperMetadata.GenerateDropButtons(card, claimId, interaction.user.id, true); + const embed = DropEmbedHelper.GenerateDropEmbed(card, inventory.Quantity, imageFileName, interaction.user.username, user.Currency); + const row = DropEmbedHelper.GenerateDropButtons(card, claimId, interaction.user.id, true); await interaction.editReply({ embeds: [ embed ], diff --git a/src/buttonEvents/Effects.ts b/src/buttonEvents/Effects.ts index 8607493..5fb1bb8 100644 --- a/src/buttonEvents/Effects.ts +++ b/src/buttonEvents/Effects.ts @@ -1,9 +1,7 @@ -import {ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder} from "discord.js"; -import {ButtonEvent} from "../type/buttonEvent"; -import EffectHelper from "../helpers/EffectHelper"; -import { EffectDetails } from "../constants/EffectDetails"; -import TimeLengthInput from "../helpers/TimeLengthInput"; -import EmbedColours from "../constants/EmbedColours"; +import { ButtonInteraction } from "discord.js"; +import { ButtonEvent } from "../type/buttonEvent"; +import List from "./Effects/List"; +import Use from "./Effects/Use"; export default class Effects extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -11,149 +9,11 @@ export default class Effects extends ButtonEvent { switch (action) { case "list": - await this.List(interaction); + await List(interaction); break; case "use": - await this.Use(interaction); + await Use(interaction); break; } } - - public async List(interaction: ButtonInteraction) { - const pageOption = interaction.customId.split(" ")[2]; - - const page = Number(pageOption); - - if (!page) { - await interaction.reply("Page option is not a valid number"); - return; - } - - const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); - - await interaction.update({ - embeds: [ result.embed ], - components: [ result.row ], - }); - } - - public async Use(interaction: ButtonInteraction) { - const subaction = interaction.customId.split(" ")[2]; - - switch (subaction) { - case "confirm": - await this.UseConfirm(interaction); - break; - case "cancel": - await this.UseCancel(interaction); - break; - } - } - - public async UseConfirm(interaction: ButtonInteraction) { - const id = interaction.customId.split(" ")[3]; - - const effectDetail = EffectDetails.get(id); - - if (!effectDetail) { - await interaction.reply("Effect not found in system!"); - return; - } - - const now = new Date(); - - const whenExpires = new Date(now.getTime() + effectDetail.duration); - - const result = await EffectHelper.UseEffect(interaction.user.id, id, whenExpires); - - if (result) { - const embed = new EmbedBuilder() - .setTitle("Effect Used") - .setDescription("You now have an active effect!") - .setColor(EmbedColours.Green) - .addFields([ - { - name: "Effect", - value: effectDetail.friendlyName, - inline: true, - }, - { - name: "Expires", - value: ``, - inline: true, - }, - ]); - - const row = new ActionRowBuilder() - .addComponents([ - new ButtonBuilder() - .setLabel("Confirm") - .setCustomId(`effects use confirm ${effectDetail.id}`) - .setStyle(ButtonStyle.Primary) - .setDisabled(true), - new ButtonBuilder() - .setLabel("Cancel") - .setCustomId(`effects use cancel ${effectDetail.id}`) - .setStyle(ButtonStyle.Danger) - .setDisabled(true), - ]); - - await interaction.update({ - embeds: [ embed ], - components: [ row ], - }); - return; - } - - await interaction.reply("Unable to use effect! Please make sure you have it in your inventory and is not on cooldown"); - } - - public async UseCancel(interaction: ButtonInteraction) { - const id = interaction.customId.split(" ")[3]; - - const effectDetail = EffectDetails.get(id); - - if (!effectDetail) { - await interaction.reply("Effect not found in system!"); - return; - } - - const timeLengthInput = TimeLengthInput.ConvertFromMilliseconds(effectDetail.duration); - - const embed = new EmbedBuilder() - .setTitle("Effect Use Cancelled") - .setDescription("The effect from your inventory has not been used") - .setColor(EmbedColours.Grey) - .addFields([ - { - name: "Effect", - value: effectDetail.friendlyName, - inline: true, - }, - { - name: "Expires", - value: timeLengthInput.GetLengthShort(), - inline: true, - }, - ]); - - const row = new ActionRowBuilder() - .addComponents([ - new ButtonBuilder() - .setLabel("Confirm") - .setCustomId(`effects use confirm ${effectDetail.id}`) - .setStyle(ButtonStyle.Primary) - .setDisabled(true), - new ButtonBuilder() - .setLabel("Cancel") - .setCustomId(`effects use cancel ${effectDetail.id}`) - .setStyle(ButtonStyle.Danger) - .setDisabled(true), - ]); - - await interaction.update({ - embeds: [ embed ], - components: [ row ], - }); - } } diff --git a/src/buttonEvents/Effects/List.ts b/src/buttonEvents/Effects/List.ts new file mode 100644 index 0000000..059623b --- /dev/null +++ b/src/buttonEvents/Effects/List.ts @@ -0,0 +1,20 @@ +import { ButtonInteraction } from "discord.js"; +import EffectHelper from "../../helpers/EffectHelper"; + +export default async function List(interaction: ButtonInteraction) { + const pageOption = interaction.customId.split(" ")[2]; + + const page = Number(pageOption); + + if (!page) { + await interaction.reply("Page option is not a valid number"); + return; + } + + const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); + + await interaction.update({ + embeds: [ result.embed ], + components: [ result.row ], + }); +} \ No newline at end of file diff --git a/src/buttonEvents/Effects/Use.ts b/src/buttonEvents/Effects/Use.ts new file mode 100644 index 0000000..25c2ba2 --- /dev/null +++ b/src/buttonEvents/Effects/Use.ts @@ -0,0 +1,125 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder } from "discord.js"; +import { EffectDetails } from "../../constants/EffectDetails"; +import EffectHelper from "../../helpers/EffectHelper"; +import EmbedColours from "../../constants/EmbedColours"; +import TimeLengthInput from "../../helpers/TimeLengthInput"; + +export default async function Use(interaction: ButtonInteraction) { + const subaction = interaction.customId.split(" ")[2]; + + switch (subaction) { + case "confirm": + await UseConfirm(interaction); + break; + case "cancel": + await UseCancel(interaction); + break; + } +} + +export async function UseConfirm(interaction: ButtonInteraction) { + const id = interaction.customId.split(" ")[3]; + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + await interaction.reply("Effect not found in system!"); + return; + } + + const now = new Date(); + + const whenExpires = new Date(now.getTime() + effectDetail.duration); + + const result = await EffectHelper.UseEffect(interaction.user.id, id, whenExpires); + + if (result) { + const embed = new EmbedBuilder() + .setTitle("Effect Used") + .setDescription("You now have an active effect!") + .setColor(EmbedColours.Green) + .addFields([ + { + name: "Effect", + value: effectDetail.friendlyName, + inline: true, + }, + { + name: "Expires", + value: ``, + inline: true, + }, + ]); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setLabel("Confirm") + .setCustomId(`effects use confirm ${effectDetail.id}`) + .setStyle(ButtonStyle.Primary) + .setDisabled(true), + new ButtonBuilder() + .setLabel("Cancel") + .setCustomId(`effects use cancel ${effectDetail.id}`) + .setStyle(ButtonStyle.Danger) + .setDisabled(true), + ]); + + await interaction.update({ + embeds: [ embed ], + components: [ row ], + }); + return; + } + + await interaction.reply("Unable to use effect! Please make sure you have it in your inventory and is not on cooldown"); +} + +export async function UseCancel(interaction: ButtonInteraction) { + const id = interaction.customId.split(" ")[3]; + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + await interaction.reply("Effect not found in system!"); + return; + } + + const timeLengthInput = TimeLengthInput.ConvertFromMilliseconds(effectDetail.duration); + + const embed = new EmbedBuilder() + .setTitle("Effect Use Cancelled") + .setDescription("The effect from your inventory has not been used") + .setColor(EmbedColours.Grey) + .addFields([ + { + name: "Effect", + value: effectDetail.friendlyName, + inline: true, + }, + { + name: "Expires", + value: timeLengthInput.GetLengthShort(), + inline: true, + }, + ]); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setLabel("Confirm") + .setCustomId(`effects use confirm ${effectDetail.id}`) + .setStyle(ButtonStyle.Primary) + .setDisabled(true), + new ButtonBuilder() + .setLabel("Cancel") + .setCustomId(`effects use cancel ${effectDetail.id}`) + .setStyle(ButtonStyle.Danger) + .setDisabled(true), + ]); + + await interaction.update({ + embeds: [ embed ], + components: [ row ], + }); +} \ No newline at end of file diff --git a/src/buttonEvents/Multidrop.ts b/src/buttonEvents/Multidrop.ts index 604f02c..e6ea7c2 100644 --- a/src/buttonEvents/Multidrop.ts +++ b/src/buttonEvents/Multidrop.ts @@ -1,7 +1,6 @@ import { AttachmentBuilder, ButtonInteraction, EmbedBuilder } from "discord.js"; import { ButtonEvent } from "../type/buttonEvent"; import AppLogger from "../client/appLogger"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import Inventory from "../database/entities/app/Inventory"; import EmbedColours from "../constants/EmbedColours"; import { readFileSync } from "fs"; @@ -9,6 +8,8 @@ import path from "path"; import ErrorMessages from "../constants/ErrorMessages"; import User from "../database/entities/app/User"; import { GetSacrificeAmount } from "../constants/CardRarity"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import MultidropEmbedHelper from "../helpers/DropHelpers/MultidropEmbedHelper"; export default class Multidrop extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -37,7 +38,7 @@ export default class Multidrop extends ButtonEvent { return; } - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!card) { await interaction.reply("Unable to find card."); @@ -85,7 +86,7 @@ export default class Multidrop extends ButtonEvent { } // Drop next card - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = GetCardsHelper.GetRandomCard(); cardsRemaining -= 1; if (!randomCard) { @@ -105,9 +106,9 @@ export default class Multidrop extends ButtonEvent { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + const embed = MultidropEmbedHelper.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); - const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); + const row = MultidropEmbedHelper.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); await interaction.editReply({ embeds: [ embed ], @@ -131,7 +132,7 @@ export default class Multidrop extends ButtonEvent { return; } - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!card) { await interaction.reply("Unable to find card."); @@ -175,7 +176,7 @@ export default class Multidrop extends ButtonEvent { } // Drop next card - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = GetCardsHelper.GetRandomCard(); cardsRemaining -= 1; if (!randomCard) { @@ -195,9 +196,9 @@ export default class Multidrop extends ButtonEvent { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + const embed = MultidropEmbedHelper.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); - const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); + const row = MultidropEmbedHelper.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); await interaction.editReply({ embeds: [ embed ], diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index 12578db..814cccc 100644 --- a/src/buttonEvents/Reroll.ts +++ b/src/buttonEvents/Reroll.ts @@ -5,11 +5,12 @@ import { v4 } from "uuid"; import { CoreClient } from "../client/client"; import Inventory from "../database/entities/app/Inventory"; import Config from "../database/entities/app/Config"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import path from "path"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Reroll extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -39,7 +40,7 @@ export default class Reroll extends ButtonEvent { return; } - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = GetCardsHelper.GetRandomCard(); if (!randomCard) { await interaction.reply("Unable to fetch card, please try again."); @@ -59,11 +60,11 @@ export default class Reroll extends ButtonEvent { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); + const embed = DropEmbedHelper.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons(randomCard, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons(randomCard, claimId, interaction.user.id); await interaction.editReply({ embeds: [ embed ], diff --git a/src/buttonEvents/Sacrifice.ts b/src/buttonEvents/Sacrifice.ts index 463ca1f..de0bb77 100644 --- a/src/buttonEvents/Sacrifice.ts +++ b/src/buttonEvents/Sacrifice.ts @@ -1,10 +1,10 @@ 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"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; export default class Sacrifice extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -42,7 +42,7 @@ export default class Sacrifice extends ButtonEvent { return; } - const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const cardData = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!cardData) { await interaction.reply("Unable to find card in the database."); @@ -124,7 +124,7 @@ export default class Sacrifice extends ButtonEvent { return; } - const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const cardData = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!cardData) { await interaction.reply("Unable to find card in the database."); diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 8d82d81..bd4d3f6 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -5,7 +5,6 @@ import { CoreClient } from "../client/client"; import { v4 } from "uuid"; import Inventory from "../database/entities/app/Inventory"; import Config from "../database/entities/app/Config"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import path from "path"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; @@ -13,6 +12,9 @@ import CardConstants from "../constants/CardConstants"; import ErrorMessages from "../constants/ErrorMessages"; import { DropResult } from "../contracts/SeriesMetadata"; import EffectHelper from "../helpers/EffectHelper"; +import GetUnclaimedCardsHelper from "../helpers/DropHelpers/GetUnclaimedCardsHelper"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Drop extends Command { constructor() { @@ -54,9 +56,9 @@ export default class Drop extends Command { const hasChanceUpEffect = await EffectHelper.HasEffect(interaction.user.id, "unclaimed"); if (hasChanceUpEffect && Math.random() <= CardConstants.UnusedChanceUpChance) { - randomCard = await CardDropHelperMetadata.GetRandomCardUnclaimed(interaction.user.id); + randomCard = await GetUnclaimedCardsHelper.GetRandomCardUnclaimed(interaction.user.id); } else { - randomCard = CardDropHelperMetadata.GetRandomCard(); + randomCard = GetCardsHelper.GetRandomCard(); } if (!randomCard) { @@ -76,11 +78,11 @@ export default class Drop extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); + const embed = DropEmbedHelper.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons(randomCard, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons(randomCard, claimId, interaction.user.id); await interaction.editReply({ embeds: [ embed ], diff --git a/src/commands/effects.ts b/src/commands/effects.ts index bc4f743..98727b9 100644 --- a/src/commands/effects.ts +++ b/src/commands/effects.ts @@ -1,9 +1,10 @@ -import {ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder} from "discord.js"; -import {Command} from "../type/command"; +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import { Command } from "../type/command"; import EffectHelper from "../helpers/EffectHelper"; -import {EffectDetails} from "../constants/EffectDetails"; +import { EffectDetails } from "../constants/EffectDetails"; import TimeLengthInput from "../helpers/TimeLengthInput"; import EmbedColours from "../constants/EmbedColours"; +import AppLogger from "../client/appLogger"; export default class Effects extends Command { constructor() { @@ -65,6 +66,8 @@ export default class Effects extends Command { const effectDetail = EffectDetails.get(id); if (!effectDetail) { + AppLogger.LogWarn("Commands/Effects", `Unable to find effect details for ${id}`); + await interaction.reply("Unable to find effect!"); return; } diff --git a/src/commands/give.ts b/src/commands/give.ts index 3ffbe8f..35dfa04 100644 --- a/src/commands/give.ts +++ b/src/commands/give.ts @@ -2,10 +2,10 @@ import { CacheType, CommandInteraction, PermissionsBitField, SlashCommandBuilder import { Command } from "../type/command"; import { CoreClient } from "../client/client"; import Config from "../database/entities/app/Config"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import Inventory from "../database/entities/app/Inventory"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; export default class Give extends Command { constructor() { @@ -81,7 +81,7 @@ export default class Give extends Command { AppLogger.LogSilly("Commands/Give/GiveCard", `Parameters: cardNumber=${cardNumber.value}, user=${user.id}`); - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber.value!.toString()); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber.value!.toString()); if (!card) { await interaction.reply("Unable to fetch card, please try again."); diff --git a/src/commands/id.ts b/src/commands/id.ts index ae924a6..072553d 100644 --- a/src/commands/id.ts +++ b/src/commands/id.ts @@ -4,8 +4,8 @@ import { CoreClient } from "../client/client"; import { readFileSync } from "fs"; import path from "path"; import Inventory from "../database/entities/app/Inventory"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import AppLogger from "../client/appLogger"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Id extends Command { constructor() { @@ -62,7 +62,7 @@ export default class Id extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); try { await interaction.editReply({ diff --git a/src/commands/multidrop.ts b/src/commands/multidrop.ts index f35b921..aa42686 100644 --- a/src/commands/multidrop.ts +++ b/src/commands/multidrop.ts @@ -6,10 +6,11 @@ import Config from "../database/entities/app/Config"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import { readFileSync } from "fs"; import path from "path"; import Inventory from "../database/entities/app/Inventory"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import MultidropEmbedHelper from "../helpers/DropHelpers/MultidropEmbedHelper"; export default class Multidrop extends Command { constructor() { @@ -49,7 +50,7 @@ export default class Multidrop extends Command { user.RemoveCurrency(CardConstants.MultidropCost); await user.Save(User, user); - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = GetCardsHelper.GetRandomCard(); const cardsRemaining = CardConstants.MultidropQuantity - 1; if (!randomCard) { @@ -69,9 +70,9 @@ export default class Multidrop extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + const embed = MultidropEmbedHelper.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); - const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id); + const row = MultidropEmbedHelper.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id); await interaction.editReply({ embeds: [ embed ], diff --git a/src/commands/sacrifice.ts b/src/commands/sacrifice.ts index 9683714..a44a69e 100644 --- a/src/commands/sacrifice.ts +++ b/src/commands/sacrifice.ts @@ -2,8 +2,8 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CacheType, CommandInterac 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"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; export default class Sacrifice extends Command { constructor() { @@ -41,7 +41,7 @@ export default class Sacrifice extends Command { return; } - const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardnumber.value! as string); + const cardData = GetCardsHelper.GetCardByCardNumber(cardnumber.value! as string); if (!cardData) { await interaction.reply("Unable to find card in the database."); diff --git a/src/commands/stage/dropnumber.ts b/src/commands/stage/dropnumber.ts index 0642327..6819a5c 100644 --- a/src/commands/stage/dropnumber.ts +++ b/src/commands/stage/dropnumber.ts @@ -5,7 +5,7 @@ import Inventory from "../../database/entities/app/Inventory"; import { v4 } from "uuid"; import { CoreClient } from "../../client/client"; import path from "path"; -import CardDropHelperMetadata from "../../helpers/CardDropHelperMetadata"; +import DropEmbedHelper from "../../helpers/DropHelpers/DropEmbedHelper"; export default class Dropnumber extends Command { constructor() { @@ -60,11 +60,11 @@ export default class Dropnumber extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons({ card, series }, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons({ card, series }, claimId, interaction.user.id); try { await interaction.editReply({ diff --git a/src/commands/stage/droprarity.ts b/src/commands/stage/droprarity.ts index be0a62d..517a443 100644 --- a/src/commands/stage/droprarity.ts +++ b/src/commands/stage/droprarity.ts @@ -5,8 +5,9 @@ import { readFileSync } from "fs"; import Inventory from "../../database/entities/app/Inventory"; import { v4 } from "uuid"; import { CoreClient } from "../../client/client"; -import CardDropHelperMetadata from "../../helpers/CardDropHelperMetadata"; import path from "path"; +import GetCardsHelper from "../../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../../helpers/DropHelpers/DropEmbedHelper"; export default class Droprarity extends Command { constructor() { @@ -39,7 +40,7 @@ export default class Droprarity extends Command { return; } - const card = await CardDropHelperMetadata.GetRandomCardByRarity(rarityType); + const card = await GetCardsHelper.GetRandomCardByRarity(rarityType); if (!card) { await interaction.reply("Card not found"); @@ -63,11 +64,11 @@ export default class Droprarity extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed(card, quantityClaimed, imageFileName); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons(card, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons(card, claimId, interaction.user.id); try { await interaction.editReply({ diff --git a/src/constants/CardConstants.ts b/src/constants/CardConstants.ts index 9330111..60a7f59 100644 --- a/src/constants/CardConstants.ts +++ b/src/constants/CardConstants.ts @@ -9,5 +9,5 @@ export default class CardConstants { public static readonly MultidropQuantity = 11; // Effects - public static readonly UnusedChanceUpChance = 1; + public static readonly UnusedChanceUpChance = 0.5; } \ No newline at end of file diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts deleted file mode 100644 index 8ca9e51..0000000 --- a/src/helpers/CardDropHelperMetadata.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; -import { CardRarity, CardRarityToColour, CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity"; -import CardRarityChances from "../constants/CardRarityChances"; -import { DropResult } from "../contracts/SeriesMetadata"; -import { CoreClient } from "../client/client"; -import AppLogger from "../client/appLogger"; -import CardConstants from "../constants/CardConstants"; -import StringTools from "./StringTools"; -import Inventory from "../database/entities/app/Inventory"; - -export default class CardDropHelperMetadata { - public static GetRandomCard(): DropResult | undefined { - const randomRarity = Math.random() * 100; - - let cardRarity: CardRarity; - - const bronzeChance = CardRarityChances.Bronze; - const silverChance = bronzeChance + CardRarityChances.Silver; - const goldChance = silverChance + CardRarityChances.Gold; - const mangaChance = goldChance + CardRarityChances.Manga; - - if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; - else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; - else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; - else if (randomRarity < mangaChance) cardRarity = CardRarity.Manga; - else cardRarity = CardRarity.Legendary; - - const randomCard = this.GetRandomCardByRarity(cardRarity); - - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCard", `Random card: ${randomCard?.card.id} ${randomCard?.card.name}`); - - return randomCard; - } - - public static GetRandomCardByRarity(rarity: CardRarity): DropResult | undefined { - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Parameters: rarity=${rarity}`); - - const allCards = CoreClient.Cards - .flatMap(x => x.cards) - .filter(x => x.type == rarity); - - const randomCardIndex = Math.floor(Math.random() * allCards.length); - - const card = allCards[randomCardIndex]; - const series = CoreClient.Cards - .find(x => x.cards.includes(card)); - - if (!series) { - AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarity", `Series not found for card ${card.id}`); - - return undefined; - } - - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Random card: ${card.id} ${card.name}`); - - return { - series: series, - card: card, - }; - } - - public static async GetRandomCardUnclaimed(userId: string): Promise { - const randomRarity = Math.random() * 100; - - let cardRarity: CardRarity; - - const bronzeChance = CardRarityChances.Bronze; - const silverChance = bronzeChance + CardRarityChances.Silver; - const goldChance = silverChance + CardRarityChances.Gold; - const mangaChance = goldChance + CardRarityChances.Manga; - - if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; - else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; - else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; - else if (randomRarity < mangaChance) cardRarity = CardRarity.Manga; - else cardRarity = CardRarity.Legendary; - - const randomCard = await this.GetRandomCardByRarityUnclaimed(cardRarity, userId); - - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardUnclaimed", `Random card: ${randomCard?.card.id} ${randomCard?.card.name}`); - - return randomCard; - } - - public static async GetRandomCardByRarityUnclaimed(rarity: CardRarity, userId: string): Promise { - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Parameters: rarity=${rarity}, userId=${userId}`); - - const claimedCards = await Inventory.FetchAllByUserId(userId); - - if (!claimedCards) { - // They don't have any cards, so safe to get any random card - return this.GetRandomCardByRarity(rarity); - } - - const allCards = CoreClient.Cards - .flatMap(x => x.cards) - .filter(x => x.type == rarity) - .filter(x => !claimedCards.find(y => y.CardNumber == x.id)); - - if (!allCards) return undefined; - - const randomCardIndex = Math.floor(Math.random() * allCards.length); - - const card = allCards[randomCardIndex]; - const series = CoreClient.Cards - .find(x => x.cards.includes(card)); - - if (!series) { - AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Series not found for card ${card.id}`); - - return undefined; - } - - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Random card: ${card.id} ${card.name}`); - - return { - series: series, - card: card, - }; - } - - public static GetCardByCardNumber(cardNumber: string): DropResult | undefined { - AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Parameters: cardNumber=${cardNumber}`); - - const card = CoreClient.Cards - .flatMap(x => x.cards) - .find(x => x.id == cardNumber); - - const series = CoreClient.Cards - .find(x => x.cards.find(y => y.id == card?.id)); - - AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Card: ${card?.id} ${card?.name}`); - AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Series: ${series?.id} ${series?.name}`); - - if (!card || !series) { - AppLogger.LogVerbose("CardDropHelperMetadata/GetCardByCardNumber", `Unable to find card metadata: ${cardNumber}`); - return undefined; - } - - return { card, series }; - } - - public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, claimedBy?: string, currency?: number): EmbedBuilder { - AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropEmbed", `Parameters: drop=${drop.card.id}, quantityClaimed=${quantityClaimed}, imageFileName=${imageFileName}`); - - const description = drop.card.subseries ?? drop.series.name; - let colour = CardRarityToColour(drop.card.type); - - if (drop.card.colour && StringTools.IsHexCode(drop.card.colour)) { - const hexCode = Number("0x" + drop.card.colour); - - if (hexCode) { - colour = hexCode; - } else { - AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); - } - } else if (drop.card.colour) { - AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); - } - - const embed = new EmbedBuilder() - .setTitle(drop.card.name) - .setDescription(description) - .setFooter({ text: `${CardRarityToString(drop.card.type)} · ${drop.card.id}` }) - .setColor(colour) - .setImage(`attachment://${imageFileName}`) - .addFields([ - { - name: "Claimed", - value: `${quantityClaimed}`, - inline: true, - } - ]); - - if (claimedBy != null) { - embed.addFields([ - { - name: "Claimed by", - value: claimedBy, - inline: true, - } - ]); - } - - if (currency != null) { - embed.addFields([ - { - name: "Currency", - value: `${currency}`, - inline: true, - } - ]); - } - - return embed; - } - - public static GenerateDropButtons(drop: DropResult, claimId: string, userId: string, disabled: boolean = false): ActionRowBuilder { - AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropButtons", `Parameters: drop=${drop.card.id}, claimId=${claimId}, userId=${userId}`); - - return new ActionRowBuilder() - .addComponents( - new ButtonBuilder() - .setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`) - .setLabel(`Claim (${CardConstants.ClaimCost} 🪙)`) - .setStyle(ButtonStyle.Primary) - .setDisabled(disabled), - new ButtonBuilder() - .setCustomId("reroll") - .setLabel("Reroll") - .setStyle(ButtonStyle.Secondary)); - } - - public static GenerateMultidropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, cardsRemaining: number, claimedBy?: string, currency?: number): EmbedBuilder { - const dropEmbed = this.GenerateDropEmbed(drop, quantityClaimed, imageFileName, claimedBy, currency); - - dropEmbed.setFooter({ text: `${dropEmbed.data.footer?.text} · ${cardsRemaining} Remaining`}); - - return dropEmbed; - } - - public static GenerateMultidropButtons(drop: DropResult, cardsRemaining: number, userId: string, disabled = false): ActionRowBuilder { - return new ActionRowBuilder() - .addComponents( - new ButtonBuilder() - .setCustomId(`multidrop keep ${drop.card.id} ${cardsRemaining} ${userId}`) - .setLabel("Keep") - .setStyle(ButtonStyle.Primary) - .setDisabled(disabled), - new ButtonBuilder() - .setCustomId(`multidrop sacrifice ${drop.card.id} ${cardsRemaining} ${userId}`) - .setLabel(`Sacrifice (+${GetSacrificeAmount(drop.card.type)} 🪙)`) - .setStyle(ButtonStyle.Secondary)); - } -} diff --git a/src/helpers/CardSearchHelper.ts b/src/helpers/CardSearchHelper.ts index 29014f7..6e848f4 100644 --- a/src/helpers/CardSearchHelper.ts +++ b/src/helpers/CardSearchHelper.ts @@ -1,11 +1,12 @@ import {ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder} from "discord.js"; import Fuse from "fuse.js"; import {CoreClient} from "../client/client.js"; -import CardDropHelperMetadata from "./CardDropHelperMetadata.js"; import Inventory from "../database/entities/app/Inventory.js"; import {readFileSync} from "fs"; import path from "path"; import AppLogger from "../client/appLogger.js"; +import GetCardsHelper from "./DropHelpers/GetCardsHelper.js"; +import DropEmbedHelper from "./DropHelpers/DropEmbedHelper.js"; interface ReturnedPage { embed: EmbedBuilder, @@ -32,7 +33,7 @@ export default class CardSearchHelper { return undefined; } - const card = CardDropHelperMetadata.GetCardByCardNumber(entry.item.id); + const card = GetCardsHelper.GetCardByCardNumber(entry.item.id); if (!card) return undefined; @@ -43,16 +44,16 @@ export default class CardSearchHelper { image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); } catch { AppLogger.LogError("CardSearchHelper/GenerateSearchQuery", `Unable to fetch image for card ${card.card.id}.`); - + return undefined; } const attachment = new AttachmentBuilder(image, { name: imageFileName }); - + const inventory = await Inventory.FetchOneByCardNumberAndUserId(userid, card.card.id); const quantityClaimed = inventory?.Quantity ?? 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed(card, quantityClaimed, imageFileName); const row = new ActionRowBuilder() .addComponents( @@ -73,7 +74,7 @@ export default class CardSearchHelper { public static async GenerateSearchPageFromQuery(results: string[], userid: string, page: number): Promise { const currentPageId = results[page - 1]; - const card = CardDropHelperMetadata.GetCardByCardNumber(currentPageId); + const card = GetCardsHelper.GetCardByCardNumber(currentPageId); if (!card) { AppLogger.LogError("CardSearchHelper/GenerateSearchPageFromQuery", `Unable to find card by id: ${currentPageId}.`); @@ -97,7 +98,7 @@ export default class CardSearchHelper { const inventory = await Inventory.FetchOneByCardNumberAndUserId(userid, card.card.id); const quantityClaimed = inventory?.Quantity ?? 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed(card, quantityClaimed, imageFileName); const row = new ActionRowBuilder() .addComponents( diff --git a/src/helpers/DropHelpers/DropEmbedHelper.ts b/src/helpers/DropHelpers/DropEmbedHelper.ts new file mode 100644 index 0000000..ba1ba47 --- /dev/null +++ b/src/helpers/DropHelpers/DropEmbedHelper.ts @@ -0,0 +1,79 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; +import { DropResult } from "../../contracts/SeriesMetadata"; +import AppLogger from "../../client/appLogger"; +import { CardRarityToColour, CardRarityToString } from "../../constants/CardRarity"; +import StringTools from "../StringTools"; +import CardConstants from "../../constants/CardConstants"; + +export default class DropEmbedHelper { + public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, claimedBy?: string, currency?: number): EmbedBuilder { + AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropEmbed", `Parameters: drop=${drop.card.id}, quantityClaimed=${quantityClaimed}, imageFileName=${imageFileName}`); + + const description = drop.card.subseries ?? drop.series.name; + let colour = CardRarityToColour(drop.card.type); + + if (drop.card.colour && StringTools.IsHexCode(drop.card.colour)) { + const hexCode = Number("0x" + drop.card.colour); + + if (hexCode) { + colour = hexCode; + } else { + AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); + } + } else if (drop.card.colour) { + AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); + } + + const embed = new EmbedBuilder() + .setTitle(drop.card.name) + .setDescription(description) + .setFooter({ text: `${CardRarityToString(drop.card.type)} · ${drop.card.id}` }) + .setColor(colour) + .setImage(`attachment://${imageFileName}`) + .addFields([ + { + name: "Claimed", + value: `${quantityClaimed}`, + inline: true, + } + ]); + + if (claimedBy != null) { + embed.addFields([ + { + name: "Claimed by", + value: claimedBy, + inline: true, + } + ]); + } + + if (currency != null) { + embed.addFields([ + { + name: "Currency", + value: `${currency}`, + inline: true, + } + ]); + } + + return embed; + } + + public static GenerateDropButtons(drop: DropResult, claimId: string, userId: string, disabled: boolean = false): ActionRowBuilder { + AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropButtons", `Parameters: drop=${drop.card.id}, claimId=${claimId}, userId=${userId}`); + + return new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`) + .setLabel(`Claim (${CardConstants.ClaimCost} 🪙)`) + .setStyle(ButtonStyle.Primary) + .setDisabled(disabled), + new ButtonBuilder() + .setCustomId("reroll") + .setLabel("Reroll") + .setStyle(ButtonStyle.Secondary)); + } +} \ No newline at end of file diff --git a/src/helpers/DropHelpers/GetCardsHelper.ts b/src/helpers/DropHelpers/GetCardsHelper.ts new file mode 100644 index 0000000..cdf4209 --- /dev/null +++ b/src/helpers/DropHelpers/GetCardsHelper.ts @@ -0,0 +1,78 @@ +import AppLogger from "../../client/appLogger"; +import { CoreClient } from "../../client/client"; +import { CardRarity } from "../../constants/CardRarity"; +import CardRarityChances from "../../constants/CardRarityChances"; +import { DropResult } from "../../contracts/SeriesMetadata"; + +export default class GetCardsHelper { + public static GetRandomCard(): DropResult | undefined { + const randomRarity = Math.random() * 100; + + let cardRarity: CardRarity; + + const bronzeChance = CardRarityChances.Bronze; + const silverChance = bronzeChance + CardRarityChances.Silver; + const goldChance = silverChance + CardRarityChances.Gold; + const mangaChance = goldChance + CardRarityChances.Manga; + + if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; + else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; + else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; + else if (randomRarity < mangaChance) cardRarity = CardRarity.Manga; + else cardRarity = CardRarity.Legendary; + + const randomCard = this.GetRandomCardByRarity(cardRarity); + + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCard", `Random card: ${randomCard?.card.id} ${randomCard?.card.name}`); + + return randomCard; + } + + public static GetRandomCardByRarity(rarity: CardRarity): DropResult | undefined { + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Parameters: rarity=${rarity}`); + + const allCards = CoreClient.Cards + .flatMap(x => x.cards) + .filter(x => x.type == rarity); + + const randomCardIndex = Math.floor(Math.random() * allCards.length); + + const card = allCards[randomCardIndex]; + const series = CoreClient.Cards + .find(x => x.cards.includes(card)); + + if (!series) { + AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarity", `Series not found for card ${card.id}`); + + return undefined; + } + + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Random card: ${card.id} ${card.name}`); + + return { + series: series, + card: card, + }; + } + + public static GetCardByCardNumber(cardNumber: string): DropResult | undefined { + AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Parameters: cardNumber=${cardNumber}`); + + const card = CoreClient.Cards + .flatMap(x => x.cards) + .find(x => x.id == cardNumber); + + const series = CoreClient.Cards + .find(x => x.cards.find(y => y.id == card?.id)); + + AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Card: ${card?.id} ${card?.name}`); + AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Series: ${series?.id} ${series?.name}`); + + if (!card || !series) { + AppLogger.LogVerbose("CardDropHelperMetadata/GetCardByCardNumber", `Unable to find card metadata: ${cardNumber}`); + return undefined; + } + + return { card, series }; + } +} diff --git a/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts new file mode 100644 index 0000000..42e9cd7 --- /dev/null +++ b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts @@ -0,0 +1,69 @@ +import AppLogger from "../../client/appLogger"; +import { CoreClient } from "../../client/client"; +import { CardRarity } from "../../constants/CardRarity"; +import CardRarityChances from "../../constants/CardRarityChances"; +import { DropResult } from "../../contracts/SeriesMetadata"; +import Inventory from "../../database/entities/app/Inventory"; +import GetCardsHelper from "./GetCardsHelper"; + +export default class GetUnclaimedCardsHelper { + public static async GetRandomCardUnclaimed(userId: string): Promise { + const randomRarity = Math.random() * 100; + + let cardRarity: CardRarity; + + const bronzeChance = CardRarityChances.Bronze; + const silverChance = bronzeChance + CardRarityChances.Silver; + const goldChance = silverChance + CardRarityChances.Gold; + const mangaChance = goldChance + CardRarityChances.Manga; + + if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; + else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; + else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; + else if (randomRarity < mangaChance) cardRarity = CardRarity.Manga; + else cardRarity = CardRarity.Legendary; + + const randomCard = await this.GetRandomCardByRarityUnclaimed(cardRarity, userId); + + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardUnclaimed", `Random card: ${randomCard?.card.id} ${randomCard?.card.name}`); + + return randomCard; + } + + public static async GetRandomCardByRarityUnclaimed(rarity: CardRarity, userId: string): Promise { + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Parameters: rarity=${rarity}, userId=${userId}`); + + const claimedCards = await Inventory.FetchAllByUserId(userId); + + if (!claimedCards) { + // They don't have any cards, so safe to get any random card + return GetCardsHelper.GetRandomCardByRarity(rarity); + } + + const allCards = CoreClient.Cards + .flatMap(x => x.cards) + .filter(x => x.type == rarity) + .filter(x => !claimedCards.find(y => y.CardNumber == x.id)); + + if (!allCards) return undefined; + + const randomCardIndex = Math.floor(Math.random() * allCards.length); + + const card = allCards[randomCardIndex]; + const series = CoreClient.Cards + .find(x => x.cards.includes(card)); + + if (!series) { + AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Series not found for card ${card.id}`); + + return undefined; + } + + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Random card: ${card.id} ${card.name}`); + + return { + series: series, + card: card, + }; + } +} diff --git a/src/helpers/DropHelpers/MultidropEmbedHelper.ts b/src/helpers/DropHelpers/MultidropEmbedHelper.ts new file mode 100644 index 0000000..526993e --- /dev/null +++ b/src/helpers/DropHelpers/MultidropEmbedHelper.ts @@ -0,0 +1,28 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; +import { DropResult } from "../../contracts/SeriesMetadata"; +import { GetSacrificeAmount } from "../../constants/CardRarity"; +import DropEmbedHelper from "./DropEmbedHelper"; + +export default class MultidropEmbedHelper { + public static GenerateMultidropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, cardsRemaining: number, claimedBy?: string, currency?: number): EmbedBuilder { + const dropEmbed = DropEmbedHelper.GenerateDropEmbed(drop, quantityClaimed, imageFileName, claimedBy, currency); + + dropEmbed.setFooter({ text: `${dropEmbed.data.footer?.text} · ${cardsRemaining} Remaining`}); + + return dropEmbed; + } + + public static GenerateMultidropButtons(drop: DropResult, cardsRemaining: number, userId: string, disabled = false): ActionRowBuilder { + return new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`multidrop keep ${drop.card.id} ${cardsRemaining} ${userId}`) + .setLabel("Keep") + .setStyle(ButtonStyle.Primary) + .setDisabled(disabled), + new ButtonBuilder() + .setCustomId(`multidrop sacrifice ${drop.card.id} ${cardsRemaining} ${userId}`) + .setLabel(`Sacrifice (+${GetSacrificeAmount(drop.card.type)} 🪙)`) + .setStyle(ButtonStyle.Secondary)); + } +}