Opt: Enter dungeon from map if possible

This commit is contained in:
LmeSzinc 2023-11-02 18:56:20 +08:00
parent 881389efce
commit e5c02fd381
6 changed files with 91 additions and 24 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -13,6 +13,16 @@ DUNGEON_COMBAT_INTERACT = ButtonWrapper(
button=(750, 411, 997, 448),
),
)
DUNGEON_COMBAT_INTERACT_TEXT = ButtonWrapper(
name='DUNGEON_COMBAT_INTERACT_TEXT',
share=Button(
file='./assets/share/combat/interact/DUNGEON_COMBAT_INTERACT_TEXT.png',
area=(790, 391, 1055, 456),
search=(770, 371, 1075, 476),
color=(47, 51, 53),
button=(790, 391, 1055, 456),
),
)
MAP_LOADING = ButtonWrapper(
name='MAP_LOADING',
share=Button(

View File

@ -65,27 +65,6 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
return False
def combat_enter_from_map(self, skip_first_screenshot=True):
"""
Pages:
in: page_main, DUNGEON_COMBAT_INTERACT
out: COMBAT_PREPARE
"""
logger.info('Combat enter from map')
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(COMBAT_PREPARE):
# Confirm page loaded
if self.image_color_count(COMBAT_PREPARE.button, color=(230, 230, 230), threshold=240, count=400):
logger.info(f'At {COMBAT_PREPARE}')
break
if self.handle_combat_interact():
continue
def combat_prepare(self, team=1, support_character: str = None):
"""
Args:

View File

@ -1,6 +1,8 @@
from module.base.utils import color_similar, get_color
from module.logger import logger
from tasks.base.ui import UI
from tasks.combat.assets.assets_combat_interact import DUNGEON_COMBAT_INTERACT, MAP_LOADING
from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
from tasks.map.assets.assets_map_control import A_BUTTON
@ -15,6 +17,27 @@ class CombatInteract(UI):
return False
def combat_enter_from_map(self, skip_first_screenshot=True):
"""
Pages:
in: page_main, DUNGEON_COMBAT_INTERACT
out: COMBAT_PREPARE
"""
logger.info('Combat enter from map')
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(COMBAT_PREPARE):
# Confirm page loaded
if self.image_color_count(COMBAT_PREPARE.button, color=(230, 230, 230), threshold=240, count=400):
logger.info(f'At {COMBAT_PREPARE}')
break
if self.handle_combat_interact():
continue
def is_map_loading(self):
if self.appear(MAP_LOADING, similarity=0.75):
return True

View File

@ -45,6 +45,10 @@ class Dungeon(DungeonUI, DungeonEvent, Combat):
logger.info(f'Dungeon: {dungeon}, team={team}, wave_limit={wave_limit}, support_character={support_character}')
if not skip_ui_switch:
interact = self.get_dungeon_interact()
if interact is not None and interact == dungeon:
logger.info('Already nearby dungeon')
else:
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
self.dungeon_goto(dungeon)

View File

@ -6,19 +6,23 @@ from module.base.base import ModuleBase
from module.base.button import ClickButton
from module.base.timer import Timer
from module.base.utils import get_color
from module.exception import ScriptError
from module.logger import logger
from module.ocr.ocr import Ocr, OcrResultButton
from module.ocr.utils import split_and_pair_button_attr
from module.ui.draggable_list import DraggableList
from module.ui.switch import Switch
from tasks.base.page import page_guide
from tasks.combat.assets.assets_combat_interact import DUNGEON_COMBAT_INTERACT, DUNGEON_COMBAT_INTERACT_TEXT
from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
from tasks.combat.interact import CombatInteract
from tasks.dungeon.assets.assets_dungeon_ui import *
from tasks.dungeon.keywords import (
DungeonList,
DungeonNav,
DungeonTab,
KEYWORDS_DUNGEON_ENTRANCE,
KEYWORDS_DUNGEON_LIST,
KEYWORDS_DUNGEON_NAV,
KEYWORDS_DUNGEON_TAB
)
@ -116,7 +120,7 @@ DUNGEON_LIST = DraggableDungeonList(
ocr_class=OcrDungeonList, search_button=OCR_DUNGEON_LIST)
class DungeonUI(DungeonState):
class DungeonUI(DungeonState, CombatInteract):
def dungeon_tab_goto(self, state: DungeonTab):
"""
Args:
@ -372,6 +376,53 @@ class DungeonUI(DungeonState):
logger.warning(f'Cannot find dungeon entrance of {dungeon}')
continue
def get_dungeon_interact(self) -> DungeonList | None:
"""
Pages:
in: page_main
"""
if not self.appear(DUNGEON_COMBAT_INTERACT):
logger.info('No dungeon interact')
return None
ocr = OcrDungeonList(DUNGEON_COMBAT_INTERACT_TEXT)
result = ocr.detect_and_ocr(self.device.image)
result = ' '.join([row.ocr_text for row in result])
# Calyx (Crimson): Bud of XXX -> Bud of XXX
result = re.sub(r'Calyx\s*\(.*?\):*', '', result)
# Stagnant Shadow: Shap XXX -> Shape of XXX
result = re.sub(r'Stagnant\s*Shadow[:\s]*\w*', 'Shape of', result)
# Cavern of Corrosion: Pa XXX -> Path of XXX
result = re.sub(r'Cavern\s*of\s*Corrosion[:\s]*\w*', 'Path of', result)
# Echo of War: XXX -> XXX
result = re.sub(r'Echo\s*of\s*War:*', '', result)
# Divine See -> Divine Seed
result = re.sub(r'Divine\s*\w*', 'Divine Seed', result)
# Destructio Beginning -> Destruction's Beginning
result = re.sub(r"Destruct[a-zA-Z0-9_']*", "Destruction's", result)
# Dungeons
try:
dungeon = DungeonList.find(result)
logger.attr('DungeonInteract', dungeon)
return dungeon
except ScriptError:
pass
# Simulated Universe returns Simulated_Universe_World_1
try:
dungeon = DungeonNav.find(result)
if dungeon == KEYWORDS_DUNGEON_NAV.Simulated_Universe:
dungeon = KEYWORDS_DUNGEON_LIST.Simulated_Universe_World_1
logger.attr('DungeonInteract', dungeon)
return dungeon
except ScriptError:
pass
# Unknown
logger.attr('DungeonInteract', None)
return None
def dungeon_goto(self, dungeon: DungeonList):
"""
Returns: