def generate_skills(attrs, archetype, high_stat):
    skill_attrs = misc.get_attrs(attrs, 'Skill')

    class_skills = misc.get_attrs_by_tag(skill_attrs, 'archetype',
                                         archetype.value)

    trained_skills = []
    select = 3
    if high_stat is not 'CON':
        stat_skills = misc.get_attrs_by_tag(skill_attrs, 'skill_stat',
                                            high_stat)
        stat_skill = roll.one(stat_skills)
        trained_skills.append(stat_skill)
        if stat_skill in class_skills:
            select = 4

    skill_pool = roll.many(skill_attrs, select, selection=class_skills)

    skill_count = roll.one_with_weights([(3, 6), (4, 2), (5, 1)])
    for i in range(skill_count):
        skill_choice = roll.one_with_removal(skill_pool, trained_skills)
        if skill_choice is not None:
            trained_skills.append(skill_choice)

    return trained_skills
def generate_archetype(attrs, high_stat, low_stat):
    arch_attrs = misc.get_attrs(attrs, 'Archetype')
    archetype_weights = []
    for arch in arch_attrs:
        if arch.get_tag('stat') == high_stat:
            archetype_weights.append((arch, 30))
        elif arch.get_tag('stat') == low_stat:
            archetype_weights.append((arch, 1))
        else:
            archetype_weights.append((arch, 10))
    return roll.one_with_weights(archetype_weights)
def generate_saving_throws(attrs, archetype):
    saving_attrs = misc.get_attrs(attrs, 'Saving')
    class_saving = misc.get_attrs_by_tag(saving_attrs, 'archetype',
                                         archetype.value)

    saving_number = roll.one_with_weights([(0, 2), (1, 5), (2, 6), (3, 1)])
    if archetype == 'Faithful':
        saving_number += 1
    if saving_number == 0:
        return None
    else:
        saving_list = []
        for i in range(saving_number):
            saving_choice = roll.one_with_removal(class_saving, saving_list)
            saving_list.append(saving_choice)
    return saving_list
def generate_armor(attrs, archetype, skills, stats):
    armor_attrs = misc.get_attrs(attrs, 'Armor')
    arch_armors = misc.get_attrs_by_tag(armor_attrs, 'archetype',
                                        archetype.value)
    arch_armors = misc.remove_attrs_by_tag(arch_armors, 'armor_type', 'shield')

    if 'Stealth' in [x.value for x in skills]:
        arch_armors = misc.remove_attrs_by_tag(arch_armors, 'stealth_dis',
                                               True)
    if stats['STR'] < 15:
        arch_armors = misc.remove_attrs_by_tag(arch_armors, 'req_str', '15')
    elif stats['STR'] > 15:
        arch_armors = misc.remove_attrs_by_tag(arch_armors, 'req_str', '13')
    if stats['DEX'] > 2:
        arch_armors = misc.get_attrs_by_tag(arch_armors, 'armor_type', 'light')

    return [roll.one(arch_armors)]
def generate_languages(attrs, race):
    language_attrs = misc.get_attrs(attrs, 'Language')
    race_languages = misc.get_attrs_by_tag(attrs, 'race', race.value)
    common = misc.get_attr_from_list(language_attrs, 'Language', 'Common')

    languages = [common]

    if race_languages is not None:
        languages += race_languages
    if race.get_tag('extra_language'):
        languages.append(
            roll.one_with_weights_and_removal(
                misc.get_attr_and_weights(language_attrs), languages))
    if randint(1, 5) == 1:
        languages.append(
            roll.one_with_weights_and_removal(
                misc.get_attr_and_weights(language_attrs), languages))
    return languages
def generate_stats(attrs, race, archetype):
    stat_attrs = misc.get_attrs(attrs, 'Stat')
    my_stats = {}
    array_choice = roll.one_with_weights([(1, 65), (2, 25), (3, 10)])

    if array_choice == 1:
        rolled_stats = roll.roll_stats(stat_array=True)
    elif array_choice == 2:
        rolled_stats = roll.roll_stats()
    else:
        rolled_stats = roll.roll_stats(drop_lowest=True)

    race_stat_array = [('STR', 10), ('DEX', 10), ('CON', 10), ('INT', 10),
                       ('WIS', 10), ('CHA', 10)]

    for k, stat in enumerate(race_stat_array):
        stat_weight = int(
            misc.get_attr_tag(stat_attrs, 'Stat', stat[0], race.value))
        if archetype is not None and archetype in misc.get_attr_tag(
                stat_attrs, 'Stat', stat[0], 'archetype'):
            stat_weight += 40
        race_stat_array[k] = (stat[0], stat_weight)

    removed_arch_weights = False
    for stat in rolled_stats:
        print(race_stat_array)
        chosen_stat = roll.one_with_weights_and_removal(
            race_stat_array, list(my_stats.keys()))
        print('{}: {}'.format(chosen_stat, stat))
        my_stats[chosen_stat] = stat
        print(my_stats)

        if not removed_arch_weights and archetype is not None \
                and archetype in misc.get_attr_tag(stat_attrs, 'Stat', chosen_stat, 'archetype'):
            removed_arch_weights = True
            print('removing additional archetype weights')
            for k, stat_val in enumerate(race_stat_array):
                if archetype in misc.get_attr_tag(stat_attrs, 'Stat',
                                                  stat_val[0], 'archetype'):
                    print('lowering {} weight from {} to {}'.format(
                        stat_val[0], stat_val[1], stat_val[1] - 40))
                    race_stat_array[k] = (stat_val[0], stat_val[1] - 40)

    return my_stats
def generate_race(attrs):
    race_attrs = misc.get_attrs(attrs, 'Race')
    race_weights = misc.get_attr_and_weights(race_attrs)
    return roll.one_with_weights(race_weights)
def generate_name(attrs):
    name_attrs = misc.get_attrs(attrs, 'Name')
    return roll.one(name_attrs)