import csv from game import Difficulty, RollInfo, LevelingPlan def safe_item_level(creature_level: int): if creature_level <= 3: return 0 if creature_level == 4: return 1 return creature_level - 4 def load_csv(name, value_parser=None): def parse_col_name(name): try: return Difficulty.from_str(name) except ValueError: return name.lower() if value_parser is None: value_parser = lambda x:x res = dict() # Table by level and Difficulty with open(f"creature_stats/{name}.csv", newline='', encoding='utf8') as file: reader = csv.DictReader(file) for row in reader: level = int(row.pop("Level")) res[level] = {parse_col_name(name): value_parser(val) for name,val in row.items()} return res def parse_stat(str_data): try: return int(str_data) except ValueError: pass separator = "-" if separator in str_data: # parse range values = [int(i) for i in str_data.split(separator)[:2]] return tuple((min(*values), max(*values))) else: return RollInfo.parse(str_data) def get_range_value(range_stat: tuple, value="avg"): if value == "min": return range_stat[0] if value == "max": return range_stat[1] if value == "avg": return (range_stat[0]+range_stat[1]) // 2 class StatsDB: stat_names = ["ac","abilities","attack_bonus", "hp", "perception", "saves", "resistances", "skills", "strike_damage"] saves = ["reflex", "will", "fortitude"] def __init__(self) -> None: self.stats = dict() for stat_name in StatsDB.stat_names: self.stats[stat_name] = load_csv(stat_name, parse_stat) self.stats["resistances"] = {k:(v["minimum"], v["maximum"]) for k,v in self.stats["resistances"].items()} def get(self, stat, level, difficulty=Difficulty.Moderate, range_value="avg"): if stat in StatsDB.saves: stat = "saves" value = self.stats[stat][level] if isinstance(value, dict): value = value[difficulty] if isinstance(value, tuple): value = get_range_value(value, range_value) return value stats = StatsDB() class CreaturePlan(LevelingPlan, dict): stat_names = ["ac", "attack_bonus", "hp", "perception", "strike_damage"] def __init__(self, data=None, default_difficulty = Difficulty.Moderate, stat_range_value="avg") -> None: super().__init__({k: default_difficulty for k in self.stat_names+StatsDB.saves}) if data is not None: self.update(data) self.stat_range_value = stat_range_value def build(self, level: int): res = dict() for stat, difficulty in self.items(): res[stat] = stats.get(stat, level, difficulty, self.stat_range_value) return res # if __name__ == '__main__': # main()