Skip to content

Commit 26c7b74

Browse files
authored
Merge pull request #276 from cc004/dev
Dev
2 parents ba99ca1 + bd513c5 commit 26c7b74

15 files changed

Lines changed: 672 additions & 18 deletions

File tree

autopcr/core/datamgr.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,16 @@ class datamgr(BaseModel, Component[apiclient]):
6060
cleared_byway_quest_id_set: Set[int] = set({})
6161
return_fes_info_list: List[ReturnFesInfo] = None
6262
data_time: int = 0
63-
version: int = 4
63+
version: int = 5
6464
caravan_dishes: typing.Counter[int] = Counter()
6565
user_clan_battle_ex_equip_restriction: Dict[int, RestrictionExtraEquip] = {}
6666
talent_quest_area_info: Dict[int, TalentQuestAreaInfo] = {}
6767
cleared_talent_quest_ids: Dict[int, int] = {}
6868
princess_knight_info: PrincessKnightInfo = None
6969
cleared_abyss_quests: Set[int] = set()
7070
abyss_quest_info: Dict[int, AbyssDailyClearCountList] = {}
71+
alces_appear_story_flag: int = 0
72+
alces_receive_tutorial_item_flag: int = 0
7173

7274
@staticmethod
7375
async def try_update_database(ver: int):
@@ -534,7 +536,9 @@ def filter_inventory(self, filter: Callable) -> List[ItemType]:
534536
return [item for item in self.inventory if filter(item) and self.inventory[item] > 0]
535537

536538
def get_inventory(self, item: ItemType) -> int:
537-
if item == db.mana:
539+
if item == db.zmana:
540+
return self.gold.gold_id_free + self.gold.gold_id_pay
541+
elif item == db.mana:
538542
return self.gold.gold_id_free + self.gold.gold_id_pay
539543
elif item == db.jewel:
540544
return self.jewel.free_jewel + self.jewel.jewel

autopcr/core/pcrclient.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,69 @@ async def clan_battle_top(self):
5959
req.current_clan_battle_coin = self.data.get_shop_gold(eSystemId.CLAN_BATTLE_SHOP)
6060
return await self.request(req)
6161

