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))
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")
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()
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")
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