예제 #1
0
    async def pay(self, ctx, *args):
        quantity = args[1]
        quantity = RSMathHelpers(self.bot).numify(args[1])

        shortQuant = RSMathHelpers(self.bot).shortNumify(quantity, 1)

        if type(quantity) != int:
            await ctx.send('Please enter a valid number.')
            return

        usersQuantity = await Economy(self.bot).getNumberOfItem(
            ctx.author.id, 'duel_users', 'gp')

        if usersQuantity < quantity:
            await ctx.send('You do not have enough gp to do that.')
            return

        person = args[0].replace('@',
                                 '').replace('>',
                                             '').replace('<',
                                                         '').replace('!', '')

        await Economy(self.bot).removeItemFromUser(ctx.author.id, 'duel_users',
                                                   'gp', quantity)
        await Economy(self.bot).giveItemToUser(person, 'duel_users', 'gp',
                                               quantity)
        await ctx.send(f"You give {shortQuant} to <@!{person}>")
        return
예제 #2
0
    async def givegp(self, ctx, *args):
        quantity = args[1]
        quantity = RSMathHelpers(self.bot).numify(args[1])

        shortQuant = RSMathHelpers(self.bot).shortNumify(quantity, 1)

        if type(quantity) != int:
            await ctx.send('Please enter a valid number.')
            return

        person = args[0].replace('@',
                                 '').replace('>',
                                             '').replace('<',
                                                         '').replace('!', '')

        await Economy(self.bot).giveItemToUser(person, 'duel_users', 'gp',
                                               quantity)
        await ctx.send(f"You gave {shortQuant} to <@!{person}>")
        return
예제 #3
0
        async def getStakeType():
            stakeType = ""
            arguments = args[0]
            itemLongName = ""
            itemId = None

            if len(arguments) == 0:
                return None
            # If there is only one argument
            if len(arguments) == 1:
                # Try to convert the argument into a number, because the stake should be GP
                value = RSMathHelpers.numify(self, arguments[0])
                try:
                    # If the number did not successfully convert to a number, this will throw an exception when int(value) is called
                    # If it is successful, it will return "gp" to indicate a monetary stake
                    intValue = int(value)
                    stakeType = "gp"
                    return [stakeType, arguments[0]]
                except:
                    return None

            # If there are two arguments (could be "[quantity] [text]" or "[text] [text]")
            if len(arguments) == 2 or len(arguments) == 3:
                try:
                    # Try to convert the arguments into a a [name, quantity] array
                    # This will fail if the
                    stakeVals = await convertArgsToItemString(arguments)
                    if stakeVals == None:
                        return

                    # Check to see if the name of the item is in either of the item dictionaries
                    if stakeVals[0] in Economy(self.bot).rareIDs.keys():
                        stakeType = "rares"
                        itemLongName = Economy(
                            self.bot).rareIDs[stakeVals[0]][2]
                        itemId = Economy(self.bot).rareIDs[stakeVals[0]][0]
                        return [stakeType, itemLongName, itemId]
                    elif stakeVals[0] in Economy(self.bot).itemList.values():
                        stakeType = "items"
                        itemId = get_key(stakeVals[0],
                                         Economy(self.bot).itemList)
                        itemLongName = Economy(self.bot).getItemName(itemId)
                        return [stakeType, itemLongName, itemId]
                    else:
                        await message.send(
                            "Couldn't find that item, please try again.")
                        return
                except:
                    await message.send(
                        "Couldn't find that item, please try again.")
                    return
            else:
                await message.send("Something went wrong.")
                return None
예제 #4
0
    async def getItemValue(self, itemId):
        print("Trying to find price for", itemId)
        url = f'http://services.runescape.com/m=itemdb_oldschool/api/catalogue/detail.json?item={itemId}'

        try:
            response = requests.get(url)
            jsonResponse = response.json()
            itemPrice = jsonResponse['item']['current']['price']
            print("Price found", itemPrice)
            return RSMathHelpers.numify(self, itemPrice)
        except:
            print(f"Err fetching item {itemId} from Database.")
            return None
예제 #5
0
    async def dice(self, message, *args):
        diceAmount = 0
        helper = RSMathHelpers(self.bot)
        winStatus = ""
        try:
            helper = RSMathHelpers(self.bot)
            diceAmount = helper.numify(args[0])

            if diceAmount <= 0:
                await message.send("You can't dice less than 1 GP.")
                return
            elif diceAmount > 2000000000:
                await message.send("You can only dice up to 2B at once.")
                return

            diceAmountString = helper.shortNumify(diceAmount, 1)

            hasMoney = await helper.removeGPFromUser(message,
                                                     message.author.id,
                                                     diceAmount)

            if hasMoney == False:
                return

            rand = randint(1, 100)
            diceDescription = ''

            if rand >= 55:
                await helper.giveGPToUser(message, message.author.id,
                                          diceAmount * 2)
                diceDescription = f'You rolled a **{rand}** and won {diceAmountString} GP'
                winStatus = "won"
            else:
                diceDescription = f'You rolled a **{rand}** and lost {diceAmountString} GP.'
                winStatus = "lost"

            embed = discord.Embed(title='**Dice Roll**',
                                  description=diceDescription,
                                  color=discord.Color.orange())
            embed.set_thumbnail(
                url=
                'https://vignette.wikia.nocookie.net/runescape2/images/f/f2/Dice_bag_detail.png/revision/latest?cb=20111120013858'
            )
            await message.send(embed=embed)
        except:
            await message.send('You must dice a valid amount.')

        # If over 100M is diced, send it to the global notifications channel
        if diceAmount >= 500000000:
            notifChannel = self.bot.get_channel(689313376286802026)
            await notifChannel.send(
                f"{ItemEmojis.Coins.coins} {message.author.nick} has just diced **{helper.shortNumify(diceAmount, 1)}** and **{winStatus}**."
            )