62+
async def alces_top(self):
63+
if not self.data.is_quest_cleared(11018002):
64+
raise SkipError("究极炼成未解锁")
65+
req = AlcesTopRequest()
66+
return await self.request(req)
67+
68+
async def alces_receive_tutorial_item(self):
69+
req = AlcesReceiveTutorialItemRequest()
70+
return await self.request(req)
71+
72+
async def alces_read_story(self, story_id: int):
73+
req = AlcesReadStoryRequest()
74+
req.story_id = story_id
75+
return await self.request(req)
76+
77+
async def alces_exec(self, serial_id: int):
78+
req = AlcesExecRequest()
79+
req.serial_id = serial_id
80+
req.current_alces_point = self.data.get_inventory((eInventoryType.Item, 26202))
81+
req.current_gold = self.data.get_mana()
82+
return await self.request(req)
83+
84+
async def alces_lock_slot(self, serial_id: int, slot_number: int, is_lock: int):
85+
req = AlcesLockSlotRequest()
86+
req.lock_list = [
87+
AlcesDataPost(
88+
serial_id=serial_id,
89+
sub_status=[ExtraEquipSubStatusPost(
90+
slot_number=slot_number,
91+
is_lock=is_lock
92+
)]
93+
)
94+
]
95+
return await self.request(req)
96+
97+
async def alces_cancel_result(self, serial_id: int):
98+
req = AlcesCancelResultRequest()
99+
req.serial_id = serial_id
100+
return await self.request(req)
101+
102+
async def alces_fix_result(self, serial_id: int):
103+
req = AlcesFixResultRequest()
104+
req.serial_id = serial_id
105+
return await self.request(req)
106+
107+
async def mirage_top(self):
108+
if not self.data.is_quest_cleared(11072001):
109+
raise SkipError("追忆战未解锁")
110+
req = MirageTopRequest()
111+
return await self.request(req)
112+
113+
async def mirage_receive_reward(self, from_system_id: int):
114+
req = MirageReceiveRewardRequest()
115+
req.from_system_id = from_system_id
116+
return await self.request(req)
117+
118+
async def mirage_nemesis_skip_multiple(self, skip_list: List[QuestSkipInfo]):
119+
req = MirageNemesisSkipMultipleRequest()
120+
req.skip_list = skip_list
121+
req.current_skip_ticket_num = self.data.get_inventory((eInventoryType.Item, 23001))
122+
req.exec_type = 2
123+
return await self.request(req)
124+
62125
async def emblem_top(self):
63126
req = EmblemTopRequest()
64127
return await self.request(req)
@@ -739,6 +802,19 @@ async def tpr_register_success(self, panel_id: int, correct_type: int, parts_id_
739802
req.parts_id_list = parts_id_list
740803
return await self.request(req)
741804

805+
async def abd_top(self):
806+
req = SubStoryAbdTopRequest()
807+
return await self.request(req)
808+
809+
async def read_abd_story(self, sub_story_id: int):
810+
req = SubStoryAbdReadStoryRequest()
811+
req.sub_story_id = sub_story_id
812+
req.skip_info = StorySkipInfo(
813+
skip_type = eStorySkipType.MENU_SKIP,
814+
scroll_coordinate = ""
815+
)
816+
return await self.request(req)
817+
742818
async def read_lss_story(self, sub_story_id: int):
743819
req = SubStoryLssReadStoryRequest()
744820
req.sub_story_id = sub_story_id

autopcr/db/database.py

Lines changed: 127 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import List, Dict, Set, Tuple, Union
22
import typing
3-
from ..model.enums import eCampaignCategory
4-
from ..model.common import ExtraEquipInfo, UnitData, eInventoryType, RoomUserItem, InventoryInfo
3+
from ..model.enums import eCampaignCategory, eParamType
4+
from ..model.common import ExtraEquipInfo, ExtraEquipSubStatus, UnitData, eInventoryType, RoomUserItem, InventoryInfo
55
from ..model.custom import ItemType, eDifficulty
66
import datetime
77
from collections import Counter, defaultdict
@@ -65,6 +65,7 @@ class database():
6565
wind_ball: ItemType = (eInventoryType.Item, 25013)
6666
sun_ball: ItemType = (eInventoryType.Item, 25014)
6767
dark_ball: ItemType = (eInventoryType.Item, 25015)
68+
ex_rainbow_enhance_pt: ItemType = (eInventoryType.Item, 26202)
6869

6970
def update(self, dbmgr):
7071
self.dbmgr = dbmgr
@@ -931,6 +932,7 @@ def inventory_name(self) -> Dict[ItemType, str]:
931932
ret[(eInventoryType.TeamExp, 92001)] = "经验"
932933
ret[(eInventoryType.Jewel, 91002)] = "宝石"
933934
ret[(eInventoryType.Gold, 94002)] = "mana"
935+
ret[(eInventoryType.Gold, 94000)] = "mana"
934936
ret[(eInventoryType.SeasonPassPoint, 98002)] = "祝福经验值"
935937
ret[(eInventoryType.SeasonPassStamina, 93002)] = "星尘体力药剂"
936938
return ret
@@ -1263,6 +1265,14 @@ def hatsune_item(self) -> Dict[int, HatsuneItem]:
12631265
.to_dict(lambda x: x.event_id, lambda x: x)
12641266
)
12651267

1268+
@lazy_property
1269+
def abd_story_data(self) -> Dict[int, AbdStoryDatum]:
1270+
with self.dbmgr.session() as db:
1271+
return (
1272+
AbdStoryDatum.query(db)
1273+
.to_dict(lambda x: x.sub_story_id, lambda x: x)
1274+
)
1275+
12661276
@lazy_property
12671277
def lss_story_data(self) -> Dict[int, LssStoryDatum]:
12681278
with self.dbmgr.session() as db:
@@ -1471,6 +1481,25 @@ def ex_equipment_data(self) -> Dict[int, ExEquipmentDatum]:
14711481
.to_dict(lambda x: x.ex_equipment_id, lambda x: x)
14721482
)
14731483

1484+
@lazy_property
1485+
def ex_equipment_sub_status(self) -> Dict[int, Dict[int, ExEquipmentSubStatus]]:
1486+
with self.dbmgr.session() as db:
1487+
return (
1488+
ExEquipmentSubStatus.query(db)
1489+
.group_by(lambda x: x.group_id)
1490+
.to_dict(lambda x: x.key, lambda x: x.to_dict(
1491+
lambda x: x.status, lambda x: x
1492+
))
1493+
)
1494+
1495+
@lazy_property
1496+
def ex_equipment_sub_status_group(self) -> Dict[int, ExEquipmentSubStatusGroup]:
1497+
with self.dbmgr.session() as db:
1498+
return (
1499+
ExEquipmentSubStatusGroup.query(db)
1500+
.to_dict(lambda x: x.ex_equipment_id, lambda x: x)
1501+
)
1502+
14741503
@lazy_property
14751504
def ex_equipment_rankup_data(self) -> Dict[int, Dict[int, ExEquipmentRankupDatum]]:
14761505
with self.dbmgr.session() as db:
@@ -1570,6 +1599,8 @@ def quest_name(self) -> Dict[int, str]:
15701599
.concat(ShioriQuest.query(db))
15711600
.concat(TrainingQuestDatum.query(db))
15721601
.concat(TalentQuestDatum.query(db))
1602+
.concat(MirageNemesisQuestDisplay.query(db))
1603+
.concat(MirageFloorQuestDisplay.query(db))
15731604
.to_dict(lambda x: x.quest_id, lambda x: x.quest_name)
15741605
)
15751606
ret.update(
@@ -1593,7 +1624,8 @@ def shop_static_price_group(self) -> Dict[int, List[ShopStaticPriceGroup]]:
15931624
1: '铜',
15941625
2: '银',
15951626
3: '金',
1596-
4: '粉'
1627+
4: '粉',
1628+
5: '彩'
15971629
}
15981630

