Esempio n. 1
0
    async def gamble(self, ctx: commands.Context):
        """
        This command is similar to slots, but doesn't cost anything.
        """

        # Pick the rarity that the user rolled
        i = utils.rarity_percentage_finder(1)
        rarity = random.choices(*i)[0]
        if rarity in ["epic", "rare", "mythic"]:
            rarity = "uncommon"

        if ctx.author.id in utils.current_fishers:
            return await ctx.send(
                f"{ctx.author.display_name}, you're already fishing!")
        utils.current_fishers.append(ctx.author.id)

        async with self.bot.database() as db:
            # Achievements
            await db(
                """INSERT INTO user_achievements (user_id, times_gambled) VALUES ($1, 1)
                ON CONFLICT (user_id) DO UPDATE SET times_gambled = user_achievements.times_gambled + 1""",
                ctx.author.id)

        # Set up some vars for later
        fish_type = []  # The list of fish that they rolled
        emoji_id = []  # The list of fish emojis that they rolled
        emojis = [
            "<a:first_set_roll:875259843571748924>",
            "<a:first_set_roll:875259843571748924>",
            "<a:first_set_roll:875259843571748924>"
        ]
        picked_buttons = [False, False, False]

        # Pick three fish names from their rarity
        for i in range(3):
            fish_type.append(
                random.choice(list(utils.EMOJI_RARITIES_SET_ONE[rarity])))

        # Get the emojis for the fish they rolled
        emoji_id.append([
            utils.EMOJI_RARITIES_SET_ONE[rarity][fish_type_single]
            for fish_type_single in fish_type
        ])
        embed = vbu.Embed(title=f"{ctx.author.display_name}'s roll")
        embed.add_field(name="Click the buttons to stop the rolls!",
                        value="".join(emojis))

        # And send the message
        components = vbu.MessageComponents(
            vbu.ActionRow(
                vbu.Button(custom_id="one",
                           emoji="1\N{COMBINING ENCLOSING KEYCAP}"),
                vbu.Button(custom_id="two",
                           emoji="2\N{COMBINING ENCLOSING KEYCAP}"),
                vbu.Button(custom_id="three",
                           emoji="3\N{COMBINING ENCLOSING KEYCAP}"),
            ), )
        gamble_message = await ctx.send(embed=embed, components=components)

        # Make the button check
        def button_check(payload):
            if payload.message.id != gamble_message.id:
                return False
            self.bot.loop.create_task(payload.defer_update())
            return payload.user.id == ctx.author.id

        # Keep going...
        while True:

            # Wait for them to click a button
            try:
                chosen_button_payload = await self.bot.wait_for(
                    'component_interaction', timeout=60.0, check=button_check)
                chosen_button = chosen_button_payload.component.custom_id.lower(
                )
            except asyncio.TimeoutError:
                await gamble_message.edit(
                    components=components.disable_components())
                break

            # Update the displayed emoji
            if chosen_button == "one" and picked_buttons[0] is False:
                emojis[0] = emoji_id[0][0]
                picked_buttons[0] = True
            if chosen_button == "two" and picked_buttons[1] is False:
                emojis[1] = emoji_id[0][1]
                picked_buttons[1] = True
            if chosen_button == "three" and picked_buttons[2] is False:
                emojis[2] = emoji_id[0][2]
                picked_buttons[2] = True

            # Disable the given button
            components.get_component(chosen_button).disable()
            await gamble_message.edit(
                embed=create_bucket_embed(
                    ctx.author,
                    (
                        "Click the buttons to stop the rolls!",
                        "".join(list(emojis)),
                    ),
                    f"{ctx.author.display_name}'s roll",
                ),
                components=components,
            )

            # Break when they're done picking fish
            if "<a:first_set_roll:875259843571748924>" not in emojis:
                break

        # Sees if they won the fish they rolled
        if emojis[0] == emojis[1] == emojis[
                2] and "<a:first_set_roll:875259843571748924>" not in emojis:
            fish_won = fish_type[0]
            for rarity, fish_types in self.bot.fish.items():
                for fish_type, fish_info in fish_types.items():
                    if fish_info["raw_name"] == fish_won:
                        fish_won_info = fish_info
                        break
            embed = discord.Embed()
            embed.add_field(name=f"{ctx.author.display_name} has won:",
                            value=' '.join(fish_won.split('_')).title())
            async with self.bot.database() as db:
                # Achievements
                await db(
                    """INSERT INTO user_achievements (user_id, times_caught) VALUES ($1, 1)
                    ON CONFLICT (user_id) DO UPDATE SET times_caught = user_achievements.times_caught + 1""",
                    ctx.author.id)
            await utils.ask_to_sell_fish(self.bot,
                                         ctx,
                                         fish_won_info,
                                         embed=embed)
        else:
            await ctx.send(f"{ctx.author.mention} lost!")

        utils.current_fishers.remove(ctx.author.id)