예제 #6
0
        async def purchaseTicket(numTicks):

            # Check to see if the quantity is an integer
            try:
                quantity = int(numTicks)
            except:
                await ctx.send('You must purchase a whole number of tickets.')
                return False

            # SQL query
            sql = f"""
            INSERT INTO lottery (user_id, nick, numTickets) 
            VALUES 
            ({ctx.author.id}, '{ctx.author.nick}', {numTicks}) 
            ON CONFLICT (user_id) DO UPDATE 
            SET numTickets = lottery.numTickets + {numTicks}
            """
            conn = None

            # Count the number of tickets purchased
            totalTickets = 0

            # Execute sql
            try:
                conn = psycopg2.connect(DATABASE_URL)
                cur = conn.cursor()
                cur.execute(sql)
                cur.close()
                conn.commit()
            except (Exception, psycopg2.DatabaseError) as error:
                print(error)
                await ctx.send('Your tickets could not be purchased.')
                return False
            finally:
                if conn is not None:
                    conn.close()
            await Economy(self.bot).removeItemFromUser(ctx.author.id,
                                                       'duel_users', 'gp',
                                                       numTicks * 5000000)
            cost = RSMathHelpers(self.bot).shortNumify(numTicks * 5000000, 1)
            await ctx.send(
                f'You have purchased {numTicks} lottery tickets {ItemEmojis.Misc.ticket} for {cost} gp'
            )
            return True
예제 #7
0
        async def pickTable():
            # Pick a random number and assign it to the table
            rng = randint(0, 599)

            table = None

            # Roll for table
            if rng <= 5:
                table = self.superRareItems
            elif rng <= 35:
                table = self.rareItems
            elif rng <= 135:
                table = self.uncommonItems
            elif rng <= 599:
                table = self.commonItems

            # Roll for random value in table -- loot is a dictionary key
            loot = random.choice(list(table.keys()))

            # Roll for random loot quantity from min/max in value for key [loot]
            lootQuantity = randint(table[loot][1], table[loot][2])

            if self.lootArray.get(loot, None) != None:
                self.lootArray[loot][
                    0] = self.lootArray[loot][0] + lootQuantity
            elif self.lootArray.get(loot, None) == None:
                self.lootArray[loot] = [
                    lootQuantity, table[loot][3]
                ]  #Stores the quantity and emoji for the item

                # User his the super rare table, send notification

            if rng <= 5:
                ultraItemPrice = await Economy(self.bot).getItemValue(int(loot)
                                                                      )
                itemPriceString = RSMathHelpers(self.bot).shortNumify(
                    ultraItemPrice, 1)
                notifChannel = self.bot.get_channel(689313376286802026)
                await notifChannel.send(
                    f"{ItemEmojis.Coins.coins} **{ctx.author.nick}** hit the ultra rare drop table and received a **{table[loot][0]}** {table[loot][3]} worth {itemPriceString} GP."
                )
예제 #8
0
        async def convertArgsToItemString(args):

            itemName = ""
            itemQuantity = 0
            try:
                try:
                    # Test if the argument is an integer
                    itemQuantity = int(args[0])
                except:
                    # Test if the argument is a string
                    try:
                        placeholderQuantity = int(
                            RSMathHelpers.numify(self, args[0]))
                        if type(placeholderQuantity) == int:
                            itemQuantity = placeholderQuantity
                    except:
                        itemQuantity = None
                #If the first argument is an integer,
                if type(itemQuantity) != int:
                    await message.send('Please enter a valid quantity.')
                    return None
            except:
                await message.send('Please enter a quantity to stake.')
                return None

            if len(
                    args
            ) == 1:  # If the user didn't include an item to purchase, but did include a quantity (is staking GP)
                itemName = "GP"
            elif len(
                    args
            ) == 2:  # If the args was two values long, including an integer
                itemName = args[1]
            else:  # If the args was more than two words long, concatenate
                for n in range(1, len(args)):
                    itemName += args[n]

            # Cast the itemName to its lowercase version
            itemName = itemName.lower()
            # Return [name of item, quantity to stake]
            return [itemName, itemQuantity]