15991631
@lazy_property
@@ -1686,6 +1718,61 @@ def experience_talent_level(self) -> Dict[int, ExperienceTalentLevel]:
16861718
.to_dict(lambda x: x.talent_level, lambda x: x)
16871719
)
16881720

1721+
@lazy_property
1722+
def mirage_setting(self) -> Dict[int, MirageSetting]:
1723+
with self.dbmgr.session() as db:
1724+
return (
1725+
MirageSetting.query(db)
1726+
.to_dict(lambda x: x.id, lambda x: x)
1727+
)
1728+
1729+
@lazy_property
1730+
def mirage_nemesis_quest(self) -> Dict[int, Dict[int, MirageNemesisQuest]]:
1731+
with self.dbmgr.session() as db:
1732+
return (
1733+
MirageNemesisQuest.query(db)
1734+
.group_by(lambda x: x.nemesis_id)
1735+
.to_dict(lambda x: x.key, lambda x: x.to_dict(
1736+
lambda x: x.area_level, lambda x: x
1737+
))
1738+
)
1739+
1740+
@lazy_property
1741+
def mirage_floor_setting(self) -> Dict[int, MirageFloorSetting]:
1742+
with self.dbmgr.session() as db:
1743+
return (
1744+
MirageFloorSetting.query(db)
1745+
.to_dict(lambda x: x.floor_num, lambda x: x)
1746+
)
1747+
1748+
@lazy_property
1749+
def mirage_nemesis_area(self) -> Dict[int, MirageNemesisArea]:
1750+
with self.dbmgr.session() as db:
1751+
return (
1752+
MirageNemesisArea.query(db)
1753+
.to_dict(lambda x: x.nemesis_id, lambda x: x)
1754+
)
1755+
1756+
@lazy_property
1757+
def alces_story(self) -> Dict[int, AlcesStory]:
1758+
with self.dbmgr.session() as db:
1759+
return (
1760+
AlcesStory.query(db)
1761+
.to_dict(lambda x: x.story_id, lambda x: x)
1762+
)
1763+
1764+
@lazy_property
1765+
def alces_cost(self) -> Dict[ItemType, AlcesCost]:
1766+
with self.dbmgr.session() as db:
1767+
return (
1768+
AlcesCost.query(db)
1769+
.to_dict(lambda x: (x.type, x.item_id), lambda x: x)
1770+
)
1771+
1772+
def get_mirage_setting(self) -> MirageSetting:
1773+
max_id = max(self.mirage_setting.keys(), default=1)
1774+
return self.mirage_setting[max_id]
1775+
16891776
def get_ex_equip_star_from_pt(self, id: int, pt: int) -> int:
16901777
rarity = self.get_ex_equip_rarity(id)
16911778
star = max([star for star, enhancement_data in self.ex_equipment_enhance_data[rarity].items() if enhancement_data.total_point <= pt], default=0)
@@ -1717,6 +1804,31 @@ def get_ex_equip_max_rank(self, id: int) -> int:
17171804
def get_ex_equip_rarity_name(self, id: int) -> str:
17181805
return self.ex_rarity_name[self.get_ex_equip_rarity(id)]
17191806

