Esempio n. 1
0
async def roll(ctx, formula=None):
    """Rolls dice
    Note: formula cannot include spaces, unless wrapped in double-quotes"""
    if not formula:
        await ctx.send(d20.roll('1d20'))
    else:
        await ctx.send(d20.roll(formula))
Esempio n. 2
0
def generate_characteristic(ctx, characteristic):
    if characteristic in ["STR", "CON", "DEX", "APP", "POW"]:
        return dtwenty.roll("3d6*5")
    elif characteristic in ["SIZ", "INT", "EDU"]:
        return dtwenty.roll("(2d6+6)*5")
    else:
        return None
Esempio n. 3
0
def test_bounding_operators():
    # mi, ma
    r = d20.roll("10d2mi2")
    assert r.total == 20

    r = d20.roll("10d2ma1")
    assert r.total == 10
Esempio n. 4
0
 def save(self, ability, advdis=''):  #advdis = "adv" or "dis"
     additional = {'adv': 'kh1', 'dis': 'kl1', '': ''}[advdis]
     if self.abilities[ability]['save'] >= 0:
         return d20.roll('d20' + additional + '+' +
                         str(self.abilities[ability]['save']))
     else:
         return d20.roll('d20' + additional +
                         str(self.abilities[ability]['save']))
Esempio n. 5
0
def test_randomness():
    rolls = [d20.roll("1d1000").total for _ in range(100)]
    # the chance of all of them being equal is 1/1000^100, so this should be safe
    # unless, of course, I broke something horribly
    assert len(set(rolls)) > 1

    # just roll 500 d20s to make codecov happy about branches
    for _ in range(500):
        d20.roll("1d20")
Esempio n. 6
0
def test_h_l_selectors():
    r = d20.roll("10d6kl1")
    assert 1 <= r.total <= 6
    assert len(r.expr.roll.keptset) == 1
    assert len([p for p in r.expr.roll.set if not p.kept]) == 9

    r = d20.roll("10d6kh2")
    assert 2 <= r.total <= 12
    assert len(r.expr.roll.keptset) == 2
    assert len([p for p in r.expr.roll.set if not p.kept]) == 8
Esempio n. 7
0
    async def game_deathsave(self, ctx, *args):
        """Commands to manage character death saves.
        __Valid Arguments__
        See `!help save`."""
        character: Character = await Character.from_ctx(ctx)

        args = argparse(args)
        adv = args.adv()
        b = args.join('b', '+')
        phrase = args.join('phrase', '\n')
        dc = args.last('dc', 10, int)

        if b:
            save_roll = d20.roll(f"{d20_with_adv(adv)}+{b}")
        else:
            save_roll = d20.roll(d20_with_adv(adv))

        embed = discord.Embed()
        embed.title = args.last('title', '') \
                          .replace('[name]', character.name) \
                          .replace('[sname]', 'Death') \
                      or f'{character.name} makes a Death Save!'
        embed.colour = character.get_color()

        death_phrase = ''
        if save_roll.crit == d20.CritType.CRIT:
            character.hp = 1
        elif save_roll.crit == d20.CritType.FAIL:
            character.death_saves.fail(2)
        elif save_roll.total >= dc:
            character.death_saves.succeed()
        else:
            character.death_saves.fail()

        if save_roll.crit == d20.CritType.CRIT:
            death_phrase = f"{character.name} is UP with 1 HP!"
        elif character.death_saves.is_dead():
            death_phrase = f"{character.name} is DEAD!"
        elif character.death_saves.is_stable():
            death_phrase = f"{character.name} is STABLE!"

        await character.commit(ctx)
        embed.description = save_roll.result + (f'\n*{phrase}*'
                                                if phrase else '')
        if death_phrase:
            embed.set_footer(text=death_phrase)
        if dc != 10:
            embed.description = f"**DC {dc}**\n" + embed.description

        embed.add_field(name="Death Saves", value=str(character.death_saves))

        if args.last('image') is not None:
            embed.set_thumbnail(url=args.last('image'))

        await ctx.send(embed=embed)
Esempio n. 8
0
def test_keeping_operators():
    # k, p
    r = d20.roll("10d6k1")
    assert len(
        r.expr.roll.keptset) == r.total  # the total is the number of 1s kept

    r = d20.roll("10d6k<11")
    assert len(r.expr.roll.keptset) == 10

    r = d20.roll("10d6p<11")
    assert len(r.expr.roll.keptset) == 0
