Esempio n. 1
0
    async def discard(self, ctx, card:int):
        """Discard a card you want to get rid of with this command. If you want to throw a fake away, make sure it's in the free slots"""
        
        user = User(ctx.author.id)
        try:
            card = Card(card)
        except CardNotFound:
            return await ctx.send('This card does not exist!')

        if not user.has_any_card(card.id):
            return await ctx.send('You are not in possesion of this card!')

        if card.id == 0:
            return await ctx.send("You cannot discard this card!")

        view = ConfirmButton(ctx.author.id, timeout=20)
        msg = await ctx.send(f"Do you really want to throw this card away? (if you want to throw a fake aware, make sure it's in the free slots (unless it's the only copy you own. You can switch cards between free and restricted slots with `{self.client.command_prefix(self.client, ctx.message)[2]}swap <card_id>`)", view=view, allowed_mentions=discord.AllowedMentions.none())
        await view.wait()
        await view.disable(msg)

        if not view.value:
            if view.timed_out:
                return await ctx.send(f'Timed out!')
            else:
                return await ctx.send(f"Successfully canceled!")

        try:
            user.remove_card(card.id, remove_fake=True, restricted_slot=False)
            # essentially here it first looks for fakes in your free slots and tried to remove them. If it doesn't find any fakes in the free slots, it will remove the first match of the card it finds in free or restricted slots
        except NoMatches:
            user.remove_card(card.id)
        await ctx.send(f'Successfully thrown away card No. `{card.id}`')
Esempio n. 2
0
    def _use_check(self, ctx, item:int, args:Optional[Union[discord.Member, int, str]], add_args: Optional[int]) -> None:
        """Makes sure the inputs are valid if they exist"""
        if item in [*DEF_SPELLS, *VIEW_DEF_SPELLS]:
            raise CheckFailure('You can only use this card in response to an attack!')

        try:
            if Card(item).type != "spell":
                raise CheckFailure("You can only use spell cards!")
        except CardNotFound:
            raise CheckFailure("Invalid card id")

        if not item in [x[0] for x in User(ctx.author.id).fs_cards] and not item in [1036]:
            raise CheckFailure('You are not in possesion of this card!')

        if args:
            if isinstance(args, discord.Member):
                if args.id == ctx.author.id:
                    raise CheckFailure('You can\'t use spell cards on yourself')
                elif args.bot:
                    raise CheckFailure("You can't use spell cards on bots")

            if isinstance(args, int):
                if args < 1:
                    raise CheckFailure('You can\'t use an integer less than 1')

        if add_args:
            if add_args < 1:
                raise CheckFailure('You can\'t use an integer less than 1')
Esempio n. 3
0
    async def card(self, ctx, item: int):
        """Buy a card from the shop with this command"""

        shop_data = shop.find_one({'_id': 'daily_offers'})
        shop_items = shop_data['offers']
        user = User(ctx.author.id)

        try:
            card = Card(item)
        except CardNotFound:
            return await ctx.send(
                f'This card is not for sale at the moment! Find what cards are in the shop with `{self.client.command_prefix(self.client, ctx.message)[2]}shop`',
                allowed_mentions=discord.AllowedMentions.none())

        if not item in shop_items:
            return await ctx.send(
                f'This card is not for sale at the moment! Find what cards are in the shop with `{self.client.command_prefix(self.client, ctx.message)[2]}shop`',
                allowed_mentions=discord.AllowedMentions.none())

        if not shop_data['reduced'] is None:
            if shop_items.index(
                    card.id) == shop_data['reduced']['reduced_item']:
                price = int(PRICES[card.rank] -
                            int(PRICES[card.rank] *
                                (shop_data['reduced']['reduced_by'] / 100)))
            else:
                price = PRICES[card.rank]
        else:
            price = PRICES[card.rank]

        if len(card.owners) >= (card.limit * ALLOWED_AMOUNT_MULTIPLE):
            return await ctx.send(
                'Unfortunately the global maximal limit of this card is reached! Someone needs to sell their card for you to buy one or trade/give it to you'
            )

        if len(user.fs_cards) >= FREE_SLOTS:
            return await ctx.send(
                f'Looks like your free slots are filled! Get rid of some with `{self.client.command_prefix(self.client, ctx.message)[2]}sell`',
                allowed_mentions=discord.AllowedMentions.none())

        if user.jenny < price:
            return await ctx.send(
                f'I\'m afraid you don\'t have enough Jenny to buy this card. Your balance is {user.jenny} while the card costs {price} Jenny'
            )
        try:
            user.add_card(item)
        except Exception as e:
            if isinstance(e, CardLimitReached):
                return await ctx.send(
                    f'Free slots card limit reached (`{FREE_SLOTS}`)! Get rid of one card in your free slots to add more cards with `{self.client.command_prefix(self.client, ctx.message)[2]}sell <card>`',
                    allowed_mentions=discord.AllowedMentions.none())
            else:
                print(e)

        user.remove_jenny(
            price
        )  #Always putting substracting points before giving the item so if the payment errors no item is given
        return await ctx.send(
            f'Successfully bought card number `{card.id}` {card.emoji} for {price} Jenny. Check it out in your inventory with `{self.client.command_prefix(self.client, ctx.message)[2]}book`!',
            allowed_mentions=discord.AllowedMentions.none())
