Ejemplo n.º 1
0
    async def dice_roll_roll(gctx,
                             roll_request,
                             comment=None,
                             comment_getter=None):
        """
        Generic roll: Display the roll in a format similar to ``!r``.

        :type gctx: ddb.gamelog.context.GameLogEventContext
        :type roll_request: ddb.dice.RollRequest
        :param comment: If comment_getter is not supplied, the comment used for all rolls.
        :type comment: str or None
        :param comment_getter: A function that takes a RollRequestRoll and returns a string, or None.
        :type comment_getter: Callable[[ddb.dice.RollRequestRoll], str]
        """
        if comment_getter is None:
            comment_getter = lambda _: comment

        results = '\n'.join(
            str(
                rr.to_d20(stringifier=VerboseMDStringifier(),
                          comment=comment_getter(rr)))
            for rr in roll_request.rolls)

        out = f"<@{gctx.discord_user_id}> **rolled from** {constants.DDB_LOGO_EMOJI}:\n{results}"
        # the user knows they rolled - don't need to ping them in discord
        await gctx.channel.send(
            out, allowed_mentions=discord.AllowedMentions.none())
Ejemplo n.º 2
0
    async def rollCmd(self, ctx, *, rollStr: str = '1d20'):
        """Rolls dice in xdy format.
        __Examples__
        !r xdy Attack!
        !r xdy+z adv Attack with Advantage!
        !r xdy-z dis Hide with Heavy Armor!
        !r xdy+xdy*z
        !r XdYkhZ
        !r 4d6mi2[fire] Elemental Adept, Fire
        !r 2d6e6 Explode on 6
        !r 10d6ra6 Spell Bombardment
        !r 4d6ro<3 Great Weapon Master
        __Supported Operators__
        k (keep)
        p (drop)
        ro (reroll once)
        rr (reroll infinitely)
        mi/ma (min/max result)
        e (explode dice of value)
        ra (reroll and add)
        __Supported Selectors__
        X (literal X)
        lX (lowest X)
        hX (highest X)
        >X (greater than X)
        <X (less than X)"""

        if rollStr == '0/0':  # easter eggs
            return await ctx.send(
                "What do you expect me to do, destroy the universe?")

        rollStr, adv = self._string_search_adv(rollStr)

        res = d20.roll(rollStr,
                       advantage=adv,
                       allow_comments=True,
                       stringifier=VerboseMDStringifier())
        out = f"{ctx.author.mention}  :game_die:\n" \
              f"{str(res)}"
        if len(out) > 1999:
            out = f"{ctx.author.mention}  :game_die:\n" \
                  f"{str(res)[:100]}...\n" \
                  f"**Total**: {res.total}"

        await try_delete(ctx.message)
        await ctx.send(
            out, allowed_mentions=discord.AllowedMentions(users=[ctx.author]))
        await Stats.increase_stat(ctx, "dice_rolled_life")
Ejemplo n.º 3
0
    async def dice_roll_roll(gctx,
                             roll_request,
                             comment=None,
                             comment_getter=None):
        """
        Generic roll: Display the roll in a format similar to ``!r``.

        :type gctx: ddb.gamelog.context.GameLogEventContext
        :type roll_request: ddb.dice.RollRequest
        :param comment: If comment_getter is not supplied, the comment used for all rolls.
        :type comment: str or None
        :param comment_getter: A function that takes a RollRequestRoll and returns a string, or None.
        :type comment_getter: Callable[[ddb.dice.RollRequestRoll], str]
        """
        if comment_getter is None:
            if comment is None:
                comment_getter = gamelogutils.default_comment_getter(
                    roll_request)
            else:
                comment_getter = lambda _: comment

        results = []
        for rr in roll_request.rolls:
            results.append(
                str(
                    rr.to_d20(stringifier=VerboseMDStringifier(),
                              comment=comment_getter(rr))))

        if sum(len(r)
               for r in results) > 1950:  # some len removed for other stuff
            final_results = '\n'.join(
                f"**{comment_getter(rr)}**: {rr.result.total}"
                for rr in roll_request.rolls)
        else:
            final_results = '\n'.join(results)

        out = f"<@!{gctx.discord_user_id}> **rolled from** {constants.DDB_LOGO_EMOJI}:\n{final_results}"
        # the user knows they rolled - don't need to ping them in discord
        await gctx.send(out, allowed_mentions=discord.AllowedMentions.none())
