Exemplo n.º 1
0
    async def send_regular_night_start_dm(self, recipient):
        """Send the query for night action for each regular night (not the first one)"""

        if DISABLE_DMS:
            return

        import globvars

        player = BOTCUtils.get_player_from_id(recipient.id)

        if player.is_alive():

            # Construct the message to send
            msg = f"***{recipient.name}#{recipient.discriminator}***, the **{self.name}**:"
            msg += "\n"
            msg += self.emoji + " " + self.instruction
            msg += "\n"

            embed = discord.Embed(description=msg)
            embed.timestamp = datetime.datetime.utcnow()
            embed.set_footer(text=copyrights_str)

            msg2 = self.action
            msg2 += globvars.master_state.game.create_sitting_order_stats_string(
            )
            embed.add_field(name=butterfly + " **「 Your Action 」**",
                            value=msg2,
                            inline=False)

            try:
                await recipient.send(embed=embed)
            except discord.Forbidden:
                pass
Exemplo n.º 2
0
    async def send_n1_end_message(self, recipient):
        """Send the number of pairs of evils sitting together."""

        from botc.BOTCUtils import get_number_image

        player = BOTCUtils.get_player_from_id(recipient.id)

        # Dead players do not receive anything
        if not player.is_alive():
            return

        # Poisoned info
        if player.is_droisoned():
            evil_pair_count = self.__create_droisoned_info()
        # Good info
        else:
            evil_pair_count = self.get_nb_pairs_of_evils()
        link = get_number_image(evil_pair_count)

        msg = f"***{recipient.name}#{recipient.discriminator}***, the **{self.name}**:"
        msg += "\n"
        msg += self.emoji + " " + self.instruction
        msg += "\n"
        msg += chef_init.format(evil_pair_count)

        embed = discord.Embed(description=msg)
        embed.set_thumbnail(url=link)
        embed.set_footer(text=copyrights_str)
        embed.timestamp = datetime.datetime.utcnow()

        try:
            await recipient.send(embed=embed)
        except discord.Forbidden:
            pass
 async def learn(self, ctx, *, learned: PlayerParser()):
     """Learn command
     usage: learn <player> and <player> and...
     characters: ravenkeeper
     """
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     await player.role.ego_self.register_learn(player, learned)
Exemplo n.º 4
0
def check_if_player_really_dead(ctx):
    """Check if the player is dead using real state"""
    player = BOTCUtils.get_player_from_id(ctx.author.id)
    if player.is_dead():
        return True
    else:
        raise DeadOnlyCommand("Command reserved for Dead Players (BoTC)")
Exemplo n.º 5
0
 async def serve(self, ctx, *, master: PlayerParser()):
     """Serve command: 
     usage: serve <player> and <player> and...
     characters: butler
     """
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     await player.role.ego_self.register_serve(player, master)
 async def poison(self, ctx, *, poisoned: PlayerParser()):
     """Poison command
     usage: poison <player> and <player> and...
     characters: poisoner
     """
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     await player.role.ego_self.register_poison(player, poisoned)
Exemplo n.º 7
0
def check_if_player_really_alive(ctx):
    """Check if the player is alive using real state"""
    player = BOTCUtils.get_player_from_id(ctx.author.id)
    if player.is_alive():
        return True
    else:
        raise AliveOnlyCommand("Command reserved for Alive Players (BoTC)")
Exemplo n.º 8
0
def check_if_not_player(ctx):
    """Return true if user is not player"""
    player = BOTCUtils.get_player_from_id(ctx.author.id)
    if player:
        raise IsAPlayer("Command not allowed: user is a player (BoTC).")
    else:
        return True
