Пример #1
0
    async def _roll_many(self, ctx, iterations, roll_str, dc=None, adv=None):
        if iterations < 1 or iterations > 100:
            return await ctx.send("Too many or too few iterations.")
        if adv is None:
            adv = d20.AdvType.NONE
        results = []
        successes = 0
        ast = d20.parse(roll_str)
        roller = d20.Roller(context=PersistentRollContext())

        for _ in range(iterations):
            res = roller.roll(ast, advantage=adv)
            if dc is not None and res.total >= dc:
                successes += 1
            results.append(res)

        if dc is None:
            header = f"Rolling {iterations} iterations..."
            footer = f"{sum(o.total for o in results)} total."
        else:
            header = f"Rolling {iterations} iterations, DC {dc}..."
            footer = f"{successes} successes, {sum(o.total for o in results)} total."

        result_strs = '\n'.join([str(o) for o in results])

        out = f"{header}\n{result_strs}\n{footer}"

        if len(out) > 1500:
            one_result = str(results[0])[:100]
            one_result = f"{one_result}..." if len(one_result) > 100 else one_result
            out = f"{header}\n{one_result}\n{footer}"

        await try_delete(ctx.message)
        await ctx.send(f"{ctx.author.mention}\n{out}")
        await Stats.increase_stat(ctx, "dice_rolled_life")
Пример #2
0
    async def do_inline_rolls(self, message):
        roll_exprs = _find_inline_exprs(message.content)

        out = []
        roller = d20.Roller(context=PersistentRollContext())
        char_replacer = CharacterReplacer(self.bot, message)
        for expr, context_before, context_after in roll_exprs:
            context_before = context_before.replace('\n', ' ')
            context_after = context_after.replace('\n', ' ')

            try:
                expr, char_comment = await char_replacer.replace(expr)
                expr, adv = string_search_adv(expr)
                result = roller.roll(expr, advantage=adv, allow_comments=True)
                if result.comment:
                    out.append(
                        f"**{result.comment.strip()}**: {result.result}")
                elif char_comment:
                    out.append(
                        f"{context_before}({char_comment}: {result.result}){context_after}"
                    )
                else:
                    out.append(
                        f"{context_before}({result.result}){context_after}")
            except d20.RollSyntaxError:
                continue
            except (d20.RollError, AvraeException) as e:
                out.append(f"{context_before}({e!s}){context_after}")

        if not out:
            return

        await message.reply('\n'.join(out))
Пример #3
0
    def __init__(self, ctx, *args, **kwargs):
        super(ScriptingEvaluator, self).__init__(*args, **kwargs)

        self.builtins.update(  # fixme character-only functions, all deprecated now
            get_cc=self.needs_char,
            set_cc=self.needs_char,
            get_cc_max=self.needs_char,
            get_cc_min=self.needs_char,
            mod_cc=self.needs_char,
            cc_exists=self.needs_char,
            create_cc_nx=self.needs_char,
            create_cc=self.needs_char,
            get_slots=self.needs_char,
            get_slots_max=self.needs_char,
            set_slots=self.needs_char,
            use_slot=self.needs_char,
            get_hp=self.needs_char,
            set_hp=self.needs_char,
            mod_hp=self.needs_char,
            hp_str=self.needs_char,
            get_temphp=self.needs_char,
            set_temphp=self.needs_char,
            set_cvar=self.needs_char,
            delete_cvar=self.needs_char,
            set_cvar_nx=self.needs_char,
            get_raw=self.needs_char)

        # char-agnostic globals
        self.builtins.update(
            set=self.set,
            exists=self.exists,
            get=self.get,
            combat=self.combat,
            character=self.character,
            get_gvar=self.get_gvar,
            get_svar=self.get_svar,
            set_uvar=self.set_uvar,
            delete_uvar=self.delete_uvar,
            set_uvar_nx=self.set_uvar_nx,
            uvar_exists=self.uvar_exists,
            chanid=self.chanid,
            servid=self.servid,  # fixme deprecated - use ctx instead
            load_json=self.load_json,
            dump_json=self.dump_json,
            argparse=argparse,
            ctx=AliasContext(ctx))

        # roll limiting
        self._roller = d20.Roller(context=PersistentRollContext(
            max_rolls=1_000, max_total_rolls=10_000))
        self.builtins.update(vroll=self._limited_vroll,
                             roll=self._limited_roll)

        self._cache = {"gvars": {}, "svars": {}, "uvars": {}}

        self.ctx = ctx
        self.character_changed = False
        self.combat_changed = False
        self.uvars_changed = set()