Esempio n. 9
0
def weapon_attack(attacker=None,
                  target=None,
                  weapon=None,
                  adv=False,
                  dis=False,
                  condition=None):
    # Attack Roll = Ability Modifier + Proficiency + Enchantment/Item Bonus + Class Features

    output = (
        f"{'' if attacker is None else attacker.name + ' is '} attacking "
        f"{'' if target is None else target} with the "
        f"{'magical +' + str(weapon.bonus_magic) if weapon.magical else ''} "
        f"{weapon.name}")
    output += f", and has {Color.BLUE}Advantage{Color.ENDC}." if adv else ""
    print(f"{' '.join(output.split())}")  # clean any repeated spaces

    if condition:
        # ToDo: placeholder to handle influence of condition, e.g., blinded
        pass

    # If Rogue and has Advantage, then add sneak attack damage to weapon
    if "Rogue" in attacker.cclass and adv:
        regexp = re.compile("(\\d+).*Rogue")
        rogue_level = int(regexp.search(
            attacker.cclass).group(1))  # get Rogue level
        weapon.damage += [[(rogue_level + 1) // 2, 6,
                           "sneak"]]  # append sneak damage to Weapon

    attack_roll_str = attacker.attack_roll(adv, dis)

    d20roll = d20.roll(attack_roll_str)

    # d20roll = d20.roll('20')
    # Critical 20, for testing
    logging.debug(d20roll.crit)
    print(f'\tYour Attack roll is ', end='')
    if d20roll.crit == d20.CritType.CRIT or d20roll.total >= attacker.crit:
        print(f"a Critical HIT: {d20roll.result}")
        criticalhit(attacker, weapon, target)
    elif d20roll.crit == d20.CritType.FAIL:  # total == 1:
        print(f"a Critical Fail: {d20roll.result}")
        critical_miss(weapon)
    else:
        attackbonus = attacker.attack_bonus(weapon)
        attack_result_str = " + ".join([str(d20roll.total), attackbonus])
        attack_result = d20.roll(f"{attack_result_str}")
        print(
            f"{attack_roll_str} + {attackbonus} = {attack_result_str.replace(' ', '')} = {Color.YELLOW}{attack_result.total}{Color.ENDC}."
        )
        hitanddamage(attacker, weapon, target)
Esempio n. 10
0
def test_rerolling_operators():
    # rr, ro, ra, e
    r = d20.roll("4d6rr1")
    assert 8 <= r.total <= 24
    assert len([p for p in r.expr.roll.set if p.number == 1 and p.kept]) == 0

    r = d20.roll("4d6rr<3")
    assert 12 <= r.total <= 24
    assert len([p for p in r.expr.roll.set if p.number < 3 and p.kept]) == 0

    r = d20.roll("10d2ra1")
    assert 11 <= r.total <= 21

    r = d20.roll("10d2e1")
    assert 20 <= r.total
Esempio n. 11
0
async def _attack(ctx, dice: str):
    #TODO: debug this command. Sometimes it raises an error
    """Tira un dado usando un'espressione (vedi `help r`) e calcola
il risultato dell'attacco secondo il regolamento di Crossdoom.

Restituisce: singoli valori e risultato dell'attacco

Per maggiori informazioni sulla sintassi utilizzata:
https://d20.readthedocs.io/en/latest/start.html#dice-syntax
Per il regolamento di Crossdoom:
https://www.crossdoom.it/
"""
    try:
        res = d20.roll(dice)
        dices = diceIterClass(res.expr.roll)  # Iterate and get dice values
        message = ['Attacco:']
        for key in dices.initial_rolls.keys():
            if isinstance(key, int) and len(dices.initial_rolls[key]) > 0:
                message.append('{}d{}{} -> {}'.format(len(dices.initial_rolls[key]), key,
                               dices.initial_rolls[key], dices.crossdoom_rolls[key]))
        total = [sum(dices.crossdoom_rolls[x]) for x in dices.crossdoom_rolls if isinstance(x,int)]
        if sum(total) > 0:
            message.append('Totale: {}'.format(sum(total)))
        else:
            message.append('Attacco fallito.')
        dice_message = '\n'.join(message)
        await ctx.send(dice_message)
    except d20.errors.RollSyntaxError:
        await ctx.send('Espressione non valida, consulta `g.help roll`')