예제 #9
0
    async def rollPlayerKills(self, ctx, region):
        # Iterate through each region
        for region, data in self.locations.items():

            for player in data["players"]:

                # Create a version of the play array that doesn't include the current player being rolled
                dataCopy = data["players"].copy()
                dataCopy.remove(player)
                playerListMinusCurrent = dataCopy

                # Number of players in the region
                numPlayersInRegion = len(playerListMinusCurrent)

                # Base chance of running into another player in the region
                modifier = 128

                # Calculate chance of running into another player
                if numPlayersInRegion < 96:
                    modifier = modifier - numPlayersInRegion
                else:
                    modifier = 32

                # Roll the chance of finding another player
                # 0 means that another player is found
                # Minimum chance: 0.78% (for 1 other player)
                # Maximum chance: 3.125% (for 96+ other players)
                roll = randint(0, modifier)

                # If the player found another opponent in the wilderness
                if roll == 0:

                    # Pick a random player to attack
                    playerRoll = randint(0, numPlayersInRegion - 1)

                    # Find the attacked player
                    attackedPlayer = playerListMinusCurrent[playerRoll]

                    # Pick a winner for the fight
                    winner = random.choice([player, attackedPlayer])

                    # Remove the attacked player from the regional player list
                    # The attacking player was removed earlier when we ceated playerListMinusCurrent
                    print("START: Attempting to remove players from list",
                          data["players"])
                    data["players"].remove(player)
                    data["players"].remove(attackedPlayer)
                    print("END: Attempting to remove players from list",
                          data["players"])

                    loser = None

                    #
                    if winner == player:
                        loser = attackedPlayer
                    elif winner == attackedPlayer:
                        loser = player

                    # Update SQL status for the winner
                    await self.endTripSQL(winner)

                    # Update SQL status for the lower
                    await self.endTripSQL(loser)

                    # Steal the item
                    stolenItem = await self.stealOpponentsLoot(winner, loser)

                    # Sort the quantity of the item (most likely 1, but if it's gp it will format)
                    quant = RSMathHelpers(self.bot).shortNumify(
                        stolenItem['quantity'], 1)

                    # Send message notifying person that their item has been stolem
                    await ctx.send(
                        f"<@!{winner}> has killed <@!{loser}> for **{quant} {stolenItem['itemName']}** {stolenItem['emoji']}"
                    )

                    # Get the nicknames of the winner and loser
                    guildList = {}
                    for guild in self.bot.guilds:
                        if guild.get_member(winner) != None:
                            guildList['winner'] = guild.get_member(winner)

                        if guild.get_member(loser) != None:
                            guildList['loser'] = guild.get_member(loser)

                    # Send a notification to the notifications channel
                    notifChannel = self.bot.get_channel(689313376286802026)
                    await notifChannel.send(
                        f"**{guildList['winner'].nick}** has killed **{guildList['loser'].nick}** for **{stolenItem['quantity']} {stolenItem['itemName']}** {stolenItem['emoji']}"
                    )

                    # Return successful player kill attempt
                    return True
예제 #10
0
    async def buyherb(self, ctx, amount):

        await self.createSkillTable(ctx.author.id)

        if amount == 'info':
            # Display info about prayer
            embed = discord.Embed(
                title="Herblore bonuses",
                description="Damage multiplier based on level",
                color=discord.Color.green())
            embed.set_thumbnail(
                url=
                'https://oldschool.runescape.wiki/images/0/03/Herblore_icon.png?ffa9e'
            )

            description_1 = f"""{ItemEmojis.Potions.attack} Attack potions - 3 - +1%
            {ItemEmojis.Potions.strength} Strength potions - 12 - +2%
            {ItemEmojis.Potions.defence} Defence potions - 30 - +5%
            {ItemEmojis.Potions.prayer} Prayer potions - 38 - +10%
            {ItemEmojis.Potions.superAttack} Super attack potions - 45 - +20%
            {ItemEmojis.Potions.superStrength} Super strength potions - 55 - +30%
            {ItemEmojis.Potions.superRestore} Super restore potions - 63 - +40%
            """
            description_2 = f"""{ItemEmojis.Potions.superDefence} Super defence potions - 66 - +50%
            {ItemEmojis.Potions.divineSuperStrength} Divine combat potions - 70 - +60%
            {ItemEmojis.Potions.saradominBrew} Saradomin brews - 81 - +70%
            {ItemEmojis.Potions.superCombat} Super combat potion - 90 - +80%
            {ItemEmojis.Potions.divineSuperCombat} Divine super combat potions - 90 - +90%
            {ItemEmojis.Skills.herblore} Mastery - 99 - +100%
            """

            description_3 = """Herblore experience costs **350 GP** per 1 experience
            To buy Herblore experience, use .buyherb (GP amount)
            """

            embed.add_field(name='\u200b', value=description_1, inline=True)
            embed.add_field(name='\u200b', value=description_2, inline=True)
            embed.add_field(name='\u200b', value=description_3, inline=False)

            await ctx.send(embed=embed)
            return

        else:
            amount = RSMathHelpers(self.bot).numify(amount)
            if amount < 200:
                await ctx.send(
                    'You must purchase at least 1 xp. Each experience point costs 350 gp.'
                )
                return

            userGP = await Economy(self.bot
                                   ).getNumberOfItem(ctx.author.id,
                                                     'duel_users', 'gp')

            if amount > userGP:
                print("Here!")
                await ctx.send("You don't have that much GP.")
                return

            print("Didn't make it here herb")
            shortAmount = RSMathHelpers(self.bot).shortNumify(amount, 1)
            herbXP = math.floor(amount / 350)
            shortHerbXp = RSMathHelpers(self.bot).shortNumify(herbXP, 1)

            if type(amount) != int:

                await ctx.send("Please enter a valid amount.")

            else:

                userGP = await Economy(self.bot).getNumberOfItem(
                    ctx.author.id, 'duel_users', 'gp')

                if userGP >= amount:

                    await Economy(self.bot
                                  ).removeItemFromUser(ctx.author.id,
                                                       'duel_users', 'gp',
                                                       amount)

                    startLevel = await self.getLevel(ctx.author.id, 'herblore')
                    await self.addExperienceToStat(ctx.author.id, 'herblore',
                                                   herbXP)
                    endLevel = await self.getLevel(ctx.author.id, 'herblore')

                    levelUpMessage = ""
                    if endLevel > startLevel:
                        levelUpMessage = f"Your herblore level is now {endLevel}."

                    await ctx.send(
                        f"{ItemEmojis.Skills.herblore} You have purchased {shortHerbXp} herblore experience for {shortAmount} GP. {levelUpMessage}"
                    )
예제 #11
0
    async def buybones(self, ctx, amount):
        await self.createSkillTable(ctx.author.id)

        if amount == 'info':
            # Display info about prayer
            embed = discord.Embed(
                title="Prayer bonuses",
                description="Damage multiplier based on level",
                color=discord.Color.from_rgb(250, 250, 250))
            embed.set_thumbnail(
                url=
                'https://oldschool.runescape.wiki/images/f/f2/Prayer_icon.png?ca0dc'
            )

            description_1 = f"""{ItemEmojis.Prayers.thickSkin} Thick skin - 1 - +0%
            {ItemEmojis.Prayers.burstOfStrength} Burst of Strength - 4 - +2%
            {ItemEmojis.Prayers.clarityOfThought} Clarity of Thought - 7 - +3.5%
            {ItemEmojis.Prayers.rockSkin} Rock Skin - 10 - +5%
            {ItemEmojis.Prayers.superhumanStrength} Superhm. Strength - 13 - +6.5%
            {ItemEmojis.Prayers.improvedReflexes} Improved Reflexes - 14 - +7%
            """
            description_2 = f"""{ItemEmojis.Prayers.steelSkin} Steel Skin - 28 - +14%
            {ItemEmojis.Prayers.ultimateStrength} Ultimate Strength - 31 - +15.5%
            {ItemEmojis.Prayers.incredibleReflexes} Incredible Reflexes - 34 - +17%
            {ItemEmojis.Prayers.chivalry} Chivalry - 60 - +30%
            {ItemEmojis.Prayers.piety} Piety - 70 - +35%
            {ItemEmojis.Skills.prayer} Mastery - 99 - 60%
            """

            description_3 = f"""Prayer experience costs **200 GP** per 1 experience
            To buy Prayer experience, use .buybones (GP amount)

            Your effective multiplier grows by ~0.5% per level, with a 10% bonus at 99.
            Even if your level is between upgrades, you will get a bonus. *(e.g. 80 prayer for +40%)*
            """

            embed.add_field(name='\u200b', value=description_1, inline=True)
            embed.add_field(name='\u200b', value=description_2, inline=True)
            embed.add_field(name='\u200b', value=description_3, inline=False)

            await ctx.send(embed=embed)
            return

        else:
            amount = RSMathHelpers(self.bot).numify(amount)
            if amount < 200:
                await ctx.send(
                    'You must purchase at least 1 xp. Each experience point costs 200 gp.'
                )
                return

            userGP = await Economy(self.bot
                                   ).getNumberOfItem(ctx.author.id,
                                                     'duel_users', 'gp')

            if amount > userGP:
                print("Here!")
                await ctx.send("You don't have that much GP.")
                return

            print("Didn't make it here")
            shortAmount = RSMathHelpers(self.bot).shortNumify(amount, 1)
            prayerXP = math.floor(amount / 200)
            shortPrayerXP = RSMathHelpers(self.bot).shortNumify(prayerXP, 1)

            if type(amount) != int:

                await ctx.send("Please enter a valid amount.")

            else:
                userGP = await Economy(self.bot).getNumberOfItem(
                    ctx.author.id, 'duel_users', 'gp')

                if userGP >= amount:

                    await Economy(self.bot
                                  ).removeItemFromUser(ctx.author.id,
                                                       'duel_users', 'gp',
                                                       amount)

                    startLevel = await self.getLevel(ctx.author.id, 'prayer')
                    await self.addExperienceToStat(ctx.author.id, 'prayer',
                                                   prayerXP)
                    endLevel = await self.getLevel(ctx.author.id, 'prayer')

                    levelUpMessage = ""
                    if endLevel > startLevel:
                        levelUpMessage = f"Your prayer level is now {endLevel}."

                    await ctx.send(
                        f"{ItemEmojis.Skills.prayer} You have purchased {shortPrayerXP} prayer experience for {shortAmount} GP. {levelUpMessage}"
                    )
예제 #12
0
        async def checkUsersItemQuantity(user):

            if channelDuel != None and stakeParams[1] == None:
                if channelDuel.stakeItem == 'gp':
                    await message.send(
                        f"You don't have {channelDuel.shortQuantity} GP to stake."
                    )
                else:
                    if len(args[0]) == 0:
                        return True
                    else:
                        if stakeParams[0] != channelDuel.itemLongName.replace(
                                ' ', '').lower():
                            await message.send(
                                f'Please type **.fight {channelDuel.shortQuantity} {channelDuel.itemLongName}** to enter this duel.'
                            )
                        elif stakeParams[
                                0] == channelDuel.itemLongName.replace(
                                    ' ', '').lower():
                            await message.send(
                                f"You don't have {channelDuel.shortQuantity} {channelDuel.itemLongName} to stake."
                            )
                return False

            # Sort out values
            _itemType = stakeType[0]
            _fullItemName = stakeType[1]
            _itemId = None
            _shortItemName = stakeParams[0]
            _itemQuantity = stakeParams[1]
            _table = None

            if _itemType == 'gp':
                _table = 'duel_users'
                _itemId = 'gp'
            elif _itemType == 'rares':
                _table = 'duel_rares'
                _itemId = f"_{stakeType[2]}"
            elif _itemType == 'items':
                _table = 'pking_items'
                _itemId = f"_{stakeType[2]}"

            _userQuantity = await Economy(self.bot).getNumberOfItem(
                user.id, _table, f"{_itemId}")

            if _userQuantity < _itemQuantity:
                if _itemType == 'gp':
                    if message.author.id == user.id:
                        await message.send(
                            f"You don't have {_shortItemName} to stake.")
                    else:
                        await message.send(
                            f"{user.nick} does not {_shortItemName} to stake.")
                else:
                    shortQuantity = RSMathHelpers(self.bot).shortNumify(
                        _itemQuantity, 1)

                    if message.author.id == user.id:
                        await message.send(
                            f"You don't have {shortQuantity} {_fullItemName} to stake."
                        )
                    else:
                        await message.send(
                            f"{user.nick} does not have {shortQuantity} {_fullItemName} to stake"
                        )
                return False
            elif _userQuantity >= _itemQuantity:
                return True
