async def ign(self, ctx, ign=None): if ign is None: await ctx.send( "Please provide your Werewolf Online in-game name: `;ign example_name`" ) return user = User.fetch_by_id(ctx, ctx.author.id) old_ign = user.ign user.ign = ign self.client.get_cog("TOrganizer").cache_ign(ctx.author, ign) await ctx.send( f"{Emote.check} {ctx.author.mention}, your Werewolf Online IGN has been set to `{ign}`." ) Log("IGN Set", description=f"{ctx.author.mention} has set their IGN to `{ign}`.", color=0x6a0dad, fields=[{ 'name': 'Previous IGN', 'value': old_ign }])
async def begin(self, ctx): if self.tournament.status != Status.Opened: raise commands.BadArgument( "The tournament cannot be closed right now.") if len(self.tournament.get_participants()) < 1: raise commands.BadArgument( "There are no participants in the tournament.") no_ign = "" for player in self.tournament.get_participants(): user = User.fetch_by_id(ctx, player.id) if user.ign is None: no_ign += f"**{player.name}**\n" if no_ign != "": raise commands.BadArgument( "Some players do not have an IGN set: \n" + no_ign) await ctx.send( f"{Emote.check} The tournament has been closed. Players can no longer join!" ) self.tournament.status = Status.Closed Log("Tournament Closed", description= f"{ctx.author.mention} closed **{self.tournament.name}**.", color=Color.dark_orange()) await self.tournament.msg.clear_reactions() embed = UpdatedEmbed(self.tournament) await self.tournament.msg.edit(embed=embed)
async def join(self, ctx): await self.CheckRequirements(ctx.author) player_count = len(self.tournament.get_participants()) mod_index = ModifierCheck("MaxParticipants", self.tournament.modifiers) if mod_index is not False: max_count = self.tournament.modifiers[mod_index]['value'] else: max_count = 15 # Default if player_count >= max_count: raise TournamentJoinException( f"the tournament is full! The maximum number of participants is **{str(max_count)}**." ) join_msg = f"{Emote.join} {ctx.author.mention} joined. **{str(player_count + 1)}** players are now ready." if player_count == 0: # First join, make singular i = join_msg[-35:].index("s are") + len(join_msg) - 35 join_msg = join_msg[:i] + " is" + join_msg[i + 5:] user = User.fetch_by_id(ctx, ctx.author.id) if user.participations == 0: join_msg += "\nThis is the first tournament they are participating in. Welcome! 🎉" await SendFirstTournamentMessage(ctx) if user.ign is None: join_msg += "\nThis player does not have an IGN set yet." else: join_msg += f"\nIGN: `{user.ign}`" ign_cache[ctx.author.id] = user.ign await ctx.author.add_roles(self.roles.participant) await ctx.author.remove_roles(self.roles.spectator) await self.channels.t_chat.send(join_msg) Log("Participant Joined", description= f"{ctx.author.mention} joined **{self.tournament.name}**.", color=Color.dark_green(), fields=[{ 'name': "Player Count", 'value': str(player_count + 1) }]) self.tournament.add_participant(ctx.author) if ctx.author in self.tournament.spectators: self.tournament.spectators.remove(ctx.author) embed = UpdatedEmbed(self.tournament) await self.tournament.msg.edit(embed=embed) await self.checklist.update_text(ctx, self.tournament)
async def stats(self, ctx, target: discord.Member = None): if target is None: target = ctx.author user = User.fetch_by_id(ctx, target.id) losses = user.participations - user.wins if user.participations > 0: raw_win_rate = user.wins / user.participations * 100 win_rate = str(round(raw_win_rate, 2)) + "%" else: win_rate = None if user.ign is not None: ign_text = user.ign else: ign_text = "`None`" xp_required = user.level * 100 xp_percentage = int(user.xp / xp_required * 100) full_progress = f"{user.progress_bar} `{xp_percentage}%`" xp_info = f"Level **{user.level}**\n{user.xp}/{xp_required}\n" embed = discord.Embed(title="Tournament Statistics", color=target.color) username = target.name + "#" + target.discriminator embed.set_author(name=username) embed.set_thumbnail(url=target.avatar_url) embed.add_field(name="In-Game Name", value=ign_text) embed.add_field(name="Tournaments Joined", value=user.participations) embed.add_field(name="Tournaments Hosted", value=user.hosted) embed.add_field(name="Wins", value=user.wins) embed.add_field(name="Losses", value=losses) embed.add_field(name="Win Rate", value=win_rate) embed.add_field(name="Current Win Streak", value=user.streak) embed.add_field(name="Max Win Streak", value=user.max_streak) embed.add_field(name="Experience", value=xp_info + full_progress, inline=False) await ctx.send(embed=embed)
async def setign(self, ctx, member: discord.Member, ign): user = User.fetch_by_id(ctx, member.id) old_ign = user.ign user.ign = ign self.client.get_cog("TOrganizer").cache_ign(member, ign) await ctx.send( f"{Emote.check} {ctx.author.mention}, **{member.name}**'s IGN has been set to `{ign}`." ) Log("IGN Set (Staff)", description= f"{ctx.author.mention} has set {member.mention}'s IGN to `{ign}`.", color=0x4a0dff, fields=[{ 'name': 'Previous IGN', 'value': old_ign }])
async def _set(self, ctx, stat, user: discord.Member, amount: int): if stat not in STATS_LIST: raise commands.BadArgument( f"The `{stat}` stat doesn't exist! Check your spelling and" " make sure everything is lowercase!") profile = User.fetch_by_id(ctx, user.id) current = getattr(profile, stat) setattr(profile, stat, amount) await ctx.send( f"{Emote.check} Set **{user.name}**'s {stat} to {str(amount)}.") Log(title=f"{stat.capitalize()} Set", description= f"{ctx.author.mention} set {user.mention}'s {stat} to {str(amount)}.", fields=[{ "name": "Value", "value": f"{str(current)} -> {str(amount)}" }], color=discord.Color.orange())
async def end(self, ctx): if self.tournament.status != 4: raise commands.BadArgument( "The tournament must have begun before you can end it. If you are trying to cancel, use the `;cancel` " "command.") if not self.tournament.winners: await ctx.send( "The winners list is empty! Are you sure you want to end this tournament? `yes`/`no`" ) def check(m): return m.author == ctx.message.author and m.channel == ctx.message.channel try: msg = await self.client.wait_for('message', check=check, timeout=30) except asyncio.TimeoutError: raise commands.BadArgument("Command cancelled.") if msg.content.lower() == "no": raise commands.BadArgument( "Alright, I will not end the tournament yet.") if msg.content.lower() != "yes": raise commands.BadArgument( "Invalid choice. Please type the command again to retry.") # OK to end from here await ctx.send( ":checkered_flag: Thanks for playing! The tournament has ended!") await self.cleanup() id_list = [player.id for player in self.tournament.get_participants()] user_list = User.fetch_by_ids(ctx, id_list) for user in user_list: player = [ x for x in self.tournament.get_participants() if x.id == user.id ][0] summary, xp = self.tournament.calculate_xp_for(player, user.streak) user.participations += 1 prev_level = user.level user.xp += xp new_level = user.level embed = Embed(title=self.tournament.name) if player in self.tournament.winners: embed.color = Color.from_rgb(200, 200, 0) embed.description = "\n**You won!** :tada:" user.wins += 1 user.streak += 1 user.streak_age = 0 embed.description += f"\nYou're now on a **{user.streak}** win streak!" if user.streak > user.max_streak: embed.description += "\nYou have beaten your max win streak! Congratulations!" user.max_streak = user.streak elif user.streak == user.max_streak: embed.description += "\nYou are tied with your max win streak!" else: embed.description += f"\nYou're on your way to beat your max win streak of **{user.max_streak}**!" else: if user.streak != 0: embed.description = f"\n **You lost!** :frowning:\nYou lost your win streak of {user.streak}." else: embed.description = "\n **You lost!** :frowning:" user.streak = 0 user.streak_age = None embed.color = Color.red() level_info = self._format_level_info(user) if new_level > prev_level: level_info += f"\n\nYou leveled up to level **{user.level}**! :partying_face:" embed.add_field(name="Experience", value=summary + "\n\n" + level_info) embed.set_footer(text="TIP: " + Tip()) embed.set_author(name="Results") try: await player.send(embed=embed) except HTTPException as e: if e.status == 403: # Forbidden await ctx.send( f"{player.mention} has direct messages disabled," " so I can't send them their results.") host = User.fetch_by_id(ctx, self.tournament.host.id) host.hosted += 1 prev_level = host.level host.xp += 150 # Hosting XP new_level = host.level level_info = self._format_level_info(host) if new_level > prev_level: level_info += f"\n\nYou leveled up to level **{host.level}**! :partying_face:" desc = "You have recieved `150xp` for hosting this tournament!\n\n" + level_info embed = Embed(title="Thank you for hosting " + self.tournament.name + "!", description=desc, color=Color.green()) try: await self.tournament.host.send(embed=embed) except HTTPException as e: if e.status == 403: # Forbidden await ctx.send( f"{self.tournament.host.mention} has direct messages disabled," " so I can't send them their results.") except AttributeError: pass # The bot user was the host so it cannot DM itself await self.client.get_command("nto").__call__(ctx) await self.channels.t_logs.send(embed=self.tournament.log_embed()) self.tournament.status = Status.Ended self.tournament.save() try: self.queue.remove(self.tournament) except ValueError: pass self.tournament = Tournament()
async def leaderboard(self, ctx, board=None, page=1): boards = { "wins": "wins", "win": "wins", "levels": "level", "xp": "level", "level": "level", "skill": "skill", "sp": "skill", "bal": "balance", "balance": "balance", "coins": "balance", "money": "balance" } colors = {"wins": 0xffff00, "level": discord.Color.green()} if board is None: embed = discord.Embed(title="Your Leaderboard Positions", color=ctx.author.color) embed.set_thumbnail( url= "https://cdn.discordapp.com/attachments/575627727013412891/721700942336229397/Trophy.png" ) user = User.fetch_by_id(ctx, ctx.author.id) win_pos, win_total = user.fetch_top_pos_by_attr("wins") level_pos, level_total = user.fetch_top_pos_by_attr("level") if win_pos: text = f"**Wins:** #{win_pos} out of {win_total} ({user.wins} wins)" else: text = "**Wins:** *Unranked*" if level_pos: text += f"\n\n**Levels:** #{level_pos} out of {level_total} (Level {user.level}, {user.xp} xp)" else: text += "\n\n**Levels:** *Unranked*" embed.description = text embed.set_footer( text= "Type \";leaderboard <board>\" to view a specific leaderboard!" ) await ctx.send(embed=embed) return try: int_page = int(page) except ValueError: raise commands.BadArgument(f"`{page}` is not a valid page number!") if int_page <= 0: page = 1 start = (page - 1) * 10 if board.lower() not in boards.keys(): raise commands.BadArgument( f"The `{board}` leaderboard doesn't exist!\nTry looking at one of these" " leaderboards: `wins` or `levels`") attr = boards[board.lower()] top, total = User.fetch_top_by_attr(attr, start=start) max_pages = total // 10 + 1 if page > max_pages: page = max_pages embed = discord.Embed( title= f"{attr.capitalize()} Leaderboard (Page {page} of {str(max_pages)})" ) embed.colour = colors[attr] text = "" position = (page - 1) * 10 + 1 for user in top: member = ctx.bot.get_guild(config['guild_id']).get_member(user.id) if member is None: mention = user.username else: mention = member.mention text += f"\n[**{position}**] {mention} - " if attr == "wins": text += f"**{user.wins}** wins" if attr == "level": text += f"Level **{user.level}**, {user.xp} xp" position += 1 user = User.fetch_by_id(ctx, ctx.author.id) pos, total = user.fetch_top_pos_by_attr(attr) text += f"\n\n__Your rank:__\n **#{str(pos)}** out of {str(total)} players" embed.description = text await ctx.send(embed=embed)