from discord.ext import commands import discord from discord import app_commands import random from typing import Optional from query.user import is_ignored, get_level, get_xp, level_up, get_ability_points_spent, increment_all_coin, get_coin, get_karma, get_theft_skill, get_random_player from common.settings import check_ignore_interaction async def setup(bot: commands.Bot): await bot.add_cog(Games(bot)) class Games(commands.Cog): """Gaming commands.""" def __init__(self, bot: commands.Bot): self.bot = bot @app_commands.command( name="level", description="Check the level for a player.", ) async def level(self, interaction: discord.Interaction, user: Optional[discord.User]) -> None: # Keep interaction alive longer then 3 seconds to give the bot time to respond. await interaction.response.defer() # Halt on ignore list or games channel settings. if await check_ignore_interaction(self.bot.pg, interaction, games=True): return if not user: user = interaction.user level = await get_level(self.bot.pg, user.id) if level == 0: if interaction.user == user: await interaction.followup.send(f"You are not playing, join the game with `/levelup`") else: await interaction.followup.send(f"`{user}` is not playing.") else: xp_spent, total_xp = await get_xp(self.bot.pg, user.id) ability_points_spent = await get_ability_points_spent(self.bot.pg, user.id) coin = await get_coin(self.bot.pg, user.id) karma = await get_karma(self.bot.pg, user.id) if interaction.user == user: await interaction.followup.send(f"You rank at level **{level}**. (exp **{xp_spent}**/{total_xp} | abp **{ability_points_spent}**/{level * 3} | coin **{coin}** | karma **{karma}**)") else: await interaction.followup.send(f"`{user}` ranks at level **{level}**. (**{xp_spent}**/{total_xp} | abp **{ability_points_spent}**/{level * 3}) | coin **{coin}** | karma **{karma}**") @app_commands.command( name="xp", description="Check the experience points for a player.", ) async def xp(self, interaction: discord.Interaction, user: Optional[discord.User]) -> None: # Keep interaction alive longer then 3 seconds to give the bot time to respond. await interaction.response.defer() # Halt on ignore list or games channel settings. if await check_ignore_interaction(self.bot.pg, interaction, games=True): return if not user: xp_spent, total_xp = await get_xp(self.bot.pg, interaction.user.id) level = await get_level(self.bot.pg, interaction.user.id) threshold = (level + 1) * 50 + xp_spent if threshold < total_xp - xp_spent: await interaction.followup.send(f"You have spent {xp_spent} experience points of your {total_xp} total and can gain 3 ability points for {threshold} xp.") else: await interaction.followup.send(f"You have spent {xp_spent} experience points of your {total_xp} total and require {threshold - (total_xp - xp_spent)} xp to `/levelup`.") else: xp_spent, total_xp = await get_xp(self.bot.pg, user.id) level = await get_level(self.bot.pg, user.id) threshold = (level + 1) * 50 + xp_spent if threshold < total_xp - xp_spent: await interaction.followup.send(f"`{user}` has spent {xp_spent} of {total_xp} experience points and can level up for {threshold} xp.") else: await interaction.followup.send(f"`{user}` has spent {xp_spent} of {total_xp} experience points and requires {threshold - (total_xp - xp_spent)} xp to level up.") @app_commands.command( name="levelup", description="Attempt to gain a level.", ) async def levelup(self, interaction: discord.Interaction) -> None: # Halt on ignore list or games channel settings. if await check_ignore_interaction(self.bot.pg, interaction, games=True): return xp_spent, total_xp = await get_xp(self.bot.pg, interaction.user.id) xp_available = total_xp - xp_spent level = await get_level(self.bot.pg, interaction.user.id) threshold = (level + 1) * 50 + xp_spent if xp_available < threshold: await interaction.followup.send(f"Not yet, you require {threshold - xp_available} more XP to level up.") else: await level_up(self.bot.pg, interaction.user.id, threshold) await interaction.send_message(f"You have gained three ability points climbed the ranks for {threshold} XP, leaving you {xp_available - threshold} remaining.") await increment_all_coin(self.bot.pg) @app_commands.command( name="rob", description="Rob another player", ) async def rob(self, interaction: discord.Interaction) -> None: # Halt on ignore list or games channel settings. if await check_ignore_interaction(self.bot.pg, interaction, games=True): return if await get_theft_skill(self.bot.pg, interaction.user.id < 1): await interaction.followup.send("You do not have the `Theft` skill.") return victim_id = get_random_player(self.bot.pg) await interaction.send_message(f"You have decided to rob{self.bot.get_user(victim_id)}, unfortunately crime has not been invited yet.") @app_commands.command( name="dice", description="Simulate dice rolls.", ) async def dice(self, interaction: discord.Interaction, amount: Optional[int], sides: Optional[int]) -> None: # Keep interaction alive longer then 3 seconds to give the bot time to respond. await interaction.response.defer() print(f"Extras: {interaction.extras}") print(f"Message: {interaction.message}") print(f"Data: {interaction.data}") # Halt on ignore list or games channel settings. if await check_ignore(self.bot.pg, interaction, games=True): return if not amount: amount = 2 if not sides: sides = 6 if amount < 1: await interaction.followup.send("You want me to roll less than one die? How!?") elif amount > 25: await interaction.followup.send("I can not hold so many dice at one time.") elif sides < 2: await interaction.followup.send("A die has physical minimum of 2 sides. Don't ask for impossible objects.") elif sides > 256: await interaction.followup.send("My tiny hands can not handle such large dice. Even if both are virtual.") else: embed = discord.Embed(title = "Dice roll", description=f"Rolling {amount} dice, with {sides} sides.") while amount > 0: embed.insert_field_at(0, name=f"Die {amount}", value=random.randint(1, sides), inline=True) amount -= 1 await interaction.followup.send(embed=embed) @app_commands.command( name="8ball", description="Ask the magic 8-ball.", ) async def eightball(self, interaction: discord.Interaction, question: str = None) -> None: theorem = f"{interaction.user.mention} asked: `{question}`" await interaction.response.send_message(theorem) # Halt on ignore list or games channel settings. if await check_ignore(self.bot.pg, interaction, games=True): return if not question: messages = [ "Don't forget to ask a question...", "Hey, that's not a question!", "What would you like to know?", "You want me to predict nothing?", "Are you intentionally not asking a question?", "Ask a question you tease!", "You will die alone.", ] elif question.strip().count(" ") == 0: messages = [ "What?", "That is not a question", "Can you use more than one word?", "What is the question?", "Sorry?" ] elif question.strip()[-1] != "?": messages = [ "Did you forget to end with a question mark?", "Is that a statement or question?", "Don't questions usually end with a question mark?", "Don't forget to use punctuation." ] else: messages = [ "Yes.", "No.", "Affirmative.", "No way!", "Negative.", "Positive.", "Correct.", "Incorrect.", "Likely", "Unlikely", "Maybe.", "Definately!", "Perhaps?", "Most indubitably.", "Does the pope shit in the woods?", "When hell freezes over.", "Only between 9 and 5.", "Only just before you die.", "ERROR: Probability failure.", "Ask again later.", "I don't know.", "Unpredictable.", "Unknown", ] await interaction.edit_original_response(content=f"{theorem}\n**{random.choice(messages)}**")