示例#1
0
    def get_resistances(self):
        out = {'resist': [], 'immune': [], 'vuln': []}
        if not self.additional:  # requires 2.0
            return Resistances.from_dict(out)

        for rownum in range(69, 80):
            for resist_type, col in RESIST_COLS:
                try:
                    dtype = self.additional.value(f"{col}{rownum}")
                except IndexError:
                    dtype = None
                if dtype:
                    out[resist_type].append(dtype.lower())

        return Resistances.from_dict(out)
示例#2
0
    def get_resistances(self):
        out = {'resist': [], 'immune': [], 'vuln': []}
        if not self.additional:  # requires 2.0
            return Resistances.from_dict(out)

        for resist_row in range(69, 80):  # T69:T79
            resist = self.additional.cell(f"T{resist_row}").value
            if resist:
                out['resist'].append(resist.lower())

        for immune_row in range(69, 80):  # AE69:AE79
            immune = self.additional.cell(f"AE{immune_row}").value
            if immune:
                out['immune'].append(immune.lower())

        return Resistances.from_dict(out)
示例#3
0
    def get_resistances(self):
        resist = {
            'resist': set(),
            'immune': set(),
            'vuln': set()
        }
        for mod in self.modifiers():
            if mod['type'] == 'resistance':
                resist['resist'].add(mod['subType'].lower())
            elif mod['type'] == 'immunity':
                resist['immune'].add(mod['subType'].lower())
            elif mod['type'] == 'vulnerability':
                resist['vuln'].add(mod['subType'].lower())

        for override in self.character_data['customDefenseAdjustments']:
            if not override['type'] == 2:
                continue
            if override['id'] not in RESIST_OVERRIDE_MAP:
                continue

            dtype, rtype = RESIST_OVERRIDE_MAP[override['id']]
            resist[RESIST_TYPE_MAP[rtype]].add(dtype.lower())

        resist = {k: list(v) for k, v in resist.items()}
        return Resistances.from_dict(resist)
示例#4
0
    def __init__(self,
                 name: str,
                 stats: BaseStats = None,
                 levels: Levels = None,
                 attacks: AttackList = None,
                 skills: Skills = None,
                 saves: Saves = None,
                 resistances: Resistances = None,
                 spellbook: Spellbook = None,
                 ac: int = None,
                 max_hp: int = None,
                 hp: int = None,
                 temp_hp: int = 0):
        if stats is None:
            stats = BaseStats.default()
        if levels is None:
            levels = Levels()
        if attacks is None:
            attacks = AttackList()
        if skills is None:
            skills = Skills.default(stats)
        if saves is None:
            saves = Saves.default(stats)
        if resistances is None:
            resistances = Resistances()
        if spellbook is None:
            spellbook = Spellbook()
        if hp is None:
            hp = max_hp

        # ===== static =====
        # all actors have a name
        self._name = name
        # ability scores
        self._stats = stats
        # at least a total level
        self._levels = levels
        # attacks - list of automation actions
        self._attacks = attacks
        # skill profs/saving throws
        self._skills = skills
        self._saves = saves
        # defensive resistances
        self._resistances = resistances

        # ===== dynamic =====
        # hp/ac
        self._ac = ac
        self._max_hp = max_hp
        self._hp = hp
        self._temp_hp = temp_hp

        # spellbook
        self._spellbook = spellbook
示例#5
0
 def get_resistances(self):
     resist = {'resist': [], 'immune': [], 'vuln': []}
     for modtype in self.character_data['modifiers'].values():
         for mod in modtype:
             if mod['type'] == 'resistance':
                 resist['resist'].append(mod['subType'])
             elif mod['type'] == 'immunity':
                 resist['immune'].append(mod['subType'])
             elif mod['type'] == 'vulnerability':
                 resist['vuln'].append(mod['subType'])
     return Resistances.from_dict(resist)
示例#6
0
 def get_resistances(self) -> Resistances:
     if self.character_data is None: raise Exception('You must call get_character() first.')
     out = {'resist': [], 'immune': [], 'vuln': []}
     for dmgType in DAMAGE_TYPES:
         mult = self.calculate_stat(f"{dmgType}Multiplier", 1)
         if mult <= 0:
             out['immune'].append(dmgType)
         elif mult < 1:
             out['resist'].append(dmgType)
         elif mult > 1:
             out['vuln'].append(dmgType)
     return Resistances.from_dict(out)
示例#7
0
 def from_bestiary(cls, data):
     for key in ('traits', 'actions', 'reactions', 'legactions'):
         data[key] = [Trait(**t) for t in data.pop(key)]
     data['spellcasting'] = Spellbook.from_dict(data.pop('spellbook'))
     data['saves'] = Saves.from_dict(data['saves'])
     data['skills'] = Skills.from_dict(data['skills'])
     data['ability_scores'] = BaseStats.from_dict(data['ability_scores'])
     data['attacks'] = AttackList.from_dict(data['attacks'])
     if 'display_resists' in data:
         data['display_resists'] = Resistances.from_dict(
             data['display_resists'])
     return cls(**data)
示例#8
0
 def resistances(self):
     checked = []
     out = {}
     for k in reversed(RESIST_TYPES):
         out[k] = []
         for _type in self.active_effects(k):
             if _type not in checked:
                 out[k].append(_type)
                 checked.append(_type)
     for k in reversed(RESIST_TYPES):
         for _type in self._resistances[k]:
             if _type not in checked:
                 out[k].append(_type)
                 checked.append(_type)
     return Resistances.from_dict(out)
