def generate_description(attrs, weapons, armors): desc_attrs = misc.get_attr_and_weights(attrs, 'Description') x = 0 while x < 5: x += 1 desc = roll.one_with_weights(desc_attrs) tag_dict = desc.get_tag_dict() tag_fills = {} for key, vals in tag_dict.items(): if key != 'weapon_name_req' or key != 'armor_name_req': tag_fills[key] = roll.one(vals) elif key == 'weapon': tag_fills[key] = roll.one(weapons) elif key == 'armor': tag_fills[key] = roll.one(armors) if 'weapon_name_req' in tag_dict.keys(): weapon = roll.from_list_if_list(tag_dict['weapon_name_req'], weapons) if weapon is None: continue else: tag_fills['weapon'] = weapon.lower() if 'armor_name_req' in tag_dict.keys(): armor = roll.from_list_if_list(tag_dict['armor_name_req'], armors) if armor is None: continue else: tag_fills['armor'] = armor.lower() return desc.value.format_map(tag_fills) else: return 'They have a blank expression on their face'
def generate_caster(archetype, level, high_stat, second_high_stat, stats): # Two things these need to capture # spells known and the number of slots available # full caster, wizard, cleric, sorceror, bard # Full casters: smart characters or faithful with WIS as highest stat if roll.one_with_weights([(0, 10), (1, 4 + (level**2))]) == 1 and ( archetype.value == 'Smart' or (archetype.value == 'Faithful' and stats['WIS'] > stats['CHA']) or (archetype.value == 'Crafty' and (high_stat == 'CHA' or second_high_stat == 'CHA'))): cantrips_known = floor(3 + (level / 10)) spell_cap = 4 + level spells_known = roll.one(list(range(int(spell_cap / 2), spell_cap))) if archetype == 'Smart': cast_stat = high_stat elif archetype == 'Crafty': cast_stat = 'CHA' else: cast_stat = 'WIS' return 'Full Caster', cantrips_known, spells_known, cast_stat # return pick_spells(archetype, level, spells_known, cantrips_known, high_stat) # half caster: faithful characters with WIS as second highest stat, crafty characters with INT or CHA as high stat # only after level 2 - SHOULD BE WARLOCKS, RANGERS, AND PALADINS if roll.one_with_weights([(0, 20), (1, min( 20, 2 * level))]) == 1 and level >= 2 and ( (archetype.value == 'Crafty' and (high_stat == 'WIS' or second_high_stat == 'WIS')) or (archetype.value == 'Faithful')): cantrips_known = 0 spell_cap = floor(3 + ((level - 1) / 2)) spells_known = roll.one(list(range(int(spell_cap / 2), spell_cap))) if archetype == 'Faithful': cast_stat = 'CHA' else: cast_stat = 'WIS' return 'Half Caster', cantrips_known, spells_known, cast_stat # return pick_spells(archetype, level, spells_known, cantrips_known, cast_stat) # 1/3 caster: Bulky characters with INT/WIS/CHA as one of top 2 stats # or crafty characters with INT or CHA as second high stat # only after level 3 if roll.one_with_weights([(0, 20), (1, min( 10, level))]) == 1 and level >= 3 and ( (archetype.value == 'Bulky' and (high_stat == 'INT' or second_high_stat == 'INT')) or (archetype.value == 'Crafty' and (high_stat == 'INT' or second_high_stat == 'INT'))): cantrips_known = floor(1 + (level / 10)) spell_cap = floor(4 + ((level - 1) / 3)) spells_known = roll.one(list(range(int(spell_cap / 2), spell_cap))) return 'Third Caster', cantrips_known, spells_known, 'INT' # return pick_spells(archetype, level, spells_known, cantrips_known, cast_stat) return False, 0, 0, None
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 get_lowest_stat(self): """ Gives you a list of the lowest stats. Generally this is one, but it could be more! :return: the lowest score :rtype: list """ lowest = 100 small_stat = [] for stat, value in self.stats.items(): if value < lowest: lowest = value small_stat = [stat] elif value == lowest: small_stat.append(stat) try: return one(small_stat) except IndexError: return one(list(self.stats.keys()))
def get_highest_stat(self): """ Gives you a list of the highest stats. If it's a tie, choose one value at random :return: the highest stats :rtype: list """ highest = 0 big_stat = [] for stat, value in self.stats.items(): if value > highest: highest = value big_stat = [stat] elif value == highest: big_stat.append(stat) # This part breaks sometimes. If it does, just return a random stat. Gives the NPC a rogue element. try: return one(big_stat) except IndexError: return one(list(self.stats.keys()))
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_name(attrs): name_attrs = misc.get_attrs(attrs, 'Name') return roll.one(name_attrs)