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
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
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
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
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}**." )
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
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." )
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]
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
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}" )
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}" )
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
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)
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()
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 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)