|
1 | 1 | from typing import List, Dict, Set, Tuple, Union |
2 | 2 | import typing |
3 | 3 | from ..model.enums import eCampaignCategory |
4 | | -from ..model.common import UnitData, eInventoryType, RoomUserItem, InventoryInfo |
5 | | -from ..model.custom import ItemType |
| 4 | +from ..model.common import ExtraEquipInfo, UnitData, eInventoryType, RoomUserItem, InventoryInfo |
| 5 | +from ..model.custom import ItemType, eDifficulty |
6 | 6 | import datetime |
7 | 7 | from collections import Counter, defaultdict |
8 | 8 | from .dbmgr import dbmgr |
|
14 | 14 | from ..core.apiclient import apiclient |
15 | 15 | from typing import TypeVar, Generic |
16 | 16 | from ..util.pcr_data import CHARA_NICKNAME |
| 17 | +from ..util.logger import instance as logger |
17 | 18 |
|
18 | 19 | T = TypeVar("T") |
19 | 20 |
|
@@ -664,9 +665,27 @@ def quest_info(self) -> Dict[int, QuestDatum]: |
664 | 665 | .concat(HatsuneQuest.query(db)) |
665 | 666 | .concat(ShioriQuest.query(db)) |
666 | 667 | .concat(TalentQuestDatum.query(db)) |
| 668 | + .concat(AbyssQuestDatum.query(db)) |
667 | 669 | .to_dict(lambda x: x.quest_id, lambda x: x) |
668 | 670 | ) |
669 | 671 |
|
| 672 | + @lazy_property |
| 673 | + def abyss_quest_info(self) -> Dict[int, List[AbyssQuestDatum]]: |
| 674 | + with self.dbmgr.session() as db: |
| 675 | + return ( |
| 676 | + AbyssQuestDatum.query(db) |
| 677 | + .group_by(lambda x: x.abyss_id) |
| 678 | + .to_dict(lambda x: x.key, lambda x: x.to_list()) |
| 679 | + ) |
| 680 | + |
| 681 | + @lazy_property |
| 682 | + def abyss_boss_data(self) -> Dict[int, AbyssBossDatum]: |
| 683 | + with self.dbmgr.session() as db: |
| 684 | + return ( |
| 685 | + AbyssBossDatum.query(db) |
| 686 | + .to_dict(lambda x: x.boss_id, lambda x: x) |
| 687 | + ) |
| 688 | + |
670 | 689 | @lazy_property |
671 | 690 | def chara_story_status(self) -> Dict[int, CharaStoryStatus]: |
672 | 691 | with self.dbmgr.session() as db: |
@@ -1070,6 +1089,22 @@ def colosseum_schedule_data(self) -> Dict[int, ColosseumScheduleDatum]: |
1070 | 1089 | .to_dict(lambda x: x.schedule_id, lambda x: x) |
1071 | 1090 | ) |
1072 | 1091 |
|
| 1092 | + @lazy_property |
| 1093 | + def dome_schedule_data(self) -> Dict[int, DomeScheduleDatum]: |
| 1094 | + with self.dbmgr.session() as db: |
| 1095 | + return ( |
| 1096 | + DomeScheduleDatum.query(db) |
| 1097 | + .to_dict(lambda x: x.schedule_id, lambda x: x) |
| 1098 | + ) |
| 1099 | + |
| 1100 | + @lazy_property |
| 1101 | + def abyss_schedule(self) -> Dict[int, AbyssSchedule]: |
| 1102 | + with self.dbmgr.session() as db: |
| 1103 | + return ( |
| 1104 | + AbyssSchedule.query(db) |
| 1105 | + .to_dict(lambda x: x.abyss_id, lambda x: x) |
| 1106 | + ) |
| 1107 | + |
1073 | 1108 | @lazy_property |
1074 | 1109 | def tower_schedule(self) -> Dict[int, TowerSchedule]: |
1075 | 1110 | with self.dbmgr.session() as db: |
@@ -1228,6 +1263,22 @@ def hatsune_item(self) -> Dict[int, HatsuneItem]: |
1228 | 1263 | .to_dict(lambda x: x.event_id, lambda x: x) |
1229 | 1264 | ) |
1230 | 1265 |
|
| 1266 | + @lazy_property |
| 1267 | + def tpr_story_data(self) -> Dict[int, TprStoryDatum]: |
| 1268 | + with self.dbmgr.session() as db: |
| 1269 | + return ( |
| 1270 | + TprStoryDatum.query(db) |
| 1271 | + .to_dict(lambda x: x.sub_story_id, lambda x: x) |
| 1272 | + ) |
| 1273 | + |
| 1274 | + @lazy_property |
| 1275 | + def tpr_panel_data(self) -> Dict[int, TprPanelDatum]: |
| 1276 | + with self.dbmgr.session() as db: |
| 1277 | + return ( |
| 1278 | + TprPanelDatum.query(db) |
| 1279 | + .to_dict(lambda x: x.panel_id, lambda x: x) |
| 1280 | + ) |
| 1281 | + |
1231 | 1282 | @lazy_property |
1232 | 1283 | def apg_story_data(self) -> Dict[int, ApgStoryDatum]: |
1233 | 1284 | with self.dbmgr.session() as db: |
@@ -1516,6 +1567,9 @@ def quest_name(self) -> Dict[int, str]: |
1516 | 1567 | ret.update( |
1517 | 1568 | {x.travel_quest_id :x.travel_quest_name for x in self.travel_quest_data.values()} |
1518 | 1569 | ) |
| 1570 | + ret.update( |
| 1571 | + {x.quest_id: f"{x.quest_name}-{eDifficulty(x.difficulty).name}" for xs in self.abyss_quest_info.values() for x in xs} |
| 1572 | + ) |
1519 | 1573 | return ret |
1520 | 1574 |
|
1521 | 1575 | @lazy_property |
@@ -1675,9 +1729,9 @@ def get_inventory_name_san(self, item: ItemType) -> str: |
1675 | 1729 | except: |
1676 | 1730 | return f"未知物品({item[0]}, {item[1]})" |
1677 | 1731 |
|
1678 | | - def get_ex_equip_name(self, item: int, rank: int = 0) -> str: |
| 1732 | + def get_ex_equip_name(self, item: int, rank: int = -1) -> str: |
1679 | 1733 | try: |
1680 | | - return f"{self.ex_rarity_name[self.ex_equipment_data[item].rarity]}{rank}-" + self.inventory_name[(eInventoryType.ExtraEquip, item)] |
| 1734 | + return f"{self.ex_rarity_name[self.ex_equipment_data[item].rarity]}{rank if rank != -1 else ''}-" + self.inventory_name[(eInventoryType.ExtraEquip, item)] |
1681 | 1735 | except: |
1682 | 1736 | return f"未知ex装备({item})" |
1683 | 1737 |
|
@@ -1791,6 +1845,9 @@ def is_talent_quest(self, quest_id: int) -> bool: |
1791 | 1845 | top = quest_id // 1000000 |
1792 | 1846 | return top >= 81 and top <= 85 |
1793 | 1847 |
|
| 1848 | + def is_abyss_quest(self, quest_id: int) -> bool: |
| 1849 | + return quest_id // 1000000 == 92 |
| 1850 | + |
1794 | 1851 | def is_hatsune_normal_quest(self, quest_id: int) -> bool: |
1795 | 1852 | return self.is_hatsune_quest(quest_id) and (quest_id // 100) % 10 == 1 |
1796 | 1853 |
|
@@ -1878,6 +1935,17 @@ def get_open_hatsune(self) -> List[HatsuneSchedule]: |
1878 | 1935 | .where(lambda x: now >= self.parse_time(x.start_time) and now <= self.parse_time(x.close_time)) \ |
1879 | 1936 | .to_list() |
1880 | 1937 |
|
| 1938 | + def get_active_abyss(self) -> List[AbyssSchedule]: |
| 1939 | + now = apiclient.datetime |
| 1940 | + return flow(self.abyss_schedule.values()) \ |
| 1941 | + .where(lambda x: now >= self.parse_time(x.start_time) and now <= self.parse_time(x.end_time)) \ |
| 1942 | + .to_list() |
| 1943 | + |
| 1944 | + def get_abyss_bosses(self, abyss_id: int) -> List[AbyssBossDatum]: |
| 1945 | + return flow(self.abyss_boss_data.values()) \ |
| 1946 | + .where(lambda x: x.abyss_id == abyss_id) \ |
| 1947 | + .to_list() |
| 1948 | + |
1881 | 1949 | def get_active_seasonpass(self) -> List[SeasonpassFoundation]: |
1882 | 1950 | now = apiclient.datetime |
1883 | 1951 | return flow(self.seasonpass_foundation.values()) \ |
@@ -2301,7 +2369,7 @@ def get_gacha_prize_name(self, gacha_id: int, prize_rarity: int) -> str: |
2301 | 2369 | def is_unit_rank_bonus(self, unit_id: int, promotion_level: int) -> bool: |
2302 | 2370 | return unit_id in self.promote_bonus and promotion_level in self.promote_bonus[unit_id] |
2303 | 2371 |
|
2304 | | - def calc_unit_attribute(self, unit_data: UnitData, read_story: Set[int]) -> UnitAttribute: |
| 2372 | + def calc_unit_attribute(self, unit_data: UnitData, read_story: Set[int], ex_equips: Dict[int, ExtraEquipInfo]) -> UnitAttribute: |
2305 | 2373 | unit_id = unit_data.id |
2306 | 2374 | promotion_level = unit_data.promotion_level.value |
2307 | 2375 | rarity = unit_data.battle_rarity if unit_data.battle_rarity else unit_data.unit_rarity |
@@ -2342,10 +2410,22 @@ def calc_unit_attribute(self, unit_data: UnitData, read_story: Set[int]) -> Unit |
2342 | 2410 | kizuna_attribute += story.get_unit_attribute() |
2343 | 2411 |
|
2344 | 2412 | unit_attribute = base_attribute.round() + rb_attribute.round() + equip_attribute.round() + unique_equip_attribute.ceil() + kizuna_attribute.round() |
| 2413 | + |
| 2414 | + # EX装备 |
| 2415 | + ex_attribute = UnitAttribute() |
| 2416 | + for ex_equip in unit_data.ex_equip_slot: |
| 2417 | + if ex_equip.serial_id: |
| 2418 | + ex_equip_data = ex_equips[ex_equip.serial_id] |
| 2419 | + star = self.get_ex_equip_star_from_pt(ex_equip_data.ex_equipment_id, ex_equip_data.enhancement_pt) |
| 2420 | + attr = self.ex_equipment_data[ex_equip_data.ex_equipment_id].get_unit_attribute(star) |
| 2421 | + bonus = unit_attribute.ex_equipment_mul(attr).ceil() |
| 2422 | + ex_attribute += bonus |
| 2423 | + unit_attribute += ex_attribute |
| 2424 | + |
2345 | 2425 | return unit_attribute |
2346 | 2426 |
|
2347 | | - def calc_unit_attribute_power(self, unit_data: UnitData, read_story: Set[int], coefficient: UnitStatusCoefficient) -> float: |
2348 | | - unit_attribute = self.calc_unit_attribute(unit_data, read_story) |
| 2427 | + def calc_unit_attribute_power(self, unit_data: UnitData, read_story: Set[int], ex_equips: Dict[int, ExtraEquipInfo], coefficient: UnitStatusCoefficient) -> float: |
| 2428 | + unit_attribute = self.calc_unit_attribute(unit_data, read_story, ex_equips) |
2349 | 2429 | return unit_attribute.get_power(coefficient) |
2350 | 2430 |
|
2351 | 2431 | def calc_skill_power(self, unit_data: UnitData, coefficient: UnitStatusCoefficient) -> float: |
@@ -2374,9 +2454,9 @@ def calc_skill_power(self, unit_data: UnitData, coefficient: UnitStatusCoefficie |
2374 | 2454 |
|
2375 | 2455 | return skill_power * coefficient.skill_lv_coefficient |
2376 | 2456 |
|
2377 | | - def calc_unit_power(self, unit_data: UnitData, read_story: Set[int]) -> float: |
| 2457 | + def calc_unit_power(self, unit_data: UnitData, read_story: Set[int], ex_equips: Dict[int, ExtraEquipInfo]) -> float: |
2378 | 2458 | coefficient = self.unit_status_coefficient[1] |
2379 | | - attribute_power = self.calc_unit_attribute_power(unit_data, read_story, coefficient) |
| 2459 | + attribute_power = self.calc_unit_attribute_power(unit_data, read_story, ex_equips, coefficient) |
2380 | 2460 | skill_power = self.calc_skill_power(unit_data, coefficient) |
2381 | 2461 | return attribute_power + skill_power |
2382 | 2462 |
|
|
0 commit comments