Exemplo n.º 9
0
 async def protect(self, ctx, *, protected: PlayerParser()):
     """Protect command
     usage: protect <player> and <player> and...
     characters: monk
     """
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     await player.role.ego_self.register_protect(player, protected)
Exemplo n.º 10
0
 async def slay(self, ctx, *, slain: PlayerParser()):
     """Slay command
     usage: slay <player> and <player> and...
     characters: slayer
     """
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     await player.role.ego_self.register_slay(player, slain)
Exemplo n.º 11
0
    async def send_n1_end_message(self, recipient):
        """Send two possible players for a particular minion character."""

        player = BOTCUtils.get_player_from_id(recipient.id)

        if DISABLE_DMS:
            return

        # Dead players do not receive anything
        if not player.is_alive():
            return

        link = self.registered_minion_type.art_link

        # Construct the message to send
        msg = f"***{recipient.name}#{recipient.discriminator}***, the **{self.name}**:"
        msg += "\n"
        msg += self.emoji + " " + self.instruction
        msg += "\n"
        msg += investigator_init.format(self.registered_minion_type.name)
        msg += "```basic\n"
        msg += f"{self.two_player_list[0].user.display_name} ({self.two_player_list[0].user.id})\n"
        msg += f"{self.two_player_list[1].user.display_name} ({self.two_player_list[1].user.id})\n"
        msg += "```"

        embed = discord.Embed(description=msg)
        embed.set_thumbnail(url=link)
        embed.set_footer(text=copyrights_str)
        embed.timestamp = datetime.datetime.utcnow()

        try:
            await recipient.send(embed=embed)
        except discord.Forbidden:
            pass
Exemplo n.º 12
0
 async def kill(self, ctx, *, killed: PlayerParser()):
     """Kill command
     usage: kill <player> and <player> and...
     characters: imp
     """
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     await player.role.ego_self.register_kill(player, killed)
 async def whisper(self, ctx, recipient: PlayerConverter(), *, content: WhisperConverter()):
     """Whisper command"""
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     try:
         msg = from_str.format(
             botutils.BotEmoji.unread_message,
             player.game_nametag,
             content
         )
         await recipient.user.send(msg)
     except discord.Forbidden:
         msg = recipient_blocked.format(botutils.BotEmoji.warning_sign)
         await ctx.send(msg)
     else:
         msg = to_str.format(
             botutils.BotEmoji.whisper,
             recipient.game_nametag,
             content
         )
         await ctx.send(msg)
         announcement_msg = whisper_announcement.format(
             botutils.BotEmoji.opened_letter,
             player.game_nametag,
             recipient.game_nametag,
         )
         lobby_message = await botutils.send_lobby(announcement_msg)
         await asyncio.sleep(WHISPER_SHOW_TIME)
         await lobby_message.delete()
Exemplo n.º 14
0
 async def read(self, ctx, *, read: PlayerParser()):
     """Read command
     usage: read <player> and <player> and...
     characters: fortune teller
     """
     player = BOTCUtils.get_player_from_id(ctx.author.id)
     await player.role.ego_self.register_read(player, read)
Exemplo n.º 15
0
    async def getrole(self, ctx):
        player = BOTCUtils.get_player_from_id(ctx.author.id)

        if not isinstance(ctx.channel, discord.channel.DMChannel):
            await ctx.send(game_text["doc"]["getrole"]["feedback"].format(
                ctx.author.mention, BotEmoji.check))

        await player.role.ego_self.send_opening_dm_embed(player.user)
Exemplo n.º 16
0
def can_use_serve(user_id):
    """Return true if the user can use the command "serve"
    Characters that can serve: 
    - Butler
    """
    from botc.gamemodes.troublebrewing._utils import TBRole
    player = BOTCUtils.get_player_from_id(user_id)
    if player.role.ego_self.name in [TBRole.butler.value]:
        return True
    return False
Exemplo n.º 17
0
def can_use_protect(user_id):
    """Return true if the user can use the command "protect"
    Characters that can poison:
    - Monk
    """
    from botc.gamemodes.troublebrewing._utils import TBRole
    player = BOTCUtils.get_player_from_id(user_id)
    if player.role.ego_self.name in [TBRole.monk.value]:
        return True
    return False
Exemplo n.º 18
0
def can_use_read(user_id):
    """Return true if the user can use the command "read"
    Characters that can poison:
    - Fortune teller
    """
    from botc.gamemodes.troublebrewing._utils import TBRole
    player = BOTCUtils.get_player_from_id(user_id)
    if player.role.ego_self.name in [TBRole.fortuneteller.value]:
        return True
    return False
Exemplo n.º 19
0
def check_if_is_player(ctx):
    """Return true if user is a player, and not in fleaved state"""
    player = BOTCUtils.get_player_from_id(ctx.author.id)
    if player:
        if player.is_fleaved():
            raise NotAPlayer(
                "Command not allowed: user has quit the game (BoTC).")
        else:
            return True
    else:
        raise NotAPlayer("Command not allowed: user is not a player (BoTC).")