Esempio n. 12
0
def test_complex_rolls():
    r = d20.roll("10d6rol5mi6ma1k1[annotation] some comments",
                 allow_comments=True)
    assert r.total == 10
    assert r.crit == 0
    assert "some comments" == r.comment

    r = d20.roll("5d6kh4e0kl3")
    assert 3 <= r.total <= 18
    assert len(r.expr.roll.keptset) == 3
    assert len([p for p in r.expr.roll.set if not p.kept]) == 2

    r = d20.roll("10d6kh4kl3")
    assert 7 <= r.total <= 42
    assert len(r.expr.roll.keptset) == 7
    assert len([p for p in r.expr.roll.set if not p.kept]) == 3
Esempio n. 13
0
def hitanddamage(attacker, weapon, target=None):
    rollplus = ""
    # print(attacker.feature)
    if attacker.feature == "Great Weapon Fighting":
        rollplus = "ro<3"
    damagebonus = attacker.damage_bonus(weapon)
    # print(damagebonus)
    rollplus += f"{damagebonus}"

    if weapon.magical > 0:
        rollplus += f"{weapon.bonus_magic:+}"

    new_dmg = []
    for d in weapon.damage:
        n, s, t = d
        t += dmg_icon(t)
        new_dmg.append([n, s, t.title()])
    # print(new_dmg)
    weapon.damage = new_dmg
    damage_roll_str = " + ".join([weapon.dice_roll_str, rollplus])
    # print(damage_roll_str)
    # dice_roll_str = damage_roll_str

    damage_result = d20.roll(damage_roll_str)
    damage_result_str = f"{damage_result.total}{rollplus}"
    damage_total = damage_result.total
    output = f"Your {weapon.name} "
    output += "caused " if target is None else f"targets {target} for "
    output += f" {damage_result.result} points of {'magical ' if weapon.magical else ''}damage."
    print(f"\t{' '.join(output.split())}")
Esempio n. 14
0
    def run(self, autoctx):
        super(TempHP, self).run(autoctx)
        args = autoctx.args
        amount = self.amount
        maxdmg = args.last('max', None, bool, ephem=True)

        # check if we actually need to run this damage roll (not in combat and roll is redundant)
        if autoctx.target.is_simple and self.is_meta(autoctx, True):
            return

        amount = autoctx.parse_annostr(amount)
        dice_ast = copy.copy(d20.parse(amount))
        dice_ast = _upcast_scaled_dice(self, autoctx, dice_ast)

        if maxdmg:
            dice_ast = d20.utils.tree_map(_max_mapper, dice_ast)

        dmgroll = roll(dice_ast)
        autoctx.queue(f"**THP**: {dmgroll.result}")

        if autoctx.target.combatant:
            autoctx.target.combatant.temp_hp = max(dmgroll.total, 0)
            autoctx.footer_queue("{}: {}".format(
                autoctx.target.combatant.name,
                autoctx.target.combatant.hp_str()))
        elif autoctx.target.character:
            autoctx.target.character.temp_hp = max(dmgroll.total, 0)
            autoctx.footer_queue("{}: {}".format(
                autoctx.target.character.name,
                autoctx.target.character.hp_str()))
Esempio n. 15
0
 async def _roll(self, ctx: Context, *, expr: str = '1d20'):
     """Rolls dice!
     This library has very similar syntax: https://d20.readthedocs.io/en/latest/start.html#dice-syntax"""
     msg: discord.Message = await ctx.send(self._d20, 'Rolling...')
     expr = await self._replace_macros(ctx, expr)
     result: d20.RollResult = d20.roll(expr)
     await msg.edit(content=f'{self._d20} {str(result)}')
Esempio n. 16
0
    def reroll_dynamic(self):
        """
        Rerolls all combatant initiatives. Returns a string representing the new init order.
        """
        rolls = {}
        for c in self._combatants:
            init_roll = roll(c.init_skill.d20())
            c.init = init_roll.total
            rolls[c] = init_roll
        self.sort_combatants()

        # reset current turn
        self._turn = 0
        self._current_index = None

        order = []
        for combatant, init_roll in sorted(rolls.items(),
                                           key=lambda r:
                                           (r[1].total, int(r[0].init_skill)),
                                           reverse=True):
            order.append(f"{init_roll.result}: {combatant.name}")

        order = "\n".join(order)

        return order