예제 #13
0
    async def createDuel(self, message, *args):
        async def convertArgsToItemString(args):

            itemName = ""
            itemQuantity = 0
            try:
                try:
                    # Test if the argument is an integer
                    itemQuantity = int(args[0])
                except:
                    # Test if the argument is a string
                    try:
                        placeholderQuantity = int(
                            RSMathHelpers.numify(self, args[0]))
                        if type(placeholderQuantity) == int:
                            itemQuantity = placeholderQuantity
                    except:
                        itemQuantity = None
                #If the first argument is an integer,
                if type(itemQuantity) != int:
                    await message.send('Please enter a valid quantity.')
                    return None
            except:
                await message.send('Please enter a quantity to stake.')
                return None

            if len(
                    args
            ) == 1:  # If the user didn't include an item to purchase, but did include a quantity (is staking GP)
                itemName = "GP"
            elif len(
                    args
            ) == 2:  # If the args was two values long, including an integer
                itemName = args[1]
            else:  # If the args was more than two words long, concatenate
                for n in range(1, len(args)):
                    itemName += args[n]

            # Cast the itemName to its lowercase version
            itemName = itemName.lower()
            # Return [name of item, quantity to stake]
            return [itemName, itemQuantity]

        def get_key(val, itemDict):
            for key, value in itemDict.items():
                if val == value:
                    return key
            return None

        async def getStakeType():
            stakeType = ""
            arguments = args[0]
            itemLongName = ""
            itemId = None

            if len(arguments) == 0:
                return None
            # If there is only one argument
            if len(arguments) == 1:
                # Try to convert the argument into a number, because the stake should be GP
                value = RSMathHelpers.numify(self, arguments[0])
                try:
                    # If the number did not successfully convert to a number, this will throw an exception when int(value) is called
                    # If it is successful, it will return "gp" to indicate a monetary stake
                    intValue = int(value)
                    stakeType = "gp"
                    return [stakeType, arguments[0]]
                except:
                    return None

            # If there are two arguments (could be "[quantity] [text]" or "[text] [text]")
            if len(arguments) == 2 or len(arguments) == 3:
                try:
                    # Try to convert the arguments into a a [name, quantity] array
                    # This will fail if the
                    stakeVals = await convertArgsToItemString(arguments)
                    if stakeVals == None:
                        return

                    # Check to see if the name of the item is in either of the item dictionaries
                    if stakeVals[0] in Economy(self.bot).rareIDs.keys():
                        stakeType = "rares"
                        itemLongName = Economy(
                            self.bot).rareIDs[stakeVals[0]][2]
                        itemId = Economy(self.bot).rareIDs[stakeVals[0]][0]
                        return [stakeType, itemLongName, itemId]
                    elif stakeVals[0] in Economy(self.bot).itemList.values():
                        stakeType = "items"
                        itemId = get_key(stakeVals[0],
                                         Economy(self.bot).itemList)
                        itemLongName = Economy(self.bot).getItemName(itemId)
                        return [stakeType, itemLongName, itemId]
                    else:
                        await message.send(
                            "Couldn't find that item, please try again.")
                        return
                except:
                    await message.send(
                        "Couldn't find that item, please try again.")
                    return
            else:
                await message.send("Something went wrong.")
                return None

        # Returns [stake type, full name, itemId]
        # Stake type can be 'items', 'rares', or 'gp'
        # i.e. ['rares', 'Christmas cracker', 962]
        stakeType = await getStakeType()

        # Get the item quantity and itemName for the stake
        # Returned as [itemName, itemQuantity]
        # i.e. ['christmasCracker', 1]
        stakeParams = None
        if stakeType == None:
            #If the duel is just a regular old duel
            stakeParams = [None, None]
        else:
            stakeParams = await convertArgsToItemString(args[0])

        # Get the global duel
        channelDuel = globals.duels.get(message.channel.id, None)

        # Determine if the user has enough of the item
        async def checkUsersItemQuantity(user):

            if channelDuel != None and stakeParams[1] == None:
                if channelDuel.stakeItem == 'gp':
                    await message.send(
                        f"You don't have {channelDuel.shortQuantity} GP to stake."
                    )
                else:
                    if len(args[0]) == 0:
                        return True
                    else:
                        if stakeParams[0] != channelDuel.itemLongName.replace(
                                ' ', '').lower():
                            await message.send(
                                f'Please type **.fight {channelDuel.shortQuantity} {channelDuel.itemLongName}** to enter this duel.'
                            )
                        elif stakeParams[
                                0] == channelDuel.itemLongName.replace(
                                    ' ', '').lower():
                            await message.send(
                                f"You don't have {channelDuel.shortQuantity} {channelDuel.itemLongName} to stake."
                            )
                return False

            # Sort out values
            _itemType = stakeType[0]
            _fullItemName = stakeType[1]
            _itemId = None
            _shortItemName = stakeParams[0]
            _itemQuantity = stakeParams[1]
            _table = None

            if _itemType == 'gp':
                _table = 'duel_users'
                _itemId = 'gp'
            elif _itemType == 'rares':
                _table = 'duel_rares'
                _itemId = f"_{stakeType[2]}"
            elif _itemType == 'items':
                _table = 'pking_items'
                _itemId = f"_{stakeType[2]}"

            _userQuantity = await Economy(self.bot).getNumberOfItem(
                user.id, _table, f"{_itemId}")

            if _userQuantity < _itemQuantity:
                if _itemType == 'gp':
                    if message.author.id == user.id:
                        await message.send(
                            f"You don't have {_shortItemName} to stake.")
                    else:
                        await message.send(
                            f"{user.nick} does not {_shortItemName} to stake.")
                else:
                    shortQuantity = RSMathHelpers(self.bot).shortNumify(
                        _itemQuantity, 1)

                    if message.author.id == user.id:
                        await message.send(
                            f"You don't have {shortQuantity} {_fullItemName} to stake."
                        )
                    else:
                        await message.send(
                            f"{user.nick} does not have {shortQuantity} {_fullItemName} to stake"
                        )
                return False
            elif _userQuantity >= _itemQuantity:
                return True

        if len(args[0]) != 0:
            user1HasItem = await checkUsersItemQuantity(message.author)

            if user1HasItem == False:
                return

        # Returns an array that details
        # where the user should have their info pulled to/written to
        # i.e. ['gp', 'duel_users'] or ['_1040', 'duel_rares']
        def returnTableColumn():
            # Sort out values
            _itemType = None
            if stakeType != None:
                _itemType = stakeType[0]
            _itemId = None
            _table = None

            if _itemType == 'gp':
                _table = 'duel_users'
                _itemId = 'gp'
            elif _itemType == 'rares':
                _table = 'duel_rares'
                _itemId = f"_{stakeType[2]}"
            elif _itemType == 'items':
                _table = 'pking_items'
                _itemId = f"_{stakeType[2]}"

            return [_itemId, _table]

        if channelDuel != None:
            if len(args[0]) > 0:
                if str(args[0][0]).lower() != str(
                        channelDuel.shortQuantity).lower(
                        ) and channelDuel.stakeItem == 'gp':
                    await message.send(
                        f'Please type **.fight {channelDuel.shortQuantity}** to enter this duel.'
                    )
                    return
                elif str(args[0][0]).lower() != str(
                        channelDuel.shortQuantity).lower(
                        ) and channelDuel.stakeItem != 'gp' and stakeParams[
                            0] != channelDuel.itemLongName.replace(' ',
                                                                   '').lower():
                    await message.send(
                        f'Please type **.fight {channelDuel.shortQuantity} {channelDuel.itemLongName}** to enter this duel.'
                    )
                    return
                else:
                    pass

            if channelDuel.stakeItem != None:
                userHasQuantity = await checkUsersItemQuantity(message.author)

                if userHasQuantity == False:
                    return

        # Check to see if a duel exists in the channel
        if channelDuel == None:
            if len(args[0]) == 0:
                # If the duel is not for any particular amount of money
                globals.duels[message.channel.id] = globals.Duel(
                    globals.DuelUser(message.author), uuid.uuid4(),
                    message.channel.id, None, None, None, None, None)
                channelDuel = globals.duels.get(message.channel.id, None)
                globals.lastMessages[message.channel.id] = await message.send(
                    f"{message.author.nick} has started a duel. Type **.fight** to duel them."
                )
                await self.startCancelCountdown(message, channelDuel.uuid)
                return
            elif args != None:
                # If the stake has a value attached to it
                table = returnTableColumn()

                if stakeParams[1] < 0:
                    await message.send(
                        "You cannot stake less than 1 of an item.")
                    return

                globals.duels[message.channel.id] = globals.Duel(
                    globals.DuelUser(message.author), uuid.uuid4(),
                    message.channel.id, table[0], stakeParams[1], table[1],
                    stakeType[1],
                    RSMathHelpers(self.bot).shortNumify(stakeParams[1], 1))
                channelDuel = globals.duels.get(message.channel.id, None)
                if stakeType[0] == 'gp':
                    globals.lastMessages[
                        message.channel.id] = await message.send(
                            f"**{message.author.nick}** has started a duel for **{args[0][0]} GP**. Type **.fight {args[0][0]}** to duel them."
                        )
                else:
                    globals.lastMessages[
                        message.channel.id] = await message.send(
                            f"**{message.author.nick}** has started a duel for **{args[0][0]} {stakeType[1]}**. Type **.fight {RSMathHelpers(self.bot).shortNumify(stakeParams[1], 1)} {stakeType[1]}** to duel them."
                        )

                await self.startCancelCountdown(message, channelDuel.uuid)
                return
        else:
            if channelDuel.stakeItem != None:
                userHasQuantity = await checkUsersItemQuantity(message.author)

                if userHasQuantity == False:
                    return

        # Check to see if the person is dueling themselves
        if self.check(message.author, message.channel.id) == False:
            await message.send("You cannot duel yourself.")
            return

        # Check to see if a duel already exists between two people
        if channelDuel.user_1 != None and channelDuel.user_2 != None:
            await message.send("There are already two people dueling.")
            return

        # Check to see if player 2 has the required items to participate in the stake
        player2HasQuantity = await checkUsersItemQuantity(message.author)
        if player2HasQuantity == False:
            return

        # # If it passed the other checks, add duel user 2 to the fight
        # channelDuel.user_2 = globals.DuelUser(message.author)

        if channelDuel.stakeItem != None and channelDuel.stakeQuantity != None:
            tableValues = returnTableColumn()

            if len(args[0]) == 0:
                await message.send(
                    f'Please type **.fight {channelDuel.shortQuantity} {channelDuel.itemLongName}** to enter this duel.'
                )
                return
            if stakeType[1].replace(
                    ' ', '').lower() == channelDuel.itemLongName.replace(
                        ' ', '').lower():
                player1HasQuantityStill = await checkUsersItemQuantity(
                    channelDuel.user_1.user)
                if player1HasQuantityStill == False:
                    await message.send(
                        f"Cancelling the duel because {channelDuel.user_1.user.nick} no longer has {RSMathHelpers(self.bot).shortNumify(stakeParams[1], 1)} {stakeType[1]}."
                    )
                    del globals.duels[message.channel.id]
                    return
            elif stakeType[1].replace(
                    ' ', '').lower() != channelDuel.itemLongName.replace(
                        ' ', '').lower():
                await message.send(
                    f"The current duel is not for {stakeType[1]}.")
                return

            # If it passed the other checks, add duel user 2 to the fight
            channelDuel.user_2 = globals.DuelUser(message.author)

            await Economy(self.bot).removeItemFromUser(
                channelDuel.user_1.user.id, channelDuel.table,
                channelDuel.stakeItem, channelDuel.stakeQuantity)
            await Economy(self.bot).removeItemFromUser(
                channelDuel.user_2.user.id, channelDuel.table,
                channelDuel.stakeItem, channelDuel.stakeQuantity)
        elif channelDuel.stakeItem == None:
            channelDuel.user_2 = globals.DuelUser(message.author)

        # Randomly pick a starting user
        startingUserBool = bool(random.getrandbits(1))
        startingUser = None
        if startingUserBool == True:
            startingUser = channelDuel.user_1
            channelDuel.turn = channelDuel.user_1
        else:
            startingUser = channelDuel.user_2
            channelDuel.turn = channelDuel.user_2

        try:
            del globals.lastMessages[message.channel.id]
        except:
            pass

        await message.send(
            f"Beginning duel between {channelDuel.user_1.user.nick} and {channelDuel.user_2.user.nick} \n**{startingUser.user.nick}** goes first."
        )

        if channelDuel.user_1 != None and channelDuel.user_2 != None:
            await self.beginFightTurnChecker(message, channelDuel)