Exemplo n.º 20
0
    async def notes_remove(self, ctx, player_or_id: Union[PlayerConverter, int], id: int = None):
        invoking_player = BOTCUtils.get_player_from_id(ctx.author.id)

        if isinstance(player_or_id, Player):
            if id is None:
                raise MissingRequiredArgument(Parameter('id', Parameter.POSITIONAL_ONLY))
        else:
            id = player_or_id
            player_or_id = invoking_player

        globvars.master_state.game.note_manager.rm_note(player_or_id, id, invoking_player)
        await ctx.send(notes_remove_feedback_str.format(BotEmoji.check))
Exemplo n.º 21
0
    async def info_add(self, ctx, *, args: str):
        invoking_player = BOTCUtils.get_player_from_id(ctx.author.id)

        args = re.split(' +', args)

        # Ensure that we have enough values in the list
        args += ['', '']

        try:
            target_phase = int(args[0])
            target_player = None
            args.pop(0)
        except ValueError:
            target_player = BOTCUtils.get_player_from_string(args[0])
            if target_player is not None:
                args.pop(0)

            try:
                target_phase = int(args[0])
                args.pop(0)
            except ValueError:
                target_phase = None

        # Remove the two dummy elements
        args.pop()
        args.pop()

        rem = ' '.join(args)

        if not rem.strip():
            if target_phase is None:
                if target_player is None:
                    raise commands.MissingRequiredArgument(Parameter('info', Parameter.POSITIONAL_ONLY))
                else:
                    # Added info was a player name
                    rem = str(target_player)
                    target_player = None
            else:
                # Added info was a number (empath for example)
                rem = str(target_phase)
                target_phase = None

        if target_phase is not None and target_phase > globvars.master_state.game._chrono.cycle:
            raise commands.BadArgument()

        if target_player is not None:
            globvars.master_state.game.note_manager.info(target_player, rem, invoking_player, target_phase)
        else:
            if globvars.master_state.game._chrono.phase == Phase.night:
                raise NotNight("Command is allowed during night phase only (BoTC)")
            globvars.master_state.game.note_manager.info(invoking_player, rem, None, target_phase)

        await ctx.send(info_add_feedback_str.format(BotEmoji.check))
Exemplo n.º 22
0
    async def claim_remove(self, ctx, player: PlayerConverter = None):
        invoking_player = BOTCUtils.get_player_from_id(ctx.author.id)

        if player is None:
            if globvars.master_state.game._chrono.phase == Phase.night:
                raise NotNight("Command is allowed during night phase only (BoTC)")
            globvars.master_state.game.note_manager.rm_claim(invoking_player)
            await botutils.send_lobby(remove_claim_str.format(ctx.author.mention), delete_after = CLAIM_SHOW_TIME)
        else:
            globvars.master_state.game.note_manager.rm_claim(player, invoking_player)

        await ctx.send(private_remove_claim_str.format(BotEmoji.check))
Exemplo n.º 23
0
    async def notes(self, ctx, *, args = None):
        invoking_player = BOTCUtils.get_player_from_id(ctx.author.id)

        if args is None:
            # Claims summary
            if isinstance(ctx.channel, discord.channel.DMChannel):
                await botutils.send_long_message(ctx.channel, globvars.master_state.game.note_manager.format_notes(invoking_player), make_code=True, delete_after=CLAIM_SHOW_TIME)
            else:
                await botutils.send_long_message(ctx.channel, globvars.master_state.game.note_manager.format_notes(), make_code=True, delete_after=CLAIM_SHOW_TIME)
            return
        else:
            if isinstance(ctx.channel, discord.channel.DMChannel):
                await self.notes_add.callback(self, ctx, args=args)