Esempio n. 2
0
    async def slots(self, ctx: commands.Context):
        """
        This command rolls the slots, costing 5 Sand Dollars.
        """

        if ctx.author.id in utils.current_fishers:
            return await ctx.send(
                f"{ctx.author.display_name}, you're already fishing!")
        utils.current_fishers.append(ctx.author.id)

        # See if the user has enough money
        if not await utils.check_price(self.bot, ctx.author.id, 5, 'balance'):
            return await ctx.send("You don't have enough money for this! (5)")

        # Remove money from the user
        async with self.bot.database() as db:
            await db(
                """UPDATE user_balance SET balance=balance-5 WHERE user_id = $1""",
                ctx.author.id)

        # Chooses the random fish for nonwinning rows
        chosen_fish = []
        rarities_of_fish = []
        for i in range(9):
            rarity_random = random.choices(
                *utils.rarity_percentage_finder(1))[0]
            new_fish = random.choice(
                list(utils.utils.EMOJI_RARITIES[rarity_random]))
            rarities_of_fish.append(rarity_random)
            chosen_fish.append(new_fish)

        # Chooses winning fish
        rarity = random.choices(*utils.rarity_percentage_finder(1))[0]
        fish_type = random.choice(list(utils.EMOJI_RARITIES[rarity]))
        emoji_id = utils.EMOJI_RARITIES[rarity][fish_type]

        # Find's the dict of winning fish
        fish_random_name = fish_type.replace("_", " ")
        used_fish = self.bot.fish[rarity][fish_random_name]

        # Checks if the user won
        win_or_lose = random.randint(1, 10)

        # Sends embed of either winning roll or losing roll
        embed = discord.Embed()
        embed.title = f"{ctx.author.display_name}'s roll..."
        row = []
        if win_or_lose == 2:
            for i in range(0, 6, 3):
                row.append(
                    f"{utils.EMOJI_RARITIES[rarities_of_fish[i]][chosen_fish[i]]}"
                    f"{utils.EMOJI_RARITIES[rarities_of_fish[i+1]][chosen_fish[i+1]]}"
                    f"{utils.EMOJI_RARITIES[rarities_of_fish[i+2]][chosen_fish[i+2]]}"
                )
            row.append(f"{emoji_id}{emoji_id}{emoji_id}")
            embed.add_field(name="*spent 5 <:sand_dollar:877646167494762586>*",
                            value="\n".join(row),
                            inline=False)
            embed.add_field(name="Lucky",
                            value=f"You won {fish_random_name.title()} :)",
                            inline=False)
            async with self.bot.database() as db:
                # Achievements
                await db(
                    """INSERT INTO user_achievements (user_id, times_caught) VALUES ($1, 1)
                    ON CONFLICT (user_id) DO UPDATE SET times_caught = user_achievements.times_caught + 1""",
                    ctx.author.id)
            await utils.ask_to_sell_fish(self.bot, ctx, used_fish, embed=embed)
            utils.current_fishers.remove(ctx.author.id)
        else:
            for i in range(0, 9, 3):
                row.append(
                    f"{utils.EMOJI_RARITIES[rarities_of_fish[i]][chosen_fish[i]]}"
                    f"{utils.EMOJI_RARITIES[rarities_of_fish[i+1]][chosen_fish[i+1]]}"
                    f"{utils.EMOJI_RARITIES[rarities_of_fish[i+2]][chosen_fish[i+2]]}"
                )
            embed.add_field(name="*spent 5 <:sand_dollar:877646167494762586>*",
                            value="\n".join(row),
                            inline=False)
            embed.add_field(name="Unlucky", value="You lost :(")
            await ctx.send(embed=embed)
            utils.current_fishers.remove(ctx.author.id)
