Esempio n. 1
0
    def run(self, autoctx):
        super(Save, self).run(autoctx)
        save = autoctx.args.last('save') or self.stat
        adv = autoctx.args.adv(False)
        dc_override = None
        if self.dc:
            try:
                dc_override = autoctx.evaluator.parse(self.dc,
                                                      autoctx.metavars)
                dc_override = int(dc_override)
            except (TypeError, ValueError):
                raise AutomationException(
                    f"{dc_override} cannot be interpreted as a DC.")

        dc = autoctx.args.last(
            'dc', type_=int
        ) or dc_override or autoctx.dc_override or autoctx.caster.spellcasting.dc

        if not dc:
            raise NoSpellDC()
        try:
            save_skill = next(s
                              for s in ('strengthSave', 'dexteritySave',
                                        'constitutionSave', 'intelligenceSave',
                                        'wisdomSave', 'charismaSave')
                              if save.lower() in s.lower())
        except StopIteration:
            raise InvalidSaveType()

        autoctx.meta_queue(f"**DC**: {dc}")
        if autoctx.target.target:
            # character save effects (#408)
            if autoctx.target.character:
                save_args = autoctx.target.character.get_skill_effects().get(
                    save_skill)
                if save_args:
                    adv = argparse(save_args).adv() + adv
                    adv = max(-1, min(1,
                                      adv))  # bound, cancel out double dis/adv

            saveroll = autoctx.target.get_save_dice(save_skill)
            save_roll = roll(saveroll,
                             adv=adv,
                             rollFor='{} Save'.format(save_skill[:3].upper()),
                             inline=True,
                             show_blurbs=False)
            is_success = save_roll.total >= dc
            autoctx.queue(save_roll.result +
                          ("; Success!" if is_success else "; Failure!"))
        else:
            autoctx.meta_queue('{} Save'.format(save_skill[:3].upper()))
            is_success = False

        if is_success:
            self.on_success(autoctx)
        else:
            self.on_fail(autoctx)
Esempio n. 2
0
    def run(self, autoctx):
        super(Save, self).run(autoctx)
        save = autoctx.args.last('save') or self.stat
        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_override = None
        if self.dc:
            try:
                dc_override = autoctx.parse_annostr(self.dc)
                dc_override = int(dc_override)
            except (TypeError, ValueError):
                raise AutomationException(f"{dc_override} cannot be interpreted as a DC.")

        dc = autoctx.args.last('dc', type_=int) or dc_override or autoctx.dc_override or autoctx.caster.spellbook.dc

        if dc is None:
            raise NoSpellDC()
        try:
            save_skill = next(s for s in ('strengthSave', 'dexteritySave', 'constitutionSave',
                                          'intelligenceSave', 'wisdomSave', 'charismaSave') if
                              save.lower() in s.lower())
        except StopIteration:
            raise InvalidSaveType()

        autoctx.meta_queue(f"**DC**: {dc}")
        if not autoctx.target.is_simple:
            save_blurb = f'{save_skill[:3].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:
                saveroll = autoctx.target.get_save_dice(save_skill, adv=autoctx.args.adv(boolwise=True))
                save_roll = roll(saveroll, rollFor=save_blurb, inline=True, show_blurbs=False)
                is_success = save_roll.total >= dc
                success_str = ("; Success!" if is_success else "; Failure!")
                if not hide:
                    autoctx.queue(f"{save_roll.result}{success_str}")
                else:
                    autoctx.add_pm(str(autoctx.ctx.author.id), f"{save_roll.result}{success_str}")
                    autoctx.queue(f"**{save_blurb}**: 1d20...{success_str}")
        else:
            autoctx.meta_queue('{} Save'.format(save_skill[:3].upper()))
            is_success = False

        if is_success:
            damage = self.on_success(autoctx)
        else:
            damage = self.on_fail(autoctx)
        return {"total": damage}
Esempio n. 3
0
    def run(self, autoctx):
        super(Save, self).run(autoctx)
        save = autoctx.args.last('save') or self.stat
        dc_override = None
        if self.dc:
            try:
                dc_override = autoctx.evaluator.parse(self.dc,
                                                      autoctx.metavars)
                dc_override = int(dc_override)
            except (TypeError, ValueError):
                raise AutomationException(
                    f"{dc_override} cannot be interpreted as a DC.")

        dc = autoctx.args.last(
            'dc', type_=int
        ) or dc_override or autoctx.dc_override or autoctx.caster.spellbook.dc

        if dc is None:
            raise NoSpellDC()
        try:
            save_skill = next(s
                              for s in ('strengthSave', 'dexteritySave',
                                        'constitutionSave', 'intelligenceSave',
                                        'wisdomSave', 'charismaSave')
                              if save.lower() in s.lower())
        except StopIteration:
            raise InvalidSaveType()

        autoctx.meta_queue(f"**DC**: {dc}")
        if not autoctx.target.is_simple:
            saveroll = autoctx.target.get_save_dice(
                save_skill, adv=autoctx.args.adv(boolwise=True))
            save_roll = roll(saveroll,
                             rollFor='{} Save'.format(save_skill[:3].upper()),
                             inline=True,
                             show_blurbs=False)
            is_success = save_roll.total >= dc
            autoctx.queue(save_roll.result +
                          ("; Success!" if is_success else "; Failure!"))
        else:
            autoctx.meta_queue('{} Save'.format(save_skill[:3].upper()))
            is_success = False

        if is_success:
            damage = self.on_success(autoctx)
        else:
            damage = self.on_fail(autoctx)
        return {"total": damage}
Esempio n. 4
0
    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)
Esempio n. 5
0
    def run(self, autoctx):
        super(Save, self).run(autoctx)
        save = autoctx.args.last('save') or self.stat
        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)
        adv = autoctx.args.adv(custom={'adv': 'sadv', 'dis': 'sdis'})

        dc_override = None
        if self.dc:
            try:
                dc_override = autoctx.parse_annostr(self.dc,
                                                    is_full_expression=True)
                dc_override = int(dc_override)
            except (TypeError, ValueError):
                raise AutomationException(
                    f"{dc_override} 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())
        except StopIteration:
            raise InvalidSaveType()

        save_roll = None

        autoctx.meta_queue(f"**DC**: {dc}")
        autoctx.metavars['lastSaveRollTotal'] = 0
        if not autoctx.target.is_simple:
            save_blurb = f'{save_skill[:3].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:
                saveroll = autoctx.target.get_save_dice(save_skill, adv=adv)
                save_roll = roll(saveroll)
                is_success = save_roll.total >= dc
                autoctx.metavars['lastSaveRollTotal'] = save_roll.total  # 1362
                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('{} Save'.format(save_skill[:3].upper()))
            is_success = False

        if is_success:
            children = self.on_success(autoctx)
        else:
            children = self.on_fail(autoctx)
        return SaveResult(dc=dc,
                          ability=save_skill,
                          save_roll=save_roll,
                          adv=adv,
                          did_save=is_success,
                          children=children)