Exemplo n.º 24
0
 async def kill_error(self, ctx, error):
     emoji = documentation["cmd_warnings"]["x_emoji"]
     # Incorrect character -> RoleCannotUseCommand
     if isinstance(error, RoleCannotUseCommand):
         return
     # If it passed all the checks but raised an error in the character class
     elif isinstance(error, AbilityForbidden):
         error = getattr(error, 'original', error)
         await ctx.send(error)
     elif isinstance(error, commands.BadArgument):
         return
     # Non-registered or quit player -> NotAPlayer
     elif isinstance(error, NotAPlayer):
         return
     # Incorrect channel -> NotDMChannel
     elif isinstance(error, NotDMChannel):
         return
     # Incorrect argument -> commands.BadArgument
     elif isinstance(error, commands.BadArgument):
         return
     # Incorrect phase -> NotNight
     elif isinstance(error, NotNight):
         try:
             await ctx.author.send(
                 documentation["cmd_warnings"]["night_only"].format(
                     ctx.author.mention, emoji))
         except discord.Forbidden:
             pass
     # Player not alive -> AliveOnlyCommand
     elif isinstance(error, AliveOnlyCommand):
         try:
             await ctx.author.send(
                 documentation["cmd_warnings"]["alive_only"].format(
                     ctx.author.mention, emoji))
         except discord.Forbidden:
             pass
     # Missing argument -> commands.MissingRequiredArgument
     elif isinstance(error, commands.MissingRequiredArgument):
         player = BOTCUtils.get_player_from_id(ctx.author.id)
         msg = player.role.ego_self.emoji + " " + player.role.ego_self.instruction + " " + player.role.ego_self.action
         try:
             await ctx.author.send(msg)
         except discord.Forbidden:
             pass
     else:
         try:
             raise error
         except Exception:
             await ctx.send(error_str)
             await botutils.log(botutils.Level.error,
                                traceback.format_exc())
Exemplo n.º 25
0
    async def info_remove(self, ctx, player_or_id: Union[int, PlayerConverter] = None, id: PlayerConverter() = None):
        invoking_player = BOTCUtils.get_player_from_id(ctx.author.id)

        if isinstance(player_or_id, int):
            id = player_or_id
            player_or_id = None

        if player_or_id is None:
            if globvars.master_state.game._chrono.phase == Phase.night:
                raise NotNight("Command is allowed during night phase only (BoTC)")
            globvars.master_state.game.note_manager.rm_info(invoking_player, id)
        else:
            globvars.master_state.game.note_manager.rm_info(player_or_id, id, invoking_player)

        await ctx.send(info_remove_feedback_str.format(BotEmoji.check))
Exemplo n.º 26
0
    async def notes_add(self, ctx, *, args):
        invoking_player = BOTCUtils.get_player_from_id(ctx.author.id)

        args = re.split(' +', args)

        target_player = BOTCUtils.get_player_from_string(args[0])
        if target_player is None:
            target_player = invoking_player
            note = ' '.join(args)
        else:
            args.pop(0)
            note = ' '.join(args)

        globvars.master_state.game.note_manager.note(target_player, note, invoking_player)
        await ctx.send(notes_add_feedback_str.format(BotEmoji.check))