Esempio n. 3
0
    async def fish(self, ctx: commands.Context):
        """
        This command catches a fish.
        """

        # Slash command defer
        if hasattr(ctx, "interaction"):
            await ctx.interaction.response.defer()

        # Check to see if they've registered with the bot before
        if not await utils.check_registered(self.bot, ctx.author.id):
            return await ctx.send(
                "Please use the `register` command before using this bot!")

        # If they're already fishing don't let them fish again, else make them already fishing
        if ctx.author.id in utils.current_fishers:
            return await ctx.send(
                f"**{ctx.author.display_name}**, you're already fishing!")
        utils.current_fishers.append(ctx.author.id)

        # Fetch their upgrades and casts
        async with vbu.Database() as db:
            upgrades = await db(
                """SELECT rod_upgrade, bait_upgrade, weight_upgrade, line_upgrade, lure_upgrade,
                crate_chance_upgrade, crate_tier_upgrade FROM user_upgrades WHERE user_id = $1""",
                ctx.author.id,
            )
            casts = await db(
                """SELECT casts FROM user_balance WHERE user_id = $1""",
                ctx.author.id,
            )

        # If they have no casts tell them they can't fish and remove them from currrent fishers
        if casts[0]["casts"] <= 0:
            utils.current_fishers.remove(ctx.author.id)
            relative_time = discord.utils.format_dt(
                self.cast_time - timedelta(hours=(utils.DAYLIGHT_SAVINGS - 1)),
                style="R",
            )
            return await ctx.send(
                f"You have no casts, You will get another {relative_time}.")

        # pick a random number using the line upgrade, if it is equal to 1 they get to fish twice
        caught_fish = 1
        two_in_one_roll = random.randint(
            1, utils.LINE_UPGRADES[upgrades[0]["line_upgrade"]])
        if two_in_one_roll == 1:
            caught_fish = 2

        # For each fish caught...
        for _ in range(caught_fish):

            # If they didn't catch trash
            if random.randint(1, 12) != 12:

                # Use upgrades for chances of rarity and mutation, and choose one with weighted randomness
                rarity = random.choices(*utils.rarity_percentage_finder(
                    upgrades[0]["bait_upgrade"]))[0]
                special = random.choices(
                    ("normal", "skinned"),
                    (1 - utils.LURE_UPGRADES[upgrades[0]["lure_upgrade"]],
                     utils.LURE_UPGRADES[upgrades[0]["lure_upgrade"]]))[0]

                # See which fish they caught by taking a random fish from the chosen rarity
                chosen_fish = random.choice(
                    utils.FishSpecies.get_rarity(rarity))

                while chosen_fish.name in utils.past_fish:
                    chosen_fish = random.choice(
                        utils.FishSpecies.get_rarity(rarity))

                # If the fish is skinned, choose one of it's skins
                fish_skin = ""
                if special == "skinned":
                    fish_skin = random.choice(chosen_fish.skins)

                # Grammar
                a_an = ("an" if rarity[0].lower() in ("a", "e", "i", "o",
                                                      "u") else "a")

                # Get their fish inventory, add 1 to their times caught in achievements, subtract 1 from their casts
                async with vbu.Database() as db:
                    user_inventory = await db(
                        "SELECT * FROM user_fish_inventory WHERE user_id=$1",
                        ctx.author.id,
                    )

                    # Achievements
                    await db(
                        """UPDATE user_achievements SET times_caught = times_caught + 1 WHERE user_id = $1""",
                        ctx.author.id,
                    )
                    await db(
                        """UPDATE user_balance SET casts = casts-1 WHERE user_id = $1""",
                        ctx.author.id,
                    )

                # Find out how many of those fish they caught previously
                amount = 0
                for row in user_inventory:
                    if row["fish"] == chosen_fish.name:
                        amount += 1

                # Set the fish file to the fishes image
                if fish_skin != "":
                    fish_file = discord.File(
                        f"{chosen_fish.image[:40]}{fish_skin}_{chosen_fish.image[40:]}",
                        "new_fish.png")
                else:
                    fish_file = discord.File(chosen_fish.image, "new_fish.png")

                # Add the fish caught's name to the choices
                choices = [chosen_fish.name.replace('_', ' ').title()]

                # For three other fish...
                for _ in range(3):

                    # Get a random other fish
                    random_rarity = random.choices(
                        *utils.rarity_percentage_finder(upgrades[0]
                                                        ["bait_upgrade"]))[0]
                    random_fish = random.choice(
                        utils.FishSpecies.get_rarity(random_rarity))

                    # If it's already a choice find a new one
                    while random_fish.name.replace('_',
                                                   ' ').title() in choices:
                        random_rarity = random.choices(
                            *utils.rarity_percentage_finder(
                                upgrades[0]["bait_upgrade"]))[0]
                        random_fish = random.choice(
                            utils.FishSpecies.get_rarity(random_rarity))

                    # Add that fish to the choices
                    choices.append(random_fish.name.replace('_', ' ').title())

                # Shuffle the choices so they're random
                random.shuffle(choices)

                # And send the choices as buttons
                components = discord.ui.MessageComponents(
                    discord.ui.ActionRow(
                        discord.ui.Button(label=choices[0],
                                          custom_id=choices[0]),
                        discord.ui.Button(label=choices[1],
                                          custom_id=choices[1]),
                        discord.ui.Button(label=choices[2],
                                          custom_id=choices[2]),
                        discord.ui.Button(label=choices[3],
                                          custom_id=choices[3]),
                    ), )

                # Sends the message with the pic of fish and buttons
                guess_message = await ctx.send("Guess the name of this fish:",
                                               file=fish_file,
                                               components=components)

                # Make the button check
                def button_check(payload):
                    if payload.message.id != guess_message.id:
                        return False
                    self.bot.loop.create_task(payload.response.defer_update())
                    return payload.user.id == ctx.author.id

                # Wait for them to click a button
                try:
                    chosen_button_payload = await self.bot.wait_for(
                        "component_interaction",
                        timeout=60.0,
                        check=button_check)
                    chosen_button = (chosen_button_payload.component.custom_id)
                    await guess_message.edit(components=None)
                except asyncio.TimeoutError:
                    await guess_message.edit(components=None)
                    await ctx.send("Timed out asking for guess.")
                    chosen_button = "AAAAAAAAAAAAAA"

                # Give them a bonus based on the fish's cost and tell them they got it correct if they did
                if chosen_button == chosen_fish.name.replace('_', ' ').title():
                    bonus = 15 + math.floor(int(chosen_fish.cost) / 10)
                    guess_message = f"<@{ctx.author.id}> guessed correctly and recieved {bonus} bonus sand dollars {EMOJIS['sand_dollar']}!"

                    # Update the users balance with the bonus
                    async with vbu.Database() as db:
                        await db(
                            """UPDATE user_balance SET balance = balance + $2 WHERE user_id = $1""",
                            ctx.author.id,
                            bonus,
                        )

                # Else tell them it was wrong
                else:
                    guess_message = f"Incorrect <@{ctx.author.id}>, no bonus given."

                # Tell the user about the fish they caught
                owned_unowned = "Owned" if amount > 0 else "Unowned"
                if fish_skin != "":
                    fish_skin_underlined = f"__{fish_skin}__"
                else:
                    fish_skin_underlined = ""
                embed = discord.Embed(
                    title=
                    f"{EMOJIS['aqua_fish']} {ctx.author.display_name} caught {a_an} *{rarity}* {fish_skin_underlined} {chosen_fish.size} **{chosen_fish.name.replace('_', ' ').title()}**!"
                )
                embed.add_field(
                    name=owned_unowned,
                    value=
                    f"You have {amount} **{chosen_fish.name.replace('_', ' ').title()}**",
                    inline=False,
                )
                embed.add_field(name="** **",
                                value=f"*{random.choice(utils.fish_footers)}*")
                embed.set_image(url="attachment://new_fish.png")
                embed.color = utils.RARITY_CULERS[rarity]
                if casts[0]["casts"] == 3:
                    guess_message += "\n⚠️You have two casts left⚠️"
                # Ask if they want to sell the fish they just caught or keep it

                await ctx.send(guess_message)
                await utils.ask_to_sell_fish(self.bot,
                                             ctx,
                                             chosen_fish,
                                             fish_skin,
                                             embed=embed)

                # Find if they catch a crate with the crate_chance_upgrade
                crate_catch = random.randint(
                    1, utils.CRATE_CHANCE_UPGRADE[upgrades[0]
                                                  ["crate_chance_upgrade"]])

                # If they caught it...
                if crate_catch == 1:
                    crate_loot = []

                    # Choose a random crate tier based on their crate_tier_upgrade and add the loot for that tier
                    crate = random.choices(
                        (
                            "Wooden",
                            "Bronze",
                            "Steel",
                            "Golden",
                            "Diamond",
                            "Enchanted",
                        ),
                        utils.CRATE_TIER_UPGRADE[upgrades[0]
                                                 ["crate_tier_upgrade"]],
                    )
                    crate_loot.append((
                        "balance",
                        random.randint(0, utils.CRATE_TIERS[crate[0]][0]),
                        "user_balance",
                    ))
                    crate_loot.append((
                        "casts",
                        random.randint(0, utils.CRATE_TIERS[crate[0]][1]),
                        "user_balance",
                    ))
                    crate_loot.append((
                        random.choices(
                            ("none", "cfb", "ufb", "rfb", "ifb", "hlfb"),
                            utils.CRATE_TIERS[crate[0]][2],
                        )[0],
                        random.randint(0, utils.CRATE_TIERS[crate[0]][3]),
                        "user_inventory",
                    ))
                    crate_loot.append((
                        random.choices(
                            ("none", "flakes", "pellets", "wafers"),
                            utils.CRATE_TIERS[crate[0]][4],
                        )[0],
                        random.randint(0, utils.CRATE_TIERS[crate[0]][5]),
                        "user_inventory",
                    ))
                    crate_loot.append((
                        random.choices(
                            ("none", "fullness", "experience", "mutation"),
                            utils.CRATE_TIERS[crate[0]][6],
                        )[0],
                        random.randint(0, utils.CRATE_TIERS[crate[0]][7]),
                        "user_inventory",
                    ))

                    # Initialize variables and display variable for every item
                    crate_message = ""
                    nl = "\n"
                    display = {
                        "balance": "Sand Dollars",
                        "casts": "Casts",
                        "cfb": "Common Fish Bags",
                        "ufb": "Uncommon Fish Bags",
                        "rfb": "Rare Fish Bags",
                        "ifb": "Inverted Fish Bags",
                        "hlfb": "High Level Fish Bags",
                        "flakes": "Fish Flakes",
                        "pellets": "Fish Pellets",
                        "wafers": "Fish Wafers",
                        "experience": "Experience Potions",
                        "mutation": "Mutation Potions",
                        "fullness": "Fullness Potions",
                    }

                    async with vbu.Database() as db:
                        # For each piece of loot in the crate
                        for data in crate_loot:

                            # Unpack the data
                            type_of_loot, amount_of_loot, table_of_loot = data
                            # If the type isn't "none" and there is an amount insert the loot into their database
                            if type_of_loot != "none" and amount_of_loot != 0:
                                await db(
                                    """UPDATE {0} SET {1} = {1} + $2 WHERE user_id = $1"""
                                    .format(table_of_loot, type_of_loot),
                                    ctx.author.id,
                                    amount_of_loot,
                                )
                                # Add a message to the end of the string to be sent
                                crate_message += f"{nl}{amount_of_loot}x {display[type_of_loot]} recieved!"

                        # Send the message telling them they caught a crate and what was in it
                        await ctx.channel.send(
                            f"{ctx.author.display_name} caught a {crate[0]} crate containing: {crate_message}"
                        )

            # Else if they catch trash...
            else:

                # Still use up a cast
                async with vbu.Database() as db:
                    await db(
                        """UPDATE user_balance SET casts = casts-1 WHERE user_id = $1""",
                        ctx.author.id,
                    )

                # Initiate the trash dict and string
                trash_dict = {}
                trash_string = ""

                # For each trash caught (1-6)...
                for i in range(random.randint(1, 6)):

                    # They catch a random weighted trash
                    caught = random.choices(
                        ("Pile Of Bottle Caps", "Plastic Bottle",
                         "Plastic Bag", "Seaweed Scraps", "Broken Fishing Net",
                         "Halfeaten Flip Flop", "Pile Of Straws", "Old Boot",
                         "Old Tire"), (
                             .15,
                             .15,
                             .15,
                             .15,
                             .1,
                             .1,
                             .1,
                             .05,
                             .05,
                         ))[0]

                    # If its not already in the dict add it with a 1, else add 1 to it
                    if caught not in trash_dict.keys():
                        trash_dict[caught] = 1
                    else:
                        trash_dict[caught] += 1

                # for each type of trash...
                for trash, amount in trash_dict.items():

                    # Add that trash to a string
                    trash_string += "\n" + \
                        f"{utils.EMOJIS[trash.replace(' ', '_').lower()]}{trash}: {amount}"

                    # Add the trash to their inventory
                    async with vbu.Database() as db:
                        await db(
                            f"""UPDATE user_item_inventory SET {trash.replace(' ', '_').lower()} = {trash.replace(' ', '_').lower()}+ {amount} WHERE user_id = $1""",
                            ctx.author.id,
                        )

                # Tell them they caught trash and how much of what types
                await ctx.send(f"You caught trash!{trash_string}")

        # And now they should be allowed to fish again
        utils.current_fishers.remove(ctx.author.id)
