Exemplo n.º 1
0
def _update_player_members(bot, after):
    """Update player members when they change."""
    try:
        player = get_player(bot.game, after)
        player.member = after
    except PlayerNotFoundError:
        pass
Exemplo n.º 2
0
    async def stnominate(self, ctx: Context, nominee: str):
        """Nominate a player for execution.

        nominee: The player to nominate.

        If you want to simulate a nomination by a player, use proxynominate.
        """
        await ctx.bot.game.current_day.nominate(
            ctx, nominee, get_player(ctx.bot.game, ctx.message.author.id))
        await safe_send(ctx, f"Successfully nominated.")
Exemplo n.º 3
0
    async def prevote(self, ctx: Context, vote: str):
        """Prevote in an ongoing nomination.

        vote: The prevote to queue.

        When it's your turn to vote, this will automatically submit the queued vote.
        """
        actual_vt = int(to_bool(vote, "vote"))
        await ctx.bot.game.current_day.current_vote.prevote(
            ctx, get_player(ctx.bot.game, ctx.author.id), actual_vt)
Exemplo n.º 4
0
async def to_player(
    ctx: Context,
    argument: str,
    all_members: bool = False,
    includes_storytellers: bool = False,
    only_one: bool = False,
    condition: Callable[["Player", Context], bool] = lambda x, y: True,
    **kwargs,
) -> "Player":
    """Convert a string to a player with a matching name.

    Functionally just a wrapper of to_member that converts the output to a player.
    The match does not have to be exact.
    The string must be contained in player.nick, player.display_name, or player.name.

    Parameters
    ----------
    ctx : Context
        The invocation context.
    argument : str
        The string to match to a script.
    all_members : bool
        Whether to include all server members or just game players.
    includes_storytellers : bool
        If all_members, whether to include storytellers.
    only_one : bool
        Whether to require exactly one initial match.
    condition: Callable[["Player", Context], bool]
        A condition to require the player to meet. If the condition is not met, should
        raise a commands.BadArgument exception.
        The condition may also take kwargs if necessary.

    Returns
    -------
    Player
        The matching player.
    """
    try:
        player = get_player(
            ctx.bot.game,
            (
                await to_member(
                    ctx, argument, all_members, includes_storytellers, only_one
                )
            ).id,
        )
        if condition(player, ctx, **kwargs):
            return player
    except ValueError as e:
        if str(e) == "player not found":
            raise commands.BadArgument(
                f"Multiple players match {argument}. Please try again."
            )
        raise
Exemplo n.º 5
0
    async def history(self, ctx: Context, *, player: str):
        """View your message history.

        player: The player to view your message history with.
        """
        player_actual = await to_player(ctx, player)
        await safe_send(
            ctx,
            get_player(ctx.bot.game, ctx.author.id,
                       False).message_history_with(player_actual),
        )
Exemplo n.º 6
0
def _update_player_members(bot, after):
    """Update player members when they change."""
    try:
        player = get_player(bot.game, after)
        player.member = after
    except TypeError as e:
        if str(e) != "no current game":
            raise
    except ValueError as e:
        if str(e) != "player not found":
            raise
Exemplo n.º 7
0
    async def history(self, ctx: "GameContext", *, player: str = None):
        """View your message history.

        player: The player to view your message history with.
        If none, this will list all possible players.
        """
        player = player or ""
        player_actual = await to_player(ctx, player)
        await safe_send(
            ctx,
            get_player(ctx.bot.game, ctx.author.id,
                       False).message_history_with(player_actual),
        )
Exemplo n.º 8
0
    async def skip(self, ctx: "DayContext"):
        """Skip your right to nominate for the current day.

        You will still be able to nominate.
        However, if all players nominate or skip, the storytellers may end the day.
        """
        author_player = get_player(ctx.bot.game, ctx.author.id, False)
        if author_player.can_nominate(ctx.bot.game):
            await author_player.add_nomination(ctx, skip=True)
            await safe_send(ctx.bot.channel,
                            f"{author_player.nick} has skipped.")
        else:
            raise commands.BadArgument("You cannot nominate today.")
Exemplo n.º 9
0
    async def nominate(self, ctx: "DayContext", *, nominee: str):
        """Nominate a player for execution.

        nominee: The player to be nominated, or "the storytellers".
        """
        try:
            await ctx.bot.game.current_day.nominate(
                ctx, nominee, get_player(ctx.bot.game, ctx.message.author.id))

        # if they can't nominate
        # raised by current_day.nominate
        except AlreadyNomniatedError:
            return await safe_send(ctx, "You cannot nominate today.")
Exemplo n.º 10
0
    async def pm(self, ctx: Context, *, recipient: str):
        """Message a player or storyteller.

        recipient: The player or storyteller to recieve the message.

        You will be asked about the content of the message.
        You can cancel by saying "cancel".
        """
        recipient_actual = await to_player(ctx,
                                           recipient,
                                           includes_storytellers=True)

        await recipient_actual.message(
            ctx, get_player(ctx.bot.game, ctx.message.author.id))
Exemplo n.º 11
0
    def predicate(ctx: "Context") -> bool:
        """Check if the command author is a player.

        Parameters
        ----------
        ctx : Context
            The invocation context.

        Returns
        -------
        bool
            True if the command succeeds, else raises an exception.

        """
        if ctx.bot.game:
            try:
                get_player(ctx.bot.game,
                           ctx.message.author.id,
                           include_storytellers=False)
                return True
            except PlayerNotFoundError:
                pass
        raise commands.CheckFailure(message="Sorry! Only players can do that.")