Exemplo n.º 27
0
    async def send_regular_night_end_dm(self, recipient):
        """Send the character of the executed player today."""

        if DISABLE_DMS:
            return

        player = BOTCUtils.get_player_from_id(recipient.id)

        # Dead players do not receive anything
        if not player.is_alive():
            return

        executed_player = globvars.master_state.game.today_executed_player
        if player.is_droisoned():
            # Poisoned info
            character_of_executed = self.__create_droisoned_info()
        else:
            if executed_player:
                executed_player.role.set_new_social_self(executed_player)
                character_of_executed = executed_player.role.social_self
            else:
                character_of_executed = None

        if not character_of_executed:
            return

        # Add information to replay
        drunk = "Drunk " if player.role.true_self.name == Drunk().name else ""
        globvars.master_state.game.replay += f"- {recipient.name} ({drunk}Undertaker) learns that "\
                                             f"{executed_player.user.name} is {character_of_executed}\n"
        executed_player.add_reminder_token('botc/assets/tb_reminder_tokens_cropped/undertaker_dead.png')

        msg = f"***{recipient.name}#{recipient.discriminator}***, the **{self.name}**:"
        msg += "\n"
        msg += self.emoji + " " + self.instruction
        msg += "\n"
        msg += undertaker_nightly.format(character_of_executed.name)

        embed = discord.Embed(description = msg)
        embed.set_thumbnail(url = character_of_executed._art_link_cropped)
        embed.set_footer(text = copyrights_str)
        embed.timestamp = datetime.datetime.utcnow()

        try:
            await recipient.send(embed = embed)
        except discord.Forbidden:
            pass
    async def send_regular_night_end_dm(self, recipient):
        """Send the character of the executed player today."""

        player = BOTCUtils.get_player_from_id(recipient.id)

        # Dead players do not receive anything
        if not player.is_alive():
            return

        # Poisoned info
        if player.is_droisoned():
            character_of_executed = self.__create_droisoned_info()
        else:
            import globvars
            executed_player = globvars.master_state.game.today_executed_player
            if executed_player:
                executed_player.role.set_new_social_self(executed_player)
                character_of_executed = executed_player.role.social_self
            else:
                character_of_executed = None

        msg = f"***{recipient.name}#{recipient.discriminator}***, the **{self.name}**:"
        msg += "\n"
        msg += self.emoji + " " + self.instruction
        msg += "\n"

        if character_of_executed:
            msg += undertaker_nightly.format(character_of_executed.name)
        else:
            msg += undertaker_none

        embed = discord.Embed(description=msg)

        if character_of_executed:
            embed.set_thumbnail(url=character_of_executed._art_link_cropped)

        embed.set_footer(text=copyrights_str)
        embed.timestamp = datetime.datetime.utcnow()

        try:
            await recipient.send(embed=embed)
        except discord.Forbidden:
            pass
    async def send_n1_end_message(self, recipient):
        """Send two possible players for a particular townsfolk character."""

        player = BOTCUtils.get_player_from_id(recipient.id)

        # Dead players do not receive anything
        if not player.is_alive():
            return

        # Poisoned info
        if player.is_droisoned():
            two_player_list = self.__create_droisoned_info(player)
        # Good info
        else:
            two_player_list = self.get_two_possible_townsfolks(recipient)

        registered_townsfolk_type = two_player_list[2]
        link = registered_townsfolk_type.art_link
        assert registered_townsfolk_type.category == Category.townsfolk, "Washerwoman did not receive a townsfolk character"

        # Get rid of the last element
        two_player_list.pop()

        # Construct the message to send
        msg = f"***{recipient.name}#{recipient.discriminator}***, the **{self.name}**:"
        msg += "\n"
        msg += self.emoji + " " + self.instruction
        msg += "\n"
        msg += washerwoman_init.format(registered_townsfolk_type.name)
        msg += "```basic\n"
        msg += f"{two_player_list[0].user.display_name} ({two_player_list[0].user.id})\n"
        msg += f"{two_player_list[1].user.display_name} ({two_player_list[1].user.id})\n"
        msg += "```"

        embed = discord.Embed(description=msg)
        embed.set_thumbnail(url=link)
        embed.set_footer(text=copyrights_str)
        embed.timestamp = datetime.datetime.utcnow()

        try:
            await recipient.send(embed=embed)
        except discord.Forbidden:
            pass
Exemplo n.º 30
0
    async def send_n1_end_message(self, recipient):
        """Send the number of alive evil neighbours"""

        if DISABLE_DMS:
            return

        from botc.BOTCUtils import get_number_image

        player = BOTCUtils.get_player_from_id(recipient.id)

        # Dead players do not receive anything
        if not player.is_alive():
            return

        # Poisoned info
        if player.is_droisoned():
            nb_evils = self.__create_droisoned_info()
        # Good info
        else:
            nb_evils = self.get_nb_evil_neighbours(recipient)
        link = get_number_image(nb_evils)

        # Add information to replay
        drunk = "Drunk " if player.role.true_self.name == Drunk().name else ""
        globvars.master_state.game.replay += f"- {recipient.name} ({drunk}Empath) learns of "\
                                            f"{nb_evils} alive evil neighbour(s)\n"

        msg = f"***{recipient.name}#{recipient.discriminator}***, the **{self.name}**:"
        msg += "\n"
        msg += self.emoji + " " + self.instruction
        msg += "\n"
        msg += empath_nightly.format(nb_evils)

        embed = discord.Embed(description=msg)
        embed.set_thumbnail(url=link)
        embed.set_footer(text=copyrights_str)
        embed.timestamp = datetime.datetime.utcnow()

        try:
            await recipient.send(embed=embed)
        except discord.Forbidden:
            pass