mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-25 18:05:26 +00:00
commit
2c2e77063c
@ -396,8 +396,8 @@ def put_arg_planner(kwargs: T_Output_Kwargs) -> Output | None:
|
|||||||
|
|
||||||
values = kwargs.pop("value", {})
|
values = kwargs.pop("value", {})
|
||||||
try:
|
try:
|
||||||
progress = values["progress"]
|
progress = float(values["progress"])
|
||||||
except KeyError:
|
except (KeyError, ValueError):
|
||||||
# Hide items not needed by the planner
|
# Hide items not needed by the planner
|
||||||
return None
|
return None
|
||||||
eta = values.get("eta", 0)
|
eta = values.get("eta", 0)
|
||||||
@ -413,7 +413,7 @@ def put_arg_planner(kwargs: T_Output_Kwargs) -> Output | None:
|
|||||||
if isinstance(total, dict):
|
if isinstance(total, dict):
|
||||||
total = tuple(total.values())
|
total = tuple(total.values())
|
||||||
|
|
||||||
if eta:
|
if progress < 100:
|
||||||
row = put_scope(f"arg_stored-stored-value-{name}", [
|
row = put_scope(f"arg_stored-stored-value-{name}", [
|
||||||
put_text(f"{progress:.2f}%{eta}").style("--dashboard-bold--"),
|
put_text(f"{progress:.2f}%{eta}").style("--dashboard-bold--"),
|
||||||
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
||||||
|
@ -49,7 +49,7 @@ class Slider:
|
|||||||
total = area[2] - area[0]
|
total = area[2] - area[0]
|
||||||
|
|
||||||
parameters = {
|
parameters = {
|
||||||
'prominence': 15,
|
'prominence': 10,
|
||||||
'wlen': wlen,
|
'wlen': wlen,
|
||||||
'width': 2,
|
'width': 2,
|
||||||
'distance': wlen / 2,
|
'distance': wlen / 2,
|
||||||
@ -58,6 +58,7 @@ class Slider:
|
|||||||
peaks, _ = signal.find_peaks(image, **parameters)
|
peaks, _ = signal.find_peaks(image, **parameters)
|
||||||
peaks //= wlen
|
peaks //= wlen
|
||||||
diff = np.diff(peaks)
|
diff = np.diff(peaks)
|
||||||
|
# print(diff)
|
||||||
|
|
||||||
# Mask controller
|
# Mask controller
|
||||||
# Controller has orange border (240, 150, 57) and white center
|
# Controller has orange border (240, 150, 57) and white center
|
||||||
|
@ -17,7 +17,7 @@ from tasks.item.slider import Slider
|
|||||||
from tasks.item.ui import ItemUI
|
from tasks.item.ui import ItemUI
|
||||||
from tasks.planner.keywords import ITEM_CLASSES, ItemCalyx, ItemTrace
|
from tasks.planner.keywords import ITEM_CLASSES, ItemCalyx, ItemTrace
|
||||||
from tasks.planner.keywords.classes import ItemBase
|
from tasks.planner.keywords.classes import ItemBase
|
||||||
from tasks.planner.model import ObtainedAmmount
|
from tasks.planner.model import ObtainedAmmount, StoredPlannerProxy
|
||||||
from tasks.planner.scan import OcrItemName
|
from tasks.planner.scan import OcrItemName
|
||||||
|
|
||||||
RARITY_COLOR = {
|
RARITY_COLOR = {
|
||||||
@ -37,7 +37,7 @@ def image_color_count(image, color, threshold=221):
|
|||||||
class WhiteStrip(Ocr):
|
class WhiteStrip(Ocr):
|
||||||
def pre_process(self, image):
|
def pre_process(self, image):
|
||||||
mask = color_similarity_2d(image, color=(255, 255, 255))
|
mask = color_similarity_2d(image, color=(255, 255, 255))
|
||||||
mask = cv2.inRange(mask, 180, 255, dst=mask)
|
mask = cv2.inRange(mask, 160, 255, dst=mask)
|
||||||
|
|
||||||
mask = np.mean(mask, axis=0)
|
mask = np.mean(mask, axis=0)
|
||||||
point = np.array(cv2.findNonZero(mask))[:, 0, 1]
|
point = np.array(cv2.findNonZero(mask))[:, 0, 1]
|
||||||
@ -52,6 +52,13 @@ class SynthesizeItemName(OcrItemName, WhiteStrip):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SynthesizeItemAmount(Digit, WhiteStrip):
|
||||||
|
def pre_process(self, image):
|
||||||
|
image = super().pre_process(image)
|
||||||
|
image = cv2.subtract((255, 255, 255, 0), image)
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
class SynthesizeInventoryManager(InventoryManager):
|
class SynthesizeInventoryManager(InventoryManager):
|
||||||
@cached_property
|
@cached_property
|
||||||
def dic_item_index(self):
|
def dic_item_index(self):
|
||||||
@ -174,26 +181,41 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
|
|
||||||
return switched
|
return switched
|
||||||
|
|
||||||
def synthesize_rarity_reset(self, skip_first_screenshot=True):
|
def synthesize_rarity_reset(self, inv=None, skip_first_screenshot=True):
|
||||||
"""
|
"""
|
||||||
Reset rarity switch, so current item will pin on the first row
|
Reset rarity switch, so current item will pin on the first row
|
||||||
|
|
||||||
|
Args:
|
||||||
|
inv: InventoryManager object if wait until item selected
|
||||||
|
skip_first_screenshot:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: If success
|
bool: If success
|
||||||
"""
|
"""
|
||||||
logger.hr('synthesize rarity reset')
|
for _ in range(3):
|
||||||
current = self.item_get_rarity_retry(ENTRY_ITEM_FROM)
|
logger.hr('synthesize rarity reset')
|
||||||
if current == 'blue':
|
current = self.item_get_rarity_retry(ENTRY_ITEM_FROM)
|
||||||
r1, r2 = 'green', 'blue'
|
if current == 'blue':
|
||||||
elif current == 'green':
|
r1, r2 = 'green', 'blue'
|
||||||
r1, r2 = 'blue', 'green'
|
elif current == 'green':
|
||||||
else:
|
r1, r2 = 'blue', 'green'
|
||||||
logger.error(f'item_synthesize_rarity_reset: Unknown current rarity {current}')
|
else:
|
||||||
return False
|
logger.error(f'item_synthesize_rarity_reset: Unknown current rarity {current}')
|
||||||
|
return False
|
||||||
|
|
||||||
self.synthesize_rarity_set(r1, skip_first_screenshot=skip_first_screenshot)
|
self.synthesize_rarity_set(r1, skip_first_screenshot=skip_first_screenshot)
|
||||||
self.synthesize_rarity_set(r2, skip_first_screenshot=True)
|
self.synthesize_rarity_set(r2, skip_first_screenshot=True)
|
||||||
return True
|
if inv is not None:
|
||||||
|
if inv.wait_selected():
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
logger.info('synthesize_rarity_reset ended without wait_selected()')
|
||||||
|
return True
|
||||||
|
|
||||||
|
logger.error('synthesize_rarity_reset failed 3 times')
|
||||||
|
return False
|
||||||
|
|
||||||
def synthesize_obtain_get(self) -> list[ObtainedAmmount]:
|
def synthesize_obtain_get(self) -> list[ObtainedAmmount]:
|
||||||
"""
|
"""
|
||||||
@ -301,7 +323,6 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
if inv.selected.loca[1] >= 3:
|
if inv.selected.loca[1] >= 3:
|
||||||
logger.info('Reached inventory view end, reset view')
|
logger.info('Reached inventory view end, reset view')
|
||||||
self.synthesize_rarity_reset()
|
self.synthesize_rarity_reset()
|
||||||
inv.wait_selected()
|
|
||||||
logger.hr('Synthesize select view', level=2)
|
logger.hr('Synthesize select view', level=2)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@ -345,7 +366,7 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
logger.hr('Synthesize amount set', level=2)
|
logger.hr('Synthesize amount set', level=2)
|
||||||
slider = Slider(main=self, slider=SYNTHESIZE_SLIDER)
|
slider = Slider(main=self, slider=SYNTHESIZE_SLIDER)
|
||||||
slider.set(value, total)
|
slider.set(value, total)
|
||||||
ocr = Digit(SYNTHESIZE_AMOUNT, lang=server.lang)
|
ocr = SynthesizeItemAmount(SYNTHESIZE_AMOUNT, lang=server.lang)
|
||||||
self.ui_ensure_index(
|
self.ui_ensure_index(
|
||||||
value, letter=ocr, next_button=SYNTHESIZE_PLUS, prev_button=SYNTHESIZE_MINUS, interval=(0.1, 0.2))
|
value, letter=ocr, next_button=SYNTHESIZE_PLUS, prev_button=SYNTHESIZE_MINUS, interval=(0.1, 0.2))
|
||||||
|
|
||||||
@ -475,6 +496,40 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
logger.info('No items need to synthesize')
|
logger.info('No items need to synthesize')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def synthesize_planner_row_select(self, row: StoredPlannerProxy):
|
||||||
|
"""
|
||||||
|
Select an item in synthesize inventory and update obtained amount to planner
|
||||||
|
|
||||||
|
Args:
|
||||||
|
row:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if success
|
||||||
|
"""
|
||||||
|
for _ in range(3):
|
||||||
|
logger.hr('Synthesize planner row', level=1)
|
||||||
|
self.synthesize_tab_set(KEYWORDS_ITEM_TAB.UpgradeMaterials, reset=True)
|
||||||
|
self.synthesize_inventory_select(row.item)
|
||||||
|
|
||||||
|
# Update obtain amount
|
||||||
|
obtained = self.synthesize_obtain_get()
|
||||||
|
self.planner.load_obtained_amount(obtained)
|
||||||
|
if not row.need_synthesize():
|
||||||
|
logger.warning('Planner row do not need to synthesize')
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check current item again
|
||||||
|
current = self.synthesize_get_item()
|
||||||
|
if current.item_group == row.item.item_group:
|
||||||
|
logger.info('Selected at target item')
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.warning(f'Item changed after getting obtain, expected: {row.item}, current: {current}')
|
||||||
|
continue
|
||||||
|
|
||||||
|
logger.error('synthesize_planner_row_select failed 3 times')
|
||||||
|
return False
|
||||||
|
|
||||||
def synthesize_planner(self):
|
def synthesize_planner(self):
|
||||||
"""
|
"""
|
||||||
Synthesize items in planner
|
Synthesize items in planner
|
||||||
@ -490,15 +545,8 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
if not row.need_synthesize():
|
if not row.need_synthesize():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logger.hr('Synthesize planner row', level=1)
|
success = self.synthesize_planner_row_select(row)
|
||||||
self.synthesize_tab_set(KEYWORDS_ITEM_TAB.UpgradeMaterials, reset=True)
|
if not success:
|
||||||
self.synthesize_inventory_select(row.item)
|
|
||||||
|
|
||||||
# Update obtain amount
|
|
||||||
obtained = self.synthesize_obtain_get()
|
|
||||||
self.planner.load_obtained_amount(obtained)
|
|
||||||
if not row.need_synthesize():
|
|
||||||
logger.warning('Planner row do not need to synthesize')
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logger.info(f'Synthesize row: {row}')
|
logger.info(f'Synthesize row: {row}')
|
||||||
|
@ -297,6 +297,8 @@ class StoredPlannerProxy(BaseModelWithFallback):
|
|||||||
return 0.
|
return 0.
|
||||||
if self.item.dungeon is None:
|
if self.item.dungeon is None:
|
||||||
return 0.
|
return 0.
|
||||||
|
if self.item.is_ItemWeekly:
|
||||||
|
return 0.
|
||||||
|
|
||||||
remain = self.progress_remain
|
remain = self.progress_remain
|
||||||
cost = self.combat_cost
|
cost = self.combat_cost
|
||||||
@ -686,7 +688,9 @@ class PlannerMixin(UI):
|
|||||||
with self.config.multi_set():
|
with self.config.multi_set():
|
||||||
# Set value
|
# Set value
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
self.config.cross_set(f'Dungeon.Planner.{key}', value)
|
current = self.config.cross_get(f'Dungeon.Planner.{key}', default={})
|
||||||
|
if value != current:
|
||||||
|
self.config.cross_set(f'Dungeon.Planner.{key}', value)
|
||||||
# Remove other value
|
# Remove other value
|
||||||
remove = []
|
remove = []
|
||||||
for key, value in self.config.cross_get('Dungeon.Planner', default={}).items():
|
for key, value in self.config.cross_get('Dungeon.Planner', default={}).items():
|
||||||
|
Loading…
Reference in New Issue
Block a user