Esempio n. 4
0
    async def fish(self, ctx: commands.Context):
        """
        This command catches a fish.
        """

        # Make sure they can't fish twice
        if ctx.author.id in utils.current_fishers:
            return await ctx.send(
                f"**{ctx.author.display_name}**, you're already fishing!")
        utils.current_fishers.append(ctx.author.id)
        caught_fish = 1

        # Upgrades be like
        async with self.bot.database() as db:
            upgrades = await db(
                """SELECT rod_upgrade, bait_upgrade, weight_upgrade, line_upgrade, lure_upgrade FROM user_upgrades WHERE user_id = $1""",
                ctx.author.id,
            )

            # no upgrades bro
            if not upgrades:
                upgrades = await db(
                    """INSERT INTO user_upgrades (user_id) VALUES ($1) RETURNING *""",
                    ctx.author.id)

        # Roll a dice to see if they caught multiple fish
        two_in_one_chance = {
            1: 10000,
            2: 9500,
            3: 8500,
            4: 6000,
            5: 1000,
        }
        two_in_one_roll = random.randint(
            1, two_in_one_chance[upgrades[0]['line_upgrade']])
        if two_in_one_roll == 1:
            caught_fish = 2

        #
        for x in range(caught_fish):

            # See what our chances of getting each fish are
            rarity = random.choices(*utils.rarity_percentage_finder(
                upgrades[0]['bait_upgrade']))[0]  # Chance of each rarity
            special = random.choices(*utils.special_percentage_finder(
                upgrades[0]['lure_upgrade']))[0]  # Chance of modifier

            # See which fish they caught
            new_fish = random.choice(list(
                self.bot.fish[rarity].values())).copy()

            # See if we want to make the fish a modifier
            special_functions = {
                "inverted": utils.make_inverted(new_fish.copy()),
                "golden": utils.make_golden(new_fish.copy())
            }
            if special in special_functions:
                new_fish = special_functions[special]

            # Say how many of those fish they caught previously
            amount = 0
            a_an = "an" if rarity[0].lower() in ("a", "e", "i", "o",
                                                 "u") else "a"
            async with self.bot.database() as db:
                user_inventory = await db(
                    "SELECT * FROM user_fish_inventory WHERE user_id=$1",
                    ctx.author.id)

                # Achievements
                await db(
                    """INSERT INTO user_achievements (user_id, times_caught) VALUES ($1, 1)
                    ON CONFLICT (user_id) DO UPDATE SET times_caught = user_achievements.times_caught + 1""",
                    ctx.author.id,
                )
            for row in user_inventory:
                if row['fish'] == new_fish['raw_name']:
                    amount += 1

            # Tell the user about the fish they caught
            owned_unowned = "Owned" if amount > 0 else "Unowned"
            embed = discord.Embed(
                title=
                f"<:AquaFish:877939115948134442> You caught {a_an} *{rarity}* {new_fish['size']} **{new_fish['name']}**!"
            )
            embed.add_field(name=owned_unowned,
                            value=f"You have {amount} **{new_fish['name']}**",
                            inline=False)
            embed.set_image(url="attachment://new_fish.png")
            embed.color = utils.RARITY_CULERS[rarity]
            fish_file = discord.File(new_fish["image"], "new_fish.png")

            # Ask if they want to sell the fish they just caught
            print(utils.current_fishers)
            await utils.ask_to_sell_fish(self.bot,
                                         ctx,
                                         new_fish,
                                         embed=embed,
                                         file=fish_file)

        # And now they should be allowed to fish again
        utils.current_fishers.remove(ctx.author.id)
        print(utils.current_fishers)
