import dataclasses import os from pkg_resources import resource_string from ..battle import WeightedList class TableData(dict): def __init__(self, header, data): for key in header: data_type = type(getattr(self, key)) setattr(self, key, data_type(data[header.index(key)])) @dataclasses.dataclass class ExpData(TableData): id: str = '' exp_max: int = 0 def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class ItemData(TableData): id: str = '' cls: str = '' param_0: int = 0 param_1: int = 0 param_2: int = 0 def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class ItemDropData(TableData): id: str = '' zone_id: str = '' item_id: str = '' weight: int = 0 def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class MonsterAppearData(TableData): id: str = '' zone_id: str = '' monster_id: str = '' weight: int = 0 def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class MonsterData(TableData): id: str = '' strength: int = 0 dexterity: int = 0 intelligence: int = 0 constitution: int = 0 luck: int = 0 defense: int = 0 skill_0: str = '' skill_1: str = '' skill_2: str = '' skill_3: str = '' reward_exp: int = 0 def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class NpcData(TableData): id: str = '' level: int = 0 class_: str = '' # noqa def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class SkillData(TableData): id: str = '' cls: str = '' class_: str = '' # noqa unlock_lv: int = 0 cast_time: int = 0 cooltime: int = 0 target_count: int = 0 power: int = 0 def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class StatsData(TableData): id: str = '' strength: int = 0 dexterity: int = 0 intelligence: int = 0 constitution: int = 0 luck: int = 0 strength_lv: int = 0 dexterity_lv: int = 0 intelligence_lv: int = 0 constitution_lv: int = 0 luck_lv: int = 0 def __init__(self, header, data): super().__init__(header, data) @dataclasses.dataclass class ZoneData(TableData): id: str = '' unlock_level: int = 0 def __init__(self, header, data): super().__init__(header, data) class Table(dict): separator = '\t' def __init__(self, filename, datacls): if type(filename) == str: self.load(filename, datacls) elif type(filename) == list: for f in filename: self.load(f, datacls) def load(self, filename, datacls): text = resource_string( 'nekoyume', os.path.join('tables', filename) ).decode('utf-8') lines = text.split('\n') header = lines[0].split(Table.separator) for line in lines[1:]: if line: data = line.split(Table.separator) self[data[0]] = datacls(header, data) def get(self, id): if type(id) is int: return super().get(str(id)) return super().get(id) class Tables: exp = Table('exp.tsv', ExpData) item_drop = Table('item_drop.tsv', ItemDropData) items = Table(['items.tsv', 'item_equips.tsv'], ItemData) monster_appear = Table('monster_appear.tsv', MonsterAppearData) monsters = Table('monsters.tsv', MonsterData) npc = Table('npc.tsv', NpcData) skills = Table(['skills.tsv', 'monster_skills.tsv'], SkillData) stats = Table('stats.tsv', StatsData) zone = Table('zone.tsv', ZoneData) @classmethod def get_exp_max(cls, level: int) -> int: try: return cls.exp[str(level)].exp_max except KeyError: return 0 @classmethod def get_item_drop_list(cls, zone: str) -> WeightedList: drop_items = WeightedList() for id_ in Tables.item_drop: data = Tables.item_drop[id_] if data.zone_id == zone: drop_items.add(data.item_id, data.weight) return drop_items @classmethod def get_monster_appear_list(cls, zone: str) -> WeightedList: appear_monsters = WeightedList() for id_ in Tables.monster_appear: data = Tables.monster_appear[id_] if data.zone_id == zone: appear_monsters.add(data.monster_id, data.weight) return appear_monsters @classmethod def get_npc_list(cls) -> WeightedList: npc_list = WeightedList() for id_ in Tables.npc: data = Tables.npc[id_] npc_list.add(data.id, 1) return npc_list