コード例 #1
0
ファイル: gamelog.py プロジェクト: storytellermahkasad/avrae
 async def dice_roll_save(self, gctx, roll_request):
     """Save: Display like ``!s``."""
     save_name = roll_request.action
     if save_name in constants.STAT_ABBREVIATIONS:
         save_name = verbose_stat(save_name)
     await self._dice_roll_embed_common(gctx,
                                        roll_request,
                                        "{name} makes {save} Save!",
                                        save=a_or_an(save_name.title()))
コード例 #2
0
ファイル: gamelog.py プロジェクト: storytellermahkasad/avrae
 async def dice_roll_check(self, gctx, roll_request):
     """Check: Display like ``!c``. Requires character - if not imported falls back to default roll."""
     check_name = roll_request.action
     if check_name in constants.STAT_ABBREVIATIONS:
         check_name = verbose_stat(check_name)
     await self._dice_roll_embed_common(gctx,
                                        roll_request,
                                        "{name} makes {check} check!",
                                        check=a_or_an(check_name.title()))
コード例 #3
0
def run_save(save_key, caster, args, embed):
    """
    Runs a caster's saving throw, building on an existing embed and handling most arguments.

    Also handles save bonuses from ieffects if caster is a combatant.

    :type save_key: str
    :type caster: cogs5e.models.sheet.statblock.StatBlock
    :type args: utils.argparser.ParsedArguments
    :type embed: discord.Embed
    :return: The total of each save.
    :rtype: SaveResult
    """
    if save_key.startswith('death'):
        save = Skill(0)
        stat_name = stat = 'Death'
        save_name = 'Death Save'
    else:
        try:
            save = caster.saves.get(save_key)
            stat = save_key[:3]
            stat_name = verbose_stat(stat).title()
            save_name = f"{stat_name} Save"
        except ValueError:
            raise InvalidArgument('That\'s not a valid save.')

    # -title
    if args.last('title'):
        embed.title = args.last('title', '') \
            .replace('[name]', caster.get_title_name()) \
            .replace('[sname]', save_name)
    elif args.last('h'):
        embed.title = f"An unknown creature makes {a_or_an(save_name)}!"
    else:
        embed.title = f'{caster.get_title_name()} makes {a_or_an(save_name)}!'

    # ieffect handling
    if isinstance(caster, init.Combatant):
        # -sb
        args['b'] = args.get('b') + caster.active_effects('sb')
        # -sadv/sdis
        sadv_effects = caster.active_effects('sadv')
        sdis_effects = caster.active_effects('sdis')
        if 'all' in sadv_effects or stat in sadv_effects:
            args[
                'adv'] = True  # Because adv() only checks last() just forcibly add them
        if 'all' in sdis_effects or stat in sdis_effects:
            args['dis'] = True

    result = _run_common(save, args, embed, rr_format="Save {}")
    return SaveResult(rolls=result.rolls,
                      skill=save,
                      skill_name=stat_name,
                      skill_roll_result=result)
コード例 #4
0
def run_save(save_key, caster, args, embed):
    """
    Runs a caster's saving throw, building on an existing embed and handling most arguments.

    Also handles save bonuses from ieffects if caster is a combatant.

    :type save_key: str
    :type caster: cogs5e.models.sheet.statblock.StatBlock
    :type args: utils.argparser.ParsedArguments
    :type embed: discord.Embed
    :return: The total of each save.
    :rtype: SaveResult
    """
    try:
        save = caster.saves.get(save_key)
        stat_name = verbose_stat(save_key[:3]).title()
        save_name = f"{stat_name} Save"
    except ValueError:
        raise InvalidArgument('That\'s not a valid save.')

    # -title
    if args.last('title'):
        embed.title = args.last('title', '') \
            .replace('[name]', caster.get_title_name()) \
            .replace('[sname]', save_name)
    elif args.last('h'):
        embed.title = f"An unknown creature makes {a_or_an(save_name)}!"
    else:
        embed.title = f'{caster.get_title_name()} makes {a_or_an(save_name)}!'

    # ieffect -sb
    if isinstance(caster, init.Combatant):
        args['b'] = args.get('b') + caster.active_effects('sb')

    result = _run_common(save, args, embed, rr_format="Save {}")
    return SaveResult(rolls=result.rolls,
                      skill=save,
                      skill_name=stat_name,
                      skill_roll_result=result)
