From 9a2835a0eb82751576460d83f052bf95c2a4ebad Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Mon, 23 Dec 2024 16:18:40 +0000
Subject: [PATCH 1/2] Add chance effect function

---
 src/commands/drop.ts                  | 12 +++++-
 src/constants/CardConstants.ts        |  3 ++
 src/helpers/CardDropHelperMetadata.ts | 59 +++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/src/commands/drop.ts b/src/commands/drop.ts
index 6799a2c..8d82d81 100644
--- a/src/commands/drop.ts
+++ b/src/commands/drop.ts
@@ -11,6 +11,8 @@ import AppLogger from "../client/appLogger";
 import User from "../database/entities/app/User";
 import CardConstants from "../constants/CardConstants";
 import ErrorMessages from "../constants/ErrorMessages";
+import { DropResult } from "../contracts/SeriesMetadata";
+import EffectHelper from "../helpers/EffectHelper";
 
 export default class Drop extends Command {
     constructor() {
@@ -47,7 +49,15 @@ export default class Drop extends Command {
             return;
         }
 
-        const randomCard = CardDropHelperMetadata.GetRandomCard();
+        let randomCard: DropResult | undefined;
+
+        const hasChanceUpEffect = await EffectHelper.HasEffect(interaction.user.id, "unclaimed");
+
+        if (hasChanceUpEffect && Math.random() <= CardConstants.UnusedChanceUpChance) {
+            randomCard = await CardDropHelperMetadata.GetRandomCardUnclaimed(interaction.user.id);
+        } else {
+            randomCard = CardDropHelperMetadata.GetRandomCard();
+        }
 
         if (!randomCard) {
             AppLogger.LogWarn("Commands/Drop", ErrorMessages.UnableToFetchCard);
diff --git a/src/constants/CardConstants.ts b/src/constants/CardConstants.ts
index 3f9723b..9330111 100644
--- a/src/constants/CardConstants.ts
+++ b/src/constants/CardConstants.ts
@@ -7,4 +7,7 @@ export default class CardConstants {
     // Multidrop
     public static readonly MultidropCost = this.ClaimCost * 10;
     public static readonly MultidropQuantity = 11;
+
+    // Effects
+    public static readonly UnusedChanceUpChance = 1;
 }
\ No newline at end of file
diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts
index 8b9b273..80f3d6b 100644
--- a/src/helpers/CardDropHelperMetadata.ts
+++ b/src/helpers/CardDropHelperMetadata.ts
@@ -6,6 +6,7 @@ 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 {
@@ -58,6 +59,64 @@ export default class CardDropHelperMetadata {
         };
     }
 
+    public static async GetRandomCardUnclaimed(userId: string): Promise<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 = 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<DropResult | undefined> {
+        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));
+
+        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}`);
 

From ff9437ba8154979d3e5b02097016c8bf915a8c8a Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Mon, 23 Dec 2024 16:20:54 +0000
Subject: [PATCH 2/2] Update .env.example variables

---
 .env.example | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/.env.example b/.env.example
index add48a5..e37a3a0 100644
--- a/.env.example
+++ b/.env.example
@@ -34,8 +34,6 @@ DB_LOGGING=
 DB_DATA_LOCATION=./.temp/database
 DB_ROOT_HOST=0.0.0.0
 
-DB_CARD_FILE=:memory:
-
 EXPRESS_PORT=3302
 
-GDRIVESYNC_AUTO=true
+GDRIVESYNC_AUTO=false