Exemple #1
0
def migrate(bestiary):
    sha256 = hashlib.sha256()
    hash_str = json.dumps(bestiary['monsters']).encode() \
               + bestiary['name'].encode() \
               + str(bestiary.get('desc')).encode()
    sha256.update(hash_str)

    active = [bestiary['owner']] if bestiary.get('active') else []
    server_active = []
    for serv_sub in bestiary.get('server_active', []):
        server_active.append({
            "subscriber_id": bestiary['owner'],
            "guild_id": serv_sub
        })

    for monster in bestiary['monsters']:
        for key in ('traits', 'actions', 'reactions', 'legactions'):
            for trait in monster[key]:
                if 'attacks' in trait:
                    del trait[
                        'attacks']  # why did we store this in the first place?

    monsters = [Monster.from_bestiary(m) for m in bestiary['monsters']]
    new_bestiary = Bestiary(None, sha256.hexdigest(), bestiary['critterdb_id'],
                            [bestiary['owner']], active, server_active,
                            bestiary['name'], monsters, bestiary.get('desc'))
    return new_bestiary
Exemple #2
0
async def select_monster_full(ctx, name, cutoff=5, return_key=False, pm=False, message=None, list_filter=None,
                              return_metadata=False):
    """
    Gets a Monster from the compendium and active bestiary/ies.
    """
    try:
        bestiary = await Bestiary.from_ctx(ctx)
        custom_monsters = bestiary.monsters
        bestiary_id = bestiary.id
    except NoActiveBrew:
        custom_monsters = []
        bestiary_id = None
    choices = list(itertools.chain(c.monster_mash, custom_monsters))
    if ctx.guild:
        async for servbestiary in ctx.bot.mdb.bestiaries.find({"server_active": str(ctx.guild.id)}, ['monsters']):
            choices.extend(
                Monster.from_bestiary(m) for m in servbestiary['monsters'] if servbestiary['_id'] != bestiary_id)

    def get_homebrew_formatted_name(monster):
        if monster.source == 'homebrew':
            return f"{monster.name} ({HOMEBREW_EMOJI})"
        return monster.name

    return await search_and_select(ctx, choices, name, lambda e: e.name, cutoff, return_key, pm, message, list_filter,
                                   selectkey=get_homebrew_formatted_name, return_metadata=return_metadata)
Exemple #3
0
 async def load_monsters(self, ctx):
     if not self._monsters:
         bestiary = await ctx.bot.mdb.bestiaries.find_one(
             {"_id": self.id}, projection=['monsters'])
         self._monsters = [
             Monster.from_bestiary(m) for m in bestiary['monsters']
         ]
     return self._monsters
Exemple #4
0
def migrate_monster(old_monster):
    def spaced_to_camel(spaced):
        return re.sub(r"\s+(\w)", lambda m: m.group(1).upper(), spaced.lower())

    for old_key in ('raw_saves', 'raw_skills'):
        if old_key in old_monster:
            del old_monster[old_key]

    if 'spellcasting' in old_monster and old_monster['spellcasting']:
        old_spellcasting = old_monster.pop('spellcasting')
        old_monster['spellbook'] = Spellbook(
            {}, {}, [SpellbookSpell(s) for s in old_spellcasting['spells']],
            old_spellcasting['dc'], old_spellcasting['attackBonus'],
            old_spellcasting['casterLevel']).to_dict()
    else:
        old_monster['spellbook'] = Spellbook({}, {}, []).to_dict()

    base_stats = BaseStats(0, old_monster.pop('strength'),
                           old_monster.pop('dexterity'),
                           old_monster.pop('constitution'),
                           old_monster.pop('intelligence'),
                           old_monster.pop('wisdom'),
                           old_monster.pop('charisma'))
    old_monster['ability_scores'] = base_stats.to_dict()

    old_saves = old_monster.pop('saves')
    saves = Saves.default(base_stats)
    save_updates = {}
    for save, value in old_saves.items():
        if value != saves[save]:
            save_updates[save] = value
    saves.update(save_updates)
    old_monster['saves'] = saves.to_dict()

    old_skills = old_monster.pop('skills')
    skills = Skills.default(base_stats)
    skill_updates = {}
    for skill, value in old_skills.items():
        name = spaced_to_camel(skill)
        if value != skills[name]:
            skill_updates[name] = value
    skills.update(skill_updates)
    old_monster['skills'] = skills.to_dict()

    new_monster = Monster.from_bestiary(old_monster)
    return new_monster
Exemple #5
0
 def from_dict(cls, d):
     if 'monsters' in d:
         d['monsters'] = [Monster.from_bestiary(m) for m in d['monsters']]
     if 'published' not in d:  # versions prior to v1.5.11 don't have this tag, default to True
         d['published'] = True
     return cls(**d)
Exemple #6
0
 def from_raw(cls, _id, raw):
     monsters = [Monster.from_bestiary(m) for m in raw['monsters']]
     return cls(_id, raw['name'], monsters)
Exemple #7
0
 def from_dict(cls, d):
     if 'monsters' in d:
         d['monsters'] = [Monster.from_bestiary(m) for m in d['monsters']]
     return cls(**d)