示例#9
0
    def __init__(self,
                 name: str,
                 size: str,
                 race: str,
                 alignment: str,
                 ac: int,
                 armortype: str,
                 hp: int,
                 hitdice: str,
                 speed: str,
                 ability_scores: BaseStats,
                 cr: str,
                 xp: int,
                 passiveperc: int = None,
                 senses: str = '',
                 vuln: list = None,
                 resist: list = None,
                 immune: list = None,
                 condition_immune: list = None,
                 saves: Saves = None,
                 skills: Skills = None,
                 languages: list = None,
                 traits: list = None,
                 actions: list = None,
                 reactions: list = None,
                 legactions: list = None,
                 la_per_round=3,
                 srd=True,
                 source='homebrew',
                 attacks: AttackList = None,
                 proper: bool = False,
                 image_url: str = None,
                 spellcasting=None,
                 page=None,
                 display_resists: Resistances = None,
                 **_):
        if vuln is None:
            vuln = []
        if resist is None:
            resist = []
        if immune is None:
            immune = []
        if condition_immune is None:
            condition_immune = []
        if saves is None:
            saves = Saves.default(ability_scores)
        if skills is None:
            skills = Skills.default(ability_scores)
        if languages is None:
            languages = []
        if traits is None:
            traits = []
        if actions is None:
            actions = []
        if reactions is None:
            reactions = []
        if legactions is None:
            legactions = []
        if attacks is None:
            attacks = AttackList()
        if spellcasting is None:
            spellcasting = Spellbook({}, {}, [])
        if passiveperc is None:
            passiveperc = 10 + skills.perception.value

        try:
            levels = Levels({"Monster": spellcasting.caster_level or int(cr)})
        except ValueError:
            levels = None

        resistances = Resistances(vuln=vuln, resist=resist, immune=immune)

        super(Monster, self).__init__(name=name,
                                      stats=ability_scores,
                                      attacks=attacks,
                                      skills=skills,
                                      saves=saves,
                                      resistances=resistances,
                                      spellbook=spellcasting,
                                      ac=ac,
                                      max_hp=hp,
                                      levels=levels)
        self.size = size
        self.race = race
        self.alignment = alignment
        self.armortype = armortype
        self.hitdice = hitdice
        self.speed = speed
        self.cr = cr
        self.xp = xp
        self.passive = passiveperc
        self.senses = senses
        self.condition_immune = condition_immune
        self.languages = languages
        self.traits = traits
        self.actions = actions
        self.reactions = reactions
        self.legactions = legactions
        self.la_per_round = la_per_round
        self.srd = srd
        self.source = source
        self.proper = proper
        self.image_url = image_url
        self.page = page  # this should really be by source, but oh well
        # resistances including notes, e.g. "Bludgeoning from nonmagical weapons"
        self._displayed_resistances = display_resists or resistances
示例#10
0
    def from_data(cls, data):
        # print(f"Parsing {data['name']}")
        _type = parse_type(data['type'])
        alignment = parse_alignment(data['alignment'])
        speed = parse_speed(data['speed'])
        ac = data['ac']['ac']
        armortype = data['ac'].get('armortype') or None
        if not 'special' in data['hp']:
            hp = data['hp']['average']
            hitdice = data['hp']['formula']
        else:
            hp = 0
            hitdice = data['hp']['special']
        scores = BaseStats(0, data['str'] or 10, data['dex'] or 10, data['con']
                           or 10, data['int'] or 10, data['wis'] or 10,
                           data['cha'] or 10)
        if isinstance(data['cr'], dict):
            cr = data['cr']['cr']
        else:
            cr = data['cr']

        # resistances
        vuln = parse_resists(data['vulnerable'],
                             notated=False) if 'vulnerable' in data else None
        resist = parse_resists(data['resist'],
                               notated=False) if 'resist' in data else None
        immune = parse_resists(data['immune'],
                               notated=False) if 'immune' in data else None

        display_resists = Resistances(*[
            parse_resists(data.get(r))
            for r in ('resist', 'immune', 'vulnerable')
        ])

        condition_immune = data.get('conditionImmune',
                                    []) if 'conditionImmune' in data else None

        languages = data.get('languages',
                             '').split(', ') if 'languages' in data else None

        traits = [Trait(t['name'], t['text']) for t in data.get('trait', [])]
        actions = [Trait(t['name'], t['text']) for t in data.get('action', [])]
        legactions = [
            Trait(t['name'], t['text']) for t in data.get('legendary', [])
        ]
        reactions = [
            Trait(t['name'], t['text']) for t in data.get('reaction', [])
        ]

        skills = Skills.default(scores)
        skills.update(data['skill'])

        saves = Saves.default(scores)
        saves.update(data['save'])

        scores.prof_bonus = _calc_prof(scores, saves, skills)

        source = data['source']
        proper = bool(data.get('isNamedCreature') or data.get('isNPC'))

        attacks = AttackList.from_dict(data.get('attacks', []))
        spellcasting = data.get('spellcasting', {})
        spells = [SpellbookSpell(s) for s in spellcasting.get('spells', [])]
        spellbook = Spellbook({}, {}, spells, spellcasting.get('dc'),
                              spellcasting.get('attackBonus'),
                              spellcasting.get('casterLevel', 1))

        return cls(data['name'],
                   parsesize(data['size']),
                   _type,
                   alignment,
                   ac,
                   armortype,
                   hp,
                   hitdice,
                   speed,
                   scores,
                   cr,
                   xp_by_cr(cr),
                   data['passive'],
                   data.get('senses', ''),
                   vuln,
                   resist,
                   immune,
                   condition_immune,
                   saves,
                   skills,
                   languages,
                   traits,
                   actions,
                   reactions,
                   legactions,
                   3,
                   data.get('srd', False),
                   source,
                   attacks,
                   spellcasting=spellbook,
                   page=data.get('page'),
                   proper=proper,
                   display_resists=display_resists)