예제 #14
0
    async def pickWinner(self):

        print('attempting to pick winner!')
        totalTickets = 0
        ticketArray = []

        def pickWinnerFromArray():
            if len(ticketArray) > 0:
                return random.choice(ticketArray)
            else:
                return None

        sql = """
        SELECT
        user_id,
        nick,
        numTickets
        FROM lottery
        """
        conn = None

        try:
            conn = psycopg2.connect(DATABASE_URL)
            cur = conn.cursor()
            cur.execute(sql)
            rows = cur.fetchall()
            for row in rows:
                print(row)
                totalTickets += row[2]
                for n in range(1, row[2]):
                    ticketArray.append([row[0], row[1], row[2]])
            cur.close()
            conn.commit()
        except (Exception, psycopg2.DatabaseError) as error:
            print(error)
            return
        finally:
            if conn is not None:
                conn.close()

        def clearWinnerDB():

            sql = "DELETE FROM lottery"
            conn = None

            try:
                conn = psycopg2.connect(DATABASE_URL)
                cur = conn.cursor()
                cur.execute(sql)
                cur.close()
                conn.commit()
            except (Exception, psycopg2.DatabaseError) as error:
                print(error)
                return
            finally:
                if conn is not None:
                    conn.close()

        # Pick a winner
        winnerList = pickWinnerFromArray()

        # Calculate the prize money
        totalPrize = RSMathHelpers(self.bot).shortNumify(
            (totalTickets * 4500000) + 100000000, 1)

        # Log that someone won the lottery
        print(f"Lottery winner chosen! {winnerList[0]} wins {totalPrize}")

        # Give the winner their prize money
        await Economy(self.bot
                      ).giveItemToUser(winnerList[0], 'duel_users', 'gp',
                                       (totalTickets * 4500000) + 100000000)

        # Send notification to the #notifications channel of the lottery winner
        notifChannel = self.bot.get_channel(689313376286802026)
        await notifChannel.send(
            f"**{winnerList[1]}** has won the lottery worth **{totalPrize}**! \n The next lottery will be in 12 hours. Use *.lottery buy (quantity)* to buy tickets for 5m each."
        )

        # Empty the lottery DB
        clearWinnerDB()