Пример #4
0
def _roll(dice, roller=None):
    if roller is None:
        roller = d20.Roller()

    try:
        result = roller.roll(dice)
    except d20.RollError:
        return 0
    return result.total
Пример #5
0
def _vroll(dice, multiply=1, add=0, roller=None):
    if roller is None:
        roller = d20.Roller()

    dice_ast = roller.parse(dice)

    if multiply != 1 or add != 0:
        def mapper(node):
            if isinstance(node, d20.ast.Dice):
                node.num = (node.num * multiply) + add
            return node

        dice_ast = d20.utils.tree_map(mapper, dice_ast)

    try:
        rolled = roller.roll(dice_ast)
    except d20.RollError:
        return None
    return SimpleRollResult(rolled)
Пример #6
0
    async def _roll_many(ctx, iterations, roll_str, dc=None, adv=None):
        if iterations < 1 or iterations > 100:
            return await ctx.send("Too many or too few iterations.")
        if adv is None:
            adv = d20.AdvType.NONE
        results = []
        successes = 0
        ast = d20.parse(roll_str, allow_comments=True)
        roller = d20.Roller(context=PersistentRollContext())

        for _ in range(iterations):
            res = roller.roll(ast, advantage=adv)
            if dc is not None and res.total >= dc:
                successes += 1
            results.append(res)

        if dc is None:
            header = f"Rolling {iterations} iterations..."
            footer = f"{sum(o.total for o in results)} total."
        else:
            header = f"Rolling {iterations} iterations, DC {dc}..."
            footer = f"{successes} successes, {sum(o.total for o in results)} total."

        if ast.comment:
            header = f"{ast.comment}: {header}"

        result_strs = '\n'.join(str(o) for o in results)

        out = f"{header}\n{result_strs}\n{footer}"

        if len(out) > 1500:
            one_result = str(results[0])
            out = f"{header}\n{one_result}\n[{len(results) - 1} results omitted for output size.]\n{footer}"

        await try_delete(ctx.message)
        await ctx.send(
            f"{ctx.author.mention}\n{out}",
            allowed_mentions=discord.AllowedMentions(users=[ctx.author]))
        await Stats.increase_stat(ctx, "dice_rolled_life")
Пример #7
0
 def make_roller(self, max_rolls: int):
     return d20.Roller(d20.RollContext(max_rolls))
Пример #8
0
    def __init__(self, ctx, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.builtins.update(  # fixme character-only functions, all deprecated now
            get_cc=self.needs_char,
            set_cc=self.needs_char,
            get_cc_max=self.needs_char,
            get_cc_min=self.needs_char,
            mod_cc=self.needs_char,
            cc_exists=self.needs_char,
            create_cc_nx=self.needs_char,
            create_cc=self.needs_char,
            get_slots=self.needs_char,
            get_slots_max=self.needs_char,
            set_slots=self.needs_char,
            use_slot=self.needs_char,
            get_hp=self.needs_char,
            set_hp=self.needs_char,
            mod_hp=self.needs_char,
            hp_str=self.needs_char,
            get_temphp=self.needs_char,
            set_temphp=self.needs_char,
            set_cvar=self.needs_char,
            delete_cvar=self.needs_char,
            set_cvar_nx=self.needs_char,
            get_raw=self.needs_char)

        # char-agnostic globals
        self.builtins.update(
            set=self.set,
            exists=self.exists,
            get=self.get,
            combat=self.combat,
            character=self.character,
            get_gvar=self.get_gvar,
            get_svar=self.get_svar,
            set_uvar=self.set_uvar,
            delete_uvar=self.delete_uvar,
            set_uvar_nx=self.set_uvar_nx,
            uvar_exists=self.uvar_exists,
            chanid=self.chanid,
            servid=self.servid,  # fixme deprecated - use ctx instead
            load_json=self.load_json,
            dump_json=self.dump_json,
            load_yaml=self.load_yaml,
            dump_yaml=self.dump_yaml,
            argparse=argparse,
            ctx=AliasContext(ctx),
            signature=self.signature,
            verify_signature=self.verify_signature)

        # roll limiting
        self._roller = d20.Roller(context=PersistentRollContext(
            max_rolls=1_000, max_total_rolls=10_000))
        self.builtins.update(vroll=self._limited_vroll,
                             roll=self._limited_roll)

        self._cache = {"gvars": {}, "svars": {}, "uvars": {}}

        self.ctx = ctx
        self.character_changed = False
        self.combat_changed = False
        self.uvars_changed = set()
        self.execution_scope: ExecutionScope = ExecutionScope.UNKNOWN
        self.invoking_object: _CodeInvokerT = None