Esempio n. 4
0
    async def cardinfo(self, ctx, card:int):
        """Check card info out about any card you own"""
        try:
            c = Card(card)
        except CardNotFound:
            return await ctx.send("Invalid card")

        author = User(ctx.author.id)
        if not author.has_any_card(c.id):
            return await ctx.send("You don't own a copy of this card so you can't view it's infos")

        embed = c._get_analysis_embed(c.id)
        if c.type == "spell" and c.id not in [*DEF_SPELLS, *VIEW_DEF_SPELLS]:
            card_class = [c for c in Card.__subclasses__() if c.__name__ == f"Card{card}"][0]
            usage = f"`{self.client.command_prefix(self.client, ctx.message)[2]}use {card} " + " ".join([f"[{k}: {v.__name__}]" for k, v in card_class.exec.__annotations__.items() if not str(k) == "return"]) + "`"
            embed.add_field(name="Usage", value=usage, inline=False)

        await ctx.send(embed=embed)
Esempio n. 5
0
    def _format_rewards(self, rewards:List[Tuple[int, int]], user:User, score:float) -> Tuple[List[list], List[str], bool]:
        """Formats the generated rewards for further use"""
        formatted_rewards: List[List[int, Dict[str, bool]]] = []
        formatted_text: List[str] = []

        for reward in rewards:
            for i in range(reward[0]):
                if len([*user.fs_cards,*[x for x in rewards if x[1] > 99 and not user.has_rs_card(x[0])]]) >= 40 and (reward[1] > 99 or (not user.has_rs_card(reward[1]) and reward[1] < 100)):
                    return formatted_rewards, formatted_text, True # if the free slots are full the process stops
                formatted_rewards.append([reward[1], {"fake": False, "clone": False}])
            card = Card(reward[1])
            formatted_text.append(f"{reward[0]}x **{card.name}**{card.emoji}")

        return formatted_rewards, formatted_text, False
Esempio n. 6
0
    async def _use_core(self, ctx, item:int, *args) -> None:
        """This passes the execution to the right class """
        card_class = [c for c in Card.__subclasses__() if c.__name__ == f"Card{item}"][0]
        
        l = []
        for p, (k, v) in enumerate([x for x in card_class.exec.__annotations__.items() if not str(x[0]) == "return"]):
            if len(args) > p and isinstance(args[p], v):
                l.append({k: args[p]})
            else:
                l.append(None)

        if None in l:
            return await ctx.send(f"Invalid arguments provided! Usage: `{self.client.command_prefix(self.client, ctx.message)[2]}use {item} " + " ".join([f"[{k}: {v.__name__}]" for k, v in card_class.exec.__annotations__.items() if not str(k) == "return"]) + "`", allowed_mentions=discord.AllowedMentions.none())
        kwargs = {k: v for d in l for k, v in d.items()}
        try:
            await card_class(ctx, card_id=item).exec(**kwargs)
        except Exception as e:
            await ctx.send(e.message, allowed_mentions=discord.AllowedMentions.none())
Esempio n. 7
0
    async def sell(self, ctx, item:int, amount=1):
        """Sell any amount of cards you own"""
        
        user = User(ctx.author.id)
        if amount < 1:
            amount = 1
        if len(user.all_cards) == 0:
            return await ctx.send('You don\'t have any cards yet!')
        try:
            card = Card(item)
        except CardNotFound:
            return await ctx.send(f'A card with the id `{item}` does not exist', allowed_mentions=discord.AllowedMentions.none())

        in_possesion = user.count_card(card.id, including_fakes=False)

        if in_possesion < amount:
            return await ctx.send(f'Seems you don\'t own enough copies of this card. You own {in_possesion} cop{"y" if in_possesion == 1 else "ies"} of this card')
        
        if item == 0:
            return await ctx.send("You cannot sell this card!")

        jenny = int((PRICES[card.rank]*amount)/10)
        if user.is_entitled_to_double_jenny:
            jenny *= 2
        view = ConfirmButton(ctx.author.id, timeout=80)
        msg = await ctx.send(f"You will receive {jenny} Jenny for selling {'this card' if amount == 1 else 'those cards'}, do you want to proceed?", view=view)
        await view.wait()
        await view.disable(msg)

        if not view.value:
            if view.timed_out:
                return await ctx.send(f'Timed out!')
            else:
                return await ctx.send(f"Successfully canceled!")
            
        card_amount = user.count_card(item, False)

        if not card_amount >= amount:
            return await ctx.send('Seems like you don\'t own enough non-fake copies of this card you try to sell')
        else:
            for i in range(amount):
                user.remove_card(item, False)
            user.add_jenny(jenny)
            await ctx.send(f'Successfully sold {amount} cop{"y" if amount == 1 else "ies"} of card number {item} for {jenny} Jenny!')