예제 #15
0
        async def getNumTickets():
            def timeUntilNoon():
                now = datetime.now()
                today = datetime.now()
                lottoEndPM = datetime(year=today.year,
                                      month=today.month,
                                      day=today.day,
                                      hour=1,
                                      minute=0,
                                      second=0)

                pmDelta = lottoEndPM - now

                delta = pmDelta

                seconds = delta.seconds
                hours = math.floor(seconds / 3600)
                minutes = math.floor((seconds / 60) % 60)
                timeSeconds = math.ceil(seconds - (hours * 3600) -
                                        (minutes * 60))

                return [hours, minutes, timeSeconds]

            sql = """
            SELECT
            numTickets
            FROM lottery
            """
            conn = None
            totalTickets = 0

            try:
                conn = psycopg2.connect(DATABASE_URL)
                cur = conn.cursor()
                cur.execute(sql)
                rows = cur.fetchall()
                for row in rows:
                    totalTickets += row[0]
                cur.close()
                conn.commit()
            except (Exception, psycopg2.DatabaseError) as error:
                print(error)
            finally:
                if conn is not None:
                    conn.close()

            totalPrize = RSMathHelpers(self.bot).shortNumify(
                (totalTickets * 4500000) + 100000000, 1)
            timeLeft = timeUntilNoon()

            sql2 = f"""
            SELECT
            numTickets
            FROM lottery
            WHERE user_id = {ctx.author.id}
            """
            conn = None
            userTickets = 0

            try:
                conn = psycopg2.connect(DATABASE_URL)
                cur = conn.cursor()
                cur.execute(sql2)
                rows = cur.fetchall()
                for row in rows:
                    userTickets += row[0]
                cur.close()
                conn.commit()
            except (Exception, psycopg2.DatabaseError) as error:
                print(error)
            finally:
                if conn is not None:
                    conn.close()

                description = f"""You have purchased **{userTickets}** tickets 
                Total tickets in lottery: **{totalTickets}**
                Total lottery prize: **{totalPrize}**
                Lottery ends in {timeLeft[0]} hours, {timeLeft[1]} minutes, and {timeLeft[2]} seconds."""

                embed = discord.Embed(title="DuelBot lottery",
                                      description=description,
                                      color=discord.Color.gold())
                embed.set_thumbnail(
                    url=
                    'https://oldschool.runescape.wiki/images/5/52/Castle_wars_ticket.png?190d3'
                )
                await ctx.send(embed=embed)