Esempio n. 17
0
    def setup(self):
        global SKILLS, DAMAGETYPES
        if self.options['rollhp']:
            self.hp = d20.roll(self.data['hit_dice']).total
        else:
            self.hp = int(self.data['hit_points'])

        self.forms = ['material']
        self.form = 0

        self.challenge = float(eval(self.data['challenge_rating']))
        self.challenge_display = self.data['challenge_rating']
        self.proficiency_bonus = self._get_proficiency()

        self.skills = {}
        for s in SKILLS.keys():
            if s in self.data['skills'].keys():
                self.skills[s] = self.data['skills'][s] + 0
            else:
                self.skills[s] = getmod(self.data[SKILLS[s]])

        self.ac = self.data['armor_class']

        self.vuln = self._parse_dmg_string(self.data['damage_vulnerabilities'])
        self.resist = self._parse_dmg_string(self.data['damage_resistances'])
        self.immune = self._parse_dmg_string(self.data['damage_immunities'])

        self.condition_immunities = self.data['condition_immunities'].split(
            ', ')

        self.actions = [self._parse_atk(atk) for atk in self.data['actions']]

        self.spellcasting = {}
        self.special_abilities = self.data['special_abilities'][:]
        for ability in self.data['special_abilities']:
            if 'spellcasting' in ability['name'].lower():
                self.spellcasting[ability['name']] = self._parse_spellcasting(
                    ability['desc'])

        self.abilities = {}
        for ability in ABILITIES:
            if self.data[ability + '_save'] == None:
                save = getmod(self.data[ability])
            else:
                save = self.data[ability + '_save']
            self.abilities[ability] = {
                'score': self.data[ability],
                'modifier': getmod(self.data[ability]),
                'save': save
            }

        self.reactions = self.data['reactions'][:]
        self.legendary_actions = self.data['legendary_actions']

        self.slug = self.data['slug']
        self.name = self.data['name']
        self.img = self.data['img_main']
        self.size = self.data['size']
        self.type = self.data['type']
        self.alignment = self.data['alignment']
Esempio n. 18
0
def chatbot_interpret(content, fingerprint, campaign, map):
    raw_split = content.split(' ')
    cmd = raw_split[0]
    args = [{'name': '__main__', 'value': []}]
    if len(raw_split) > 1:
        _args = raw_split[1:]
        current = 0
        for a in _args:
            if a.startswith('-') and len(a) > 1:
                args.append({'name': a[1:], 'value': []})
                current += 1
            else:
                args[current]['value'].append(a)
    args = [{'name': i['name'], 'value': ' '.join(i['value'])} for i in args]
    args[0]['value'] = args[0]['value'].split(' ')

    logger.info(
        f'User {fingerprint} sent command {cmd} with args {str(args)} to map {map} in campaign {campaign}'
    )

    if cmd in ['r', 'roll']:
        roll_args = []
        jnr = ''
        for i in args[0]['value'][0]:
            jnr += i
            if i in ['+', '-', '*', '/']:
                roll_args.append(jnr)
                jnr = ''
        if len(jnr) > 0:
            roll_args.append(jnr)

        if 'adv' in args[0]['value']:
            c = 0
            for arg in roll_args:
                if 'd' in arg:
                    roll_args[c] = '2d' + roll_args[c].split(
                        'd')[1][:len(roll_args[c].split('d')[1]) -
                                1] + 'kh1' + cond(
                                    roll_args[c].split('d')[1]
                                    [len(roll_args[c].split('d')[1]) - 1] in [
                                        '+', '-', '*', '/'
                                    ], roll_args[c].split('d')[1]
                                    [len(roll_args[c].split('d')[1]) - 1], '')
                c += 1
        elif 'dis' in args[0]['value']:
            c = 0
            for arg in roll_args:
                if 'd' in arg:
                    roll_args[c] = '2d' + roll_args[c].split(
                        'd')[1][:len(roll_args[c].split('d')[1]) -
                                1] + 'kl1' + cond(
                                    roll_args[c].split('d')[1]
                                    [len(roll_args[c].split('d')[1]) - 1] in [
                                        '+', '-', '*', '/'
                                    ], roll_args[c].split('d')[1]
                                    [len(roll_args[c].split('d')[1]) - 1], '')
                c += 1
        roll_args = ''.join(roll_args)
        return str(d20.roll(roll_args))
Esempio n. 19
0
 async def roll(self, ctx: commands.Context, *, expr: str = "1d6"):
     """Rolls dice based on the expression given."""
     result = d20.roll(expr)
     await HanalonEmbed(
         title="Dice 🎲",
         description=str(result),
         context=ctx,
     ).respond(True)