Esempio n. 5
0
    async def use(self, ctx: commands.Context, *, item: str):
        """
        This command is only for using fish bags, and is just like using the fish command.
        """

        if not await utils.check_registered(self.bot, ctx.author.id):
            return await ctx.send("Please use the `register` command before using this bot!")

        # Don't let them use anything if they're fishing
        if ctx.author.id in utils.current_fishers:
            return await ctx.send(
                f"{ctx.author.display_name}, you're already fishing!"
            )

        # Set a bunch of variables up for bags
        rarity_of_bag = None
        used_bag = None
        used_bag_humanize = None
        type_of_bag = None

        # Based on the type of bag, unpack the variables
        if item.title() in utils.COMMON_BAG_NAMES:
            used_bag_humanize, rarity_of_bag, used_bag = utils.COMMON_BAG_NAMES
        elif item.title() in utils.UNCOMMON_BAG_NAMES:
            (
                used_bag_humanize,
                rarity_of_bag,
                used_bag,
            ) = utils.UNCOMMON_BAG_NAMES
        elif item.title() in utils.RARE_BAG_NAMES:
            used_bag_humanize, rarity_of_bag, used_bag = utils.RARE_BAG_NAMES
        elif item.title() in utils.INVERTED_BAG_NAMES:
            used_bag_humanize, type_of_bag, used_bag = utils.INVERTED_BAG_NAMES
        elif item.title() in utils.HIGH_LEVEL_BAG_NAMES:
            (
                used_bag_humanize,
                type_of_bag,
                used_bag,
            ) = utils.HIGH_LEVEL_BAG_NAMES

        # Else if they want to use a potion
        elif item.title() in (
            utils.EXPERIENCE_POTION_NAMES
            + utils.MUTATION_POTION_NAMES
            + utils.FEEDING_POTION_NAMES
        ):

            # Figure out the type of potion used
            if item.title() in utils.EXPERIENCE_POTION_NAMES:
                type_of_potion = "experience_potions"
            elif item.title() in utils.MUTATION_POTION_NAMES:
                type_of_potion = "mutation_potions"
            elif item.title() in utils.FEEDING_POTION_NAMES:
                type_of_potion = "feeding_potions"

            # Get their items from database
            async with vbu.Database() as db:
                inventory_rows = await db(
                    """SELECT * FROM user_item_inventory WHERE user_id = $1""",
                    ctx.author.id,
                )

                # If they don't have any potions tell them that
                if inventory_rows[0][type_of_potion] == 0:
                    return await ctx.send("You have no potions of that type!")

            # Find the fish with that name
            async with vbu.Database() as db:
                fish_rows = await db(
                    """SELECT * FROM user_fish_inventory WHERE user_id = $1 AND tank_fish != '' AND death_time != Null""",
                    ctx.author.id,
                )

            fish_rows_names = []
            for row in fish_rows:
                fish_rows_names.append(row['fish_name'])

            # Add the buttons to the message
            components = discord.ui.MessageComponents(
                discord.ui.ActionRow(
                    discord.ui.Button(emoji=EMOJIS["aqua_smile"]),
                ),
            )
            # Asks for the name of the tank the user is putting the theme on and makes sure it is correct
            message = await ctx.send(
                f"Press the button to specify fish you want to give the potion to",
                components=components
            )

            def button_check(payload):
                if payload.message.id != message.id:
                    return False
                return payload.user.id == ctx.author.id

            # Wait for them to click a button
            try:
                chosen_button_payload = await self.bot.wait_for(
                    "component_interaction", timeout=60.0, check=button_check
                )
            except asyncio.TimeoutError:
                return await ctx.send(
                    "Timed out asking for interaction, no available slots given."
                )

            name, interaction = await utils.create_modal(self.bot, chosen_button_payload, "Choose a fish", "Fish in a tank to give potion to")

            if not name:
                return await ctx.send(
                    "Timed out asking for name, no available name given."
                )

            # Find the fish with that name
            await interaction.response.defer_update()
            async with vbu.Database() as db:
                fish_row = await db(
                    """SELECT * FROM user_fish_inventory WHERE user_id = $1 AND fish_name = $2 AND tank_fish != ''""",
                    ctx.author.id,
                    name
                )

            # Check for if the fish exists
            if not fish_row:
                return await ctx.send("There is no fish in a tank with that name.")

            # Remove one potion from the user
            async with vbu.Database() as db:
                await db(
                    f"""UPDATE user_item_inventory SET {type_of_potion} = {type_of_potion} - 1 Where user_id = $1""",
                    ctx.author.id,
                )

            # If they use an experience potion...
            if item.title() in utils.EXPERIENCE_POTION_NAMES:

                # Add 10k xp to the fish
                await utils.xp_finder_adder(ctx.author, name, 25000, False)\

                # Get the new rows
                async with vbu.Database() as db:
                    new_fish_rows = await db(
                        """SELECT * FROM user_fish_inventory WHERE user_id = $1 AND fish_name = $2""",
                        ctx.author.id,
                        name,
                    )

                # Let them know the new info of their fish
                return await ctx.send(
                    f"{new_fish_rows[0]['fish_name']} is now level {new_fish_rows[0]['fish_level']}, {new_fish_rows[0]['fish_xp']}/{new_fish_rows[0]['fish_xp_max']}"
                )

            # If they bought a mutation potion...
            if item.title() in utils.MUTATION_POTION_NAMES:

                # Add inverted to the fish type and update the database
                async with vbu.Database() as db:

                    await db(
                        """UPDATE user_fish_inventory SET fish_skin = $1 where user_id = $2 AND fish = $3""",
                        'inverted',
                        ctx.author.id,
                        fish_row[0]["fish"],
                    )

                    # Let them know it worked
                    return await ctx.send(
                        f"{fish_row[0]['fish_name']} looks kind of strange now..."
                    )

            # If the item is a feeding potion...
            if item.title() in utils.FEEDING_POTION_NAMES:

                # Set the time to be now + the new death date
                death_date = fish_row[0]["death_time"] + timedelta(
                    days=30, hours=0
                )

                # Update the fish's death date
                async with vbu.Database() as db:
                    await db(
                        """UPDATE user_fish_inventory SET death_time = $3, fish_feed_time = $4 WHERE user_id = $1 AND fish_name = $2""",
                        ctx.author.id,
                        fish_row[0]["fish_name"],
                        death_date,
                        dt.utcnow(),
                    )

                # Let them know the potion worked
                return await ctx.send("That fish feels strangely full now...")

        # Add them to current fishers so they can't fish
        utils.current_fishers.append(ctx.author.id)

        # Deal with bag usage
        if used_bag is not None:

            # If its a bag with rarity just lower it, else pick a random rarity
            if rarity_of_bag:
                rarity_of_bag = rarity_of_bag.lower()
            else:
                rarity_of_bag = random.choices(
                    *utils.rarity_percentage_finder(0)
                )[0]

            # Lower the used bag
            used_bag = used_bag.lower()

            # Find the users items
            async with vbu.Database() as db:
                user_rows = await db(
                    """SELECT * FROM user_item_inventory WHERE user_id=$1""",
                    ctx.author.id,
                )

                # Find how many bags of that type they have
                user_bag_count = user_rows[0][used_bag]

            # If they have none tell them they have no bags and remove them from current fishers
            if not user_bag_count:
                utils.current_fishers.remove(ctx.author.id)
                return await ctx.send(f"You have no {used_bag_humanize}s!")

            # See which fish they caught by taking a random fish from the chosen rarity
            chosen_fish = random.choice(
                utils.FishSpecies.get_rarity(rarity_of_bag))

            while chosen_fish.name in utils.past_fish:
                chosen_fish = random.choice(
                    utils.FishSpecies.get_rarity(rarity_of_bag))

            # find if its skinned
            fish_skin = ""
            if type_of_bag == "Inverted":
                fish_skin = random.choice(chosen_fish.skins)

            # Set the level to 0 and if its a high level bag set level to 10 - 50
            level = 0
            if type_of_bag == "High Level":
                level = random.randint(25, 50)

            # Remove the bag from their inventory
            async with vbu.Database() as db:
                await db(
                    f"""UPDATE user_item_inventory SET {used_bag}={used_bag}-1 WHERE user_id=$1""",
                    ctx.author.id,
                )

        # A fish bag wasn't used
        elif used_bag is None:
            utils.current_fishers.remove(ctx.author.id)
            return await ctx.send("That is not a usable item!")

        # Grammar
        a_an = (
            "an" if rarity_of_bag[0].lower() in (
                "a", "e", "i", "o", "u") else "a"
        )

        # Get their fish inventory, add 1 to their times caught in achievements, subtract 1 from their casts
        async with vbu.Database() as db:
            user_inventory = await db(
                "SELECT * FROM user_fish_inventory WHERE user_id=$1",
                ctx.author.id,
            )

            # Achievements
            await db(
                """UPDATE user_achievements SET times_caught = times_caught + 1 WHERE user_id = $1""",
                ctx.author.id,
            )
            await db(
                """UPDATE user_balance SET casts = casts-1 WHERE user_id = $1""",
                ctx.author.id,
            )

        # Find out how many of those fish they caught previously
        amount = 0
        for row in user_inventory:
            if row["fish"] == chosen_fish.name:
                amount += 1

        # Set the fish file to the fishes image
        if fish_skin != "":
            fish_file = discord.File(
                f"{chosen_fish.image[:40]}{fish_skin}_{chosen_fish.image[40:]}", "new_fish.png")
        else:
            fish_file = discord.File(chosen_fish.image, "new_fish.png")

        # Tell the user about the fish they caught
        owned_unowned = "Owned" if amount > 0 else "Unowned"
        embed = discord.Embed(
            title=f"{EMOJIS['aqua_fish']} {ctx.author.display_name} caught {a_an} *{rarity_of_bag}* {chosen_fish.size} **{chosen_fish.name.replace('_', ' ').title()}**!"
        )
        embed.add_field(
            name=owned_unowned,
            value=f"You have {amount} **{chosen_fish.name.replace('_', ' ').title()}**",
            inline=False,
        )
        embed.set_image(url="attachment://new_fish.png")
        embed.color = utils.RARITY_CULERS[rarity_of_bag]

        # Ask if they want to sell the fish they just caught or keep it
        await ctx.send(file=fish_file)
        await utils.ask_to_sell_fish(self.bot, ctx, level_inserted=level, chosen_fish=chosen_fish, skin=fish_skin, embed=embed)

        # Remove them from current fishers
        utils.current_fishers.remove(ctx.author.id)