Ejemplo n.º 4
0
    async def roll_cmd(self, ctx, *, dice: str = '1d20'):
        """Roll is used to roll any combination of dice in the `XdY` format. (`1d6`, `2d8`, etc)

        Multiple rolls can be added together as an equation. Standard Math operators and Parentheses can be used: `() + - / *`

        Roll also accepts `adv` and `dis` for Advantage and Disadvantage. Rolls can also be tagged with `[text]` for informational purposes. Any text after the roll will assign the name of the roll.

        ___Examples___
        `!r` or `!r 1d20` - Roll a single d20, just like at the table
        `!r 1d20+4` - A skill check or attack roll
        `!r 1d8+2+1d6` - Longbow damage with Hunter’s Mark

        `!r 1d20+1 adv` - A skill check or attack roll with Advantage
        `!r 1d20-3 dis` - A skill check or attack roll with Disadvantage

        `!r (1d8+4)*2` - Warhammer damage against bludgeoning vulnerability

        `!r 1d10[cold]+2d6[piercing] Ice Knife` - The Ice Knife Spell does cold and piercing damage

        **Advanced Options**
        __Operators__
        Operators are always followed by a selector, and operate on the items in the set that match the selector.
        A set can be made of a single or multiple entries i.e. `1d20` or `(1d6,1d8,1d10)`

        These operations work on dice and sets of numbers
        `k` - keep - Keeps all matched values.
        `p` - drop - Drops all matched values.

        These operators only work on dice rolls.
        `rr` - reroll - Rerolls all matched die values until none match.
        `ro` - reroll - once - Rerolls all matched die values once.
        `ra` - reroll and add - Rerolls up to one matched die value once, add to the roll.
        `mi` - minimum - Sets the minimum value of each die.
        `ma` - maximum - Sets the maximum value of each die.
        `e` - explode on - Rolls an additional die for each matched die value. Exploded dice can explode.

        __Selectors__
        Selectors select from the remaining kept values in a set.
        `X`  | literal X
        `lX` | lowest X
        `hX` | highest X
        `>X` | greater than X
        `<X` | less than X

        __Examples__
        `!r 2d20kh1+4` - Advantage roll, using Keep Highest format
        `!r 2d20kl1-2` - Disadvantage roll, using Keep Lowest format
        `!r 4d6mi2[fire]` - Elemental Adept, Fire
        `!r 10d6ra6` - Wild Magic Sorcerer Spell Bombardment
        `!r 4d6ro<3` - Great Weapon Fighting
        `!r 2d6e6` - Explode on 6
        `!r (1d6,1d8,1d10)kh2` - Keep 2 highest rolls of a set of dice

        **Additional Information can be found at:**
        https://d20.readthedocs.io/en/latest/start.html#dice-syntax"""  # noqa: E501

        if dice == '0/0':  # easter eggs
            return await ctx.send(
                "What do you expect me to do, destroy the universe?")

        dice, adv = string_search_adv(dice)

        res = d20.roll(dice,
                       advantage=adv,
                       allow_comments=True,
                       stringifier=VerboseMDStringifier())
        out = f"{ctx.author.mention}  :game_die:\n" \
              f"{str(res)}"
        if len(out) > 1999:
            out = f"{ctx.author.mention}  :game_die:\n" \
                  f"{str(res)[:100]}...\n" \
                  f"**Total**: {res.total}"

        await try_delete(ctx.message)
        await ctx.send(
            out, allowed_mentions=discord.AllowedMentions(users=[ctx.author]))
        await Stats.increase_stat(ctx, "dice_rolled_life")
        if gamelog := self.bot.get_cog('GameLog'):
            await gamelog.send_roll(ctx, res)