Esempio n. 8
0
    async def _check(self, ctx, card_id:int):
        """Lets you see how many copies of the specified card are fakes"""
        try:
            Card(card_id)
        except CardNotFound:
            return await ctx.send("Invalid card")

        author = User(ctx.author.id)

        if not author.has_any_card(card_id, only_allow_fakes=True):
            return await ctx.send("You don't any copies of this card which are fake")

        text = ""

        if len([x for x in author.rs_cards if x[1]["fake"] is True and x[0] == card_id]) > 0:
            text += f"The card in your restricted slots is fake"

        if (fs:= len([x for x in author.fs_cards if x[1]["fake"] is True and x[0] == card_id])) > 0:
            text += (" and " if len(text) > 0 else "") + f"{fs} cop{'ies' if fs > 1 else 'y'} of this card in your free slots {'are' if fs > 1 else 'is'} fake"
Esempio n. 9
0
    async def swap(self, ctx, card_id:int):
        """Allows you to swap cards from your free slots with the restricted slots and the other way around"""
        
        user = User(ctx.author.id)
        if len(user.all_cards) == 0:
            return await ctx.send('You don\'t have any cards yet!')
        try:
            card = Card(card_id)
        except CardNotFound:
            return await ctx.send('Please use a valid card number!')

        if card_id == 0:
            return await ctx.send("You cannot swap out card No. 0!")

        sw = user.swap(card_id)

        if sw is False:
            return await ctx.send(f'You don\'t own a fake and real copy of card `{card.name}` you can swap out!')
        
        await ctx.send(f'Successfully swapped out card No. {card_id}')
Esempio n. 10
0
    async def gain(self, ctx, t:str, item:str):
        """An owner restricted command allowing the user to obtain any card or amount of jenny or any lootbox"""
        user = User(ctx.author.id)
        if not t.lower() in ["jenny", "card", "lootbox"]:
            return await ctx.send(f'You need to provide a valid type! `{self.client.command_prefix(self.client, ctx.message)[2]}gain <jenny/card/lootbox> <amount/id>`', allowed_mentions=discord.AllowedMentions.none())
        if t.lower() == 'card':
            try:
                item = int(item)
                card = Card(item)
            except CardNotFound:
                return await ctx.send('Invalid card id')
            if card.id == 0:
                return await ctx.send("No")
            if len(card.owners) >= card.limit * ALLOWED_AMOUNT_MULTIPLE:
                return await ctx.send('Sorry! Global card limit reached!')
            if len(user.fs_cards) >= FREE_SLOTS and (item > 99 or item in [x[0] for x in user.rs_cards]):
                return await ctx.send('Seems like you have no space left in your free slots!')
            user.add_card(item)
            return await ctx.send(f'Added card "{card.name}" to your inventory')

        if t.lower() == 'jenny':
            if not item.isdigit():
                return await ctx.send('Please provide a valid amount of jenny!')
            item = int(item)
            if item < 1:
                return await ctx.send('Please provide a valid amount of jenny!')
            if item > 69420:
                return await ctx.send('Be reasonable.')
            user.add_jenny(item)
            return await ctx.send(f'Added {item} Jenny to your account')

        if t.lower() == "lootbox":
            if not item.isdigit() or not int(item) in list(LOOTBOXES.keys()):
                return await ctx.send("Invalid lootbox!")
            user.add_lootbox(int(item))
            return await ctx.send(f"Done! Added lootbox \"{LOOTBOXES[int(item)]['name']}\" to your inventory")
Esempio n. 11
0
    @check()
    @give.command(name="card",
                  extras={"category": Category.CARDS},
                  usage="card <user> <card_id>")
    async def _card(self, ctx, other: discord.Member, item: int):
        """If you're feeling generous give another user a card"""

        if isinstance((val := await self._validate(ctx, other)),
                      discord.Message):
            return
        else:
            user, o = val

        try:
            Card(item)
        except CardNotFound:
            return await ctx.send('Invalid card number')
        if user.has_any_card(item, False) is False:
            return await ctx.send(
                'You don\'t have any not fake copies of this card!')
        if (len(o.fs_cards) >= 40 and item < 100
                and o.has_rs_card(item)) or (len(o.fs_cards) >= 40
                                             and item > 99):
            return await ctx.send(
                'The user you are trying to give the cards\'s free slots are full!'
            )

        removed_card = user.remove_card(item)
        o.add_card(item, clone=removed_card[1]["clone"])
        return await ctx.send(f'✉️ gave `{other}` card No. {item}!',