コード例 #5
0
def parse_stat_str(stat_list):
    if 'all' in stat_list:
        return 'All'
    return ', '.join(verbose_stat(s) for s in stat_list)
コード例 #6
0
ファイル: save.py プロジェクト: driesceuppens/avrae
    def run(self, autoctx):
        super().run(autoctx)
        if autoctx.target is None:
            raise TargetException("Tried to make a save without a target! Make sure all Save effects are inside "
                                  "of a Target effect.")

        # ==== args ====
        save = autoctx.args.last('save') or self.stat
        sb = autoctx.args.get('sb', ephem=True)
        auto_pass = autoctx.args.last('pass', type_=bool, ephem=True)
        auto_fail = autoctx.args.last('fail', type_=bool, ephem=True)
        hide = autoctx.args.last('h', type_=bool)

        # ==== dc ====
        dc_override = None
        if self.dc:
            try:
                dc_override = autoctx.parse_intexpression(self.dc)
            except Exception:
                raise AutomationException(f"{self.dc!r} cannot be interpreted as a DC.")

        # dc hierarchy: arg > self.dc > spell cast override > spellbook dc
        dc = dc_override or autoctx.dc_override or autoctx.caster.spellbook.dc
        if 'dc' in autoctx.args:
            dc = maybe_mod(autoctx.args.last('dc'), dc)

        if dc is None:
            raise NoSpellDC("No spell save DC found. Use the `-dc` argument to specify one!")
        try:
            save_skill = next(s for s in ('strengthSave', 'dexteritySave', 'constitutionSave',
                                          'intelligenceSave', 'wisdomSave', 'charismaSave') if
                              save.lower() in s.lower())
            stat = save_skill[:3]
        except StopIteration:
            raise InvalidSaveType()

        # ==== ieffects ====
        if autoctx.target.combatant:
            # Combine args/ieffect advantages - adv/dis (#1552)
            sadv_effects = autoctx.target.combatant.active_effects('sadv')
            sdis_effects = autoctx.target.combatant.active_effects('sdis')
            sadv = 'all' in sadv_effects or stat in sadv_effects
            sdis = 'all' in sdis_effects or stat in sdis_effects
            adv = reconcile_adv(
                adv=autoctx.args.last('sadv', type_=bool, ephem=True) or sadv,
                dis=autoctx.args.last('sdis', type_=bool, ephem=True) or sdis
            )
        else:
            adv = autoctx.args.adv(custom={'adv': 'sadv', 'dis': 'sdis'})

        # ==== execution ====
        save_roll = None
        autoctx.metavars['lastSaveRollTotal'] = 0
        autoctx.metavars['lastSaveNaturalRoll'] = 0  # 1495
        autoctx.metavars['lastSaveDC'] = dc
        autoctx.metavars['lastSaveAbility'] = verbose_stat(stat)
        autoctx.meta_queue(f"**DC**: {dc}")

        if not autoctx.target.is_simple:
            save_blurb = f'{stat.upper()} Save'
            if auto_pass:
                is_success = True
                autoctx.queue(f"**{save_blurb}:** Automatic success!")
            elif auto_fail:
                is_success = False
                autoctx.queue(f"**{save_blurb}:** Automatic failure!")
            else:
                save_dice = autoctx.target.get_save_dice(save_skill, adv=adv, sb=sb)
                save_roll = d20.roll(save_dice)
                is_success = save_roll.total >= dc

                # get natural roll
                d20_value = d20.utils.leftmost(save_roll.expr).total

                autoctx.metavars['lastSaveRollTotal'] = save_roll.total  # 1362
                autoctx.metavars['lastSaveNaturalRoll'] = d20_value  # 1495

                success_str = ("; Success!" if is_success else "; Failure!")
                out = f"**{save_blurb}**: {save_roll.result}{success_str}"
                if not hide:
                    autoctx.queue(out)
                else:
                    autoctx.add_pm(str(autoctx.ctx.author.id), out)
                    autoctx.queue(f"**{save_blurb}**: 1d20...{success_str}")
        else:
            autoctx.meta_queue(f'{stat.upper()} Save')
            is_success = False

        # Disable critical damage state for children (#1556)
        original = autoctx.in_save
        autoctx.in_save = True

        if is_success:
            children = self.on_success(autoctx)
        else:
            children = self.on_fail(autoctx)

        autoctx.in_save = original  # Restore proper crit state (#1556)

        return SaveResult(dc=dc, ability=save_skill, save_roll=save_roll, adv=adv, did_save=is_success,
                          children=children)