Exemplo n.º 12
0
    async def on_message(self, message):
        """Handle messages."""
        if message.author.bot:
            return

        if not message.channel == self.bot.channel:
            return

        if self.bot.game is None or self.bot.game.current_day is None:
            return

        try:
            player = get_player(self.bot.game, message.author.id, False)
            await player.make_active(self.bot.game)
        except PlayerNotFoundError:
            pass
Exemplo n.º 13
0
    async def pm(self, ctx: "DayContext", *, recipient: str = None):
        """Message a player or storyteller.

        recipient: The player or storyteller to recieve the message.
        If none, this will list all possible recipients.

        You will be asked about the content of the message.
        You can cancel by saying "cancel".
        """
        recipient = recipient or ""
        recipient_actual = await to_player(ctx,
                                           recipient,
                                           includes_storytellers=True)

        await recipient_actual.message(
            ctx, get_player(ctx.bot.game, ctx.message.author.id))
Exemplo n.º 14
0
    async def on_message(self, message):
        """Handle messages."""
        if message.author.bot:
            return

        if not message.channel == self.bot.channel:
            return

        if self.bot.game is None or self.bot.game.current_day is None:
            return

        try:
            player = get_player(self.bot.game, message.author.id, False)
            await player.make_active(self.bot.game)
        except TypeError as e:
            if str(e) != "no current game":
                raise
        except ValueError as e:
            if str(e) != "player not found":
                raise
Exemplo n.º 15
0
    async def reply(self, ctx: Context):
        """Reply to the previously recieved message.

        You will be asked about the content of the message.
        You can cancel by saying "cancel".
        """
        author_player = get_player(ctx.bot.game, ctx.message.author.id)

        most_recent_time = ctx.bot.game.seating_order_message.created_at
        most_recent_author = None  # type: Optional[Player]

        for message in author_player.message_history:
            if message["from"] != author_player:
                if message["time"] > most_recent_time:
                    most_recent_time = message["time"]
                    most_recent_author = message["from"]

        if not most_recent_author:
            await safe_send(ctx, "No messages to reply to.")

        else:
            await most_recent_author.message(ctx, author_player)
Exemplo n.º 16
0
    async def vote(self, ctx: Context, *, vote: str):
        """Vote in an ongoing nomination.

        vote: The vote to submit.
        """
        vote_actual = to_bool(vote, "vote")

        player = get_player(ctx.bot.game, ctx.message.author.id)

        # verify it's their turn to vote
        if ctx.bot.game.current_day.current_vote.to_vote != player:
            await safe_send(
                ctx,
                ("It is {actual_voter}'s vote, not yours, silly! "
                 "(Unless this is a bug. In which case I'm silly. "
                 "I hope I'm not silly.)").format(
                     actual_voter=ctx.bot.game.current_day.current_vote.
                     to_vote.nick),
            )

        # do the vote
        await ctx.bot.game.current_day.current_vote.vote(
            ctx, player, vote_actual)
Exemplo n.º 17
0
    async def addtraveler(
        self,
        ctx: Context,
        traveler: str,
        upwards_neighbor: str,
        alignment: str,
        *,
        character: str,
    ):
        """Add a traveler to the game.

        traveler: The player to join the game.
        character: Their traveler character.
        upwards_neighbor: The player above them in the seating order.
        alignment: The traveler's alignment; 'good' or 'evil'.
        """
        # convert the traveler
        traveler_actual = await to_member(ctx, traveler)

        # check alignment is valid
        if not alignment.lower() in ["good", "evil"]:
            raise commands.BadArgument(
                "The alignment must be 'good' or 'evil' exactly.")

        # check if person is in the game
        try:
            get_player(ctx.bot.game, traveler_actual.id)
            raise commands.BadArgument(
                f"{load_preferences(traveler_actual).nick} is already in the game."
            )

        except ValueError as e:

            if str(e) == "player not found":

                # find the character
                character_actual = to_character(ctx, character)

                # determine the position
                upwards_neighbor_actual = await to_player(
                    ctx, upwards_neighbor)

                # make the Player
                player = Player(
                    traveler_actual,
                    character_actual,
                    upwards_neighbor_actual.position + 1,
                )

                # check that the character is a traveler
                if not player.character_type(ctx) == "traveler":
                    raise commands.BadArgument(
                        f"{player.character.name} is not a traveler.")

                # add the alignment
                if alignment.lower() == "good":
                    player.add_effect(ctx, Good, player)
                elif alignment.lower() == "evil":
                    player.add_effect(ctx, Evil, player)

                # add the player role
                await traveler_actual.add_roles(ctx.bot.player_role)

                # add them to the seating order
                ctx.bot.game.seating_order.insert(
                    upwards_neighbor_actual.position + 1, player)

                # announcement
                await safe_send(
                    ctx.bot.channel,
                    ("{townsfolk}, {player} has joined the town as the {traveler}. "
                     "Let's tell {pronoun} hello!").format(
                         traveler=player.character.name,
                         pronoun=load_preferences(player).pronouns[1],
                         townsfolk=ctx.bot.player_role.mention,
                         player=player.nick,
                     ),
                )

                # rules
                msg = await safe_send(
                    ctx.bot.channel,
                    f"\n**{player.character.name}** - {player.character.rules_text}",
                )
                await msg.pin()
                await safe_send(
                    ctx,
                    f"Successfully added {player.nick} as the {player.character.name}.",
                )

            else:
                raise