mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-15 22:19:18 +00:00
commit
ca7202d075
BIN
assets/share/item/synthesize/SYNTHESIZE_INSUFFICIENT.png
Normal file
BIN
assets/share/item/synthesize/SYNTHESIZE_INSUFFICIENT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -123,6 +123,18 @@ def has_cached_property(obj, name):
|
||||
return name in obj.__dict__
|
||||
|
||||
|
||||
def set_cached_property(obj, name, value):
|
||||
"""
|
||||
Set a cached property.
|
||||
|
||||
Args:
|
||||
obj:
|
||||
name (str):
|
||||
value:
|
||||
"""
|
||||
obj.__dict__[name] = value
|
||||
|
||||
|
||||
def function_drop(rate=0.5, default=None):
|
||||
"""
|
||||
Drop function calls to simulate random emulator stuck, for testing purpose.
|
||||
|
@ -1016,7 +1016,24 @@ class Connection(ConnectionAttr):
|
||||
# Set server
|
||||
# logger.info('Server changed, release resources')
|
||||
# set_server(self.package)
|
||||
return
|
||||
else:
|
||||
if self.config.is_cloud_game:
|
||||
packages = [p for p in packages if p in server_.VALID_CLOUD_PACKAGE]
|
||||
if len(packages) == 1:
|
||||
logger.info('Auto package detection found only one package, using it')
|
||||
self.package = packages[0]
|
||||
if set_config:
|
||||
self.config.Emulator_PackageName = server_.to_server(self.package)
|
||||
return
|
||||
else:
|
||||
packages = [p for p in packages if p in server_.VALID_PACKAGE]
|
||||
if len(packages) == 1:
|
||||
logger.info('Auto package detection found only one package, using it')
|
||||
self.package = packages[0]
|
||||
if set_config:
|
||||
self.config.Emulator_PackageName = server_.to_server(self.package)
|
||||
return
|
||||
logger.critical(
|
||||
f'Multiple Star Rail packages found, auto package detection cannot decide which to choose, '
|
||||
'please copy one of the available devices listed above to Alas.Emulator.PackageName')
|
||||
|
@ -413,10 +413,16 @@ def put_arg_planner(kwargs: T_Output_Kwargs) -> Output | None:
|
||||
if isinstance(total, dict):
|
||||
total = tuple(total.values())
|
||||
|
||||
if eta:
|
||||
row = put_scope(f"arg_stored-stored-value-{name}", [
|
||||
put_text(f"{progress:.2f}%{eta}").style("--dashboard-bold--"),
|
||||
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
||||
])
|
||||
else:
|
||||
row = put_scope(f"arg_stored-stored-value-{name}", [
|
||||
put_text(f"{progress:.2f}%").style("--dashboard-value--"),
|
||||
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
||||
])
|
||||
|
||||
return put_scope(
|
||||
f"arg_container-planner-{name}",
|
||||
|
@ -74,6 +74,11 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
delay = min(self.dispatched.values())
|
||||
logger.info(f'Delay assignment check to {str(delay)}')
|
||||
self.config.task_delay(target=delay)
|
||||
# Align server update
|
||||
update = get_server_next_update(self.config.Scheduler_ServerUpdate)
|
||||
if update - delay < timedelta(hours=4):
|
||||
logger.info('Approaching next day, delay to server update instead')
|
||||
self.config.task_delay(target=update)
|
||||
else:
|
||||
# ValueError: min() arg is an empty sequence
|
||||
logger.error('Empty dispatched list, delay 2 hours instead')
|
||||
|
@ -253,7 +253,13 @@ class CombatObtain(PlannerMixin):
|
||||
ItemAmount: Arrow_of_the_Beast_Hunter, 85
|
||||
"""
|
||||
self.planner.load_obtained_amount(items)
|
||||
with self.config.multi_set():
|
||||
self.planner_write()
|
||||
# Sync to dashboard
|
||||
for item in items:
|
||||
if item.item.name == 'Credit':
|
||||
self.config.stored.Credit.value = item.value
|
||||
|
||||
return items
|
||||
|
||||
def obtained_is_full(self, dungeon: DungeonList | None, wave_done=0, obtain_get=True) -> bool:
|
||||
|
@ -1,3 +1,4 @@
|
||||
from module.base.decorator import set_cached_property
|
||||
from module.base.utils import area_offset
|
||||
from module.logger import logger
|
||||
from tasks.battle_pass.keywords import KEYWORDS_BATTLE_PASS_QUEST
|
||||
@ -191,6 +192,7 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
def run(self):
|
||||
self.config.update_battle_pass_quests()
|
||||
self.config.update_daily_quests()
|
||||
self.check_synthesize()
|
||||
self.called_daily_support = False
|
||||
self.achieved_daily_quest = False
|
||||
self.achieved_weekly_quest = False
|
||||
@ -309,6 +311,7 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
def check_synthesize(self):
|
||||
logger.info('Check synthesize')
|
||||
synthesize = Synthesize(config=self.config, device=self.device, task=self.config.task.command)
|
||||
set_cached_property(synthesize, 'planner', self.planner)
|
||||
if synthesize.synthesize_needed():
|
||||
synthesize.synthesize_planner()
|
||||
|
||||
|
@ -55,6 +55,7 @@ class WeeklyDungeon(Dungeon):
|
||||
planner = self.planner.get_weekly()
|
||||
if planner is not None:
|
||||
dungeon = planner
|
||||
self.is_doing_planner = True
|
||||
logger.attr('DungeonWeekly', dungeon)
|
||||
|
||||
# UI switches
|
||||
@ -81,6 +82,7 @@ class WeeklyDungeon(Dungeon):
|
||||
|
||||
# Combat
|
||||
count = self.dungeon_run(dungeon, wave_limit=min(remain, 3))
|
||||
self.is_doing_planner = False
|
||||
|
||||
logger.attr('achieved_daily_quest', self.achieved_daily_quest)
|
||||
logger.attr('achieved_weekly_quest', self.achieved_weekly_quest)
|
||||
|
@ -63,6 +63,16 @@ SYNTHESIZE_CONFIRM = ButtonWrapper(
|
||||
button=(730, 641, 998, 675),
|
||||
),
|
||||
)
|
||||
SYNTHESIZE_INSUFFICIENT = ButtonWrapper(
|
||||
name='SYNTHESIZE_INSUFFICIENT',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/SYNTHESIZE_INSUFFICIENT.png',
|
||||
area=(510, 564, 1220, 594),
|
||||
search=(490, 544, 1240, 614),
|
||||
color=(177, 102, 95),
|
||||
button=(510, 564, 1220, 594),
|
||||
),
|
||||
)
|
||||
SYNTHESIZE_INVENTORY = ButtonWrapper(
|
||||
name='SYNTHESIZE_INVENTORY',
|
||||
share=Button(
|
||||
|
@ -7,6 +7,7 @@ from tasks.base.page import page_item
|
||||
from tasks.item.assets.assets_item_data import OCR_DATA
|
||||
from tasks.item.keywords import KEYWORDS_ITEM_TAB
|
||||
from tasks.item.ui import ItemUI
|
||||
from tasks.planner.model import PlannerMixin
|
||||
|
||||
|
||||
class DataDigit(Digit):
|
||||
@ -16,7 +17,7 @@ class DataDigit(Digit):
|
||||
return super().after_process(result)
|
||||
|
||||
|
||||
class DataUpdate(ItemUI):
|
||||
class DataUpdate(ItemUI, PlannerMixin):
|
||||
def _get_data(self):
|
||||
"""
|
||||
Page:
|
||||
@ -53,3 +54,9 @@ class DataUpdate(ItemUI):
|
||||
self.config.stored.Credit.value = credit
|
||||
self.config.stored.StallerJade.value = jade
|
||||
self.config.task_delay(server_update=True)
|
||||
# Sync to planner
|
||||
require = self.config.cross_get('Dungeon.Planner.Item_Credit.total', default=0)
|
||||
if require:
|
||||
self.config.cross_set('Dungeon.Planner.Item_Credit.value', credit)
|
||||
self.config.cross_set('Dungeon.Planner.Item_Credit.time', self.config.stored.Credit.time)
|
||||
self.planner_write()
|
||||
|
@ -94,6 +94,12 @@ class InventoryManager:
|
||||
if count == 1:
|
||||
return mids
|
||||
elif count == 2:
|
||||
# Only one row, [173.5 175. ]
|
||||
mid_diff_mean = np.mean(mid_diff_range)
|
||||
diff = max(mids) - min(mids)
|
||||
if diff < mid_diff_mean * 0.3:
|
||||
return np.mean(mids).reshape((1,))
|
||||
# Double rows
|
||||
return mids
|
||||
# print(mids)
|
||||
encourage = self.COINCIDENT_POINT_ENCOURAGE_DISTANCE ** 2
|
||||
@ -179,6 +185,8 @@ class InventoryManager:
|
||||
area = self.inventory.area
|
||||
x_list = np.unique(np.sort(points[:, 0]))
|
||||
y_list = np.unique(np.sort(points[:, 1]))
|
||||
# print(x_list)
|
||||
# print(y_list)
|
||||
x_list = self.mid_cleanse(
|
||||
x_list,
|
||||
mid_diff_range=(self.GRID_DELTA[0] - 3, self.GRID_DELTA[0] + 3),
|
||||
@ -189,6 +197,8 @@ class InventoryManager:
|
||||
mid_diff_range=(self.GRID_DELTA[1] - 3, self.GRID_DELTA[1] + 3),
|
||||
edge_range=(area[1], area[3])
|
||||
)
|
||||
# print(x_list)
|
||||
# print(y_list)
|
||||
|
||||
def is_near_existing(p):
|
||||
diff = np.linalg.norm(points - p, axis=1)
|
||||
|
@ -387,10 +387,14 @@ class Synthesize(CombatObtain, ItemUI):
|
||||
out: page_synthesize, SYNTHESIZE_CONFIRM
|
||||
"""
|
||||
logger.hr('Synthesize confirm')
|
||||
self.interval_clear([SYNTHESIZE_CONFIRM, page_synthesize.check_button])
|
||||
|
||||
def appear_confirm():
|
||||
return self.image_color_count(SYNTHESIZE_CONFIRM, color=(226, 229, 232), threshold=221, count=1000)
|
||||
|
||||
def appear_insufficient():
|
||||
return self.image_color_count(SYNTHESIZE_INSUFFICIENT, color=(172, 95, 87), threshold=221, count=5000)
|
||||
|
||||
# SYNTHESIZE_CONFIRM -> reward_appear
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
@ -404,6 +408,7 @@ class Synthesize(CombatObtain, ItemUI):
|
||||
break
|
||||
# Click
|
||||
if self.handle_popup_confirm():
|
||||
self.interval_reset(page_synthesize.check_button)
|
||||
continue
|
||||
if appear_confirm() and self.ui_page_appear(page_synthesize, interval=2):
|
||||
self.device.click(SYNTHESIZE_CONFIRM)
|
||||
@ -421,10 +426,15 @@ class Synthesize(CombatObtain, ItemUI):
|
||||
if appear_confirm():
|
||||
logger.info('Synthesize end')
|
||||
break
|
||||
if appear_insufficient():
|
||||
logger.info('Synthesize end, item insufficient')
|
||||
break
|
||||
# Click
|
||||
if self.handle_reward(click_button=SYNTHESIZE_MINUS):
|
||||
continue
|
||||
|
||||
self.interval_clear([SYNTHESIZE_CONFIRM, page_synthesize.check_button])
|
||||
|
||||
def synthesize_exit(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Pages:
|
||||
|
@ -652,6 +652,15 @@ class PlannerMixin(UI):
|
||||
if add:
|
||||
planner.add_planner_result(self.planner)
|
||||
|
||||
# Load from dashboard
|
||||
try:
|
||||
row = planner.rows['Credit']
|
||||
value = self.config.stored.Credit.value
|
||||
if value:
|
||||
row.value = value
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
self.planner_write(planner)
|
||||
|
||||
@cached_property
|
||||
|
Loading…
Reference in New Issue
Block a user