1807+
def get_ex_equip_sub_status(self, ex_equip_id: int, sub_status: List[ExtraEquipSubStatus]) -> Dict[int, int]:
1808+
data = Counter()
1809+
group = self.ex_equipment_sub_status_group[ex_equip_id]
1810+
sub_status_data = self.ex_equipment_sub_status[group.group_id]
1811+
for status in sub_status or []:
1812+
data[status.status] += sub_status_data[status.status].step_value(status.step)
1813+
return data
1814+
1815+
def get_ex_equip_sub_status_str(self, ex_equip_id: int, sub_status: List[ExtraEquipSubStatus]) -> str:
1816+
data = self.get_ex_equip_sub_status(ex_equip_id, sub_status)
1817+
msg = []
1818+
for param, count in sorted(data.items()):
1819+
en_name = UnitAttribute.index2name.get(eParamType(param), f"unknown_param_{param}")
1820+
name = UnitAttribute.index2ch.get(eParamType(param), f"未知属性{param}")
1821+
is_present = UnitAttribute.is_present.get(en_name, False)
1822+
if is_present:
1823+
count /= 100
1824+
msg.append(f"{name}x{count:.2f}%")
1825+
else:
1826+
msg.append(f"{name}x{count}")
1827+
1828+
if not msg:
1829+
return '空'
1830+
return '/'.join(msg)
1831+
17201832
def get_ex_equip_rankup_cost(self, id: int, start_rank: int, end_rank: int) -> int:
17211833
rarity = self.get_ex_equip_rarity(id)
17221834
if rarity not in self.ex_equipment_rankup_data:
@@ -2426,6 +2538,14 @@ def calc_unit_attribute(self, unit_data: UnitData, read_story: Set[int], ex_equi
24262538
ex_equip_data = ex_equips[ex_equip.serial_id]
24272539
star = self.get_ex_equip_star_from_pt(ex_equip_data.ex_equipment_id, ex_equip_data.enhancement_pt)
24282540
attr = self.ex_equipment_data[ex_equip_data.ex_equipment_id].get_unit_attribute(star)
2541+
if ex_equip_data.sub_status:
2542+
group = self.ex_equipment_sub_status_group[ex_equip_data.ex_equipment_id]
2543+
sub_status_data = db.ex_equipment_sub_status[group.group_id]
2544+
for status in ex_equip_data.sub_status:
2545+
value = sub_status_data[status.status].step_value(status.step)
2546+
a = UnitAttribute()
2547+
a.set_value(status.status, value)
2548+
attr += a
24292549
bonus = unit_attribute.ex_equipment_mul(attr).ceil()
24302550
ex_attribute += bonus
24312551
unit_attribute += ex_attribute
@@ -2491,5 +2611,9 @@ def free_gacha_ids_candidate(self):
24912611
free_gacha_campaign = min(free_gacha_campaigns)
24922612
return [gacha.gacha_id for gacha in self.campaign_free_gacha_data[free_gacha_campaign]]
24932613

2614+
def ex_equip_sub_status_candidate(self) -> List[int]:
2615+
ids = list(set(j.status for i in self.ex_equipment_sub_status.values() for j in i.values()))
2616+
ids.append(0)
2617+
return sorted(ids)
24942618

24952619
db = database()

autopcr/db/methods.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ def get_unit_attribute(self, level: int) -> UnitAttribute:
4141
min_val = UnitAttribute.load(self, pre='default_')
4242
max_val = UnitAttribute.load(self, pre='max_')
4343
max_rank = db.get_ex_equip_max_rank(self.ex_equipment_id)
44-
return min_val + (max_val - min_val) * (level / db.get_ex_equip_max_star(self.ex_equipment_id, max_rank))
44+
max_star = db.get_ex_equip_max_star(self.ex_equipment_id, max_rank)
45+
return (min_val + (max_val - min_val) * (level / max_star)) if max_star > 0 else min_val
4546

4647
@method
4748
class EquipmentDatum(models.EquipmentDatum):
@@ -241,3 +242,7 @@ def get_another_parts(self):
241242
if self.another_parts_id_4 != 0:
242243
yield self.another_parts_id_4
243244

245+
@method
246+
class ExEquipmentSubStatus(models.ExEquipmentSubStatus):
247+
def step_value(self, step: int) -> int:
248+
return getattr(self, f"value_{step}")

autopcr/model/custom.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,26 @@ class UnitAttribute:
3232
energy_reduce_rate: Decimal = Decimal(0)
3333
accuracy: Decimal = Decimal(0)
3434

35+
index2ch = {
36+
eParamType.HP: "血量",
37+
eParamType.ATK: "物攻",
38+
eParamType.MAGIC_ATK: "魔攻",
39+
eParamType.DEF: "物防",
40+
eParamType.MAGIC_DEF: "魔防",
41+
eParamType.PHYSICAL_CRITICAL: "物爆",
42+
eParamType.MAGIC_CRITICAL: "法爆",
43+
eParamType.WAVE_HP_RECOVERY: "wave_hp_recovery",
44+
eParamType.WAVE_ENERGY_RECOVERY: "wave_energy_recovery",
45+
eParamType.DODGE: "闪避",
46+
eParamType.PHYSICAL_PENETRATE: "物贯",
47+
eParamType.MAGIC_PENETRATE: "法贯",
48+
eParamType.LIFE_STEAL: "吸血",
49+
eParamType.HP_RECOVERY_RATE: "hp_recovery_rate",
50+
eParamType.ENERGY_RECOVERY_RATE: "物爆提升",
51+
eParamType.ENERGY_REDUCE_RATE: "法爆提升",
52+
eParamType.ACCURACY: "命中"
53+
}
54+
3555
index2name = {
3656
eParamType.HP: "hp",
3757
eParamType.ATK: "atk",

0 commit comments

Comments
 (0)