Esempio n. 20
0
 async def game_hp_set(self, ctx, *, hp):
     """Sets the character's HP to a certain value."""
     character: Character = await Character.from_ctx(ctx)
     before = character.hp
     hp_roll = d20.roll(hp)
     character.hp = hp_roll.total
     await character.commit(ctx)
     await ctx.send(f"{character.name}: {character.hp_str()} ({character.hp - before:+})")
Esempio n. 21
0
def critical_miss(weapon=None):
    print(f"{Color.RED}Critical Fail!{Color.ENDC}")

    def indent(my_paragraph) -> str:
        return f"\t{my_paragraph}"

    print(f"Critical fail roll for d100 is {roll(100)}"
          )  # for David Gavrin's table

    mymiss = roll(20)
    if mymiss == 1:
        if weapon:
            if weapon.magical:
                print(f"\tMagic backfires!")
                magic_damage = d20.roll('+'.join(
                    [die_roll_str(weapon.damage[0]),
                     str(weapon.bonus_magic)]))
                print(
                    f"\tYou take {magic_damage.result} points of {weapon.damage[0][2]} damage."
                )
            elif weapon.list == "ranged":
                print(
                    f"\tThe bowstring on {weapon.name} broke!\n"
                    f"\tOn your next turn you lose your Action and half your movement.\n"
                    f"\tEither use your next turn to replace the string, or switch weapons."
                )
            else:
                print(
                    f"\tDangerous Design-Flaw! {weapon.name} broke, and injured you.\n"
                    f"\tTake {d20.roll(die_roll_str(weapon.damage[0])).result} points of {weapon.damage[0][2]} damage."
                )
            print(f"")
        # print("Weapon breaks!")
    elif mymiss < 4:
        print(
            "\tPoor attack: Has 50% chance to hit any character in the line of attack or within 5' of the target."
        )
        if random.randint(0, 1):
            print(f"\tWhuh? Looks like you missed everyone.")
        else:
            print(
                f"\tYour victim takes {d20.roll(weapon.dice_roll_str).result} points of damage."
            )
        print(
            f"\tAlso, due to dismay, lose your next Bonus Action (either this turn or the next turn)."
        )
    elif mymiss < 6:
        print(
            "\tDropped weapon! Disadvantage on next attack, and lose 10ft of motion next turn to pick up weapon."
        )
    elif mymiss < 11:
        print(
            "\tFumbled weapon! Lose half your motion until the end of your next turn as you regain your composure."
        )
    else:
        print(
            "\tYou missed spectacularly, and your opponent snickered at your failure."
        )
Esempio n. 22
0
 def check(self, skill_or_ability, advdis=''):  #advdis = "adv" or "dis"
     additional = {'adv': 'kh1', 'dis': 'kl1', '': ''}[advdis]
     if skill_or_ability in SKILLS.keys():
         if self.skills[skill_or_ability] >= 0:
             return d20.roll('d20' + additional + '+' +
                             str(self.skills[skill_or_ability]))
         else:
             return d20.roll('d20' + additional +
                             str(self.skills[skill_or_ability]))
     elif skill_or_ability in ABILITIES:
         if self.abilities[skill_or_ability]['modifier'] >= 0:
             return d20.roll(
                 'd20' + additional + '+' +
                 str(self.abilities[skill_or_ability]['modifier']))
         else:
             return d20.roll(
                 'd20' + additional +
                 str(self.abilities[skill_or_ability]['modifier']))
Esempio n. 23
0
    async def game_hp_set(self, ctx, *, hp):
        """Sets the character's HP to a certain value."""
        character: Character = await Character.from_ctx(ctx)
        caster = await targetutils.maybe_combat_caster(ctx, character)

        before = caster.hp
        hp_roll = d20.roll(hp)
        caster.hp = hp_roll.total
        await character.commit(ctx)
        await gameutils.send_hp_result(ctx, caster, f"{caster.hp - before:+}")