예제 #16
0
    async def lottery(self, ctx, *args):

        quantity = None
        print(args)
        if len(args) > 0:
            if args[0] == 'buy':
                quantity = int(args[1])

        async def getNumTickets():
            def timeUntilNoon():
                now = datetime.now()
                today = datetime.now()
                lottoEndPM = datetime(year=today.year,
                                      month=today.month,
                                      day=today.day,
                                      hour=1,
                                      minute=0,
                                      second=0)

                pmDelta = lottoEndPM - now

                delta = pmDelta

                seconds = delta.seconds
                hours = math.floor(seconds / 3600)
                minutes = math.floor((seconds / 60) % 60)
                timeSeconds = math.ceil(seconds - (hours * 3600) -
                                        (minutes * 60))

                return [hours, minutes, timeSeconds]

            sql = """
            SELECT
            numTickets
            FROM lottery
            """
            conn = None
            totalTickets = 0

            try:
                conn = psycopg2.connect(DATABASE_URL)
                cur = conn.cursor()
                cur.execute(sql)
                rows = cur.fetchall()
                for row in rows:
                    totalTickets += row[0]
                cur.close()
                conn.commit()
            except (Exception, psycopg2.DatabaseError) as error:
                print(error)
            finally:
                if conn is not None:
                    conn.close()

            totalPrize = RSMathHelpers(self.bot).shortNumify(
                (totalTickets * 4500000) + 100000000, 1)
            timeLeft = timeUntilNoon()

            sql2 = f"""
            SELECT
            numTickets
            FROM lottery
            WHERE user_id = {ctx.author.id}
            """
            conn = None
            userTickets = 0

            try:
                conn = psycopg2.connect(DATABASE_URL)
                cur = conn.cursor()
                cur.execute(sql2)
                rows = cur.fetchall()
                for row in rows:
                    userTickets += row[0]
                cur.close()
                conn.commit()
            except (Exception, psycopg2.DatabaseError) as error:
                print(error)
            finally:
                if conn is not None:
                    conn.close()

                description = f"""You have purchased **{userTickets}** tickets 
                Total tickets in lottery: **{totalTickets}**
                Total lottery prize: **{totalPrize}**
                Lottery ends in {timeLeft[0]} hours, {timeLeft[1]} minutes, and {timeLeft[2]} seconds."""

                embed = discord.Embed(title="DuelBot lottery",
                                      description=description,
                                      color=discord.Color.gold())
                embed.set_thumbnail(
                    url=
                    'https://oldschool.runescape.wiki/images/5/52/Castle_wars_ticket.png?190d3'
                )
                await ctx.send(embed=embed)

        async def purchaseTicket(numTicks):

            # Check to see if the quantity is an integer
            try:
                quantity = int(numTicks)
            except:
                await ctx.send('You must purchase a whole number of tickets.')
                return False

            # SQL query
            sql = f"""
            INSERT INTO lottery (user_id, nick, numTickets) 
            VALUES 
            ({ctx.author.id}, '{ctx.author.nick}', {numTicks}) 
            ON CONFLICT (user_id) DO UPDATE 
            SET numTickets = lottery.numTickets + {numTicks}
            """
            conn = None

            # Count the number of tickets purchased
            totalTickets = 0

            # Execute sql
            try:
                conn = psycopg2.connect(DATABASE_URL)
                cur = conn.cursor()
                cur.execute(sql)
                cur.close()
                conn.commit()
            except (Exception, psycopg2.DatabaseError) as error:
                print(error)
                await ctx.send('Your tickets could not be purchased.')
                return False
            finally:
                if conn is not None:
                    conn.close()
            await Economy(self.bot).removeItemFromUser(ctx.author.id,
                                                       'duel_users', 'gp',
                                                       numTicks * 5000000)
            cost = RSMathHelpers(self.bot).shortNumify(numTicks * 5000000, 1)
            await ctx.send(
                f'You have purchased {numTicks} lottery tickets {ItemEmojis.Misc.ticket} for {cost} gp'
            )
            return True

        if len(args) == 0:
            await getNumTickets()
        # If the comand is to buy a ticket and there is a valid quantity being purchased
        elif args[0] == 'buy' and type(quantity) == int:

            # Get the user's current FP
            userGP = await Economy(self.bot
                                   ).getNumberOfItem(ctx.author.id,
                                                     'duel_users', 'gp')

            # Verify the user has enough gp to make the purchase
            if userGP >= quantity * 5000000:
                # Attempt to purchase the ticket if the user has enough gp
                success = await purchaseTicket(quantity)
                if success == False:
                    return
            else:
                # Return a message saying the user doesn't have enough gp
                cost = RSMathHelpers(self.bot).shortNumify(
                    quantity * 5000000, 1)
                await ctx.send(
                    f"You need {cost} gp to purchase {quantity} lottery tickets."
                )
                return

        # If the command is to get info about the lottery
        elif args[0] == 'info':
            await getNumTickets()

        # User wants more info about the lottery
        elif args[0] == 'help':
            message = """
            ```Lottery commands
            .lottery buy (number) - buys lottery tickets for 5m gp each
            .lottery or .lottery info - shows information about the current lottery```
            """

            await ctx.send(message)