Esempio n. 24
0
 def saving_throw(self,
                  ability='Constitution',
                  *,
                  adv=False,
                  dis=False,
                  bless=False):
     import d20
     if adv:
         roll_str = "2d20kh1"
     elif dis:
         roll_str = "2d20kl1"
     else:
         roll_str = f"1d20"
     my_d20 = d20.roll(roll_str).total
     my_d4 = d20.roll('1d4').total
     my_total = my_d20 + my_d4 if bless else my_d20
     if 'death' in ability.lower():
         print(f"{self.name} rolls a Death Saving Throw, and ", end='')
         if my_d20 == 1:
             print(f"Failed TWICE with a roll of 1.")
             return
         elif my_d20 == 20:
             print(f"Succeeded TWICE with a roll of 20.")
             return
         if my_total < 10:
             print(f"Failed with a roll of {my_total}.")
             return
         else:
             print(f"Succeeded with a roll of {my_total}.")
             return
     else:
         mymod = ability_score_mod(getattr(self,
                                           f"c{ability.lower()[0:3]}"))
         roll_str += f"{mymod:+}"
         # print(self.proficiency['save'])
         roll_str += f"{level_proficiency(self.level):+}" if ability in self.proficiency[
             'save'] else ""
         roll_str += f"+1d4" if bless else ""
         print(
             f"{self.name} performs a {ability} check : {d20.roll(roll_str)}"
         )
Esempio n. 25
0
def test_gt_lt_selectors():
    r = d20.roll("10d6k>6")
    assert r.total == 0
    assert len(r.expr.roll.keptset) == 0
    assert len([p for p in r.expr.roll.set if not p.kept]) == 10

    r = d20.roll("10d6k<1")
    assert r.total == 0
    assert len(r.expr.roll.keptset) == 0
    assert len([p for p in r.expr.roll.set if not p.kept]) == 10

    r = d20.roll("10d6rr<6")
    assert r.total == 60

    r = d20.roll("10d6rr>1")
    assert r.total == 10

    r = d20.roll("10d6k<6")
    assert 10 <= r.total <= 50
    assert len(r.expr.roll.keptset) <= 10
    assert all(p.number < 6 for p in r.expr.roll.keptset)
Esempio n. 26
0
async def roll(ctx):
    message = ctx.message.content[2:].strip()
    await delete_message(ctx)

    if len(message) == 0:
        percentile = d10p.roll()
        unit = d10.roll()
        await ctx.send(f"{ctx.author.mention} rolled `{percentile + unit}`")
    else:
        result = dtwenty.roll(message.lower())
        result_string = str(result).replace("**", "")
        await ctx.send(f"{ctx.author.mention} rolled {result_string}")
Esempio n. 27
0
 def roll(self, fp, args):  # [Roll string]
     self.logger.debug('User ' + fp + ' is rolling ' + args[0])
     try:
         roll = d20.roll(args[0])
         elements = str(roll)
         print(elements)
         self.logger.debug('User ' + fp + ' rolled ' + args[0] +
                           ' and got ' + str(roll.total))
         return {'code': 200, 'roll': roll.total, 'elements': elements}
     except d20.errors.RollSyntaxError as e:
         self.logger.exception('Dice error: ')
         return {'code': 400, 'reason': 'Dice error: ' + str(e)}
Esempio n. 28
0
 def attack_roll(self, type='damage'):
     import d20
     if type in 'attack':
         #
         self.rollstr += f"{self.bonus_attack:+}"
     elif type in 'damage':
         self.rollstr += f"{self.bonus_damage:+}"
     if self.rollstrappend:
         self.rollstr += f"{self.rollstrappend:+}"
     # rolls = [random.randint(1, self.sides) for _ in range(self.dice)]
     rolls = d20.roll(self.rollstr).total
     # print(rolls)
     return rolls
Esempio n. 29
0
 def weapon_roll(self, type='attack'):
     # todo: unify as 'weapon_roll('attack'|'damage)
     import d20
     if type in 'attack':
         self.rollstr += f"{self.bonus_attack:+}"
     elif type in 'damage':
         self.rollstr += f"{self.bonus_damage:+}"
     if self.rollstrappend:
         self.rollstr += f"{self.rollstrappend:+}"
     # rolls = [random.randint(1, self.sides) for _ in range(self.dice)]
     rolls = d20.roll(self.rollstr).total
     # print(rolls)
     return rolls
Esempio n. 30
0
def AddCharacter(command):
    try:
        character = command.characters[command.base[1]]
        characterinit = d20.roll('1d20+{}'.format(
            character['initiative'])).total
        returnMessage = "{} has rolled a {} and will be added to initiative!".format(
            character['charactername'], str(characterinit))
        initiatebattle.add_to_initiative(command.room, character,
                                         characterinit)

    except:
        returnMessage = "This character was not found"
    return returnMessage